Game Development Community

PhysX WheeledVehicle

by CodingChris · in Torque Game Engine · 09/20/2007 (10:01 am) · 25 replies

Hi,
I'm using this resource(http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=10258). Does anyone know how to do use this with wheeledvehicles?
Thanks,
Christian
Page «Previous 1 2
#1
09/20/2007 (10:04 am)
I don't know if anyone has plugged it into the vehicle physics yet.
#2
09/21/2007 (5:00 am)
I don't want to add the whole vehicle functions, I just want the wheeledvehicle datablock to collide with the physX actors.
#3
09/21/2007 (6:00 am)
@Christian - I've already started my modification of the PhysX resource. I faced a similar challenge in getting the projectile object to collide with physX actors. Took a little reading of the code, but I got it working quite nicely. I assume the same can be applied to the wheeledvehicle. Take a look at how the resource implements the Player class into the physX system. I went by that to get projectile to work.

Just remember this mantra and you can't go wrong:
Quote:
Read. Read code. Code

Translation:
Read the physX documentation. Read over the stock code from the resource. Code your modification.
#4
09/21/2007 (6:34 am)
Sorry, but I am not C++ programmer. I'll need your help. This is was I made:
vehicle.h
struct sNxActor;
struct VehicleData: public ShapeBaseData
{
   typedef ShapeBaseData Parent;
sNxActor *mVehicle;
vehicle.cc
#include "physX/PhysX.h"
#include "physX/PhysXWorld.h"
#include "game/vehicles/vehicle.h"
...
VehicleData::VehicleData()
{
   shadowEnable = true;
   shadowCanMove = true;
   shadowCanAnimate = true;

   body.friction = 0;
   body.restitution = 1;

   minImpactSpeed = 25;
   softImpactSpeed = 25;
   hardImpactSpeed = 50;
   minRollSpeed = 0;
   maxSteeringAngle = 0.785; // 45 deg.

   cameraRoll = true;
   cameraLag = 0;
   cameraDecay = 0;
   cameraOffset = 0;

   minDrag = 0;
   maxDrag = 0;
   integration = 1;
   collisionTol = 0.1;
   contactTol = 0.1;
   massCenter.set(0,0,0);
   massBox.set(0,0,0);

   drag = 0.7;
   density = 4;

   jetForce = 500;
   jetEnergyDrain =  0.8;
   minJetEnergy = 1;

   for (S32 i = 0; i < Body::MaxSounds; i++)
      body.sound[i] = 0;

   dustEmitter = NULL;
   dustID = 0;
   triggerDustHeight = 3.0;
   dustHeight = 1.0;

   dMemset( damageEmitterList, 0, sizeof( damageEmitterList ) );
   dMemset( damageEmitterIDList, 0, sizeof( damageEmitterIDList ) );
   dMemset( damageLevelTolerance, 0, sizeof( damageLevelTolerance ) );
   dMemset( splashEmitterList, 0, sizeof( splashEmitterList ) );
   dMemset( splashEmitterIDList, 0, sizeof( splashEmitterIDList ) );

   numDmgEmitterAreas = 0;

   splashFreqMod = 300.0;
   splashVelEpsilon = 0.50;
   exitSplashSoundVel = 2.0;
   softSplashSoundVel = 1.0;
   medSplashSoundVel = 2.0;
   hardSplashSoundVel = 3.0;

   genericShadowLevel = Vehicle_GenericShadowLevel;
   noShadowLevel = Vehicle_NoShadowLevel;

   dMemset(waterSound, 0, sizeof(waterSound));

   collDamageThresholdVel = 20;
   collDamageMultiplier   = 0.05;
mVehicle = NULL;
   
}
...
Vehicle::Vehicle()
{
   mDataBlock = 0;
   mTypeMask |= VehicleObjectType;

   mDelta.pos = Point3F(0,0,0);
   mDelta.posVec = Point3F(0,0,0);
   mDelta.warpTicks = mDelta.warpCount = 0;
   mDelta.dt = 1;
   mDelta.move = NullMove;
   mPredictionCount = 0;
   mDelta.cameraOffset.set(0,0,0);
   mDelta.cameraVec.set(0,0,0);
   mDelta.cameraRot.set(0,0,0);
   mDelta.cameraRotVec.set(0,0,0);

   mRigid.linPosition.set(0, 0, 0);
   mRigid.linVelocity.set(0, 0, 0);
   mRigid.angPosition.identity();
   mRigid.angVelocity.set(0, 0, 0);
   mRigid.linMomentum.set(0, 0, 0);
   mRigid.angMomentum.set(0, 0, 0);
   mContacts.count = 0;

   mSteering.set(0,0);
   mThrottle = 0;
   mJetting = false;

   mCameraOffset.set(0,0,0);

   dMemset( mDustEmitterList, 0, sizeof( mDustEmitterList ) );
   dMemset( mDamageEmitterList, 0, sizeof( mDamageEmitterList ) );
   dMemset( mSplashEmitterList, 0, sizeof( mSplashEmitterList ) );

   mDisableMove = false;
   restCount = 0;

   inLiquid = false;
   waterWakeHandle = 0;
   mVehicle = NULL;
}
...
bool Vehicle::onAdd()
...
PhysXWorld *PxWorld = PhysXWorld::getWorld(isServerObject());
	 if (PxWorld) {
		 mVehicle = PxWorld->AddShapeBase(this);
	 }

   return true;
}
#5
09/21/2007 (7:19 am)
Well, so long as you take the time to perform the mantra, you will find your answers. In the mean time, since you are new to C++ take these notes into consideration:

- You are putting the sNxActor* in the wrong area. Place it within the Vehicle class, not VehicleData

- You integrated properly in the Vehicle::onAdd() method (good job)

- You forgot to integrate the physX stuff in Vehicle::setPosition(). Have a look at how Player::setPosition() is modified to use physX

(edited for Vehicle class instead of wheeledVehicle, my mistake. Corrections are up)
#6
09/21/2007 (7:23 am)
Appending to my last post, it is recommended that you try and adhere to a naming convention and style used by the rest of the resource. For instance:

What you named your sNxActor*:
sNxActor* mVehicle;

What I recommend:
sNxActor* mActor;

While it's just a name and doesn't affect the functionality of your code, it helps keep modules isolated and less confusing. After all, the sNxActor is a component of the Vehicle class, and not the vehicle itself. See what I mean?
#7
09/21/2007 (7:53 am)
Now I made this:
wheeledvehicle.h:
struct sNxActor;
class WheeledVehicle: public Vehicle
{
   typedef Vehicle Parent;
sNxActor *mActor;
...
}
wheeledvehicle.cc
WheeledVehicle::WheeledVehicle()
{
   mDataBlock = 0;
   mBraking = false;
   mJetSound = 0;
   mEngineSound = 0;
   mSquealSound = 0;
   mTailLightThread = 0;
   mSteeringThread = 0;

   for (S32 i = 0; i < WheeledVehicleData::MaxWheels; i++) {
      mWheel[i].springThread = 0;
      mWheel[i].Dy = mWheel[i].Dx = 0;
      mWheel[i].tire = 0;
      mWheel[i].spring = 0;
      mWheel[i].shapeInstance = 0;
      mWheel[i].steering = 0;
      mWheel[i].powered = true;
      mWheel[i].slipping = false;
   }
   mActor = NULL;
}
...
bool WheeledVehicle::onAdd()
{
   if(!Parent::onAdd())
      return false;

   addToScene();
   if (isServerObject())
      scriptOnAdd();
    PhysXWorld *PxWorld = PhysXWorld::getWorld(isServerObject());
	 if (PxWorld) {
		 mActor = PxWorld->AddShapeBase(this);
	 }
   return true;
}
in wheeledvehicle.cc there is no function called setposition...
Sometimes the bridge in the example is working, sometimes torque crashes here.
the crates do not work, the joints either.
#8
09/21/2007 (11:46 am)
Now I added this(and it still doesn't work):
void WheeledVehicle::setPosition(const Point3F& pos,const QuatF& rot)
{
   MatrixF mat;
   rot.setMatrix(&mat);
   mat.setColumn(3,pos);
 if (mActor) {
      QuatF q(mat);
      Point3F pos;
      mat.getColumn(3,&pos);
      NxQuat quat;
      quat.setXYZW(q.x,q.y,q.z,q.w);
      mActor->actor->setGlobalOrientationQuat(quat);
      mActor->actor->setGlobalPosition(NxVec3(pos.x,pos.y,pos.z));
   }
   Parent::setTransform(mat);
}
#9
09/21/2007 (2:26 pm)
I haven't put it to the the test yet, but i have an idea. WheeledVehicle inherits from Vehicle, which mean it inherits all of its variables and methods. This means it already has an sNxActor, which means something in the code could be "short circuiting". Try it without the second sNxActor.
#10
09/22/2007 (1:38 am)
Now I removed everything from wheeledvehicle.cc/h and made this:

vehicle.h
struct sNxActor;
struct VehicleData: public ShapeBaseData
{
   typedef ShapeBaseData Parent;
sNxActor *mActor;
...
vehicle.cc:
...
Vehicle::Vehicle()
{
   mDataBlock = 0;
   mTypeMask |= VehicleObjectType;

   mDelta.pos = Point3F(0,0,0);
   mDelta.posVec = Point3F(0,0,0);
   mDelta.warpTicks = mDelta.warpCount = 0;
   mDelta.dt = 1;
   mDelta.move = NullMove;
   mPredictionCount = 0;
   mDelta.cameraOffset.set(0,0,0);
   mDelta.cameraVec.set(0,0,0);
   mDelta.cameraRot.set(0,0,0);
   mDelta.cameraRotVec.set(0,0,0);

   mRigid.linPosition.set(0, 0, 0);
   mRigid.linVelocity.set(0, 0, 0);
   mRigid.angPosition.identity();
   mRigid.angVelocity.set(0, 0, 0);
   mRigid.linMomentum.set(0, 0, 0);
   mRigid.angMomentum.set(0, 0, 0);
   mContacts.count = 0;

   mSteering.set(0,0);
   mThrottle = 0;
   mJetting = false;

   mCameraOffset.set(0,0,0);

   dMemset( mDustEmitterList, 0, sizeof( mDustEmitterList ) );
   dMemset( mDamageEmitterList, 0, sizeof( mDamageEmitterList ) );
   dMemset( mSplashEmitterList, 0, sizeof( mSplashEmitterList ) );

   mDisableMove = false;
   restCount = 0;

   inLiquid = false;
   waterWakeHandle = 0;
   mActor = NULL;

}
...
bool Vehicle::onAdd()
...
   mConvex.findNodeTransform();
 PhysXWorld *PxWorld = PhysXWorld::getWorld(isServerObject());
	 if (PxWorld) {
		 mActor = PxWorld->AddShapeBase(this);
	 }

   return true;
}
...
void Vehicle::setPosition(const Point3F& pos,const QuatF& rot)
{
   MatrixF mat;
   rot.setMatrix(&mat);
   mat.setColumn(3,pos);
   if (mActor) {
      QuatF q(mat);
      Point3F pos;
      mat.getColumn(3,&pos);
      NxQuat quat;
      quat.setXYZW(q.x,q.y,q.z,q.w);
      mActor->actor->setGlobalOrientationQuat(quat);
      mActor->actor->setGlobalPosition(NxVec3(pos.x,pos.y,pos.z));
   }
   Parent::setTransform(mat);
}
And I get these errors:
Error 9 error C2227: left of '->setGlobalPosition' must point to class/struct/union/generic type c:\PhySX\engine\game\vehicles\vehicle.cc 906 Torque Demo
Error 6 error C2227: left of '->setGlobalOrientationQuat' must point to class/struct/union/generic type c:\PhySX\engine\game\vehicles\vehicle.cc 905 Torque Demo
Error 5 error C2227: left of '->actor' must point to class/struct/union/generic type c:\PhySX\engine\game\vehicles\vehicle.cc 905 Torque Demo
Error 8 error C2227: left of '->actor' must point to class/struct/union/generic type c:\PhySX\engine\game\vehicles\vehicle.cc 906 Torque Demo
Error 1 error C2065: 'mActor' : undeclared identifier c:\PhySX\engine\game\vehicles\vehicle.cc 473 Torque Demo
Error 2 error C2065: 'mActor' : undeclared identifier c:\PhySX\engine\game\vehicles\vehicle.cc 567 Torque Demo
Error 3 error C2065: 'mActor' : undeclared identifier c:\PhySX\engine\game\vehicles\vehicle.cc 899 Torque Demo
Error 4 error C2065: 'mActor' : undeclared identifier c:\PhySX\engine\game\vehicles\vehicle.cc 905 Torque Demo
Error 7 error C2065: 'mActor' : undeclared identifier c:\PhySX\engine\game\vehicles\vehicle.cc 906 Torque Demo
#11
09/22/2007 (11:22 am)
Quick and easy fix for this =)

Remember what I said in one of my earlier posts? Read. Read Code. Code? Well it goes in reverse order as well. You have now coded, so if you read over the code you wrote and then read these posts again, you will notice that you have put the sNxActor* in the wrong spot again.

Move mActor from vehicleData into the Vehicle class, and your compiler problems will go away. The error:

Quote:
...must point to class/struct/union/generic type...

Means you are trying to access a variable that exists in an whole other struct/class. You are trying to call one of mActor's functions, but mActor only exists in vehicleData. Move it to Vehicle and give it a spin.
#12
09/22/2007 (11:40 am)
Now I made this:
Vehicle::Vehicle()
{
   mDataBlock = 0;
   mTypeMask |= VehicleObjectType;

   mDelta.pos = Point3F(0,0,0);
   mDelta.posVec = Point3F(0,0,0);
   mDelta.warpTicks = mDelta.warpCount = 0;
   mDelta.dt = 1;
   mDelta.move = NullMove;
   mPredictionCount = 0;
   mDelta.cameraOffset.set(0,0,0);
   mDelta.cameraVec.set(0,0,0);
   mDelta.cameraRot.set(0,0,0);
   mDelta.cameraRotVec.set(0,0,0);

   mRigid.linPosition.set(0, 0, 0);
   mRigid.linVelocity.set(0, 0, 0);
   mRigid.angPosition.identity();
   mRigid.angVelocity.set(0, 0, 0);
   mRigid.linMomentum.set(0, 0, 0);
   mRigid.angMomentum.set(0, 0, 0);
   mContacts.count = 0;

   mSteering.set(0,0);
   mThrottle = 0;
   mJetting = false;

   mCameraOffset.set(0,0,0);

   dMemset( mDustEmitterList, 0, sizeof( mDustEmitterList ) );
   dMemset( mDamageEmitterList, 0, sizeof( mDamageEmitterList ) );
   dMemset( mSplashEmitterList, 0, sizeof( mSplashEmitterList ) );

   mDisableMove = false;
   restCount = 0;

   inLiquid = false;
   waterWakeHandle = 0;

   mActor = NULL;

}
and it still doesn't work.(I get still the same errors)
#13
09/22/2007 (12:32 pm)
Did you make these changes as well:

[b]Instead of this:
struct sNxActor; // Remove this[/b]
struct VehicleData: public ShapeBaseData
{
   typedef ShapeBaseData Parent;
[b]sNxActor *mActor;  // Remove this[/b]
...

[b]Do this:
struct sNxActor; // forward declare the struct here[/b]
class Vehicle: public ShapeBase
{
   typedef ShapeBase Parent;
   [b]sNxActor *mActor;   // Place mActor here![/b]
...
}
#14
09/22/2007 (12:38 pm)
Sorry, silly misstake. Thanks, now everything works fine. Just a question: In PhysX you can create deformable objects is it possible to create a deformable actor? Would it be much work?
#15
09/22/2007 (1:51 pm)
Two things to note.

1. There is still a lot that can be expanded when it comes to the vehicle physics provided by physX. Getting a TGE vehicle to collide with other objects appropriately is just the tip of the iceberg.

2. What kind of deformable actor are you thinking of? Do you mean cloth, or something else?
#16
09/22/2007 (1:53 pm)
I'm thinking about softbodies.
#17
09/22/2007 (1:54 pm)
I think he means when the vehicle hits something the mesh impact will cause it to crunch together like a real car when its hits something. Ive seen this in a demo movie for physx and I cant seem to find the actual code for it in the sdk.
#18
09/22/2007 (2:07 pm)
@Adam: Yes, I mean that.
#19
09/22/2007 (2:19 pm)
Ah ha...this was going to be my next TGE-PhysX project. I'm currently finishing up my cloth implementation (which is just gorgeous in TGE btw). I'm sure it's possible, but I haven't even begun to R&D how I'm going to implement it. Soft bodies are certainly cool and would add much to the overall feel of a game. I'll let you know what I cook up, and if someone beats me to it please let us know =)
#20
09/23/2007 (1:37 am)
Maybe I'am wrong, but I'll need a cloth implementation to do what I want, or not? I looked at the cloth sample, scene 8, the metal demo, thats what I need. Is this also possible with softbodies?
Page «Previous 1 2