Exemplo n.º 1
0
void TSShapeLoader::generateDefaultStates()
{
   // Generate default object states (includes initial geometry)
   for (int iObject = 0; iObject < shape->objects.size(); iObject++)
   {
      updateProgress(Load_GenerateDefaultStates, "Generating initial mesh and node states...",
         shape->objects.size(), iObject);

      TSShape::Object& obj = shape->objects[iObject];

      // Calculate the objectOffset for each mesh at T=0
      for (int iMesh = 0; iMesh < obj.numMeshes; iMesh++)
      {
         AppMesh* appMesh = appMeshes[obj.startMeshIndex + iMesh];
         AppNode* appNode = obj.nodeIndex >= 0 ? appNodes[obj.nodeIndex] : boundsNode;

         MatrixF meshMat(appMesh->getMeshTransform(DefaultTime));
         MatrixF nodeMat(appMesh->isSkin() ? meshMat : appNode->getNodeTransform(DefaultTime));

         zapScale(nodeMat);

         appMesh->objectOffset = nodeMat.inverse() * meshMat;
      }

      generateObjectState(shape->objects[iObject], DefaultTime, true, true);
   }

   // Generate default node transforms
   for (int iNode = 0; iNode < appNodes.size(); iNode++)
   {
      // Determine the default translation and rotation for the node
      QuatF rot, srot;
      Point3F trans, scale;
      generateNodeTransform(appNodes[iNode], DefaultTime, false, 0, rot, trans, srot, scale);

      // Add default node translation and rotation
      addNodeRotation(rot, true);
      addNodeTranslation(trans, true);
   }
}
Exemplo n.º 2
0
void AITurretShape::_trackTarget(F32 dt)
{
   // Only on server
   if (isClientObject())
      return;

   // We can only track a target if we have one
   if (!mTarget.isValid())
      return;

   Point3F targetPos = mTarget.target->getBoxCenter();

   // Can we see the target?
   MatrixF aimMat;
   getAimTransform(aimMat);
   Point3F start;
   aimMat.getColumn(3, &start);
   RayInfo ri;

   Point3F sightPoint;

   disableCollision();
   bool los = _testTargetLineOfSight(start, mTarget.target, sightPoint);
   enableCollision();

   if (!los)
   {
      // Target is blocked.  Should we try to track from its last
      // known position and velocity?
      SimTime curTime = Sim::getCurrentTime();
      if ( (curTime - mTarget.lastSightTime) > (mDataBlock->trackLostTargetTime * 1000.0f) )
      {
         // Time's up.  Stop tracking.
         _cleanupTargetAndTurret();
         return;
      }
      
      // Use last known information to attempt to
      // continue to track target for a while.
      targetPos = mTarget.lastPos + mTarget.lastVel * F32(curTime - mTarget.lastSightTime) / 1000.0f;
   }
   else
   {
      // Target is visible

      // We only track targets that are alive
      if (mTarget.target->getDamageState() != Enabled)
      {
         // We can't track any more
         _cleanupTargetAndTurret();
         return;
      }

      targetPos = sightPoint;

      // Store latest target info
      mTarget.lastPos = targetPos;
      mTarget.lastVel = mTarget.target->getVelocity();
      mTarget.lastSightTime = Sim::getCurrentTime();
   }

   // Calculate angles to face the target, specifically the part that we can see
   VectorF toTarget;
   MatrixF mat;
   S32 node = mDataBlock->aimNode;
   if (node != -1)
   {
      // Get the current position of our node
      MatrixF* nodeTrans = &mShapeInstance->mNodeTransforms[node];
      Point3F currentPos;
      nodeTrans->getColumn(3, &currentPos);

      // Turn this into a matrix we can use to put the target
      // position into our space.
      MatrixF nodeMat(true);
      nodeMat.setColumn(3, currentPos);
      mat.mul(mObjToWorld, nodeMat);
      mat.affineInverse();
   }
   else
   {
      mat = mWorldToObj;
   }
   mat.mulP(targetPos, &toTarget);

   // lead the target
   F32 timeToTargetSquared = (mWeaponLeadVelocitySquared > 0) ? toTarget.lenSquared() / mWeaponLeadVelocitySquared : 0;
   if (timeToTargetSquared > 1.0)
   {
      targetPos = targetPos + (mTarget.lastVel * mSqrt(timeToTargetSquared));
      mat.mulP(targetPos, &toTarget);
   }

   F32 yaw, pitch;
   MathUtils::getAnglesFromVector(toTarget, yaw, pitch);
   if (yaw > M_PI_F)
      yaw = yaw - M_2PI_F;
   //if (pitch > M_PI_F)
   //   pitch = -(pitch - M_2PI_F);

   Point3F rot(-pitch, 0.0f, yaw);

   // If we have a rotation rate make sure we follow it
   if (mHeadingRate > 0)
   {
      F32 rate = mHeadingRate * dt;
      F32 rateCheck = mFabs(rot.z - mRot.z);
      if (rateCheck > rate)
      {
         // This will clamp the new value to the rate regardless if it
         // is increasing or decreasing.
         rot.z = mClampF(rot.z, mRot.z-rate, mRot.z+rate);
      }
   }
   if (mPitchRate > 0)
   {
      F32 rate = mPitchRate * dt;
      F32 rateCheck = mFabs(rot.x - mRot.x);
      if (rateCheck > rate)
      {
         // This will clamp the new value to the rate regardless if it
         // is increasing or decreasing.
         rot.x = mClampF(rot.x, mRot.x-rate, mRot.x+rate);
      }
   }

   // Test if the rotation to the target is outside of our limits
   if (_outsideLimits(rot))
   {
      // We can't track any more
      _cleanupTargetAndTurret();
      return;
   }

   // Test if the target is out of weapons range
   if (toTarget.lenSquared() > mWeaponRangeSquared)
   {
      // We can't track any more
      _cleanupTargetAndTurret();
      return;
   }

   mRot = rot;

   _setRotation( mRot );
   setMaskBits(TurretUpdateMask);
}
Exemplo n.º 3
0
// Create meshes from the 3ds File
void GLC_3dsToWorld::createMeshes(GLC_StructOccurence* pProduct, Lib3dsNode* pFatherNode)
{
	GLC_StructOccurence* pChildProduct= NULL;
	Lib3dsMesh *pMesh= NULL;

	if (pFatherNode->type == LIB3DS_OBJECT_NODE)
	{
		//qDebug() << "Node type LIB3DS_OBJECT_NODE is named : " << QString(pFatherNode->name);
		//qDebug() << "Node Matrix :";
		//qDebug() << GLC_Matrix4x4(&(pFatherNode->matrix[0][0])).toString();

		// Check if the node is a mesh or dummy
		if (!(strcmp(pFatherNode->name,"$$$DUMMY")==0))
		{
	    	pMesh = lib3ds_file_mesh_by_name(m_pLib3dsFile, pFatherNode->name);
		    if( pMesh != NULL )
		    {
		    	GLC_3DRep representation(create3DRep(pMesh));
		    	// Test if there is vertex in the mesh
		    	if (0 != representation.vertexCount())
		    	{
		    		m_LoadedMeshes.insert(representation.name());
			    	// Load node matrix
			    	GLC_Matrix4x4 nodeMat(&(pFatherNode->matrix[0][0]));
					// The mesh matrix to inverse
			    	GLC_Matrix4x4 matInv(&(pMesh->matrix[0][0]));
					matInv.invert();
					// Get the node pivot
					Lib3dsObjectData *pObjectData;
					pObjectData= &pFatherNode->data.object;
					GLC_Matrix4x4 trans(-pObjectData->pivot[0], -pObjectData->pivot[1], -pObjectData->pivot[2]);
					// Compute the part matrix
					nodeMat= nodeMat * trans * matInv; // I don't know why...
					nodeMat.optimise();
					// move the part by the matrix
					pProduct->addChild((new GLC_StructInstance(new GLC_3DRep(representation)))->move(nodeMat));
		    	}
		    	else
		    	{
		    		// the instance will be deleted, check material usage
		    		QSet<GLC_Material*> meshMaterials= representation.materialSet();
		    		QSet<GLC_Material*>::const_iterator iMat= meshMaterials.constBegin();
		    		while (iMat != meshMaterials.constEnd())
		    		{
		    			if ((*iMat)->numberOfUsage() == 1)
		    			{
		    				m_Materials.remove((*iMat)->name());
		    			}
		    			++iMat;
		    		}
		    	}
		    }
		} // End If DUMMY
	}
	else return;
	// If there is a child, create a child product
	if (NULL != pFatherNode->childs)
	{
		pChildProduct= new GLC_StructOccurence();
		pProduct->addChild(pChildProduct);

		pChildProduct->setName(QString("Product") + QString::number(pFatherNode->node_id));

		//pChildProduct->move(GLC_Matrix4x4(&(pFatherNode->matrix[0][0])));

		// Create Childs meshes if exists
		for (Lib3dsNode* pNode= pFatherNode->childs; pNode!=0; pNode= pNode->next)
		{
			createMeshes(pChildProduct, pNode);
		}
	}


}