Adobe Director Online
 
Poonam Yadav

Sridevi Aishwariya .G
Director Developer

Physics for Beginners - Part 1

 
Download the source here
 

3D physics in Director allows you to create a dynamic scene from a static 3D scene. Imagine you have created a ball and a floor model in your 3D world, inorder to create the bouncing effect, you need to move the ball towards the floor and detect collision at every frame instead the physics engine can be used to act like a middleware that handles your collision, motion and other interactions between the models.

The first step in adding physics to the 3D Scene is creating a physX internal cast member. Click on Insert->Media->Physics, name the castmember as “physX”.

Initialize the physics engine using Lingo.

mySprite = sprite(me.spriteNum)

tMember  = mySprite.member

tMember.resetWorld()

 

-- Steps the physics world by the actual time elapsed or by the time specified in the init call's timeStep

pTimeStepMode = #equal

 

-- Used in the #equal time step mode, specifies the step time for the physics world.

pTimeStep = 0.33

 

-- Represents the number of substeps for each simulate call

pSubSteps = 5

 

pPhysicsMember = member("physX")

pPhysicsMember.Init(member(tMember), vector(1,1,1),#equal, pTimeStep, pSubSteps )

The Init() method is used to initialize the physics world, it takes 4 arguments, the 3D world, the scaling factor, the Timestep, the Timestepmode and the subStepcount. The scaling factor determines the scaling factor of the 3D world in physics. The Timestep can be either #equal or #automatic, when it is initialized to #automatic the physics world is stepped by the actual time elapsed and when it is initialized to #equal the physics world is stepped by the time specified in the timeStep parameter, the subStepcount is used to provide accuracy.

A ‘-2’ error is thrown if an attempt is made to set/get a physics world property before the world is initialized.

The gravity property for the Physics World is set as follows

pPhysicsMember.gravity = vector(0,-10,0)

The vector specifies that the gravity force is applied in the y-direction since the ball has to move down towards the floor

The other Physics World properties that can be set are

  • angularDamping
  • contactTolerance
  • friction
  • gravity
  • IsInitialized
  • linearDamping
  • restitution
  • scalingFactor
  • sleepMode
  • sleepThreshold
  • subSteps
  • timeStep
  • timeStepMode

The rigidbodies are created in the Physics world from the 3D models. The #meshdeform modifier must be added to the 3D model before creating a rigid body from it, a “-21” error is displayed if the #meshdeform modifier is not added.

-- create the sphere model

sphereResource          = tMember.newModelResource("Sphere", #sphere)

sphereResource.radius   = 5

sphereModel             = tMember.newModel("Sphere", sphereResource)

 

-- create a rigid body for the sphereModel

sphereModel.addmodifier(#meshdeform)

sphereRigidBody = pPhysicsMember.createRigidBody(sphereModel.name,sphereModel.name,#sphere,#dynamic)

The rigid body is created using the createRigidBody() method, the first argument specifies the Model on which the rigidbody is created, the second argument specifies the  name of the rigidbody, the third argument can be #box, #Sphere, #convexShape or #concaveShape depending on the shape of the rigid body, the fourth argument can either be #static, if the body is an immovable body or #dynamic if the body is movable. The last argument flipNormals is optional, and if specified it inverts the face normals of the object.

sphereRigidBody.restitution = 1

sphereRigidBody.mass = 1

The mass of the sphere is set to one since it has to be lighter than the floor to bounces off from it, setting the restitution value to 1, causes the ball to bounce when it collides with the floor. [The law of Restitution]

Other Rigid Body properties that can be set are
  • angularDamping
  • angularMomemtum
  • angularVelocity
  • centerOfMass
  • contactTolerance
  • friction
  • isPinned
  • isSleeping
  • linearDamping
  • linearMomemtum
  • linearVelocity
  • mass
  • model
  • name
  • orientation
  • position
  • restitution
  • properties
  • shape
  • sleepMode
  • sleepThreshold
  • type
  • userData

The simulate() method is called at the end of each frame, it is used to step the physics world through the timeStep that is set during the init() call.

on exitFrame me  

  pPhysicsMember.simulate(pTimeStep, pSubSteps) 

end

The destroy() method is used to stop the simulation and free all the resources in the Physics world .

on endSprite me

  if pPhysicsMember.isInitialized then

    pPhysicsMember.destroy()

  end if 

end

The destroy() method must be called before calling another init() function on the same 3D scene. And the resetworld() method should not be called between the init() and destroy() methods.

The code for the complete 3D physics application is as follows.

Import an Image and label it “MyImage” to create texture for the 3D models. Insert a physics cast member (Insert-> Media Element-> Physics) and name it “physX”. Insert a 3D scenes (Insert-> Media Element-> Shockwave 3D), name the cast member as “3D world”.

Drag and Drop the “3D world” cast member on the stage, and then drag and drop the physics cast member on the 3D scene. Left click on the 3D scene and add the following code

property pTimeStep

property pSubSteps

property pPhysicsMember

property tMember

 

on beginSprite me

 

  mySprite = sprite(me.spriteNum)

  tMember  = mySprite.member

  tMember.resetWorld()

 

  -- Steps the physics world by the actual time elapsed or by the time specified in the init call's timeStep

  pTimeStepMode = #equal

 

  -- Used in the #equal time step mode, specifies the step time for the physics world.

  pTimeStep = 0.33

 

  -- Represents the number of substeps for each simulate call

  pSubSteps = 5

 

  pPhysicsMember = member("physX")

  pPhysicsMember.Init(member(tMember), vector(1,1,1),#equal, pTimeStep, pSubSteps )    

 

  pPhysicsMember.gravity = vector(0,-10,0)

 

  -- create the sphere model

  sphereResource          = tMember.newModelResource("Sphere", #sphere)

  sphereResource.radius   = 5

  sphereModel             = tMember.newModel("Sphere", sphereResource)

 

  -- add new shader and texture to the ball model

  tMember.newTexture("Texture01",#fromImageObject,member("MyImage").image)

  newShader01 = tMember.newShader("newPainter01",#standard)

  newShader01.texture = tMember.texture("Texture01")

  tMember.shader("newPainter01").texturemode = #wrapSpherical

  sphereModel.shader = newShader01

 

  -- create a rigid body for the sphereModel

 

  sphereModel.addmodifier(#meshdeform)

  sphereRigidBody = pPhysicsMember.createRigidBody(sphereModel.name,sphereModel.name,#sphere,#dynamic)

  sphereRigidBody.restitution = 1

  sphereRigidBody.mass = 1

 

  -- create the floor

  bwallResource          = tMember.newModelResource("bwall", #box)

  bwallResource.height   = 10

  bwallResource.width    = 180

  bwallResource.length   = 5

  bottomwallModel        = tMember.newModel("bwall", bwallResource)

 

  bottomwallModel.transform.identity()

  bottomwallModel.transform.translate(0,-75,0)

 

 

  -- add new shader and texture to the ball model

  tMember.newTexture("Texture02",#fromImageObject,member("MyImage").image)

  tMember.model("bwall").shader.texture= tMember.texture("Texture02")

 

 

  bottomwallModel.addmodifier(#meshdeform)

  floorRigidBody = pPhysicsMember.createRigidBody(bottomwallModel.name,bottomwallModel.name,#box,#static)

  floorRigidBody.restitution = 1

  floorRigidBody.mass = 100

 

end

 

on endSprite me

  if pPhysicsMember.isInitialized then

    pPhysicsMember.destroy()

  end if 

end 

 

on exitFrame me  

  pPhysicsMember.simulate(pTimeStep, pSubSteps) 

end

References:
[1] 3D samples from coderecipe http://coderecipe.com/physics-samples/

Feedback:
If you have any questions or comments concerning this article, please send me a message at srideviaishwariya@gmail.com

 
spacer image
This is not an official site from Adobe. If you need any clarifications, please mail me at info@adobedirectoronline.com