/*********************************************************** create box actor ***********************************************************/ NxActor* PhysXEngine::CreateBox(const NxVec3 & StartPosition, float dimX, float dimY, float dimZ, float density, bool Pushable) { // Add a single-shape actor to the scene NxActorDesc actorDesc; // The actor has one shape, a box, 1m on a side NxBoxShapeDesc boxDesc; boxDesc.dimensions.set(dimX, dimY, dimZ); boxDesc.localPose.t = NxVec3(0, 0, 0); if(Pushable) { NxBodyDesc bodyDesc; actorDesc.body = &bodyDesc; actorDesc.density = density; boxDesc.group = GROUP_COLLIDABLE_PUSHABLE; } else boxDesc.group = GROUP_COLLIDABLE_NON_PUSHABLE; actorDesc.shapes.pushBack(&boxDesc); actorDesc.globalPose.t = StartPosition; assert(actorDesc.isValid()); NxActor *pActor = gScene->createActor(actorDesc); assert(pActor); return pActor; }
// Create a static trigger static void CreateTrigger(const NxVec3& pos, NxF32 size = 2, const NxVec3* initial_velocity=NULL, bool kinematic = false) { // Our trigger is a cube NxBodyDesc triggerBody; NxBoxShapeDesc dummyShape; NxBoxShapeDesc BoxDesc; BoxDesc.dimensions = NxVec3(size, size, size); BoxDesc.shapeFlags |= NX_TRIGGER_ENABLE; NxActorDesc ActorDesc; if(initial_velocity || kinematic) { if (initial_velocity) { triggerBody.linearVelocity = *initial_velocity; } if (kinematic) { triggerBody.flags |= NX_BF_KINEMATIC; } triggerBody.mass = 1; ActorDesc.body = &triggerBody; NxF32 sizeinc = 1.01f; dummyShape.dimensions.set(size*sizeinc, size*sizeinc, size*sizeinc); dummyShape.group = 1; ActorDesc.shapes.pushBack(&dummyShape); } ActorDesc.shapes.pushBack(&BoxDesc); ActorDesc.globalPose.t = pos; int thisNb = ++gNbTriggers; gNbTouchedBodies.pushBack(0); NX_ASSERT(gNbTouchedBodies.size() == gNbTriggers); gMyPhysX.getScene()->setGroupCollisionFlag(1,0, false); gMyPhysX.getScene()->setGroupCollisionFlag(1,1, false); gMyPhysX.getScene()->setGroupCollisionFlag(1,2, true); ActorDesc.userData = (void*)(-thisNb); if (!ActorDesc.isValid()) { printf("Invalid ActorDesc\n"); return; } NxActor* actor = gMyPhysX.getScene()->createActor(ActorDesc); // This is just a quick-and-dirty way to identify the trigger for rendering NX_ASSERT(actor != NULL); if (kinematic) { KinematicActor k; k.actor = actor; if (initial_velocity) { k.vel = *initial_velocity; } else { k.vel.set(0,0,0); } gKinematicActors.pushBack(k); } gMyPhysX.getScene()->setUserTriggerReport(&myTriggerCallback); }
NxActor* CreateSphere(const NxVec3 &pos, int flag) { // Add a single-shape actor to the scene NxActorDesc actorDesc; NxBodyDesc bodyDesc; // The actor has one shape, a sphere NxSphereShapeDesc sphereDesc; sphereDesc.radius = 1.5f; sphereDesc.localPose.t = NxVec3(0,2.0f,0); assert(sphereDesc.isValid()); actorDesc.shapes.pushBack(&sphereDesc); if (0 == flag) { //Dynamic actor bodyDesc.flags |= NX_BF_DISABLE_GRAVITY; actorDesc.body = &bodyDesc; actorDesc.density = 1.0f; } else if (1 == flag) { //Static actor actorDesc.body = NULL; actorDesc.density = 1.0f; } else if (2 == flag) { // Kinematic actor bodyDesc.flags |= NX_BF_KINEMATIC; actorDesc.body = &bodyDesc; actorDesc.density = 1.0f; } actorDesc.globalPose.t = pos; //NxVec3(-6.5f, 0, 0); assert(actorDesc.isValid()); NxActor *pActor = gScene->createActor(actorDesc); assert(pActor); return pActor; }
pRigidBody*pFactory::createBox(CK3dEntity *referenceObject,CK3dEntity *worldReferenceObject,pObjectDescr*descr,int creationFlags) { pWorld *world=getManager()->getWorld(worldReferenceObject,referenceObject); pRigidBody*result = world->getBody(referenceObject); if(result) { result->destroy(); delete result; result = NULL; } // we create our final body in the given world : result = createBody(referenceObject,worldReferenceObject); if (result) { result->setWorld(world); using namespace vtTools::AttributeTools; result->setFlags(descr->flags); result->setHullType(descr->hullType); result->setDataFlags(0x000); result->checkDataFlags(); if (result->getSkinWidth()==-1.0f) { result->setSkinWidth(0.01f); } VxMatrix v_matrix ; VxVector position,scale; VxQuaternion quat; v_matrix = referenceObject->GetWorldMatrix(); Vx3DDecomposeMatrix(v_matrix,quat,position,scale); VxVector box_s= BoxGetZero(referenceObject); NxVec3 pos = pMath::getFrom(position); NxQuat rot = pMath::getFrom(quat); float density = result->getDensity(); float radius = referenceObject->GetRadius(); if (referenceObject->GetRadius() < 0.001f ) { radius = 1.0f; } ////////////////////////////////////////////////////////////////////////// //create actors description NxActorDesc actorDesc;actorDesc.setToDefault(); NxBodyDesc bodyDesc;bodyDesc.setToDefault(); ////////////////////////////////////////////////////////////////////////// NxMaterialDesc *materialDescr = NULL; NxMaterial *material = NULL; if (isFlagOn(result->getDataFlags(),EDF_MATERIAL_PARAMETER)) { NxMaterialDesc entMatNull;entMatNull.setToDefault(); NxMaterialDesc *entMat = createMaterialFromEntity(referenceObject); material = world->getScene()->createMaterial(entMatNull); material->loadFromDesc(*entMat); result->setMaterial(material); }else{ if (world->getDefaultMaterial()) { result->setMaterial(world->getDefaultMaterial()); } } ////////////////////////////////////////////////////////////////////////// NxBoxShapeDesc boxShape; if (creationFlags & E_OFC_DIMENSION ) { boxShape.dimensions = pMath::getFrom(box_s)*0.5f; } boxShape.density = descr->density; boxShape.materialIndex = result->getMaterial()->getMaterialIndex(); if (result->getSkinWidth()!=-1.0f) boxShape.skinWidth = result->getSkinWidth(); actorDesc.shapes.pushBack(&boxShape); ////////////////////////////////////////////////////////////////////////// //dynamic object ? if (result->getFlags() & BF_Moving){ actorDesc.body = &bodyDesc; } else actorDesc.body = NULL; ////////////////////////////////////////////////////////////////////////// //set transformations actorDesc.density = descr->density; if (creationFlags & E_OFC_POSITION) { actorDesc.globalPose.t = pos; } if (creationFlags & E_OFC_POSITION) { actorDesc.globalPose.M = rot; } ////////////////////////////////////////////////////////////////////////// //create the actor int v = actorDesc.isValid(); NxActor *actor = world->getScene()->createActor(actorDesc); if (!actor) { xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Couldn't create actor"); delete result; return NULL; } ////////////////////////////////////////////////////////////////////////// //set additional settings : result->setActor(actor); actor->setName(referenceObject->GetName()); actor->userData= result; if (result->getFlags() & BF_Moving) { VxVector massOffsetOut;referenceObject->Transform(&massOffsetOut,&result->getMassOffset()); actor->setCMassOffsetGlobalPosition(pMath::getFrom(massOffsetOut)); } if (result->getFlags() & BF_Kinematic) { actor->raiseBodyFlag(NX_BF_KINEMATIC); } result->enableCollision((result->getFlags() & BF_Collision)); if (result->getFlags() & BF_Moving) { if (!(result->getFlags() & BF_Gravity)) { actor->raiseBodyFlag(NX_BF_DISABLE_GRAVITY); } } NxShape *shape = result->getShapeByIndex(); if (shape) { pSubMeshInfo *sInfo = new pSubMeshInfo(); sInfo->entID = referenceObject->GetID(); sInfo->refObject = (CKBeObject*)referenceObject; shape->userData = (void*)sInfo; result->setMainShape(shape); shape->setName(referenceObject->GetName()); } } return result; }
pRigidBody*pFactory::createRigidBodyFull(CK3dEntity *referenceObject, CK3dEntity *worldReferenceObject) { //################################################################ // // Sanity checks // pWorld *world=getManager()->getWorld(worldReferenceObject,referenceObject); pRigidBody*result = world->getBody(referenceObject); if(result) { result->destroy(); delete result; result = NULL; } //################################################################ // // Construct the result // result = createBody(referenceObject,worldReferenceObject); if (result) { result->setWorld(world); //---------------------------------------------------------------- // // Handle different attribute types (Object or pBSetup) // int attTypeOld = GetPMan()->GetPAttribute(); int attTypeNew = GetPMan()->getAttributeTypeByGuid(VTS_PHYSIC_ACTOR); pObjectDescr *oDescr = NULL; //---------------------------------------------------------------- // // the old way : // if (referenceObject->HasAttribute(attTypeOld)) { result->retrieveSettingsFromAttribute(); oDescr = pFactory::Instance()->createPObjectDescrFromParameter(referenceObject->GetAttributeParameter(GetPMan()->GetPAttribute())); } bool hierarchy = result->getFlags() & BF_Hierarchy; bool isDeformable = result->getFlags() & BF_Deformable; bool trigger = (result->getFlags() & BF_TriggerShape); //---------------------------------------------------------------- // // the new way // if (referenceObject->HasAttribute(attTypeNew)) { oDescr = new pObjectDescr(); } result->checkDataFlags(); /* pObjectDescr *oDescr = if (!oDescr) return result; */ //################################################################ // // Older versions have the hierarchy mode settings not the body flags // We migrate it : // if (oDescr->hirarchy) { result->setFlags( (result->getFlags() | BF_Hierarchy )); } if (hierarchy) { oDescr->hirarchy = hierarchy; } //################################################################ // // Deformable ? // pCloth *cloth = NULL; pClothDesc cDescr; if (isDeformable) { cDescr.setToDefault(); cDescr.worldReference = worldReferenceObject->GetID(); if ( result->getFlags() & BF_Gravity ) { cDescr.flags |= PCF_Gravity; } if ( result->getFlags() & BF_Collision ) { } if (!cloth) { cloth = pFactory::Instance()->createCloth(referenceObject,cDescr); if (!cloth) { xLogger::xLog(XL_START,ELOGERROR,E_LI_MANAGER,"Cannot create cloth : factory object failed !"); } } } //################################################################ // // Some settings // if (result->getSkinWidth()==-1.0f) { result->setSkinWidth(0.01f); } float radius = referenceObject->GetRadius(); if (referenceObject->GetRadius() < 0.001f ) { radius = 1.0f; } float density = result->getDensity(); VxVector box_s= BoxGetZero(referenceObject); //################################################################ // // Calculate destination matrix // VxMatrix v_matrix ; VxVector position,scale; VxQuaternion quat; v_matrix = referenceObject->GetWorldMatrix(); Vx3DDecomposeMatrix(v_matrix,quat,position,scale); NxVec3 pos = pMath::getFrom(position); NxQuat rot = pMath::getFrom(quat); ////////////////////////////////////////////////////////////////////////// //create actors description NxActorDesc actorDesc;actorDesc.setToDefault(); NxBodyDesc bodyDesc;bodyDesc.setToDefault(); NxMaterialDesc *materialDescr = NULL; NxMaterial *material = NULL; switch(result->getHullType()) { ////////////////////////////////////////////////////////////////////////// case HT_Box: { NxBoxShapeDesc shape; if (! isDeformable ) { shape.dimensions = pMath::getFrom(box_s)*0.5f; } shape.density = density; //shape.localPose.t = pMath::getFrom(shapeOffset); if (result->getSkinWidth()!=-1.0f) shape.skinWidth = result->getSkinWidth(); actorDesc.shapes.pushBack(&shape); break; } ////////////////////////////////////////////////////////////////////////// case HT_Sphere: { NxSphereShapeDesc shape; if (! isDeformable ) { shape.radius = radius; } shape.density = density; //shape.localPose.t = pMath::getFrom(shapeOffset); if (result->getSkinWidth()!=-1.0f) shape.skinWidth = result->getSkinWidth(); actorDesc.shapes.pushBack(&shape); break; } ////////////////////////////////////////////////////////////////////////// case HT_Mesh: { if (! (result->getFlags() & BF_Deformable) ) { //xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Can not use a mesh as de"); //return NULL; } NxTriangleMeshDesc myMesh; myMesh.setToDefault(); createMesh(world->getScene(),referenceObject->GetCurrentMesh(),myMesh); NxTriangleMeshShapeDesc shape; bool status = InitCooking(); if (!status) { xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Couldn't initiate cooking lib!"); return NULL; } MemoryWriteBuffer buf; status = CookTriangleMesh(myMesh, buf); if (!status) { xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Couldn't cook mesh!"); return NULL; } shape.meshData = getManager()->getPhysicsSDK()->createTriangleMesh(MemoryReadBuffer(buf.data)); shape.density = density; // shape.materialIndex = result->getMaterial()->getMaterialIndex(); actorDesc.shapes.pushBack(&shape); //shape.localPose.t = pMath::getFrom(shapeOffset); if (result->getSkinWidth()!=-1.0f) shape.skinWidth = result->getSkinWidth(); CloseCooking(); if (myMesh.points) { delete [] myMesh.points; } if (myMesh.triangles) { delete []myMesh.triangles; } break; } ////////////////////////////////////////////////////////////////////////// case HT_ConvexMesh: { if (referenceObject->GetCurrentMesh()) { if (referenceObject->GetCurrentMesh()->GetVertexCount()>=256 ) { xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Only 256 vertices for convex meshs allowed, by Ageia!"); goto nothing; } }else { xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Object has no mesh!"); goto nothing; } NxConvexMeshDesc myMesh; myMesh.setToDefault(); createConvexMesh(world->getScene(),referenceObject->GetCurrentMesh(),myMesh); NxConvexShapeDesc shape; bool status = InitCooking(); if (!status) { xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,"Couldn't initiate cooking lib!"); goto nothing; } MemoryWriteBuffer buf; status = CookConvexMesh(myMesh, buf); if (!status) { xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,"Couldn't cook convex mesh!"); goto nothing; } shape.meshData = getManager()->getPhysicsSDK()->createConvexMesh(MemoryReadBuffer(buf.data)); shape.density = density; // shape.materialIndex = result->getMaterial()->getMaterialIndex(); actorDesc.shapes.pushBack(&shape); //shape.localPose.t = pMath::getFrom(shapeOffset); if (result->getSkinWidth()!=-1.0f) shape.skinWidth = result->getSkinWidth(); int h = shape.isValid(); CloseCooking(); if (myMesh.points) { delete [] myMesh.points; } if (myMesh.triangles) { delete []myMesh.triangles; } break; } ////////////////////////////////////////////////////////////////////////// case HT_ConvexCylinder: { NxConvexShapeDesc shape; if (!_createConvexCylinder(&shape,referenceObject)) xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,"Couldn't create convex cylinder mesh"); shape.density = density; if (result->getSkinWidth()!=-1.0f) shape.skinWidth = result->getSkinWidth(); actorDesc.shapes.pushBack(&shape); break; } ////////////////////////////////////////////////////////////////////////// case HT_Capsule: { NxCapsuleShapeDesc shape; if ( !isDeformable ) { pCapsuleSettings cSettings; pFactory::Instance()->findSettings(cSettings,referenceObject); shape.radius = cSettings.radius > 0.0f ? cSettings.radius : box_s.v[cSettings.localRadiusAxis] * 0.5f; shape.height = cSettings.height > 0.0f ? cSettings.height : box_s.v[cSettings.localLengthAxis] - ( 2*shape.radius) ; } shape.density = density; // shape.materialIndex = result->getMaterial()->getMaterialIndex(); // shape.localPose.t = pMath::getFrom(shapeOffset); if (result->getSkinWidth()!=-1.0f) shape.skinWidth = result->getSkinWidth(); actorDesc.shapes.pushBack(&shape); break; } case HT_Wheel: { // xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,"Couldn't create convex cylinder mesh"); /* NxWheelShapeDesc shape; shape.radius = box_s.z*0.5f; shape.density = density; if (result->getSkinWidth()!=-1.0f) shape.skinWidth = result->getSkinWidth(); if (referenceObject && referenceObject->HasAttribute(GetPMan()->att_wheelDescr )) { CKParameter *par = referenceObject->GetAttributeParameter(GetPMan()->att_wheelDescr ); if (par) { pWheelDescr *wheelDescr = pFactory::Instance()->copyTo(par); if (wheelDescr) { float heightModifier = (wheelDescr->wheelSuspension + radius ) / wheelDescr->wheelSuspension; shape.suspension.damper = wheelDescr->springDamping * heightModifier; shape.suspension.targetValue = wheelDescr->springBias * heightModifier; shape.suspensionTravel = wheelDescr->wheelSuspension; shape.lateralTireForceFunction.stiffnessFactor *= wheelDescr->frictionToSide; shape.longitudalTireForceFunction.stiffnessFactor*=wheelDescr->frictionToFront; shape.inverseWheelMass = 0.1; int isValid = shape.isValid(); actorDesc.shapes.pushBack(&shape); } }else { XString name = result->GetVT3DObject()->GetName(); name << " needs to have an additional wheel attribute attached ! "; xLogger::xLog(XL_START,ELOGERROR,E_LI_AGEIA,name.CStr()); } } */ break; } } ////////////////////////////////////////////////////////////////////////// //dynamic object ? if (result->getFlags() & BF_Moving){ actorDesc.body = &bodyDesc; } else actorDesc.body = NULL; ////////////////////////////////////////////////////////////////////////// //set transformations actorDesc.density = result->getDensity(); if ( !isDeformable) { actorDesc.globalPose.t = pos; actorDesc.globalPose.M = rot; } ////////////////////////////////////////////////////////////////////////// //create the actor int v = actorDesc.isValid(); NxActor *actor = world->getScene()->createActor(actorDesc); if (!actor) { xLogger::xLog(ELOGERROR,E_LI_AGEIA,"Couldn't create actor"); delete result; return NULL; } ////////////////////////////////////////////////////////////////////////// //set additional settings : result->setActor(actor); actor->setName(referenceObject->GetName()); actor->userData= result; ////////////////////////////////////////////////////////////////////////// //Deformable : if (isDeformable && cloth) { pDeformableSettings dSettings; dSettings.ImpulsThresold = 50.0f; dSettings.PenetrationDepth= 0.1f ; dSettings.MaxDeform = 2.0f; CKParameterOut *poutDS = referenceObject->GetAttributeParameter(GetPMan()->att_deformable); if (poutDS) { pFactory::Instance()->copyTo(dSettings,poutDS); } cloth->attachToCore(referenceObject,dSettings.ImpulsThresold,dSettings.PenetrationDepth,dSettings.MaxDeform); result->setCloth(cloth); } ////////////////////////////////////////////////////////////////////////// // // Extra settings : // if (result->getFlags() & BF_Moving) { VxVector massOffsetOut;referenceObject->Transform(&massOffsetOut,&result->getMassOffset()); actor->setCMassOffsetGlobalPosition(pMath::getFrom(massOffsetOut)); } if (result->getFlags() & BF_Kinematic) { result->setKinematic(true); } if (result->getFlags() & BF_Moving ) { result->enableGravity(result->getFlags() & BF_Gravity); } //---------------------------------------------------------------- // // Special Parameters // //- look for optimization attribute : result->checkForOptimization(); //---------------------------------------------------------------- // // store mesh meta info in the first main mesh // NxShape *shape = result->getShapeByIndex(); if (shape) { pSubMeshInfo *sInfo = new pSubMeshInfo(); sInfo->entID = referenceObject->GetID(); sInfo->refObject = (CKBeObject*)referenceObject; shape->userData = (void*)sInfo; result->setMainShape(shape); shape->setName(referenceObject->GetName()); pMaterial bMaterial; bool hasMaterial = pFactory::Instance()->findSettings(bMaterial,referenceObject); if (!hasMaterial) { if (world->getDefaultMaterial()) { int z = (int)world->getDefaultMaterial()->userData; shape->setMaterial(world->getDefaultMaterial()->getMaterialIndex()); //pFactory::Instance()->copyTo(bMaterial,world->getDefaultMaterial()); } }else{ NxMaterialDesc nxMatDescr; pFactory::Instance()->copyTo(nxMatDescr,bMaterial); NxMaterial *nxMaterial = world->getScene()->createMaterial(nxMatDescr); if (nxMaterial) { shape->setMaterial(nxMaterial->getMaterialIndex()); } } } result->enableCollision( (result->getFlags() & BF_Collision), referenceObject ); //- handle collisions setup if (oDescr->version == pObjectDescr::E_OD_VERSION::OD_DECR_V1) result->updateCollisionSettings(*oDescr,referenceObject); xLogger::xLog(ELOGINFO,E_LI_MANAGER,"Rigid body creation successful : %s",referenceObject->GetName()); //---------------------------------------------------------------- // // Parse hierarchy // if (!oDescr->hirarchy) return result; CK3dEntity* subEntity = NULL; while (subEntity= referenceObject->HierarchyParser(subEntity) ) { if (subEntity->HasAttribute(GetPMan()->GetPAttribute())) { pObjectDescr *subDescr = pFactory::Instance()->createPObjectDescrFromParameter(subEntity->GetAttributeParameter(GetPMan()->GetPAttribute())); if (subDescr->flags & BF_SubShape) { ////////////////////////////////////////////////////////////////////////// // // Regular Mesh : // if (subDescr->hullType != HT_Cloth) { result->addSubShape(NULL,*oDescr,subEntity); } ////////////////////////////////////////////////////////////////////////// // // Cloth Mesh : // if (subDescr->hullType == HT_Cloth) { //pClothDesc *cloth = pFactory::Instance()->createPObjectDescrFromParameter(subEntity->GetAttributeParameter(GetPMan()->GetPAttribute())); } } } } if (oDescr->hirarchy) { if (oDescr->newDensity!=0.0f || oDescr->totalMass!=0.0f ) { result->updateMassFromShapes(oDescr->newDensity,oDescr->totalMass); } } return result; } nothing: return result; }
//----------------------------------------------------------------------- PhysicsActor* PhysXActorExtern::createPhysicsActor(PhysicsActorDesc* physicsActorDesc, PhysicsShapeDesc* physicsShapeDesc) { if (!PhysXBridge::getSingletonPtr()->getScene() || !physicsActorDesc || !physicsShapeDesc) return 0; NxBodyDesc bodyDesc; bodyDesc.setToDefault(); NxReal angularDamping = bodyDesc.angularDamping; NxVec3 angularVelocity = bodyDesc.angularVelocity; NxVec3 linearVelocity = bodyDesc.linearVelocity; bodyDesc.angularDamping = physicsShapeDesc->mAngularDamping; bodyDesc.angularVelocity = PhysXMath::convert(physicsShapeDesc->mAngularVelocity); bodyDesc.linearVelocity = PhysXMath::convert(physicsActorDesc->direction); NxActorDesc actorDesc; NxActorDesc defaultActorDesc; actorDesc.setToDefault(); defaultActorDesc.setToDefault(); switch (physicsShapeDesc->mPhysicsShapeType) { case ST_BOX: { PhysicsBoxDesc* physicsBoxDesc = static_cast<PhysicsBoxDesc*>(physicsShapeDesc); NxBoxShapeDesc boxDesc; boxDesc.setToDefault(); boxDesc.dimensions = PhysXMath::convert(physicsBoxDesc->mDimensions); boxDesc.group = physicsBoxDesc->mCollisionGroup; boxDesc.groupsMask = PhysXMath::convert(physicsBoxDesc->mGroupMask); boxDesc.materialIndex = physicsBoxDesc->mMaterialIndex; actorDesc.density = NxComputeBoxDensity(2 * boxDesc.dimensions, physicsActorDesc->mass); actorDesc.shapes.pushBack(&boxDesc); } break; case ST_SPHERE: { PhysicsSphereDesc* physicsSphereDesc = static_cast<PhysicsSphereDesc*>(physicsShapeDesc); NxSphereShapeDesc sphereDec; sphereDec.setToDefault(); sphereDec.radius = physicsSphereDesc->mRadius; sphereDec.group = physicsSphereDesc->mCollisionGroup; sphereDec.groupsMask = PhysXMath::convert(physicsSphereDesc->mGroupMask); sphereDec.materialIndex = physicsSphereDesc->mMaterialIndex; actorDesc.density = NxComputeSphereDensity(sphereDec.radius, physicsActorDesc->mass); actorDesc.shapes.pushBack(&sphereDec); } break; case ST_CAPSULE: { PhysicsCapsuleDesc* physicsCapsuleDesc = static_cast<PhysicsCapsuleDesc*>(physicsShapeDesc); NxCapsuleShapeDesc capsuleDec; capsuleDec.setToDefault(); capsuleDec.radius = physicsCapsuleDesc->mRadius; capsuleDec.height = physicsCapsuleDesc->mHeight; capsuleDec.group = physicsCapsuleDesc->mCollisionGroup; capsuleDec.groupsMask = PhysXMath::convert(physicsCapsuleDesc->mGroupMask); capsuleDec.materialIndex = physicsCapsuleDesc->mMaterialIndex; actorDesc.density = NxComputeCylinderDensity(capsuleDec.radius, capsuleDec.height, physicsActorDesc->mass); actorDesc.shapes.pushBack(&capsuleDec); } break; } actorDesc.globalPose.t = PhysXMath::convert(physicsActorDesc->position); actorDesc.body = &bodyDesc; actorDesc.group = physicsActorDesc->collisionGroup; PhysXActor* physXActor = 0; if (!actorDesc.isValid()) { actorDesc = defaultActorDesc; Ogre::LogManager::getSingleton().logMessage("ParticleUniverse PhysXActor: Cannot create actor; use default attributes."); } NxActor* nxActor = PhysXBridge::getSingletonPtr()->getScene()->createActor(actorDesc); if (nxActor) { physXActor = OGRE_NEW_T(PhysXActor, Ogre::MEMCATEGORY_SCENE_OBJECTS)(); physXActor->position = PhysXMath::convert(nxActor->getGlobalPosition()); physXActor->direction = PhysXMath::convert(nxActor->getLinearVelocity()); nxActor->setGlobalOrientationQuat(PhysXMath::convert(physicsActorDesc->orientation)); physXActor->orientation = physicsActorDesc->orientation; physXActor->mass = nxActor->getMass(); physXActor->collisionGroup = nxActor->getGroup(); physXActor->nxActor = nxActor; } return physXActor; }
NxActor* CreateConvex(const NxVec3 &pos, int flag) { NxActorDesc actorDesc; NxBodyDesc bodyDesc; NxVec3 boxDim(1,0.8,1.5); // Pyramid NxVec3 verts[8] = { NxVec3(boxDim.x, -boxDim.y, -boxDim.z), NxVec3(-boxDim.x, -boxDim.y, -boxDim.z), NxVec3(-boxDim.x, -boxDim.y, boxDim.z), NxVec3(boxDim.x, -boxDim.y, boxDim.z), NxVec3(boxDim.x*0.5, boxDim.y, -boxDim.z*0.5), NxVec3(-boxDim.x*0.5, boxDim.y, -boxDim.z*0.5), NxVec3(-boxDim.x*0.5, boxDim.y, boxDim.z*0.5), NxVec3(boxDim.x*0.5, boxDim.y, boxDim.z*0.5) }; // Create descriptor for convex mesh if (!convexDesc) { convexDesc = new NxConvexMeshDesc(); assert(convexDesc); } convexDesc->numVertices = 8; convexDesc->pointStrideBytes = sizeof(NxVec3); convexDesc->points = verts; convexDesc->flags = NX_CF_COMPUTE_CONVEX; NxConvexShapeDesc convexShapeDesc; convexShapeDesc.localPose.t = NxVec3(0, 2.0f, boxDim.z * 0.4); convexShapeDesc.userData = convexDesc; NxInitCooking(); // Cooking from memory MemoryWriteBuffer buf; bool status = NxCookConvexMesh(*convexDesc, buf); // // Please note about the created Convex Mesh, user needs to release it when no one uses it to save memory. It can be detected // by API "meshData->getReferenceCount() == 0". And, the release API is "gPhysicsSDK->releaseConvexMesh(*convexShapeDesc.meshData);" // NxConvexMesh *pMesh = gPhysicsSDK->createConvexMesh(MemoryReadBuffer(buf.data)); assert(pMesh); convexShapeDesc.meshData = pMesh; NxCloseCooking(); if (pMesh) { // Save mesh in userData for drawing. pMesh->saveToDesc(*convexDesc); // NxActorDesc actorDesc; assert(convexShapeDesc.isValid()); actorDesc.shapes.pushBack(&convexShapeDesc); if (0 == flag) { //Dynamic actor bodyDesc.flags |= NX_BF_DISABLE_GRAVITY; actorDesc.body = &bodyDesc; actorDesc.density = 1.0f; } else if (1 == flag) { //Static actor actorDesc.body = NULL; actorDesc.density = 1.0f; } else if (2 == flag) { // Kinematic actor bodyDesc.flags |= NX_BF_KINEMATIC; actorDesc.body = &bodyDesc; actorDesc.density = 1.0f; } actorDesc.globalPose.t = pos; //NxVec3(6.5f, 0.0f, 0.0f); assert(actorDesc.isValid()); NxActor* actor = gScene->createActor(actorDesc); assert(actor); return actor; } return NULL; }
NxActor* CreateLander(NxVec3 position) { NxActor* actor=NULL; switch (gLanderType) { case CAPSULE_LANDER: actor = CreateCapsuleGrain(position,gLanderMass/pow(gLanderSize.x,3.0f),gLanderSize.x); break; case SPHERE_LANDER: actor = CreateSphericalGrain(position,gLanderMass/pow(gLanderSize.x,3.0f),gLanderSize.x); break; case ROLY_POLY: {// Two slightly offset spheres, one heavy, one slightly smaller, and hollow NxActorDesc actorDesc; NxBodyDesc bodyDesc; NxReal radius=gLanderSize.x; // The bottom "roly" NxSphereShapeDesc rolyDesc; rolyDesc.radius=radius*gLanderSize.z; // relative to top hemisphere rolyDesc.localPose.t=NxVec3(0.0f,radius,0.0f); rolyDesc.materialIndex=gLanderDownMaterial->getMaterialIndex(); // note: both hemispheres use "down" material rolyDesc.mass=1; // relative to top hemisphere rolyDesc.skinWidth=radius/60; rolyDesc.name="downside"; actorDesc.shapes.pushBack(&rolyDesc); // The top "poly" NxSphereShapeDesc polyDesc; polyDesc.radius=radius; polyDesc.localPose.t=NxVec3(0.0f,radius+gLanderSize.y,0.0f); polyDesc.materialIndex=gLanderDownMaterial->getMaterialIndex(); // note: both hemispheres use "down" material polyDesc.mass=1; polyDesc.skinWidth=radius/60; polyDesc.name="upside"; actorDesc.shapes.pushBack(&polyDesc); // The weight NxSphereShapeDesc wDesc; wDesc.radius=radius/10; wDesc.localPose.t=NxVec3(0.0f,wDesc.radius,0.0f); wDesc.materialIndex=gLanderDownMaterial->getMaterialIndex(); // note: this is irrelevant wDesc.mass=gRPWeight; // relative to top hemisphere wDesc.skinWidth=radius/120; wDesc.name="weight"; actorDesc.shapes.pushBack(&wDesc); // the lander bodyDesc.mass=gLanderMass; actorDesc.body=&bodyDesc; actorDesc.globalPose.t=position; assert(actorDesc.isValid()); actor=gScene->createActor(actorDesc); assert(actor); actor->setName("~lander"); //actor->raiseBodyFlag(NX_BF_KINEMATIC); break; } case SHAPED_CHARGE: {// Two flat plates, like a two-layer ruler, one heavy and absorbing, one hollow and elastic NxActorDesc actorDesc; NxBodyDesc bodyDesc; NxVec3 boxDim=gLanderSize/2; // remember NxShapeDesc.dimension is the "radius" boxDim.y/=2; // remember we're going to stack two of these // The down side NxBoxShapeDesc downsideDesc; downsideDesc.dimensions.set(boxDim); downsideDesc.localPose.t=NxVec3(0.0f,boxDim.y,0.0f); downsideDesc.materialIndex=gLanderDownMaterial->getMaterialIndex(); downsideDesc.density=gLanderMassRatio; downsideDesc.skinWidth=boxDim.y/60; downsideDesc.name="downside"; actorDesc.shapes.pushBack(&downsideDesc); // The up side NxBoxShapeDesc upsideDesc; upsideDesc.dimensions.set(boxDim); upsideDesc.localPose.t=NxVec3(0.0f,3.0*boxDim.y,0.0f); upsideDesc.materialIndex=gLanderUpMaterial->getMaterialIndex(); upsideDesc.density=1; upsideDesc.skinWidth=boxDim.y/60; upsideDesc.name="upside"; actorDesc.shapes.pushBack(&upsideDesc); // The Lander bodyDesc.mass=gLanderMass; actorDesc.body = &bodyDesc; actorDesc.globalPose.t = position; assert(actorDesc.isValid()); actor = gScene->createActor(actorDesc); assert(actor); actor->setName("~lander"); break; } case CUBESAT: {// JPL's new fad, comes in units of 10x10x10 cm NxActorDesc actorDesc; NxBodyDesc bodyDesc; NxVec3 boxDim(0.05); // remember NxShapeDesc.dimension is the "radius" // U1 - the dead weight NxBoxShapeDesc U1Desc; U1Desc.dimensions.set(boxDim); U1Desc.localPose.t=NxVec3(0.0f,boxDim.y,0.0f); U1Desc.materialIndex=gLanderDownMaterial->getMaterialIndex(); U1Desc.mass=10*gLanderMass; U1Desc.skinWidth=boxDim.y/60; U1Desc.name="U1"; actorDesc.shapes.pushBack(&U1Desc); // U2 NxBoxShapeDesc U2Desc; U2Desc.dimensions.set(boxDim); U2Desc.localPose.t=NxVec3(0.0f,3.0*boxDim.y,0.0f); U2Desc.materialIndex=gLanderUpMaterial->getMaterialIndex(); U2Desc.mass=gLanderMass; U2Desc.skinWidth=boxDim.y/60; U2Desc.name="U2"; actorDesc.shapes.pushBack(&U2Desc); // U3 NxBoxShapeDesc U3Desc; U3Desc.dimensions.set(boxDim); U3Desc.localPose.t=NxVec3(0.0f,5.0*boxDim.y,0.0f); U3Desc.materialIndex=gLanderUpMaterial->getMaterialIndex(); U3Desc.mass=gLanderMass; U3Desc.skinWidth=boxDim.y/60; U3Desc.name="U3"; actorDesc.shapes.pushBack(&U3Desc); // The Cubesat bodyDesc.mass=gLanderMass; actorDesc.body = &bodyDesc; actorDesc.globalPose.t = position; assert(actorDesc.isValid()); actor = gScene->createActor(actorDesc); assert(actor); actor->setName("~lander"); break; } default: printf("Error: unknown lander type\n"); break; } return actor; }