Why can’t we just get along??

31 01 2009

Weekend is here and I’m going away. Still I spent an hour or two tonight and move code around, which, if you’re into game programming, you know that you will do often. Suddenly you just realize that the code should be somewhere else, in another class, called another thing. Hopefully it will lead to a somewhat cleaner and more logical code. Sometimes it doesn’t :(

There are a some things with PV3D that I really don’t understand why they did like they did. Take size as an example. This is the first time ever (EVER) I stumbled apon a 3dobject that cannot tell me how big it is. It moves around in a 3dspace uses exact coordinates to travel. Still there is no sign of the object knowing what height it has or how wide it is??? There is this bounding box parameter inside the geometry param so it wouldn’t be that hard to implement a recursive check for size both before and after transform. Am I missing something? Why dont I extend the DO3D then and put the functions in there myself? Well, as the whole PV3D is built on DO3D it will not use my extended class so it’s no use.

“So why don’t you just hack the original class then. Just put the features in there?” Well I actually did, and removed it , and did it again and finally removed it  because I know that PV3D is always under development. I am a news freak and always want the latest build and it would be a drag just to update the library manually, putting in my beloved code, each time I update PV3D. Also I wouldn’t be able to write this kind of blog as I cannot expect every single reader out there to hack their basic library classes just to get my examples in here to work.

No, I’m satisfied with just cursing.  :)

So? What’s the deal with layers anyway?? I promised to show you and as I’m leaving in a few minutes, this is an excellent time to bring up that subject.

To be able to draw 3D objects correctly on the screen, the renderer always draws the thing that is furthest away from the camera first. That is logical because if then something appears in the way that is closer to the camera it should overwrite the object far away. But there are times that you actually want to force the renderer to draw the objects in another order thatn it’s default behaviour. This is where layers come in.

In the case of this game, I will use viewportlayers for 2 reasons. 1: the annoying Z-fighting problem and 2: Visual effects.

The Z-problem is a little thingie that has been haunting the 3D world since the beginning of time. As I mentioned earlier the renderer automatically renders the furthest objects first. But how does it know that it is furthest away? Well EVERY single triangle in the 3D-world has got a centerpoint (yes right in the center of the 3 vertices drawing the triangle) and the triangle itself then can calculate how far from that centrepoint it is to the camera. It’s a simple question of distance (and math).

But what happenes if the triangle is a big ass giant triangle? Well it is still the center that decides when it will be drawn. Our arena ground in the game is a perfect example!! It is built up with big ass triangles!! So if our car happens to be on a place on the ground where the centrepoint is behind it. The scene wil be drawn as normal BUT if the car (Defender) moves away at places itself in the ground far away it as a very big chance that the centrepoint is now closer to the camera that the Defendertriangles are. Then the renderer will draw the Defender first and then the ground, causin the defender to suddenly disappear (be drawn uderneath the ground).. hmmm damn.

So now layers is our saviour. We kind of “put” all the objects in different layers and then the renderer will render ALL objects in one layer and then continue to the next layer that has a larger layerindex.  Problem solved!

Effects, we’ll take when we get there. You just think about all cool effects you can do with viewportlayers… mmmm…   in front, in back, in front. Amazing huh? no? Tutorial coming up!

Advertisements




Papervision3D – an introduction to the 3D world.

27 01 2009

Ok, lets take a small break from the game creating. I assume you already know about Flash and AS3 but if you haven’t worked with 3D programming before it would be good with some foundational theory.  Let’s start with the dimensions (no, kidding! a third??)

coordinatesystems

As you can see by the figures the 3D coordinate system differs in many aspects. First of all, there is a third axis showing the depth of the image. Imagine the screen as the 2D image a normal FlashMovie can project. Now think of the Z-axis as if you could put in your hand in the screen and push that movie further away or drag it closer to you. The movie would then move on the Z-axis. (I know this is not the whole truth but will you please pretend for a while, ok?)

Now, something is new with the other “normal” ones as well. It seems like the origo (0,0) has moved away from being in the topleft corner to the absolute middle of the screen. Ok, fair enough, so as soon as you want things to move to the left of the screen you will set the X-value negative. The last thing that might be easy to forget for you “Flashers” is that Y-axis is now pointing upwards meaning that negative values are below the 0,0,0 (origo). So whenever you want something to move upwards you increase the Y-axis.

There are many ways to use this 3D space but in my game I will look at the 3Dworld as if Y is the altitude of everything meaning that the flat arena we will create and all the units moving around will mostly be stretching out and move through the X and the Z-axis.

Today I will not dive deeper into 3D and how the models are built up rather then just present the core objects that are needed to even display something in 3D. Lets begin:

Viewport

There is no real 3D. You know that, right? I mean, we’re only simulating a 3D environment but in the end it will be projected on a 2D surface (the screen). The viewport is exactly that. It’s the 2D area where all this simulating will take place. For now, just think of it as a small rectangular MovieClip that you will just add to the displaylist just as normal. It’s what will be within this rectangle that is the cool stuff.

Camera

A camera is nothing else but your eyes in the 3D world. Think of it as an object in this 3D environment I just explained above that could move around in all axis and also rotate around. Wherever it is located, from that angle all objects in the scene will be projected.  The projected image will be visible in the Viewport explained above. (aaaah so the camera is the camera, and the viewport is like the TV showing whats catched be the camera?? … yes)

DisplayObjects3D

Now this is the objects that will be visible in the 3D-world. Damn, you know this already. It’s just like using DisplayObjects in flash. Actually, the PV3D team has worked hard for you to be as comfortable with this new technique giving you almost the same methods to work with 3D as with 2D. Want to add a DisplayObject3D in the scene?  use addChild(). Want to move it to the right?   Increase the X parameter. It’s that simple :)

Also, while we at it. DO3D is very much a container just like it’s cousins DisplayObjectContainers. This means that you can put other DO3D’s into other DO3D’s just like you would add a Sprite into a MovieClip etc. Works like a charm (because charms work, right?)

Light

Now this one is somehow new to some of you 2Dguys. Creating 3D projections is a lot about fooling the eye and mind with small tricks just to come closer to the “real thing” and what we expect to see in a 3D environment. One crucial thing that adds to the illusion of depth is light. If all sides of a green shape were litten equally, the viewer have a really hard time both getting the feeling of 3D-depth and to make out the correct form of that shape. See the image below:

lightsource1

We will work with PointLights (Pointlight3d) that as the word hints is a light placed in a point in the world. This means that you will be able to move that light just as you move objects and cameras around. With a good light you can enhance a 3D-environment to extreme standards!

Now that you are introduced to the basic components of a 3D-world, lets start the engines up and create our first bad ass scene!

First, lets create a FLA. Just create a new AS3 FLA in Flash and set the document class to ‘Main’

Now let’s create our Main.as   class and make it as simple as possible. I’ve always liked to keep the document class as clean as possible and as soon as it gets cluttery I move most of the code into a new class, cleaning Main up again.

package {

	public class Main extends Sprite
	{
		private var view:View3D

		public function Main()
		{
			view = new View3D()
			addChild(view)
		}
	}
}

View3D will be our class with all fancy 3Dstuff. To make it very (VERY) simple I will now extend a class called ‘BasicView’ and turn it into my View3D.as . Basicview’s only purpose is to take one viewport and one camera and put it all in one scene so that you are ready to go immediatly. Let’s have a look at it:

package
{

	import org.papervision3d.lights.PointLight3D;
	import org.papervision3d.view.BasicView;

	public class View3D extends BasicView
	{
		private var light:PointLight3D

		public function View3D()
		{
			super();
			createSomeObjectsOnTheScene()
			this.startRendering()
		}

		public function createSomeObjectsOnTheScene()
		{
			light = new PointLight3D()
			light.x = 1000
			light.y = 5000
			light.z = -6000
			scene.addChild(light)
			var tSphere:Sphere = new Sphere()
			scene.addChild(tSphere)
			}
		}
	}
}

Now let me take you through what just happened. First when View3D is created, I call super() meaning I call the BasicView constructor. BasicView class creates a ‘scene’ and puts a ‘camera’ on that scene. It also places the camera on z:-1000 so that it can view all objects from a fair distance (camera is by default “looking” towards 0,0,0). I then call my own function ‘createSomeObjectsOnTheScene’ where I first create a light and locates it somewhere fairly random. In the end I create the first really visible object and puts it in the displaylist using addChild. As i don’t locate it somewhere it will be placed on 0,0,0 (where camera is looking). taddaaa… but when running you will find the sphere looking kind of .. wireframed. Yes, and thats actually the correct term for that look as well.
It is as simple as if you havent specified HOW the surface will look on the sphere it will draw it in wireframe mode (as a sign of not having any material wrapped around itself. Tomorrow I’ll show you how to set some materials and then we will also head back to the game. Otherwise I will never be able to finish it!