Skip to content

C3D 05 Adding Physics

robsilv edited this page Apr 12, 2013 · 13 revisions

Following on in the same pattern, this tutorial is as similar to the 2D equivalent as possible in order to demonstrate the similarities and differences in implementation.

Adding Physics screenshot

For this example, create a new class named CadetHelloPhysics in the default package, set it to be the default application and copy and paste the code below into it.

package
{
	import flash.display.Sprite;
	import flash.events.Event;
	
	import cadet.core.CadetScene;
	
	import cadet3D.components.cameras.CameraComponent;
	import cadet3D.components.core.MeshComponent;
	import cadet3D.components.debug.TridentComponent;
	import cadet3D.components.geom.CubeGeometryComponent;
	import cadet3D.components.geom.PlaneGeometryComponent;
	import cadet3D.components.lights.DirectionalLightComponent;
	import cadet3D.components.materials.ColorMaterialComponent;
	import cadet3D.components.renderers.Renderer3D;
	
	import cadet3DPhysics.components.behaviours.RigidBodyBehaviour;
	import cadet3DPhysics.components.processes.PhysicsProcess;
	
	[SWF( width="700", height="400", backgroundColor="0x002135", frameRate="60" )]
	public class CadetHelloPhysics extends Sprite
	{
		private var cadetScene:CadetScene;
		
		private var defaultMaterial:ColorMaterialComponent;
		
		public function CadetHelloPhysics()
		{
			cadetScene = new CadetScene();
			
			// Add Renderer
			var renderer:Renderer3D = new Renderer3D();
			renderer.viewportWidth = stage.stageWidth;
			renderer.viewportHeight = stage.stageHeight;
			cadetScene.children.addItem(renderer);
			renderer.enable(this);
			
			// Add Trident
			var trident:TridentComponent = new TridentComponent();
			cadetScene.children.addItem(trident);
			
			// Add Camera
			var camera:CameraComponent = new CameraComponent();
			camera.rotationX = -145;
			camera.rotationY = -45;
			camera.rotationZ = -180;
			camera.x = 1000;
			camera.y = 1000;
			camera.z = 1000;
			cadetScene.children.addItem(camera);
			
			// Add Light source
			var dirLight:DirectionalLightComponent = new DirectionalLightComponent();
			dirLight.ambient = 0.3;
			dirLight.diffuse = 1;
			dirLight.rotationX = 65;
			dirLight.rotationY = -90;
			cadetScene.children.addItem(dirLight);
			
			// Add Physics Process
			cadetScene.children.addItem(new PhysicsProcess());
			
			// Add default Material
			defaultMaterial = new ColorMaterialComponent();
			cadetScene.children.addItem(defaultMaterial);
			
			// Create floor
			var planeGeometry:PlaneGeometryComponent = new PlaneGeometryComponent(6000, 6000);
			var planeEntity:MeshComponent = new MeshComponent();
			planeEntity.materialComponent = defaultMaterial;
			planeEntity.geometryComponent = planeGeometry;
			planeEntity.children.addItem(planeGeometry);
			planeEntity.children.addItem(new RigidBodyBehaviour());
			cadetScene.children.addItem(planeEntity);
			
			// Create cubes
			var sceneWidth:uint = 2000;
			var sceneHeight:uint = 6000;
			var sceneDepth:uint = 2000;
			var cubeSize:uint = 80;
			var variation:uint = 20;
			for ( var i:int = 0; i < 150; i++ )
			{
				var x:Number = Math.random() * sceneWidth - sceneWidth/2;
				var y:Number = Math.random() * sceneHeight;
				var z:Number = Math.random() * sceneDepth - sceneDepth/2;
				var width:Number = cubeSize + Math.random() * variation;
				var height:Number = cubeSize + Math.random() * variation;
				var depth:Number = cubeSize + Math.random() * variation;
				addCubeEntity( x, y, z, width, height, depth );
			}
			
			addEventListener( Event.ENTER_FRAME, enterFrameHandler );
		}
		
		private function addCubeEntity( x:Number, y:Number, z:Number, width:Number, height:Number, depth:Number ):MeshComponent
		{
			var cubeGeometry:CubeGeometryComponent = new CubeGeometryComponent(width, height, depth);
			
			var cubeEntity:MeshComponent = new MeshComponent();
			cubeEntity.x = x;
			cubeEntity.y = y;
			cubeEntity.z = z;
			cubeEntity.materialComponent = defaultMaterial;
			cubeEntity.geometryComponent = cubeGeometry;
			cubeEntity.children.addItem(cubeGeometry);
			cubeEntity.children.addItem(new RigidBodyBehaviour());
			
			cadetScene.children.addItem(cubeEntity);
			
			return cubeEntity;
		}
		
		private function enterFrameHandler( event:Event ):void
		{
			cadetScene.step();
		}
	}
}

The first part of the CadetHelloPhysics constructor, designated by the following comments should be familiar from the previous tutorial:

//Add Renderer
//Add Trident
//Add Camera
//Add Light source

The first new bit of code is:

// Add Physics Process
cadetScene.children.addItem(new PhysicsProcess());

Note how the implementation is identical to the 2D equivalent, except PhysicsProcess in this instance refers to cadet3DPhysics.components.processes.PhysicsProcess, rather than cadet2DBox2D.components.processes.PhysicsProcess.

For our next trick we create a default material:

// Add default Material
defaultMaterial = new ColorMaterialComponent();
cadetScene.children.addItem(defaultMaterial);

This is the grey material shared between all the boxes, which we need only create one instance of.

Next up is the floor:

// Create floor
var planeGeometry:PlaneGeometryComponent = new PlaneGeometryComponent(6000, 6000);
var planeEntity:MeshComponent = new MeshComponent();
planeEntity.materialComponent = defaultMaterial;
planeEntity.geometryComponent = planeGeometry;
planeEntity.children.addItem(planeGeometry);
planeEntity.children.addItem(new RigidBodyBehaviour());
cadetScene.children.addItem(planeEntity);

For this we create a large PlaneGeometryComponent, then add references to it and the defaultMaterial to a new MeshComponent named planeEntity. In order to make the floor solid, we add a RigidBodyBehaviour as a child of the planeEntity too. On being added to its parent, the RigidBodyBehaviour checks to see if it has a sibling Geometry; if so, it creates the relevant AwayPhysics equivalent object in order to give it a presence in the physics scene.

Finally, we add some cubes by creating a for loop which calls the addCubeEntity method, passing in some randomised values. Note how a RigidBodyBehaviour is also added to each cubeEntity, ensuring that each has a presence in the physics scene.

Build and run to watch the boxes fall!

< Previous | Next >

Clone this wiki locally