Game Development Community

Question on T3DRigidComponent

by David Everhart · in Torque X 2D · 07/09/2008 (9:24 pm) · 4 replies

I have been using this to create my player in game:

public void CreatePlayer() 
        {  
            //create the simple torque object    
            TorqueObject objPlayer = new TorqueObject();
            objPlayer.Name = "CurrentPlayer";
            
            //create the render component
            T3DTSRenderComponent componentRender = new T3DTSRenderComponent();
            componentRender.ShapeName = @"data\Skeleton\test.dts";
            componentRender.SceneGroupName = "CurrentPlayer";
            
            //create the scene component    
            T3DSceneComponent componentScene = new T3DSceneComponent();
            componentScene.Position = new Vector3(1024, 1024, 295);
            componentScene.SceneGroup = "CurrentPlayer";

            //add both of the components
            objPlayer.Components.AddComponent(componentRender);
            objPlayer.Components.AddComponent(componentScene);
            //register the object
            TorqueObjectDatabase.Instance.Register(objPlayer);
        }

This will create my character, but floating in mid air. After browsing through several threads, as there is no documentation on this, it looked like I needed to add a physics component. I added this to the code above:

// Create the RigidManager
            RigidCollisionManager rigidManager = TorqueObjectDatabase.Instance.FindObject<RigidCollisionManager>("RigidManager");
            

            //define a proper collision shape
            CollisionSphereShape collisionShape = new CollisionSphereShape();
            collisionShape.Radius = 0.5f;
            
            T3DRigidComponent componentPhysics = new T3DRigidComponent();
            componentPhysics.SceneGroupName = "CurrentPlayer";
            componentPhysics.GravityScale = 1f; 
            componentPhysics.Mass = 30.0f;
            componentPhysics.RigidManager = rigidManager;
            componentPhysics.RotationScale = 0f;
            componentPhysics.CollisionBody.AddCollisionShape(collisionShape);
                        
            
            //add both of the components
            objPlayer.Components.AddComponent(componentRender);
            objPlayer.Components.AddComponent(componentScene);
            objPlayer.Components.AddComponent(componentPhysics);

This will now drop my character to the ground, but he is now several (for lack of a good metric) feet off the ground. My understanding is that the terrain has a rigidcomponent, and it has a gravity scale of 0. As my character has a gravity scale of 1, it falls at a specific rate relative to that number( aka .1 is slower than 1). I am guessing he is off the ground, because the collisionshape is there , but I cannot see it. When I add this to see it :

componentPhysics.RenderCollisionBounds = true;

It bombs out, because the _boundsMesh in the collisionShape base class is null. I saw some samples where they created a T3DSphere the same size as the collision shape, and then added it to the root object via the components.addcomponent , but it seems that has been changed in TX 2.0. How would I go about making the collision mesh visible for testing purposes?

#1
07/10/2008 (9:55 pm)
Ok, I think I got it. After checking the FPSDemo, it looks like the OnLoaded for theshape you chose needs to be called. For me, it was:

collisionShape.OnLoaded(objPlayer);

It goes in after the objPlayer is registered. This will set the_boundsMesh, and the call to RenderCollisionBounds will be ok. It wil show up as a red tint on whatever shape you picked . I used :

CollisionBoxShape collisionShape = new CollisionBoxShape();
            collisionShape.Size = new Vector3(4.95f,1f,4.2f);
            collisionShape.Center = new Vector3(0,-.1f,2f);
Not sure why the collisionshape is offkilter, I had to mess with it to encompass my player. I will probably need to add a console method to change it runtime so I can see it being adjusted (assuming I can do so).
#2
07/10/2008 (10:29 pm)
The collision shape is required, but you don't have to add it after the object is registered. I created something similar for a projectile template.

public TorqueObject CreateProjectileTemplate()
{
//find the physics resolver
RigidCollisionManager rigidManager = TorqueObjectDatabase.
Instance.FindObject<RigidCollisionManager>("RigidManager");
 
TorqueObject objProjectile = new TorqueObject();
objProjectile.Name = "ProjectileTemplate";
objProjectile.IsTemplate = true;
 
T3DSceneComponent componentScene = new
T3DSceneComponent();
componentScene.SceneGroup = "ProjectileTemplate";
objProjectile.Components.AddComponent(componentScene);
 
SimpleMaterial material = new SimpleMaterial();
material.TextureFilename = "data/shapes/maze/stone.jpg";
 
T3DSphere sphereComponent = new T3DSphere();
sphereComponent.SceneGroupName = "ProjectileTemplate";
sphereComponent.Material = material;
sphereComponent.Radius = 0.05f;
objProjectile.Components.AddComponent(sphereComponent);
 
//define a proper collision shape
CollisionSphereShape collisionShape = new CollisionSphereShape();
collisionShape.Radius = 0.65f;
collisionShape.Center = new Vector3(0.0f, -0.2f, 0.65f);
 
//give the player some physics attributes, like gravity and collision
T3DRigidComponent componentPhysics = new
T3DRigidComponent();
componentPhysics.SceneGroupName = "ProjectileTemplate";
componentPhysics.OnCollision = ProcessProjectileCollision;
componentPhysics.RigidManager = rigidManager;
componentPhysics.CollisionBody.AddCollisionShape(collisionShape);
objProjectile.Components.AddComponent(componentPhysics);
 
//add a new template to the TorqueObjectDatabase dictionary
TorqueObjectDatabase.Instance.Dictionary.SetValue<TorqueObject>
(objProjectile, objProjectile.Name, null);
return objProjectile;
}

Also note that you can add multiple collision shapes to an object. I think the FPSDemo uses two spheres of different diameter stacked one above another (like a snowman).

John K.
#3
07/11/2008 (6:50 am)
Hey John!

The T3dSphere is no longer accessible in stock TorqueX 2.0 unless you change the source to make it publicly availible. It looks like it is considered a T3DPrimitiveRenderComponent. The only way I stumbled upon the onloaded was in the fpsdemo function called CreateRigidBox.

protected void CreateRigidBox(float val)
        {
            if (val < 1.0f)
                return;

            CollisionBoxShape box = new CollisionBoxShape();
            T3DRigidComponent coll = new T3DRigidComponent();
            T3DSceneComponent sceneObj = new T3DSceneComponent();

            box.Size = new Vector3(10.0f);
            coll.CollisionBody.AddCollisionShape(box);
            coll.RigidManager = TorqueObjectDatabase.Instance.FindObject<RigidCollisionManager>("RigidManager");
            coll.RenderCollisionBounds = true;
            coll.GravityScale = 0.0f;

            Vector3 dir = MatrixUtil.MatrixGetRow(1, ref _transform);
            sceneObj.Transform = _transform;
            sceneObj.Position = _transform.Translation + dir * 15;

            TorqueObject obj = new TorqueObject();
            obj.Components.AddComponent(coll);
            obj.Components.AddComponent(sceneObj);
            TorqueObjectDatabase.Instance.Register(obj);
            box.OnLoaded(obj);
        }

Thats kinda slick you can have multiple collision meshes. I was planning on using a mesh made in Lightwave, but I read on a thread somewhere on this forum that TorqueX ignores the collision mesh if imported. Ahh well, when is your book coming out!!!! :)
#4
08/06/2008 (10:56 pm)
@John

Does your character bounce after starting off in the game? I thought that the groundcontrolcomponent handled that, but it looks like I am going down a dead end. My character now starts n the air, then falls a little, and then bounces up and down :(

Is there a way to get him to stay on the ground? I noticed in the fpsdemo, they had some type of step logic going on, but not sure what keeps the robot in the fps demo grounded and not bouncing all around.