1.7.4 : MountForce can't be zeroed
by DragonSix · in Torque Game Builder · 09/07/2008 (9:45 am) · 32 replies
I try to have mounted objects without any mount force, that follow faithfully the moves of the parent with no lag.
Since 1.7.4, it is not possible anymore O_o
%object.setmountforce(0) doesn't set the mount force to 0, ever.
I tested using the exact same code on the 1.5.1 executable, and it does set the mount force correctly.
This is a 1.7 issue.
PS : on 1.7 it seems sometimes it works, sometimes it doesn't, this is very odd...
Since 1.7.4, it is not possible anymore O_o
%object.setmountforce(0) doesn't set the mount force to 0, ever.
I tested using the exact same code on the 1.5.1 executable, and it does set the mount force correctly.
This is a 1.7 issue.
PS : on 1.7 it seems sometimes it works, sometimes it doesn't, this is very odd...
About the author
#22
In "t2dSceneObject.cc" replace the "t2dSceneObject::setPosition(...)" method with the following:
In "t2dSceneObject.cc" replace the "t2dSceneObject::updateMount(...)" method with the following:
In "t2dSceneObject.cc" add the following "t2dSceneObject::updateChildRigidMounts()" method:
In "t2dSceneObject.h" replace the "t2dSceneObject::updateMount(...)" method declaration with the following:
In "t2dSceneObject.h" add the following "t2dSceneObject::updateChildRigidMounts(...)" method declaration:
So the check-list becomes:
- Modified the existing "t2dSceneObject::setPosition(...)" method. in the "t2dSceneObject.cc" file.
- Modify the existing "t2dSceneObject::updateMount(...)" method in the "t2dSceneObject.cc" file.
- Add a new "t2dSceneObject::updateChildRigidMounts(...)" method in the "t2dSceneObject.cc" file.
- Add a new "t2dSceneObject::updateChildRigidMounts(...)" method declaration in the "t2dSceneObject.h" file.
- Modify the existing "t2dSceneObject::updateMount(...)" method declaration in the "t2dSceneObject.h" file.
Melv.
10/29/2008 (4:44 am)
Code Changes:In "t2dSceneObject.cc" replace the "t2dSceneObject::setPosition(...)" method with the following:
// Set Position.
void t2dSceneObject::setPosition( const t2dVector& position )
{
// Set Position.
getParentPhysics().setPosition( position );
// Reset Tick Positions.
getParentPhysics().resetTickPosition();
// Calculate Mount Nodes.
calculateMountNodes( getPosition() );
// Update Child Rigid-Mounts.
updateChildRigidMounts();
}In "t2dSceneObject.cc" replace the "t2dSceneObject::updateMount(...)" method with the following:
//-----------------------------------------------------------------------------
// Update Mount.
//-----------------------------------------------------------------------------
void t2dSceneObject::updateMount( const F32 elapsedTime, bool ignoreRigidTick )
{
// Ignore if not mounted.
if ( !processIsMounted() )
return;
// T2D Debug Profiling.
#ifdef TORQUE_ENABLE_PROFILER
PROFILE_START(T2D_t2dSceneObject_updateMount);
#endif
// Fetch Mount Position.
const t2dVector& mountPos = mpMountedTo->getMountNode(mMountToID)->mWorldMountPosition;
// Update mount offset.
mMountOffset = mpMountedTo->getMountNode(mMountToID)->mLocalMountPosition;
// Fetch Current Position.
const t2dVector currentPos = getPosition();
// Are we fractionally close to the mount position?
if ( currentPos.notEqual(mountPos) && (mountPos-currentPos).lenSquared() < T2D_CONST_EPSILON )
{
// Yes, so set to mount position.
getParentPhysics().updateTickPosition( mountPos );
}
else
{
// No, so are we mounted rigidly?
if ( mNotZero(mMountForce) )
{
// No, so calculate direction to mount position.
t2dVector direction = mountPos - currentPos;
// Fetch Direction Magnitude.
F32 magnitude = direction.len();
// Skip normalisation if at mount position.
if ( mNotZero(magnitude) )
{
// Renomalise to mount-force magnitude.
direction.normalise( magnitude * mMountForce * elapsedTime );
}
// Have we exceeded our step!
if ( mLessThan(direction.len(), magnitude) )
{
// No, so set new position.
getParentPhysics().updateTickPosition( currentPos + direction );
}
else
{
// Yes, so set to mount position.
getParentPhysics().updateTickPosition( mountPos );
}
}
else
{
// Yes, so set new position.
if ( ignoreRigidTick )
{
setPosition( mountPos );
}
else
{
getParentPhysics().updateTickPosition( mountPos );
}
}
}
// Track rotation ( if selected ).
if ( mMountTrackRotation )
{
// Calculate Mount Rotation.
// NOTE:- We're using the parents mount-rotation, rotation and this objects pre-rotation value.
const F32 mountRotation = mpMountedTo->getMountRotation() + mpMountedTo->getRotation() + mMountPreRotation;
// Update Tick Rotation.
getParentPhysics().updateTickRotation( mountRotation );
// Are we at the target mount rotation?
if ( mNotEqual(mountRotation, getRotation()) )
{
// No, so set rotation.
setRotation( mountRotation);
}
}
else
{
// Non-Tracked Rotation...
// Update Tick Rotation.
getParentPhysics().updateTickRotation();
}
// Are we inheriting attributes?
if ( mMountInheritAttributes )
{
// Yes, so we share common attributes...
// Enabled.
setEnabled( mpMountedTo->isEnabled() );
// Visibility.
setVisible( mpMountedTo->getVisible() );
// Flip.
setFlip( mpMountedTo->getFlipX(), mpMountedTo->getFlipY() );
// Paused.
setPaused( mpMountedTo->getPaused() );
}
// Update Container Configuration (not mount-nodes).
updateSpatialConfig( false );
// T2D Debug Profiling.
#ifdef TORQUE_ENABLE_PROFILER
PROFILE_END(); // T2D_t2dSceneObject_updateMount
#endif
}In "t2dSceneObject.cc" add the following "t2dSceneObject::updateChildRigidMounts()" method:
//-----------------------------------------------------------------------------
// Update Child Rigid-Mounts.
//-----------------------------------------------------------------------------
void t2dSceneObject::updateChildRigidMounts( void )
{
// Find object in notification list.
for ( U32 n = 0; n < mDestroyNotifyList.size(); n++ )
{
// Fetch Notification.
tDestroyNotification& notification = mDestroyNotifyList[n];
// Only action if we've got a reference active.
if ( notification.mRefCount > 0 )
{
// Fetch Child Scene Object.
t2dSceneObject* pChildSceneObject = notification.mpSceneObject;
// Is this object mounted to us?
if ( pChildSceneObject->getMountedParent() == this )
{
// Yes, so is it mounted rigidly?
if ( pChildSceneObject->processIsMountedRigid() )
{
// Yes, so update its position.
pChildSceneObject->updateMount( 0.0f, true );
}
}
}
}
}In "t2dSceneObject.h" replace the "t2dSceneObject::updateMount(...)" method declaration with the following:
void updateMount( const F32 elapsedTime, bool ignoreRigidTick = false );
In "t2dSceneObject.h" add the following "t2dSceneObject::updateChildRigidMounts(...)" method declaration:
void updateChildRigidMounts( void );
So the check-list becomes:
- Modified the existing "t2dSceneObject::setPosition(...)" method. in the "t2dSceneObject.cc" file.
- Modify the existing "t2dSceneObject::updateMount(...)" method in the "t2dSceneObject.cc" file.
- Add a new "t2dSceneObject::updateChildRigidMounts(...)" method in the "t2dSceneObject.cc" file.
- Add a new "t2dSceneObject::updateChildRigidMounts(...)" method declaration in the "t2dSceneObject.h" file.
- Modify the existing "t2dSceneObject::updateMount(...)" method declaration in the "t2dSceneObject.h" file.
Melv.
#23
01/07/2009 (12:58 pm)
This works great, thanks for the fixes Melv!
#24
01/07/2009 (1:33 pm)
Cool beans.
#25
04/04/2009 (11:42 am)
Works great for me too.... thanks so much Melv!
#27
I'm currently using 1.7.5
06/08/2010 (6:36 pm)
Is there a way to fix this without modifying the source? I'm currently using 1.7.5
#28
06/08/2010 (9:17 pm)
I could have sworn that this was fixed in 1.7.5. Have you tried it and it fails?
#29
06/09/2010 (4:51 am)
Yes. Well, is there something more I have to do? I installed 175. Opened my project in the level editor (the gui is obviously different). And ran the game noticing with despair the bouncy effect of my mounted objects. Should I delete the dso's and try it again?
#30
"Torque Game Builder (v1.7.4) initialized..."
I get this from Torison and building out of the level editor.
v1.7.4 is uninstalled. I see version 1.7.5 in the "About" screen.
06/11/2010 (4:29 pm)
Interestingly, I still see this in the console:"Torque Game Builder (v1.7.4) initialized..."
I get this from Torison and building out of the level editor.
v1.7.4 is uninstalled. I see version 1.7.5 in the "About" screen.
#31
So in other words while the object mounted to the player is rigid, the child mounts appear to be mounted elastically.
Edit: The solution linked in the first page fixes the issue.
09/19/2011 (1:31 pm)
I just wanted to confirm this is still an issue in 1.7.5, if I understand it correctly. I have objects mounted rigidly to another object mounted to a player, and they do not behave that way. Best I can understand is that they are still attempting to interpolate, causing them to appear to have a looser mount force than their parent, and certainly not the same force. So in other words while the object mounted to the player is rigid, the child mounts appear to be mounted elastically.
Edit: The solution linked in the first page fixes the issue.
Associate Melv May
Here's the explanation for what's going wrong but you can obviously skip down to the code changes:
All scene-objects, every tick, setup an interpolated move from their last position to the new calculated position. An object moving "under-its-own-steam" with some arbitrary velocity will continuously interpolate its movement. This gives very smooth movement.
If a "setPosition" call is made from the scripts then the object in question has its "last position" and "new position" set immediatley to the specified position. This stops crazy interpolation problems and the net result is that for the remainder of the tick, the object is stationary. This is why continuously setting the position isn't as smooth as letting the engine use tick-interpolation coupled with inherent object velocity. Anyway, I digress.
If an object is mounted to something then instead of script "setPosition" calls being made each tick, the engine looks at the rules for the mount and calculates a new position. Then, during the tick-interpolation, the position is smoothly interpolated.
The problem comes when an object has mounted children and its position is changed via the scripts using "setPosition". Setting the position of the parent object does not affect the children directly as they just "feed" off its position as described above. This causes a disjoint motion between the parent and child and whilst this is not so much a problem on a non-rigid mount, with a rigid mount it breaks the contract between the parent and children.
To solve this, if an object has "setPosition" called on it via the scripts, it automatically updates all its rigidly mounted children.
I will be honest and say that this solution isn't perfect but nor is it in any way a performance hog, it's just that a certain amount of refactoring is called for in many areas of the engine and that's work that I am looking into now.
SPLIT POST...