void Sim3DAudioEvent::unpack(NetConnection *con, BitStream *bstream)
{
   SimObjectId id = bstream->readInt(DataBlockObjectIdBitSize) + DataBlockObjectIdFirst;
   Sim::findObject(id, mProfile);

   if (bstream->readFlag()) {
      QuatF q;
      q.x = bstream->readFloat(SoundRotBits);
      q.y = bstream->readFloat(SoundRotBits);
      q.z = bstream->readFloat(SoundRotBits);
      F32 value = ((q.x * q.x) + (q.y * q.y) + (q.z * q.z));
// #ifdef __linux
      // Hmm, this should never happen, but it does...
      if ( value > 1.f )
         value = 1.f;
// #endif
      q.w = mSqrt(1.f - value);
      if (bstream->readFlag())
         q.w = -q.w;
      q.setMatrix(&mTransform);
   }
   else
      mTransform.identity();

   Point3F pos;
   bstream->readCompressedPoint(&pos,SoundPosAccuracy);
   mTransform.setColumn(3, pos);
}
예제 #2
0
bool ConvexShape::protectedSetSurface( void *object, const char *index, const char *data )
{
   ConvexShape *shape = static_cast< ConvexShape* >( object );

   QuatF quat;
	Point3F pos;
	//MatrixF mat;

	/*
   dSscanf( data, "%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g", 
      &mat[0], &mat[1], &mat[2], &mat[3], 
      &mat[4], &mat[5], &mat[6], &mat[7], 
      &mat[8], &mat[9], &mat[10], &mat[11],
      &mat[12], &mat[13], &mat[14], &mat[15] );
	*/

	dSscanf( data, "%g %g %g %g %g %g %g", &quat.x, &quat.y, &quat.z, &quat.w, &pos.x, &pos.y, &pos.z );

	MatrixF surface;
	quat.setMatrix( &surface );
	surface.setPosition( pos );

   shape->mSurfaces.push_back( surface );   

   return false;
}
예제 #3
0
void RigidBody::setRenderPosition(const Point3F& pos, const QuatF& rot)
{
	MatrixF mat;
	rot.setMatrix(&mat);
	mat.setColumn(3,pos);
	setRenderTransform(mat);
}
예제 #4
0
void	PhysShape::setRotation(const QuatF& rot)
{
    MatrixF tr;
    rot.setMatrix(&tr);
    tr.setPosition(getPosition());
    setTransform(tr);
}
예제 #5
0
void ConvexShape::unpackUpdate( NetConnection *conn, BitStream *stream )
{
   Parent::unpackUpdate( conn, stream );

   if ( stream->readFlag() )  // TransformMask
   {
      mathRead(*stream, &mObjToWorld);
      mathRead(*stream, &mObjScale);

      setTransform( mObjToWorld );
      setScale( mObjScale );
   }

   if ( stream->readFlag() ) // UpdateMask
   {
      stream->read( &mMaterialName );      

      if ( isProperlyAdded() )
         _updateMaterial();

      mSurfaces.clear();

      const U32 surfCount = stream->readInt( 32 );
      for ( S32 i = 0; i < surfCount; i++ )
      {
         mSurfaces.increment();
         MatrixF &mat = mSurfaces.last();

         QuatF quat;
         Point3F pos;

         mathRead( *stream, &quat );
         mathRead( *stream, &pos ); 

         quat.setMatrix( &mat );
         mat.setPosition( pos );
      }

      if ( isProperlyAdded() )
         _updateGeometry( true );
   }
}
예제 #6
0
void PxSingleActor::interpolateTick( F32 delta )
{
   Point3F interpPos;
   QuatF interpRot;

   // Interpolate the position based on the delta.
   interpPos.interpolate( mNextPos, mLastPos, delta );

   // Interpolate the rotation based on the delta.
   interpRot.interpolate( mNextRot, mLastRot, delta );

   // Set up the interpolated transform.
   MatrixF interpMat;

   // Set the interpolated position and rotation.
   interpRot.setMatrix( &interpMat );
   interpMat.setPosition( interpPos );

   // Set the transform to the interpolated transform.
   Parent::setTransform( interpMat );
}
예제 #7
0
void ProximityMine::unpackUpdate( NetConnection* connection, BitStream* stream )
{
   Parent::unpackUpdate( connection, stream );

   // Item::RotationMask
   if ( stream->readFlag() )
   {
      QuatF rot;
      mathRead( *stream, &rot );

      Point3F pos = mObjToWorld.getPosition();
      rot.setMatrix( &mObjToWorld );
      mObjToWorld.setPosition( pos );
   }

   // !mStatic && ( mask & DeployedMask ) && ( mState > Thrown )
   if ( stream->readFlag() )
   {
      mathRead( *stream, &mStickyCollisionPos );
      mathRead( *stream, &mStickyCollisionNormal );

      mAtRest = true;

      setDeployedPos( mStickyCollisionPos, mStickyCollisionNormal );
   }

   // ( mask & ExplosionMask ) && ( mState == Exploded )
   if ( stream->readFlag() )
   {
      // start the explosion visuals on the client
      explode();
   }

   if ( mStatic && mState <= Deployed )
   {
      // static mines are armed immediately
      mState = Deployed;
      mStateTimeout = 0;
   }
}
예제 #8
0
void TurretShape::unpackUpdate(NetConnection *connection, BitStream *stream)
{
   Parent::unpackUpdate(connection,stream);

   // InitialUpdateMask
   if (stream->readFlag()) {
      mRespawn = stream->readFlag();
   }

   // Item::RotationMask
   if ( stream->readFlag() )
   {
      QuatF rot;
      mathRead( *stream, &rot );

      Point3F pos = mObjToWorld.getPosition();
      rot.setMatrix( &mObjToWorld );
      mObjToWorld.setPosition( pos );
   }

   // controlled by the client?
   if(stream->readFlag())
      return;

   // TurretUpdateMask
   if (stream->readFlag())
   {
      Point3F rot(0.0f, 0.0f, 0.0f);
      stream->read(&rot.x);
      stream->read(&rot.z);
      _setRotation(rot);

      // New delta for client side interpolation
      mTurretDelta.rot = rot;
      mTurretDelta.rotVec = VectorF(0.0f, 0.0f, 0.0f);

      stream->read(&allowManualRotation);
      stream->read(&allowManualFire);
   }
}
void fxShapeReplicator::CreateShapes(void)
{
   F32				HypX, HypY;
   F32				Angle;
   U32				RelocationRetry;
   Point3F			ShapePosition;
   Point3F			ShapeStart;
   Point3F			ShapeEnd;
   Point3F			ShapeScale;
   EulerF			ShapeRotation;
   QuatF			QRotation;
   bool			CollisionResult;
   RayInfo			RayEvent;
   TSShape*		pShape;


   // Don't create shapes if we are hiding replications.
   if (mFieldData.mHideReplications) return;

   // Cannot continue without shapes!
   if (dStrcmp(mFieldData.mShapeFile, "") == 0) return;

   // Check that we can position somewhere!
   if (!(	mFieldData.mAllowOnTerrain ||
      mFieldData.mAllowStatics ||
      mFieldData.mAllowOnWater))
   {
      // Problem ...
      Con::warnf(ConsoleLogEntry::General, "[%s] - Could not place object, All alloweds are off!", getName());

      // Return here.
      return;
   }

   // Check Shapes.
   AssertFatal(mCurrentShapeCount==0,"Shapes already present, this should not be possible!")

      // Check that we have a shape...
      if (!mFieldData.mShapeFile) return;

   // Set Seed.
   RandomGen.setSeed(mFieldData.mSeed);

   // Set shape vector.
   mReplicatedShapes.clear();

   // Add shapes.
   for (U32 idx = 0; idx < mFieldData.mShapeCount; idx++)
   {
      fxShapeReplicatedStatic*	fxStatic;

      // Create our static shape.
      fxStatic = new fxShapeReplicatedStatic();

      // Set the 'shapeName' field.
      fxStatic->setField("shapeName", mFieldData.mShapeFile);

      // Is this Replicator on the Server?
      if (isServerObject())
         // Yes, so stop it from Ghosting. (Hack, Hack, Hack!)
         fxStatic->touchNetFlags(Ghostable, false);
      else
         // No, so flag as ghost object. (Another damn Hack!)
         fxStatic->touchNetFlags(IsGhost, true);

      // Register the Object.
      if (!fxStatic->registerObject())
      {
         // Problem ...
         Con::warnf(ConsoleLogEntry::General, "[%s] - Could not load shape file '%s'!", getName(), mFieldData.mShapeFile);

         // Destroy Shape.
         delete fxStatic;

         // Destroy existing hapes.
         DestroyShapes();

         // Quit.
         return;
      }

      // Get Allocated Shape.
      pShape = fxStatic->getShape();

      // Reset Relocation Retry.
      RelocationRetry = mFieldData.mShapeRetries;

      // Find it a home ...
      do
      {
         // Get the Replicator Position.
         ShapePosition = getPosition();

         // Calculate a random offset
         HypX	= RandomGen.randF(mFieldData.mInnerRadiusX, mFieldData.mOuterRadiusX);
         HypY	= RandomGen.randF(mFieldData.mInnerRadiusY, mFieldData.mOuterRadiusY);
         Angle	= RandomGen.randF(0, (F32)M_2PI);

         // Calcualte the new position.
         ShapePosition.x += HypX * mCos(Angle);
         ShapePosition.y += HypY * mSin(Angle);


         // Initialise RayCast Search Start/End Positions.
         ShapeStart = ShapeEnd = ShapePosition;
         ShapeStart.z = 2000.f;
         ShapeEnd.z= -2000.f;

         // Is this the Server?
         if (isServerObject())
            // Perform Ray Cast Collision on Server Terrain.
            CollisionResult = gServerContainer.castRay(ShapeStart, ShapeEnd, FXREPLICATOR_COLLISION_MASK, &RayEvent);
         else
            // Perform Ray Cast Collision on Client Terrain.
            CollisionResult = gClientContainer.castRay(	ShapeStart, ShapeEnd, FXREPLICATOR_COLLISION_MASK, &RayEvent);

         // Did we hit anything?
         if (CollisionResult)
         {
            // For now, let's pretend we didn't get a collision.
            CollisionResult = false;

            // Yes, so get it's type.
            U32 CollisionType = RayEvent.object->getTypeMask();

            // Check Illegal Placements.
            if (((CollisionType & TerrainObjectType) && !mFieldData.mAllowOnTerrain)	||
               ((CollisionType & StaticShapeObjectType) && !mFieldData.mAllowStatics)	||
               ((CollisionType & WaterObjectType) && !mFieldData.mAllowOnWater) ) continue;

            // If we collided with water and are not allowing on the water surface then let's find the
            // terrain underneath and pass this on as the original collision else fail.
            //
            // NOTE:- We need to do this on the server/client as appropriate.
            if ((CollisionType & WaterObjectType) && !mFieldData.mAllowWaterSurface)
            {
               // Is this the Server?
               if (isServerObject())
               {
                  // Yes, so do it on the server container.
                  if (!gServerContainer.castRay( ShapeStart, ShapeEnd, FXREPLICATOR_NOWATER_COLLISION_MASK, &RayEvent)) continue;
               }
               else
               {
                  // No, so do it on the client container.
                  if (!gClientContainer.castRay( ShapeStart, ShapeEnd, FXREPLICATOR_NOWATER_COLLISION_MASK, &RayEvent)) continue;
               }
            }

            // We passed with flying colours so carry on.
            CollisionResult = true;
         }

         // Invalidate if we are below Allowed Terrain Angle.
         if (RayEvent.normal.z < mSin(mDegToRad(90.0f-mFieldData.mAllowedTerrainSlope))) CollisionResult = false;

         // Wait until we get a collision.
      } while(!CollisionResult && --RelocationRetry);

      // Check for Relocation Problem.
      if (RelocationRetry > 0)
      {
         // Adjust Impact point.
         RayEvent.point.z += mFieldData.mOffsetZ;

         // Set New Position.
         ShapePosition = RayEvent.point;
      }
      else
      {
         // Warning.
         Con::warnf(ConsoleLogEntry::General, "[%s] - Could not find satisfactory position for shape '%s' on %s!", getName(), mFieldData.mShapeFile,isServerObject()?"Server":"Client");

         // Unregister Object.
         fxStatic->unregisterObject();

         // Destroy Shape.
         delete fxStatic;

         // Skip to next.
         continue;
      }

      // Get Shape Transform.
      MatrixF XForm = fxStatic->getTransform();

      // Are we aligning to Terrain?
      if (mFieldData.mAlignToTerrain)
      {
         // Yes, so set rotation to Terrain Impact Normal.
         ShapeRotation = RayEvent.normal * mFieldData.mTerrainAlignment;
      }
      else
      {
         // No, so choose a new Rotation (in Radians).
         ShapeRotation.set(	mDegToRad(RandomGen.randF(mFieldData.mShapeRotateMin.x, mFieldData.mShapeRotateMax.x)),
            mDegToRad(RandomGen.randF(mFieldData.mShapeRotateMin.y, mFieldData.mShapeRotateMax.y)),
            mDegToRad(RandomGen.randF(mFieldData.mShapeRotateMin.z, mFieldData.mShapeRotateMax.z)));
      }

      // Set Quaternion Roation.
      QRotation.set(ShapeRotation);

      // Set Transform Rotation.
      QRotation.setMatrix(&XForm);

      // Set Position.
      XForm.setColumn(3, ShapePosition);

      // Set Shape Position / Rotation.
      fxStatic->setTransform(XForm);

      // Choose a new Scale.
      ShapeScale.set(	RandomGen.randF(mFieldData.mShapeScaleMin.x, mFieldData.mShapeScaleMax.x),
         RandomGen.randF(mFieldData.mShapeScaleMin.y, mFieldData.mShapeScaleMax.y),
         RandomGen.randF(mFieldData.mShapeScaleMin.z, mFieldData.mShapeScaleMax.z));

      // Set Shape Scale.
      fxStatic->setScale(ShapeScale);

      // Lock it.
      fxStatic->setLocked(true);

      // Store Shape in Replicated Shapes Vector.
      //mReplicatedShapes[mCurrentShapeCount++] = fxStatic;
      mReplicatedShapes.push_back(fxStatic);

   }

   mCurrentShapeCount = mReplicatedShapes.size();

   // Take first Timestamp.
   mLastRenderTime = Platform::getVirtualMilliseconds();
}