|
@@ -1106,68 +1106,61 @@ void Projectile::simulate( F32 dt )
|
|
|
if ( isServerObject() && ( rInfo.object->getTypeMask() & csmStaticCollisionMask ) == 0 )
|
|
|
setMaskBits( BounceMask );
|
|
|
|
|
|
+ MatrixF xform( true );
|
|
|
+ xform.setColumn( 3, rInfo.point );
|
|
|
+ setTransform( xform );
|
|
|
+ mCurrPosition = rInfo.point;
|
|
|
+ mCurrVelocity = Point3F::Zero;
|
|
|
+
|
|
|
+ // Get the object type before the onCollision call, in case
|
|
|
+ // the object is destroyed.
|
|
|
+ U32 objectType = rInfo.object->getTypeMask();
|
|
|
+
|
|
|
+ // re-enable the collision response on the source object since
|
|
|
+ // we need to process the onCollision and explode calls
|
|
|
+ if ( disableSourceObjCollision )
|
|
|
+ mSourceObject->enableCollision();
|
|
|
+
|
|
|
+ // Ok, here is how this works:
|
|
|
+ // onCollision is called to notify the server scripts that a collision has occurred, then
|
|
|
+ // a call to explode is made to start the explosion process. The call to explode is made
|
|
|
+ // twice, once on the server and once on the client.
|
|
|
+ // The server process is responsible for two things:
|
|
|
+ // 1) setting the ExplosionMask network bit to guarantee that the client calls explode
|
|
|
+ // 2) initiate the explosion process on the server scripts
|
|
|
+ // The client process is responsible for only one thing:
|
|
|
+ // 1) drawing the appropriate explosion
|
|
|
+
|
|
|
+ // It is possible that during the processTick the server may have decided that a hit
|
|
|
+ // has occurred while the client prediction has decided that a hit has not occurred.
|
|
|
+ // In this particular scenario the client will have failed to call onCollision and
|
|
|
+ // explode during the processTick. However, the explode function will be called
|
|
|
+ // during the next packet update, due to the ExplosionMask network bit being set.
|
|
|
+ // onCollision will remain uncalled on the client however, therefore no client
|
|
|
+ // specific code should be placed inside the function!
|
|
|
+ onCollision( rInfo.point, rInfo.normal, rInfo.object );
|
|
|
// Next order of business: do we explode on this hit?
|
|
|
if ( mCurrTick > mDataBlock->armingDelay || mDataBlock->armingDelay == 0 )
|
|
|
- {
|
|
|
- MatrixF xform( true );
|
|
|
- xform.setColumn( 3, rInfo.point );
|
|
|
- setTransform( xform );
|
|
|
- mCurrPosition = rInfo.point;
|
|
|
- mCurrVelocity = Point3F::Zero;
|
|
|
-
|
|
|
- // Get the object type before the onCollision call, in case
|
|
|
- // the object is destroyed.
|
|
|
- U32 objectType = rInfo.object->getTypeMask();
|
|
|
-
|
|
|
- // re-enable the collision response on the source object since
|
|
|
- // we need to process the onCollision and explode calls
|
|
|
- if ( disableSourceObjCollision )
|
|
|
- mSourceObject->enableCollision();
|
|
|
-
|
|
|
- // Ok, here is how this works:
|
|
|
- // onCollision is called to notify the server scripts that a collision has occurred, then
|
|
|
- // a call to explode is made to start the explosion process. The call to explode is made
|
|
|
- // twice, once on the server and once on the client.
|
|
|
- // The server process is responsible for two things:
|
|
|
- // 1) setting the ExplosionMask network bit to guarantee that the client calls explode
|
|
|
- // 2) initiate the explosion process on the server scripts
|
|
|
- // The client process is responsible for only one thing:
|
|
|
- // 1) drawing the appropriate explosion
|
|
|
-
|
|
|
- // It is possible that during the processTick the server may have decided that a hit
|
|
|
- // has occurred while the client prediction has decided that a hit has not occurred.
|
|
|
- // In this particular scenario the client will have failed to call onCollision and
|
|
|
- // explode during the processTick. However, the explode function will be called
|
|
|
- // during the next packet update, due to the ExplosionMask network bit being set.
|
|
|
- // onCollision will remain uncalled on the client however, therefore no client
|
|
|
- // specific code should be placed inside the function!
|
|
|
- onCollision( rInfo.point, rInfo.normal, rInfo.object );
|
|
|
explode( rInfo.point, rInfo.normal, objectType );
|
|
|
|
|
|
- // break out of the collision check, since we've exploded
|
|
|
- // we don't want to mess with the position and velocity
|
|
|
- }
|
|
|
- else
|
|
|
+ if ( mDataBlock->isBallistic )
|
|
|
{
|
|
|
- if ( mDataBlock->isBallistic )
|
|
|
- {
|
|
|
- // Otherwise, this represents a bounce. First, reflect our velocity
|
|
|
- // around the normal...
|
|
|
- Point3F bounceVel = mCurrVelocity - rInfo.normal * (mDot( mCurrVelocity, rInfo.normal ) * 2.0);
|
|
|
- mCurrVelocity = bounceVel;
|
|
|
-
|
|
|
- // Add in surface friction...
|
|
|
- Point3F tangent = bounceVel - rInfo.normal * mDot(bounceVel, rInfo.normal);
|
|
|
- mCurrVelocity -= tangent * mDataBlock->bounceFriction;
|
|
|
-
|
|
|
- // Now, take elasticity into account for modulating the speed of the grenade
|
|
|
- mCurrVelocity *= mDataBlock->bounceElasticity;
|
|
|
-
|
|
|
- // Set the new position to the impact and the bounce
|
|
|
- // will apply on the next frame.
|
|
|
- //F32 timeLeft = 1.0f - rInfo.t;
|
|
|
- newPosition = oldPosition = rInfo.point + rInfo.normal * 0.05f;
|
|
|
- }
|
|
|
+ // Otherwise, this represents a bounce. First, reflect our velocity
|
|
|
+ // around the normal...
|
|
|
+ Point3F bounceVel = mCurrVelocity - rInfo.normal * (mDot( mCurrVelocity, rInfo.normal ) * 2.0);
|
|
|
+ mCurrVelocity = bounceVel;
|
|
|
+
|
|
|
+ // Add in surface friction...
|
|
|
+ Point3F tangent = bounceVel - rInfo.normal * mDot(bounceVel, rInfo.normal);
|
|
|
+ mCurrVelocity -= tangent * mDataBlock->bounceFriction;
|
|
|
+
|
|
|
+ // Now, take elasticity into account for modulating the speed of the grenade
|
|
|
+ mCurrVelocity *= mDataBlock->bounceElasticity;
|
|
|
+
|
|
|
+ // Set the new position to the impact and the bounce
|
|
|
+ // will apply on the next frame.
|
|
|
+ //F32 timeLeft = 1.0f - rInfo.t;
|
|
|
+ newPosition = oldPosition = rInfo.point + rInfo.normal * 0.05f;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1444,4 +1437,4 @@ DefineEngineMethod(Projectile, presimulate, void, (F32 seconds), (1.0f),
|
|
|
"@note This function is not called if the SimObject::hidden is true.")
|
|
|
{
|
|
|
object->simulate( seconds );
|
|
|
-}
|
|
|
+}
|