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); } }
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, ¤tPos); // 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); }
// 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); } } }