3D-Collisions basics

13 02 2009

One thing that is absolutely vital in most games is the actual event when two objects somehow collides.

Be it bullets that collides with it’s target, wheels touching the floor, a paperMario reaching the end of the map or just a FPS-player that tries to walk through a wall, we just need to see whether something is touching something else (especially if inappropriate :) ) Now, there are several ways to detect this and as usual it’s all about processor vs quality. The absolute best and accurate way to do this is to let every single face check with every other single face out there if it has intersected and then dispatch that a collision has occured. Now, this (we call it face <-> face collision) is extremely demanding and even top notch 3D accelerated AAA-titles barely uses it so let’s just put that aside for the mathgeeks and dreamers and let’s look at some realistic aternatives.

Let us start in the other end. How fast can we go??? Well, I say (you can bash me as much as you want to, I have not studied this at all) that he fastest kind of collisiontest you can have is to just make a static numbercheck.

if (mesh.y < 0) { mesh.y = 0}

Yes, we all fid it extremely obvious but sometimes people make things WAY to difficult for them. Still in this game I have used this collisiontype many times where some people would have tried a more demanding approach just for the sake of being dynamic. Just because of the processorpower it takes to detect collisions I have purposely chosen to create a rectangular arena, opposite to the arena I used in my last game. It doesnt have any walls at the moment but when it get walls I don’t have to create some difficult collisioncheck, just a static numbercheck will make the job!

What about the ground?? Well I could have added bumbs in a sandy arena but now I choose a flat one for several reasons.

1. As soon as something like the grenade goes Z < 0 it will bounce up again.

2. When it’s flat and no units will be able to jump/have physics, I can remove all bottom faces of the unit. You should see them, they are all stripped and seethrough from underneath.

3. Putting obstacles on the arena (extra walls, barrels etc) is as easy as Z=0

Now you probably already knew this stupid collisioncheck but I still want you all to remember this simple solution when creating your design for the game. Maybe your 3D pong should go with square walls instead of your freakishly new plasmastyle.

Now, lets start with some “real” collisiontesting then. After the static one, I might be brave enough to say that the next least perfomancedemanding collisioncheck is a single distancecheck. “How far from this object is that object?? Is it to close? then BOOOM!” -style.

In Papervision we got the math already done with it’s  function: DisplayObject3D.distanceTo(otherObj:DisplayObject3D) .  (no it’s not rocketsciencemath either but it’s nice we don’t have to dig out mr.Pythagoras more than needed)

If the distance is lesser than your set value, then you consider it to be a collision. Now, this method is very rarely used but if we enhance it just a liiiiittle bit you will have one of the most common collisiontests in games…

Sphere-collision

When I was a kid, (yes, I promise i have been) I just couldn’t understand how spherecollision could be faster to use than ermm.. other that we will bring up in a short while. Spheres are complicated and as soon as round shapes are involved it means using PI and Sinus and maybe derivata. No, not this time. If you just think of it for a second: distanceTo() is really a sphere. It doesn’t have any direction but checks the distance in EVERY direction building a kind of a “sphere” around the object where the distance is actually the radius of the sphere. Look at this image:

spherecollision

Here I have set a distanceTo limit on the Defender and a distanceTo limit on the grenade so in code it is just:

if (defender.distanceTo(grenade)- (defender.collisionSphereRadius+grenade.collisionSphereRadius) < 0)  { trace(“defender is FUBAR!!!”)}

It’s all about the distance between the objects but we added some kind of radius to each object simulating it’s size. In my game I have set this radius manually and actually do have a “showCollisionSphere” function on each unit and bullet so I can see that it is somewhat correct with the size of the mesh. Still in Papervision3D DisplayObject3D you already have tis kind of collisiondetection in the function: hitTestObject( obj:DisplayObject3D, multiplier:Number=1 ):Boolean

This function takes the furthest pixels away and creates a radius out of that. This could create a collisionsphere that might not be the best for the whole object and therefor there is also a multiplier parameter if you would like to increase or decrease the size of your “sphere”. It works great (I just wanted to create my own flexible collisioncheck but I recommend using the inbuilt one).

Box Collision

What if my object is very flat? It might even be a plane! Creating a collisionsphere around that would just be stupic as it would, in worst cases, trigger collisions way beyond the actual planes location. The other single method that is used just as much as sphere collisions is the box collision. You have probably done it a thousands times already keeping something within a boundary or similar tasks.. does this looks familiar?

if (obj.x > MAX_WIDTH){obj.x = MAX_WIDTH;}

else if (obj.x < MIN_WIDTH){obj.x = MIN_WIDTH;}

if (obj.y > MAX_HEIGHT){obj.y = MAX_HEIGHT;}

else if (obj.y < MIN_HEIGHT){obj.y = MIN_HEIGHT;}

this is actually the technique to use with box collisions. Just check wether a box is within another box.

In every DisplayObject3D that contains a geometryobject you can somewhat easily achieve this as the geometryobject contains a variable with the freakedout name: aabb

This is actually the bounding box we need ( yes it is short for AxisAlignedBoundingBox). It holds all the MAX and MIN values of your mesh in all 3 dimensions so it’s just a matter of creating a lot of “If”‘ rows and you will have your own box collisiontest. Box collision is not as fast as spherecollision but is a very good alternativ for meshes with different proportions.

This was just some simple theory. I will try to stitch this up in some real code in the game to show you later on. Now already I can tell you that if you want to optimize collisioncheck you really should think about WHICH objects really do need to be checked with each other?? Can I remove some of the collisionchecks without harm? All geometry will probably not need to be checked against each other and even some units doesnt have to be checked with some bullets (eg the unit that shot the grenade doesn’t need to be collisionchecked with the nade). I am fond of lists in different ways so I will probably create one now again where objects subscribes to the list where it needs to check with other objects in that particular list.

59

The just-released StreetFighter IV went back from polygon collision to use classical box-collision just to speed up and recreate the classical feel of the game.

Also one small notice is that there are several other types of collisionchecks but thse are by far the most common ones. They are also very easy to mix together and it’s not unusual that game uses BOX <-> SPHERE collisions and POLYGON <->BOX etc.   Hope I could at least enlighten someone with this basic theoretical text. Have a great time creating things I can play!

Advertisements




Kill your darlings

9 02 2009

One of the most important tips I could give you in here is not in any AS3 area nor is it a 3D tweak but it’s a pretty common saying in many creative industries.

‘Kill your darlings’. The simple meaning of this is to try to be as objective as possible and don’t fall in love in some of your best functions, your nicest effects or you genius structures. The hardest thing you will face is when you show your work to the crowd/your friends/or even worse your children and they just say..  “Why did it act like that?” It’s so idiotic obvious and STILL they have the guts and ask such a question??? Or maybe: “So what am I going to do now then?”, “It feels like it’s warping”. But bugs, and bad playability can be dealt with. The WORST thing you will face is when things work terrific! When your effect is just heavenly and you have just created the smartest AI ever and then you’re audience is telling you that, “The effect is bringing the speed down”, or “The guys act too smart, remember it is meant to be casual game. Let them just jump out and be shot!”

I’ve worked with a couple of game publishers and game development has never been as hard as when it is chopped, sliced and stripped from all genius quality just because it need to be more accessible for a bigger audience. You’re genius gameplay is switched with an old overused controlscheme, just because people want what they always done…

Now, we are not all there and most of us will probably face that problem having to answer in front of a publisher BUT this is an important lesson to be learnt in everyday game development. Take this tank I created today:

flamethrower

This tank has been in my plans for a long time and when I finally created the flamethrower I think it looks just great to be Papervision. Still I know I cannot even consider using this weapon after creating it. Why? Well, when holding down the mousebutton, spraying out all that fire the fps drops under 22 fps. It’s a nice effect and I’m quite proud of the result but I know that in the end, I will cut off a lot of players if I let such a demanding effect be in the game. 22 FPS is no big deal but this is just one tank, what if both players use the tanks? Many players will have lesser performing computers than I have, there is still a HUD to be implanted, some collisiondetection, environmentart, sound etc…

Listing it up like this it sounds obvious not to use the effect but I see this over and over again. People fall in love in their physics, in their animated textures, in their multiplied blendmodes.. and in the end as the FPS drops they just can’t ‘kill their darlings’ and instead loose the interest.

Have I removed the idea of the flamethrower? No, not yet, I still have a couple of methods to try but Papervision is really a tight area and demands optimization and chokes immediatly at the slightest overuse of effects or bad coding. Just face it. Choose what few elements you want to have and stick with it. You cannot have shadows, particles and physics and in the middle of development include environmentmaps. You will have great screenshots but you will never be able to release the game to public.

Kill them. Move on.





Special Effects

8 02 2009

This is one of the last core parts of the game, at least when it comes to the Arenafighting (we got a lot of lobby, networking and boardgame to take care of). This is also one of the best parts as we will be able to handle explosions, lightnings, sparkles and other effects. I have decided to create an EffectEngine similar to the ShotEngine but to tweak it and keep it a little more open as effects will probably act and look very different depending on the effect we want to create.

First, as usual, I start with an Interface:

package interfaces
{
	public interface IEffect
	{
		function update():void
		function updateDying():void
		function remove():void
	}
}

As you can see, the effects will not have many common functions, but the ones they have, the EffectEngine will use. Let’s build an abstract class of the Effects, using the Interface we just made:

package effects
{
	import interfaces.IEffect;

	// abstract
	public class AEffect implements IEffect
	{
		public var life:int
		public var flag_Dying:Boolean
		public var flag_Dead:Boolean

		public function AEffect(life:int)
		{
			this.life = life
			flag_Dying = false
			flag_Dead = false
		}

		public function update():void
		{
			// here the effect will be updated each frametick
		}

		public function updateDying():void
		{
			// if flag_Dying==true , update with this function
			// instead of the normal update()
			// this is to be able to smoothly remove effects
			// when they are done
		}

		public function remove():void
		{
			// when updateDying is done (flag_Dead==true), remove effect
		}

	}
}

The only thing we add in this abstract class is 3 variables. time is the time the effect will be visible in millisecs. Now we are ready to create our EffectEngine.

package engine
{
	import effects.AEffect;
	import managers.Time;

	public class EffectEngine
	{

		static private var instance:EffectEngine
		private var aEffects:Array

		// ************ SINGLETON CLASS *************
		public function EffectEngine()
		{
			init()
		}

		public static function getInstance():EffectEngine
		{
			if (EffectEngine.instance == null)
			{
				EffectEngine.instance = new EffectEngine();
			}
			return EffectEngine.instance;
		}

		private function init()
		{
			aEffects = new Array()
		}

		public function addEffect(effect:AEffect)
		{
			//Add a new effect into the effectlist
			aEffects.push(effect);

			// different from the other engines, the effects
			// has their own addChild procedure as they looke very
			// different to each other.
		}

		public function updateEffects():void
		{
			var tempEffect:AEffect
			var flagDelete:Boolean

			for (var i:int = aEffects.length-1 ; i>-1 ; i--)
			{
				flagDelete = false	// reseting deleteflag.
				tempEffect = aEffects[i]

				if (tempEffect.flag_Dying == false)
				{
					// if effect is alive and kicking!
					tempEffect.update()
					if (tempEffect.life < 0)
					{
						tempEffect.flag_Dying = true
					}
					tempEffect.life -= Time.getInstance().timeElapsed
				}
				else
				{
					// if effect is about to die out
					tempEffect.updateDying()
					if (tempEffect.flag_Dead == true)
					{
						tempEffect.remove()
						flagDelete = true
					}
				}

				if (flagDelete == true)
				{
					trace("Removing effect from list")
					aEffects.splice(i,1) // removing shot from the shot list.
				}
			}
		}
	}
}&#91;/sourcecode&#93;

As usual, it is a Singleton-class preventing several instances of EffectsEngine being created. Also, The normal 'add' function is there just like the shotEngine. Biggest difference is in the updateEffects() function, hopefully it is explaining itself. The procedure of an effect is this:
First it gets created and then immediatly added to the EffectEngine.
The effect updates itself using update() until 'life' has reached 0.
Then the effect update the updateDying() instead until , flag_Dead == true
Last the effect is removed from the list and is running the function remove().

Now I will create two effects that will need some kind of explanation. One Explosion (that is actually two effects in one, I'll explain later) and one BombDust that will dust up the arenaground where the explosion has been.
Let's start with the Explosion :) Here is my visual idea of creating it:

<img class="alignnone size-full wp-image-215" title="explosion" src="https://papergem.files.wordpress.com/2009/02/explosion.jpg" alt="explosion" width="510" height="250" />

I will use two planes. One that is aligned to the ground giving a lightEffect on the ground, and one that is a "billboard". A Billboard is a plane that is always facing the camera, no matter where the camera is placed. The Billboard will have an animated movieclip where I use an explosion I rendered in 3DSMax. The groundaligned plane will just have a BitmapMaterial with an image I created in Photoshop. I will scale this image back and forth to simulate an intensity increase and decrease of the explosion.

One important thing I want to stress right now before we get to coding is that png and alpha-channels doesn't match good with performance and optimization. In some projects it is very convinient to use alpha-channels and transparency but when creating a PV3D-game you will immediatly choke the system with more than a few alphatransparencies on the screen.

My solution to this is to use the blendmode ADD. ADD 'adds' it's RGB values to the normal RGB-values giving a "lighter" effect whereever the RGB is more than 0,0,0. If you didn't catch that just remember this: Whatever on the image you don't want to impact the screen, use 0,0,0. Hmm I maybe should show you the images instead:

<img class="alignnone size-full wp-image-216" title="explosionground1" src="https://papergem.files.wordpress.com/2009/02/explosionground1.jpg" alt="explosionground1" width="90" height="89" /><img class="alignnone size-full wp-image-217" title="010" src="https://papergem.files.wordpress.com/2009/02/010.jpg" alt="010" width="128" height="128" />

Wherever it is black, it will be invisible. The brighter the rgb is, the more it will lighten up the actual screen, AND most important, this is a faster way to create lighteffects with than using alphachannels, transparency and png's. Let's look at our implementation of the Explosion.

package effects
{
    import flash.display.BlendMode;
    import managers.Layers;
    import org.papervision3d.materials.BitmapMaterial;
    import org.papervision3d.materials.MovieMaterial;
    import org.papervision3d.objects.primitives.Plane;
    import org.papervision3d.view.layer.ViewportLayer;
    import se.xcom.math.Degrees;

    public class Explosion extends AEffect
    {
        private static var layerIndex:int = 1
        private var airExp:Plane
        private var groundExp:Plane
        private var groundCount:int
        private var layerAir:ViewportLayer
        private var layerGround:ViewportLayer

        public function Explosion(posX:Number,posY:Number, posZ:Number)
        {
            super(1100);
            init(posX,posY,posZ)
        }

        private function init(posX:Number,posY:Number,posZ:Number)
        {
        // create round sphere explosion in air
            var expMat:MovieMaterial = new MovieMaterial(new mcExplosion1(),false,true)
            airExp = new Plane(expMat,1000,1000)
            airExp.x = posX
            airExp.y = posY
            airExp.z = posZ
            airExp.lookAt(View3D.scope.camera)

            layerAir = new ViewportLayer(View3D.scope.viewport,airExp)
            layerAir.blendMode = BlendMode.ADD
            layerAir.layerIndex = layerIndex
            Layers.EFFECTAIR.addLayer(layerAir)

        // create the explosionlight on ground
            var groundMat:BitmapMaterial = new BitmapMaterial(new bmpGroundExplosion1(0,0))
            groundExp = new Plane (groundMat,600,600)
            groundExp.x = posX
            groundExp.y = 0
            groundExp.z = posZ
            groundExp.rotationX = 90

            layerGround = new ViewportLayer(View3D.scope.viewport,groundExp)
            layerGround.blendMode = BlendMode.ADD
            layerGround.layerIndex = layerIndex++
            Layers.EFFECTGROUND_EXP.addLayer(layerGround)

            View3D.scope.scene.addChild(airExp)
            View3D.scope.scene.addChild(groundExp)

        }

        override public function update():void
        {
            airExp.lookAt(View3D.scope.camera)
            airExp.pitch(180)

            groundExp.scaleX = 1+Degrees.dSin(groundCount)*1
            groundExp.scaleY = 1+Degrees.dSin(groundCount)*1
            groundCount += 10
        } 

        override public function updateDying():void
        {
            this.flag_Dead = true
        }

        override public function remove():void
        {
            View3D.scope.scene.removeChild(airExp)
            View3D.scope.scene.removeChild(groundExp)
            Layers.EFFECTAIR.removeLayer(layerAir)
            Layers.EFFECTGROUND_EXP.removeLayer(layerGround)

        }

    }
}

Some explanation here is needed. In my Layers.as class I have created a lot of different layers and put them in a, in my opinion, good indexed order. Now if I just put my objects directly in one of those layers I would get a very strange effect where two explosions would be drawn upon each other like transparent squares. I want the light of the effects to blend with each other if several explosions are on the screen and that is why I put every object in a single unique layer, put the correct blendmode on them and finally put those layers on the parent layer in Layers.as
Yes it could take some time to get your head around, but hey, it works. This is this typical thing that is hard to explain unless you’ve been there yourself.
Well! The explosion now works! This one doesn’t have any long fading when it’s time to “die” but is removed immediatly.

As we’re on it, let’s create a simpler effect, the BombDust.as

package effects
{
	import flash.display.BlendMode;

	import managers.Layers;

	import org.papervision3d.materials.BitmapMaterial;
	import org.papervision3d.objects.primitives.Plane;
	import org.papervision3d.view.layer.ViewportLayer;

	public class BombDust extends AEffect
	{
		private static var layerIndex:int = 1
		private var layer:ViewportLayer
		private var airExp:Plane
		private var dust:Plane
		private var groundCount:int

		public function BombDust(posX:Number,posZ:Number)
		{
			super(8000);
			init(posX,posZ)
		}

		private function init(posX:Number,posZ:Number)
		{
		// create dustPlane
			var dustMat:BitmapMaterial = new BitmapMaterial(new bmpBombDust(0,0))
			dust = new Plane (dustMat,600,600)
			dust.x = posX
			dust.y = 0
			dust.z = posZ
			dust.rotationX = 90
			layer = new ViewportLayer(View3D.scope.viewport,dust)
			layer.blendMode = BlendMode.MULTIPLY
			layer.layerIndex = layerIndex++
			Layers.EFFECTGROUND_DUST.addLayer(layer)
			View3D.scope.scene.addChild(dust)
		}

		override public function updateDying():void
		{
			this.flag_Dead = true
		}

		override public function remove():void
		{
			View3D.scope.scene.removeChild(dust)
			Layers.EFFECTGROUND_DUST.removeLayer(layer)
		}
	}
}

Instead of the ADD-blenmode, this one uses the MULTIPLY, darkening the area instead of brighten it up.
bombdust

Now its just a few lines of code that must be implanted in the GrenadeClass just to spawn these effects whenever the grenade explodes.

override public function killByAge():void
        {
            var exp:Explosion = new Explosion(this.x,this.y,this.z)
            var dust:BombDust = new BombDust(this.x,this.z)

            EffectEngine.getInstance().addEffect(exp)
            EffectEngine.getInstance().addEffect(dust)
        }

Try out the link at the new page above (yes in the menu, called Archon2160). If you’re lucky, there might be a build there where you can see how the effects are triggered. Have fun and hope you learn something. I always do!





Important things to know when creating graphics for PV3D

30 01 2009

Behind this blog a lot of activity is going on, assetswise. The best thing with developing a game by yourself is that you can actually put something aside for a while and do something completely different. Tired of coding? Well grab that keyboard and create some music then? No, what about modelling? Not today, huh? Well, there’s always, texturing, level design, 2D-art, sound effects, visual effects, PR, in game dialogue, websites… etc etc.
So I’m creating a lot of content for the game and want to share some fundamental tips when it comes to modelling and texturing for PV3D.
First we need to realize that PV3D is way behind when it comes to 3D performance. We all probably know the reasons why and the fact that it is a great new experience for the flash environment doesn’t make it fresh and new as a 3D experience. Even back when 3dfx released it’s first Vodoo chip more than 13 years ago the computer could render polygons much faster and more accurate than PV3D is able to do. Still this doesn’t have to be something genuinly bad. Personally I see this as a wonderful creative challenge to actually be able to trick and cheat my way through PV3D to push the limits so the endresult still can intruige, shock and amaze users.

There are several PV3D users out there that compare the whole situation with the old demo scene from the C64, Atari and Amiga eras and I agree.

Now, then. Question is what CAN PV3D handle and how do we create optimized assets for the engine?

Let’s start with modelling:

Every triangle counts! Its obvious that it does but still people are really bad modelling optimized 3Dmodels. Even if you think you cannot remove any more polygons without distorting the whole model, you probably can. Let’s take my car as an example:

defender This model was created for another engine and even though it runs smooth as it is now on our testscenes , the model is way too detailed both for the game and for PV3D. At the moment the jeep is built up with 1108 triangles and a lot of them are very very useless. We always need to consider how close the camera will come to the unit as it’s closest and calculate whether some details are worth it.  The two crash pipes on top themselves use way too many polys and could easily be built up with 2 or 3 planes facing upwards. As the game will be a top viewed game I can remove all polygons underneath. There will be no physics in this game so the jeep won’t roll around showcasing whats underneath.

Rounded areas is always a problem so even if we cannot have square wheels we could easily take a few of the polys there. Remember that the camera will be rather zoomed out most of the time.

You can always keep the detailed model as well as might want to try a LOD technique as the camera moves in. LOD (Level of detail) is working in the way that when the camera gets closer to an object, the object switches to a more detailed model whenever the details will be more visible. In this manner you can save a lot of resources when the camera is zoomed out. I think I will try this technique in the game. Also remember to check for loose vertexes and faces when you are creating your model. In several 3D-apps there are a few automatic optimizefunctions that both removes unused vertices and also tries to optimize the model (based on angles). You could come very far with these features.

I cannot stress enough how important it is to keep the polycount down. There is nothing worse than realize in the middle of your development you will only be able to spawn 3 models and 2 bullets at the same time in a shoot’em up or the gameplay will be ruined by a framerate at 6 fps. Even though it runs smooth when you test your models, it might not do that when there are 3 in there + AI code + 2Dfx + HUD + networking etc etc. A lot of games has gone down the drain just because it lagged too much and the joy of creating the game just disappears.

Now there is another problem with PV3D. As PV3D is not able to set perspective correctly on each face, it “fakes” perspective by “skewing” the triangles. It works like a charm when a lot of triangles are involved and when its facing the camera but if you eg create a plane  with no division (only 2 triangles) and then rotate it on the y-axis you will clearly see a great distortion of the texture when ever it is facing any of the sides. This is not happening in a normal 3D-engine but is a terrible must in PV3D due to what we are given through Flash. This means that certain flat surfaces that easily could be built up with 2 triangles not instead requires a lot of polygons not to distort terribly.

This will be a huge problem for the arena ground in my game so I will think about a solution.

What about texturing then??? Well, how you handle textures in PV3D are more forgiving than triangles but if you try using a texture (BitmapMaterial) compared to a ColourMaterial you will of course see a huge difference in performance. But still.. we want textures, right?

texture_sizetest21

Above you can see the texture for the defender cannon. The difference between the 3 is the size of the texture (from left to right 128×128 , 512×512 , 256×256). Comparing the left and the right cannon you can see that the texture is of course smoothed out with 128×128 and there are more details in the 512×512 one. Same here is the question, how CLOSE will the camera get to the object? At the same time you must ask yourself, is it worth it?

I know that in this game during gameplay, the camera will be very much zoomed out just like the pic below:

hudSo in this case, any big textures are just a waste om memory and processor resources that I could use for a lot of other things. Still, usually in PV3D projects, I see a LOT of too small textures giving you that squary pixel textures. That aint cool! Using a 256×256  or 512×512 texture is more a question of memory than really that much processor so is you are seeing too many and too big pixels, try a bigger texture.

The classic way of deciding which size the texture should have is to make it on any size of 32,64,128,256 or 512. Now, (correct me if I’m wrong), believe that is a heritance from how the arcitechture of the gpu’s were built and one were always recommended not to use any bigger than 512×512. I do not believe that’s the case for PV3D as there is no GPU Hardware acceleration involved here so we’re using the normal memory. Still, going over 512×512 shouldnt be necessary unless you are working with big environments (eg the Arena ground in this game).

This texture-tips has only been about the “diffuse-maps” (the colour that are visible on the model) there are a lot to be covered when it comes to textures and materials that I probably will bring up later on in this blog. I’m not sure if any of the shaders will be used in the game but I would still like to mention them both for experience purposes and to uphold this blog as a tutorial blog :)

Now go and create some assets! Here’s some wip of mine:

djn2sallysizecomparison





Paint the paper

28 01 2009

My guess is that PV3D chose the word “paper” because the way to treat 3D objects is very much like folding paper in different ways. Even if a 3D-object in the end could look like a very solid rock it is built up with simple planes and triangles that is carefully bent and rotated (actually the building blocks gets smaller than that but let’s rest here for a while). The small sides (triangles) that are building up the world doesn’t even have two sides. If you are looking on the other side of a triangle you will actually see… nothing. Nothing at all! So to even create the simpliest sheet of paper you will need to create two planes and flip one and stick it to the other to make it look like in real life (have both a front and a back side).

Now, technically, Papervision have a lot to wish for when it comes to performance and no matter how amazing you might be codewise you won’t just be able to create detailed lifelike models because it will take you thousands and thousands of these triangles to fold and model the details of a reallife complex object. Here is where “texturing comes in”.

Instead of using all these resourcedemanding triangles to showcase something you can actually paint stuff right on the triangles. Say you want to create an orange. Instead of creating every single small bump on an orange you could just paint those bumps on an image and then ‘wrap’ this image around a more simple sphere still creating the illusion of an orange.

Now, I’ve started up creating a few of the models I want to use in my game. Below you will see my unit: “DEFENDER” – a smaller buggy-like car which later on will have a big ass cannon on the roof.

textures

To create such a model, you will need some kind of a 3D-program. I’ve been working with 3D Studio MAX for the last 10 years so that is choice of app. First of all you create the actual “folding” of the object. Placing all triangles where they should be, bending rotating and modelling out all planes will give you a model something like the untextured one above. The texture in the picture is what I draw on a regular image in Photoshop. Wrapping that image on the planes causes the textured model which gives an impression of a much more detailed model than it really is. Good textures are very very important to create a good looking game. Spend a lot of time on that!

If you are interested in special tutorials in modelling, texturing, UVW-mapping etc.. just give me a call and I’ll see what I can do. At the moment I just want to get my “defender” to be a part of the game. To use these kind of custom models you will have to save them into some format that PV3D recognizes like *.3ds or collada.  In this case I will save my model into the *.3ds format and use the inbuilt parser Max3DS in PV3D.

package
{
	import controllers.*;
	import flash.events.*;
	import interfaces.*;
	import org.papervision3d.events.FileLoadEvent;
	import org.papervision3d.lights.PointLight3D;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.parsers.Max3DS;
	import org.papervision3d.view.BasicView;
	import transformers.*;
	import units.*;

	public class View3D extends BasicView
	{
		private var defender:AUnit
		private var defenderMesh:Max3DS
		private var light:PointLight3D

		public function View3D()
		{
			super();

			// set the camera in a nice position
			camera.y = 200
			camera.z = -1000
			camera.zoom = 90

			// place a light somewhere (just to get used to it, this one doesn't do much at the moment)
			light = new PointLight3D()
			light.x = 1000
			light.y = 5000
			light.z = -6000
			scene.addChild(light)

			startLoadMesh()

		}

		private function startLoadMesh()
		{
			// lets load our mesh
			defenderMesh = new Max3DS()
			defenderMesh.load("meshes/units/DefenderBody.3DS",null,"./meshes/units/")
			defenderMesh.addEventListener(FileLoadEvent.LOAD_COMPLETE,meshLoaded)
		}

		private function meshLoaded(e:Event)
		{
			// mesh has been loaded and is now put in as a parameter in this new object called Defender
			defender = new Defender(defenderMesh,new LocalController(),new CarTransform(7,0.85,0.3));
			scene.addChild(defender)

			// startRendering() must be called for the 3D-engine to actually start drawing each frame
			this.startRendering()

			// each time the 3Dengine redraws the screen, onFrameTick is called.
			this.addEventListener(Event.ENTER_FRAME,onFrameTick)
		}

		private function onFrameTick(e:Event)
		{
			// lets transform the unit due to the control-data it recieves.
			defender.transformUnit()
		}
	}
}

The code above actually loads my mesh and adds it on the scene in 3D. Not only that, the mesh is passed into my new class: Defender.as which is extended from AUnit so now FINALLY the chain is connected and I got a unit that do have a mesh, a control component and a transform component. I got my first primitive unit driving around on the scene!! Well.. almost, I just need to create that Defender class..

package units
{
	import interfaces.*;
	import org.papervision3d.objects.DisplayObject3D;

	public class Defender extends AUnit
	{
		public function Ball(mesh:DisplayObject3D,controller:IUnitController,transformer:ITransformer)
		{

			super(mesh,controller,transformer,0);
		}

	}
}

We need no more than that to create our unit. Remember now that we can create as many different components as we want to. Just combine them, reuse them and experiment with them to create new units.