Stigatle.net

Site sponsored by Nettkroken.no

  • Increase font size
  • Default font size
  • Decrease font size
Home Mogre and ogre3d Mogre ( Managed Ogre3d ) and Physx

Mogre ( Managed Ogre3d ) and Physx

E-mail Print PDF

Sample video here:

http://www.youtube.com/user/steffensensa#p/a/u/0/qX7xoOEyJMM

Hi,

 I've been wanting to have Nvidia Physx in my projects for a long time,
so I was finally able to do so, for now it's really simple, I press a button to add cubes to my scene,
which get's their transformation and rotation from the physx objects.

Please note that I ported this straight from a openGL example, and there are probably many other way's of doing this.
I just wanted it "to work" and start from there, and I'm no guru, so don't expect it to be perfect.
But I've got to start somewhere.

This is how I did it:

 

Go and download 'Physx candy wrapper' from here
get the mogrephysx dll, and add it as reference to your project.

Variables. these goes in top of your class:

[code]
        protected const long tickspersec = 10000000;
        protected static long lasttickcount;
        protected static double t = 0;
        protected static double dt = 0;
        protected Scene phscene;
        protected bool StartToUpdatePhysx = false;
        protected Physics physics;
        private int PhysxBoxCount = 1;
        private int tempCounter = 1;
        int linecount = 1;
[/code]

 

Next step is to create your physx scene, to put physx objects into:
I also connect to the 'physx debugger' to make life easier.
Just call this one while creating your scene.


[code]

 protected void Initphysx()
        {

//"Start" physx
            var physics = Physics.Create();
//Set the skin widht.
           physics.Parameters.SkinWidth = 0.002F;
//Create a new physx scene
           phscene = physics.CreateScene( new SceneDesc() );
//set the max timestep
          phscene.Timing.MaxTimestep = 1.0f / (3 * 24);
//set gravity in physx
           phscene.Gravity = new Mogre.Vector3( 0, -9.81f, 0 );

//Create a material defining properties for the physx objects
           var defm = phscene.Materials[0];
            defm.Restitution = 0.5f;
            defm.DynamicFriction = defm.StaticFriction = 10.6f;

//Connect to the debugger.           
            physics.RemoteDebugger.Connect("localhost");
        }

[/code]

 

Spawning boxes:

[code]

public void Spawncube()
            {
//make a vector variable named pos.
                Vector3 pos = new Mogre.Vector3(0, 0, 0);
                
                float tempy = pos.y;
//this is where we spawn boxes in our scene
               pos.x = 0;
                pos.y = 1000;
                pos.z = 0;
 
//Create a physx ground plane
             phscene.CreateActor(new ActorDesc(new PlaneShapeDesc()));               

//Create a new box in physx
               var ad = new ActorDesc(new BodyDesc(), 1, new BoxShapeDesc(new Vector3(1, 1, 1)));
//Set it's position to spawnpoint
                ad.GlobalPosition = pos;
//Create the physx actor and give it a name
                var a = phscene.CreateActor(ad);
                a.Name = "Actor_" + PhysxBoxCount;
//Here we create the mogre entity and give it the same name as the physx object
               var planeEnt = sceneMgr.CreateEntity( ("Actor_" + PhysxBoxCount) , SceneManager.PrefabType.PT_CUBE);
                var physxnodew = sceneMgr.CreateSceneNode("Actor_" + PhysxBoxCount);
                physxnodew.AttachObject(planeEnt);
                physxnodew._update(true, true);
                PhysxBoxCount += 1;
//Scale the object down a bit
               planeEnt.ParentSceneNode.Scale(0.2f, 0.2f, 0.2f);

// this one is to enable us to start it when the objects are created.
                if (!StartToUpdatePhysx)
                {
                    
                    StartToUpdatePhysx = true;
                }
                return;
            }

[/code]

 

Now we need a update loop.. this is done like this:

 Add these two functions, and add to the "on each frame" loop,
there you add the "onidle" function.

[code]

//Call this one (OnIdle) on each frame.

  private void OnIdle()
        {
            System.Threading.Thread.Sleep( 1 );
            long ticks = DateTime.Now.Ticks;
            if ( lasttickcount == 0 ) lasttickcount = ticks;
            long tickselapsed = ticks - lasttickcount;
            lasttickcount = ticks;
            dt = (double)tickselapsed / tickspersec;
            t += dt;
            OnFrame();      
        }
    
        protected virtual void OnFrame()
        {
            System.Threading.Thread.Sleep( 1 );
            phscene.Simulate(1.0);
            phscene.Simulate( dt );
            phscene.FlushStream();
            phscene.FetchResults( SimulationStatuses.AllFinished, true );
        }

[/code]

 

Updating the translation \ rotation of all the objects:

Call this one per frame.

[code]

  protected void UpdatePhysics()
        {           
            foreach (var a in phscene.Actors)
            {

                if (!a.IsDynamic) continue;

                if (StartToUpdatePhysx)
                {
                  
                   if (sceneMgr.HasSceneNode(a.Name))
                   {
                       var mat = a.GlobalPose;
                       var rot = a.GlobalOrientationQuaternion;

                       var tempnode = sceneMgr.GetSceneNode(a.Name);

                           tempnode.Orientation = rot;
                           tempnode.Position = mat.GetTrans();
                      
                   }
                }
            }
        }

[/code]

Last Updated on Sunday, 04 April 2010 08:42