Seamine* SampleSubmarine::createSeamine(const PxVec3& inPosition, PxReal inHeight) { static const PxReal chainLinkLength = 2.0f; static const PxReal linkSpacing = 0.05f; static const PxReal mineHeadRadius = 1.5f; const PxVec3 mineStartPos = inPosition; static const PxVec3 linkOffset = PxVec3(0, chainLinkLength + linkSpacing, 0); static const PxVec3 halfLinkOffset = linkOffset * 0.5f; static const PxVec3 linkDim = PxVec3(chainLinkLength*0.125f, chainLinkLength*0.5f, chainLinkLength*0.125f); PxU32 numLinks = PxU32((inHeight - 2.0f*mineHeadRadius) / (chainLinkLength + linkSpacing)); numLinks = numLinks ? numLinks : 1; Seamine* seamine = SAMPLE_NEW(Seamine); mSeamines.push_back(seamine); // create links from floor PxVec3 linkPos = mineStartPos + halfLinkOffset; PxRigidActor* prevActor = NULL; for(PxU32 i = 0; i < numLinks; i++) { // create the link actor PxRigidDynamic* link = createBox(linkPos, linkDim, NULL, mSeamineMaterial, 1.0f)->is<PxRigidDynamic>(); if(!link) fatalError("createBox failed!"); // back reference to mineHead link->userData = seamine; seamine->mLinks.push_back(link); setupFiltering(link, FilterGroup::eMINE_LINK, FilterGroup::eSUBMARINE); link->setLinearDamping(0.5f); link->setAngularDamping(0.5f); link->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, true); // create distance joint between link and prevActor PxTransform linkFrameA = prevActor ? PxTransform(halfLinkOffset, PxQuat::createIdentity()) : PxTransform(mineStartPos, PxQuat::createIdentity()); PxTransform linkFrameB = PxTransform(-halfLinkOffset, PxQuat::createIdentity()); PxDistanceJoint *joint = PxDistanceJointCreate(getPhysics(), prevActor, linkFrameA, link, linkFrameB); if(!joint) fatalError("PxDistanceJointCreate failed!"); // set min & max distance to 0 joint->setMaxDistance(0.0f); joint->setMinDistance(0.0f); // setup damping & spring joint->setDamping(1.0f * link->getMass()); joint->setSpring(400.0f * link->getMass()); joint->setDistanceJointFlags(PxDistanceJointFlag::eMAX_DISTANCE_ENABLED | PxDistanceJointFlag::eMIN_DISTANCE_ENABLED | PxDistanceJointFlag::eSPRING_ENABLED); // add to joints array for cleanup mJoints.push_back(joint); prevActor = link; linkPos += linkOffset; } // create mine head linkPos.y += mineHeadRadius - (chainLinkLength*0.5f); PxRigidDynamic* mineHead = createSphere(linkPos, mineHeadRadius, NULL, mSeamineMaterial, 1.0f)->is<PxRigidDynamic>(); mineHead->userData = seamine; seamine->mMineHead = mineHead; mineHead->setLinearDamping(0.5f); mineHead->setAngularDamping(0.5f); mineHead->setActorFlag(PxActorFlag::eDISABLE_GRAVITY, true); // setup filtering to trigger contact reports when submarine touches the minehead setupFiltering(mineHead, FilterGroup::eMINE_HEAD, FilterGroup::eSUBMARINE); // create distance joint between mine head and prevActor PxTransform linkFrameA = PxTransform(halfLinkOffset, PxQuat::createIdentity()); PxTransform linkFrameB = PxTransform(PxVec3(0, -mineHeadRadius - linkSpacing*0.5f, 0), PxQuat::createIdentity()); PxDistanceJoint *joint = PxDistanceJointCreate(getPhysics(), prevActor, linkFrameA, mineHead, linkFrameB); if(!joint) fatalError("PxDistanceJointCreate failed!"); // set min & max distance to 0 joint->setMaxDistance(0.0f); joint->setMinDistance(0.0f); // setup damping & spring joint->setDamping(1.0f * mineHead->getMass()); joint->setSpring(400.0f * mineHead->getMass()); joint->setDistanceJointFlags(PxDistanceJointFlag::eMAX_DISTANCE_ENABLED | PxDistanceJointFlag::eMIN_DISTANCE_ENABLED | PxDistanceJointFlag::eSPRING_ENABLED); // add to joints array for cleanup mJoints.push_back(joint); return seamine; }
void InitializePhysX() { gFoundation = PxCreateFoundation( PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback); // Creating instance of PhysX SDK gPhysicsSDK = PxCreatePhysics( PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale()); if(gPhysicsSDK==NULL) { cerr<<"Error creating PhysX3 device."<<endl; cerr<<"Exiting..."<<endl; exit(1); } if(!PxInitExtensions(*gPhysicsSDK)) cerr<<"PxInitExtensions failed!"<<endl; //PxExtensionVisualDebugger::connect(gPhysicsSDK->getPvdConnectionManager(),"localhost",5425, 10000, true); //Create the scene PxSceneDesc sceneDesc(gPhysicsSDK->getTolerancesScale()); sceneDesc.gravity = PxVec3(0.0f, -9.8f, 0.0f); if(!sceneDesc.cpuDispatcher) { PxDefaultCpuDispatcher* mCpuDispatcher = PxDefaultCpuDispatcherCreate(1); if(!mCpuDispatcher) cerr<<"PxDefaultCpuDispatcherCreate failed!"<<endl; sceneDesc.cpuDispatcher = mCpuDispatcher; } if(!sceneDesc.filterShader) sceneDesc.filterShader = gDefaultFilterShader; gScene = gPhysicsSDK->createScene(sceneDesc); if(!gScene) cerr<<"createScene failed!"<<endl; gScene->setVisualizationParameter(PxVisualizationParameter::eSCALE, 1.0); gScene->setVisualizationParameter(PxVisualizationParameter::eCOLLISION_SHAPES, 1.0f); PxMaterial* mMaterial = gPhysicsSDK->createMaterial(0.5, 0.5, 0.5); //Create actors //1) Create ground plane PxReal d = 0.0f; PxTransform pose = PxTransform(PxVec3(0.0f, 0, 0.0f), PxQuat(PxHalfPi, PxVec3(0.0f, 0.0f, 1.0f))); PxRigidStatic* plane = gPhysicsSDK->createRigidStatic(pose); if(!plane) cerr<<"create plane failed!"<<endl; PxShape* shape = plane->createShape(PxPlaneGeometry(), *mMaterial); if(!shape) cerr<<"create shape failed!"<<endl; gScene->addActor(*plane); //2) Create dynamic cube PxReal density = 1.0f; PxTransform transform(PxVec3(0.0f, 3.0, 0.0f), PxQuat::createIdentity()); PxVec3 dimensions(0.5, 0.5, 0.5); PxBoxGeometry geometry(dimensions); PxRigidDynamic *dyn_box = PxCreateDynamic(*gPhysicsSDK, transform, geometry, *mMaterial, density); if(!dyn_box) cerr<<"create actor failed!"<<endl; dyn_box->setAngularDamping(0.75); dyn_box->setLinearVelocity(PxVec3(0, 0, 0)); gScene->addActor(*dyn_box); boxes.push_back(dyn_box); //create static cube transform.p = PxVec3(0, 5, 0); PxRigidStatic *static_box = PxCreateStatic(*gPhysicsSDK, transform, geometry, *mMaterial); if(!static_box) cerr<<"create actor failed!"<<endl; gScene->addActor(*static_box); boxes.push_back(static_box); //create a joint PxDistanceJoint* j = PxDistanceJointCreate(*gPhysicsSDK, dyn_box, PxTransform::createIdentity(), static_box, PxTransform::createIdentity()); j->setDamping(1); //j->setSpring(200); j->setMinDistance(1); j->setMaxDistance(2); j->setConstraintFlag(PxConstraintFlag::eCOLLISION_ENABLED, true); j->setDistanceJointFlag(PxDistanceJointFlag::eMIN_DISTANCE_ENABLED, true); j->setDistanceJointFlag(PxDistanceJointFlag::eMAX_DISTANCE_ENABLED, true); j->setDistanceJointFlag(PxDistanceJointFlag::eSPRING_ENABLED, true); }