mountObject working??
by deepscratch · in Torque 3D Professional · 12/04/2010 (3:03 pm) · 6 replies
hi all,
is mountObject working at all in 11B3?, not mountImage, thats fine.
I find no examples, and have tried a million ways,
someone know how to mount objects?
to vehicles preferably, but to player would help too
thanks
is mountObject working at all in 11B3?, not mountImage, thats fine.
I find no examples, and have tried a million ways,
someone know how to mount objects?
to vehicles preferably, but to player would help too
thanks
About the author
email me at medan121@gmail.com
Recent Threads
#2
trying it now,
I'm actually trying to mount physicsShape's,
any ideas?
12/04/2010 (9:45 pm)
thanks Henry,trying it now,
I'm actually trying to mount physicsShape's,
any ideas?
#3
Here's my more half-assed idea:
Basically you just want to reverse how the physicsShape usually works. Normally it reads transform and velocity data from the physics sim version of itself and applies those to its Torque scenegraph version. When it's mounted we want to get the mountpoint transform and apply that to the physics sim object instead.
For the record this is all theoretical. I'm on my laptop which isn't set up to build the engine but I'll test it out tomorrow. In physicsShape.cpp, in processTick, try this:
That's basically exactly what Turret does, except this time I also did mPhysicsRep->setTransform(mat); Honestly don't know why we keep checking to see if mPhysicsRep exists (probably because it would explode the engine if it didn't exist, but shouldn't that be done onAdd and the object removed if there's no physics sim to handle it?), but I went ahead and included it since everything else seems to.
Now for the renderPosition update:
I really think that should work. In theory at least. My only concern is that the objects might be stuck bumping into each other, as I somehow doubt whatever collision handling keeps normal Torque mounted objects from touching each other is going to work here.
If this proves to be an issue a call to mPhysicsRep->setSimulationEnabled(false) should stop the physics object from engaging in any collision hyjinks while it's mounted (but will also stop it from colliding with other physics objects). That would need to be called when the mount occurs... Here are onMount and onUnmount added to PhysicsShape:
I'm pretty sure onMount/onUnmount are both called on the client & server since their SceneObject versions both check !isGhost before setting a maskbit. Anyway don't bother with those unless you have issues with collision between the Vehicle and mounted PhysicsShape. After thinking about it a bit I realized that Vehicles probably don't have any link to the physics abstraction system in the first place since it was always planned that they themselves would get linked into Bullet & PhysX as a replacement for Rigid.
12/05/2010 (8:55 am)
That sounds a bit more difficult but should be doable. The best case scenario would be that you actually create some kind of joint or weld between the two objects in the physics sim itself at the mount point, which would allow you to go as far as adding physics object wheels to a FlyingVehicle using only object mounting, or whatever else you might want to do. That said, I don't have enough experience with Bullet of PhysX to do that, and I don't think the abstraction layer ever got as far as joints. Still if you happen to know how to make joints that's the best method.Here's my more half-assed idea:
Basically you just want to reverse how the physicsShape usually works. Normally it reads transform and velocity data from the physics sim version of itself and applies those to its Torque scenegraph version. When it's mounted we want to get the mountpoint transform and apply that to the physics sim object instead.
For the record this is all theoretical. I'm on my laptop which isn't set up to build the engine but I'll test it out tomorrow. In physicsShape.cpp, in processTick, try this:
... START OF FUNCTION ...
if ( !mPhysicsRep->isDynamic() )
return;
// [Mounting]
if (isMounted() && mPhysicsRep) {
MatrixF mat;
mMount.object->getMountTransform(mMount.node,mMount.xfm,&mat);
Parent::setTransform(mat);
Parent::setRenderTransform(mat);
mPhysicsRep->setTransform(mat);
return; // almost seems too easy...
}
// [/Mounting]
// SINGLE PLAYER HACK!!!!
if ( PHYSICSMGR->isSinglePlayer() && isClientObject() && getServerObject() )
...REST OF FUNCTION...That's basically exactly what Turret does, except this time I also did mPhysicsRep->setTransform(mat); Honestly don't know why we keep checking to see if mPhysicsRep exists (probably because it would explode the engine if it didn't exist, but shouldn't that be done onAdd and the object removed if there's no physics sim to handle it?), but I went ahead and included it since everything else seems to.
Now for the renderPosition update:
void PhysicsShape::interpolateTick( F32 delta )
{
AssertFatal( !mDestroyed, "PhysicsShape::interpolateTick - Shouldn't be processing a destroyed shape!" );
if ( !mPhysicsRep->isDynamic() )
return;
// [Mounting]
if (isMounted() && mPhysicsRep) {
MatrixF mat;
mMount.object->getRenderMountTransform(delta,mMount.node,mMount.xfm,&mat);
Parent::setRenderTransform(mat);
mPhysicsRep->setTransform(mat);
return;
}
// [/Mounting]
// Interpolate the position and rotation based on the delta.
PhysicsState state;
state.interpolate( mRenderState[1], mRenderState[0], delta );
// Set the transform to the interpolated transform.
setRenderTransform( state.getTransform() );
}I really think that should work. In theory at least. My only concern is that the objects might be stuck bumping into each other, as I somehow doubt whatever collision handling keeps normal Torque mounted objects from touching each other is going to work here.
If this proves to be an issue a call to mPhysicsRep->setSimulationEnabled(false) should stop the physics object from engaging in any collision hyjinks while it's mounted (but will also stop it from colliding with other physics objects). That would need to be called when the mount occurs... Here are onMount and onUnmount added to PhysicsShape:
void PhysicsShape::onMount( SceneObject *obj, S32 node )
{
Parent::onMount(obj, node);
if (mPhysicsRep && mPhysicsRep->isDynamic())
mPhysicsRep->setSimulationEnabled(false);
}
void PhysicsShape::onUnmount( SceneObject *obj, S32 node )
{
Parent::onUnmount(obj, node);
if (mPhysicsRep && mPhysicsRep->isDynamic())
mPhysicsRep->setSimulationEnabled(true);
}And to the header somewhere in the public section of the PhysicsShape Class:void onMount(SceneObject *obj, S32 node); void onUnmount(SceneObject *obj, S32 node);
I'm pretty sure onMount/onUnmount are both called on the client & server since their SceneObject versions both check !isGhost before setting a maskbit. Anyway don't bother with those unless you have issues with collision between the Vehicle and mounted PhysicsShape. After thinking about it a bit I realized that Vehicles probably don't have any link to the physics abstraction system in the first place since it was always planned that they themselves would get linked into Bullet & PhysX as a replacement for Rigid.
#4
got the physicsShape to mount with a small change to what you suggested Henry,
also got pxMultiActor to mount on vehicles.
now,
the physicsShape "jumps" a bit, twitching back and forward like, and I cant work out how to stop this. the physicsShape retains destruction, so shooting barrels or boxes on the moving vehicle causes them to break.
my goal with this is to have destructable vehicles,
the physicsShapes being damageable panels,
its a perfect solution,
but only if I can get them to stop jumping.
now pxMultiActors on the other hand, update position correctly, but do not "animate" ie, there is no physics.
anyone have a clue how to get pxMultiActor to continue "animating" when mounted?
anyway, any help with these issues would be very much appreciated.
and btw, this is all with stock torque objects, no additions.
12/07/2010 (9:36 pm)
ok, an update,got the physicsShape to mount with a small change to what you suggested Henry,
also got pxMultiActor to mount on vehicles.
now,
the physicsShape "jumps" a bit, twitching back and forward like, and I cant work out how to stop this. the physicsShape retains destruction, so shooting barrels or boxes on the moving vehicle causes them to break.
my goal with this is to have destructable vehicles,
the physicsShapes being damageable panels,
its a perfect solution,
but only if I can get them to stop jumping.
now pxMultiActors on the other hand, update position correctly, but do not "animate" ie, there is no physics.
anyone have a clue how to get pxMultiActor to continue "animating" when mounted?
anyway, any help with these issues would be very much appreciated.
and btw, this is all with stock torque objects, no additions.
#5
The only other place I can think might have some impact is unpackUpdate, but it only seems to call setTransform during the initial update packet. As long as the position is being overriden in interpolateTick I wouldn't see how that could have any impact.
I'll try actually building this as soon as I get a chance today and see if I can figure it out. What did you have to alter to get the original stuff I posted to build?
12/09/2010 (3:40 pm)
This is just another guess (I should test these before I post them maybe?) but I forgot that physicsShape also has its own setTransform function. You might try something like this:void PhysicsShape::setTransform( const MatrixF &newMat )
{
// [Mounting]
if (isMounted() && mPhysicsRep) {
MatrixF mat;
mMount.object->getMountTransform(delta,mMount.node,mMount.xfm,&mat);
Parent::setTransform(mat);
mPhysicsRep->setTransform(mat);
return;
}
// [/Mounting]
Parent::setTransform( newMat );
// This is only called to set an absolute position
// so we discard the delta state.
mState.position = getPosition();
mState.orientation.set( newMat );
mRenderState[0] = mRenderState[1] = mState;
setMaskBits( StateMask );
if ( mPhysicsRep )
mPhysicsRep->setTransform( newMat );
}The only other place I can think might have some impact is unpackUpdate, but it only seems to call setTransform during the initial update packet. As long as the position is being overriden in interpolateTick I wouldn't see how that could have any impact.
I'll try actually building this as soon as I get a chance today and see if I can figure it out. What did you have to alter to get the original stuff I posted to build?
#6
mPhysicsRep->setSimulationEnabled(false);
to
mPhysicsRep->setSimulationEnabled(true);
in the onmount,
to get the physics on.
I'm running through what you mentioned now, lets see.....
12/09/2010 (5:52 pm)
just changedmPhysicsRep->setSimulationEnabled(false);
to
mPhysicsRep->setSimulationEnabled(true);
in the onmount,
to get the physics on.
I'm running through what you mentioned now, lets see.....
Torque Owner Henry Todd
Atomic Walrus
That said not every object type will work by default when mounted. Mounting is now implemented in SceneObject so you might expect it to just work for everything, but mounting itself is just a link between objects and doesn't imply anything about position syncing. Basically only objects that specifically include code for using the position of the mount point they're attached to will actually move with the parent object. I believe Player handles it here:
void Player::setPosition(const Point3F& pos,const Point3F& rot) { MatrixF mat; if (isMounted()) { // Use transform from mounted object MatrixF nmat,zrot; mMount.object->getMountTransform( mMount.node, mMount.xfm, &nmat ); zrot.set(EulerF(0.0f, 0.0f, rot.z)); mat.mul(nmat,zrot); } else { mat.set(EulerF(0.0f, 0.0f, rot.z)); mat.setColumn(3,pos); } Parent::setTransform(mat); mRot = rot; if ( mPhysicsRep ) mPhysicsRep->setTransform( mat ); }and then in updatePos it actually calls setPosition every tick if it's mounted (in this case it allows Z-rotation so you can turn in your seat):
if (isMounted()) { mVelocity = mMount.object->getVelocity(); setPosition(Point3F(0.0f, 0.0f, 0.0f), mRot); setMaskBits(MoveMask); return true; }Turret, being a much simpler class, just does the whole thing in processTick:
if (isMounted()) { MatrixF mat; // [HNT] mMount.object->getMountTransform(mMount.node,mMount.xfm,&mat); // [/HNT] Parent::setTransform(mat); Parent::setRenderTransform(mat); }And then again in interpolateTick (to get the renderPosition lined up):if (isMounted()) { MatrixF mat; // [HNT] mMount.object->getRenderMountTransform(dt,mMount.node,mMount.xfm,&mat); // [/HNT] Parent::setRenderTransform(mat); }(I obviously modded something in these functions, I believe it was just to update the format of the getMountTransform function for T3D).For most object types this is probably a simpler method. Anyway if you let me know what type of object you're trying to mount I might be able to be more specifically helpful.