void InitPhysX() { gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback); gPhysicsSDK = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale() ); if(gPhysicsSDK == NULL) { cerr<<"Error create PhysX."<<endl; } PxSceneDesc sceneDesc(gPhysicsSDK->getTolerancesScale()); sceneDesc.gravity = PxVec3(0.0f, -9.8f, 0.0f); sceneDesc.cpuDispatcher = PxDefaultCpuDispatcherCreate(1); sceneDesc.filterShader = PxDefaultSimulationFilterShader; gScene = gPhysicsSDK->createScene(sceneDesc); PxMaterial* material = gPhysicsSDK->createMaterial(0.5,0.5,0.5); PxTransform planePos = PxTransform(PxVec3(0.0f),PxQuat(PxHalfPi, PxVec3(0.0f, 0.0f, 1.0f))); PxRigidStatic* plane = gPhysicsSDK->createRigidStatic(planePos); plane->createShape(PxPlaneGeometry(), *material); gScene->addActor(*plane); PxTransform boxPos(PxVec3(0.0f, 10.0f, 0.0f)); PxBoxGeometry boxGeometry(PxVec3(2,2,2)); gBox = PxCreateDynamic(*gPhysicsSDK, boxPos, boxGeometry, *material, 1.0f); gScene->addActor(*gBox); }
void CPhysics::CreateGround (int samplesX, int samplesY, float hScale, float wScale, const float* heightmap) { PxHeightFieldDesc hfDesc; PxHeightFieldSample* Samples = new PxHeightFieldSample[sizeof(PxHeightFieldSample)*(samplesX*samplesY)]; for (int x = 0; x < samplesX; ++x) { for (int y = 0; y < samplesY; ++ y) { Samples[x*samplesY + y].materialIndex0 = 0; Samples[x*samplesY + y].materialIndex1 = 0; short Height = heightmap[x*samplesY + y] * 32000; Samples[x*samplesY + y].height = Height; } } hfDesc.format = PxHeightFieldFormat::eS16_TM; hfDesc.nbColumns = samplesX; hfDesc.nbRows = samplesY; hfDesc.samples.data = Samples; hfDesc.samples.stride = sizeof(PxHeightFieldSample); PxHeightField* aHeightField = m_SDK->createHeightField(hfDesc); if (!aHeightField) _CrtDbgBreak(); PxHeightFieldGeometry hfGeom(aHeightField, PxMeshGeometryFlags(), hScale / 32000.f, wScale, wScale); PxTransform Pose = PxTransform(PxVec3(0.f, 0.0f, 0.0f)); PxRigidStatic* aHeightFieldActor = m_SDK->createRigidStatic(Pose); if (!aHeightFieldActor) _CrtDbgBreak(); PxShape* aHeightFieldShape = aHeightFieldActor->createShape(hfGeom, *m_Material); m_Scene->addActor(*aHeightFieldActor); delete Samples; }
PxRigidStatic* createDrivablePlane(physx::PxMaterial* material, PxPhysics* physics) { //Add a plane to the scene. PxRigidStatic* groundPlane = PxCreatePlane(*physics, PxPlane(0,1,0,0), *material); //Get the plane shape so we can set query and simulation filter data. PxShape* shapes[1]; groundPlane->getShapes(shapes, 1); //Set the query filter data of the ground plane so that the vehicle raycasts can hit the ground. physx::PxFilterData qryFilterData; setupDrivableSurface(qryFilterData); shapes[0]->setQueryFilterData(qryFilterData); //Set the simulation filter data of the ground plane so that it collides with the chassis of a vehicle but not the wheels. PxFilterData simFilterData; simFilterData.word0 = COLLISION_FLAG_GROUND; simFilterData.word1 = COLLISION_FLAG_GROUND_AGAINST; shapes[0]->setSimulationFilterData(simFilterData); return groundPlane; }
void Apex::LoadTriangleMesh(int numVerts, PxVec3* verts, ObjectInfo info) { PxRigidStatic* meshActor = mPhysics->createRigidStatic(PxTransform::createIdentity()); PxShape* meshShape; if(meshActor) { PxTriangleMeshDesc meshDesc; meshDesc.points.count = numVerts; meshDesc.points.stride = sizeof(PxVec3); meshDesc.points.data = verts; //meshDesc.triangles.count = numInds/3.; //meshDesc.triangles.stride = 3*sizeof(int); //meshDesc.triangles.data = inds; PxToolkit::MemoryOutputStream writeBuffer; bool status = mCooking->cookTriangleMesh(meshDesc, writeBuffer); if(!status) return; PxToolkit::MemoryInputData readBuffer(writeBuffer.getData(), writeBuffer.getSize()); PxTriangleMeshGeometry triGeom; triGeom.triangleMesh = mPhysics->createTriangleMesh(readBuffer); triGeom.scale = PxMeshScale(PxVec3(info.sx,info.sy,info.sz),physx::PxQuat::createIdentity()); meshShape = meshActor->createShape(triGeom, *defaultMaterial); meshShape->setLocalPose(PxTransform(PxVec3(info.x,info.y,info.z), PxQuat(info.ry, PxVec3(0.0f,1.0f,0.0f)))); meshShape->setFlag(PxShapeFlag::eUSE_SWEPT_BOUNDS, true); meshShape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, true); mScene[mCurrentScene]->addActor(*meshActor); } }
void PhysicalTile::createPxObjects(PxRigidStatic & pxActor) { const unsigned int numSamples = samplesPerAxis * samplesPerAxis; // create the list of material references PxHeightFieldSample * hfSamples = new PxHeightFieldSample[numSamples]; PxMaterial ** materials = new PxMaterial*[m_elementNames.size()]; for (uint8_t i = 0; i < m_elementNames.size(); ++i) materials[i] = Elements::pxMaterial(m_elementNames.at(i)); // scale height so that we use the full range of PxI16=short PxReal heightScaleToWorld = m_terrain.settings.maxHeight / std::numeric_limits<PxI16>::max(); assert(heightScaleToWorld >= PX_MIN_HEIGHTFIELD_Y_SCALE); float heightScaleToPx = std::numeric_limits<PxI16>::max() / m_terrain.settings.maxHeight; // copy the material and height data into the physx height field for (unsigned int row = 0; row < samplesPerAxis; ++row) { const unsigned int rowOffset = row * samplesPerAxis; for (unsigned int column = 0; column < samplesPerAxis; ++column) { const unsigned int index = column + rowOffset; hfSamples[index].materialIndex0 = hfSamples[index].materialIndex1 = elementIndexAt(index); hfSamples[index].height = static_cast<PxI16>(m_values.at(index) * heightScaleToPx); } } PxHeightFieldDesc hfDesc; hfDesc.format = PxHeightFieldFormat::eS16_TM; hfDesc.nbRows = samplesPerAxis; hfDesc.nbColumns = samplesPerAxis; hfDesc.samples.data = hfSamples; hfDesc.samples.stride = sizeof(PxHeightFieldSample); PxHeightField * pxHeightField = PxGetPhysics().createHeightField(hfDesc); assert(sampleInterval >= PX_MIN_HEIGHTFIELD_XZ_SCALE); // create height field geometry and set scale PxHeightFieldGeometry pxHfGeometry(pxHeightField, PxMeshGeometryFlags(), heightScaleToWorld, sampleInterval, sampleInterval); m_pxShape = pxActor.createShape(pxHfGeometry, materials, 1); assert(m_pxShape); #ifdef PX_WINDOWS if (PhysicsWrapper::physxGpuAvailable()) PxParticleGpu::createHeightFieldMirror(*pxHeightField, *PhysicsWrapper::getInstance()->cudaContextManager()); #endif delete[] hfSamples; delete[] materials; }
PxRigidStatic* CServer::createStaticBox(const Vector3 &position, const Vector3 &dimensions, bool trigger, int group, const IPhysics *component) { assert(_scene); // Nota: PhysX coloca el sistema de coordenadas local en el centro de la caja, mientras // que la lógica asume que el origen del sistema de coordenadas está en el centro de la // cara inferior. Para unificar necesitamos realizar una traslación en el eje Y. // Afortunadamente, el descriptor que se usa para crear el actor permite definir esta // transformación local, por lo que la conversión entre sistemas de coordenadas es transparente. // Crear un cubo estático PxTransform pose(Vector3ToPxVec3(position)); PxBoxGeometry geom(Vector3ToPxVec3(dimensions)); PxMaterial *material = _defaultMaterial; PxTransform localPose(PxVec3(0, dimensions.y, 0)); // Transformación de coordenadas lógicas a coodenadas de PhysX PxRigidStatic *actor = PxCreateStatic(*_physics, pose, geom, *material, localPose); // Transformarlo en trigger si es necesario if (trigger) { PxShape *shape; actor->getShapes(&shape, 1, 0); shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false); shape->setFlag(PxShapeFlag::eTRIGGER_SHAPE, true); } // Anotar el componente lógico asociado a la entidad física actor->userData = (void *) component; // Establecer el grupo de colisión PxSetGroup(*actor, group); // Añadir el actor a la escena _scene->addActor(*actor); return actor; }
void Border::Create() { PxRigidStatic* rgd = PHYSICS->createRigidStatic(m_pose); Board* b = const_cast<Board*>(P::board); // Determine Poses Transform p_top, p_bottom_lft, p_bottom_rgt, p_left, p_right; p_top = Transform(b->Top() - Vec3(0,0,m_width)); p_bottom_lft = Transform(Vec3(b->Left().x - m_geometrys[BDR_ID_BTM_LFT].box().halfExtents.x, 0, b->Bottom().z)); p_bottom_rgt = Transform(Vec3(b->Right().x + m_geometrys[BDR_ID_BTM_RGT].box().halfExtents.x + b->PlungerLaneWidth() + m_width*3, 0, b->Bottom().z)); p_left = Transform(b->Left() - Vec3(m_width, 0, 0)); p_right = Transform(b->Right() + Vec3(m_width, 0, -m_width)); // Create Shapes PxShape* sT = rgd->createShape(m_geometrys[BDR_ID_TOP].box(), *m_material); PxShape* sBl = rgd->createShape(m_geometrys[BDR_ID_BTM_LFT].box(), *m_material); PxShape* sBr = rgd->createShape(m_geometrys[BDR_ID_BTM_RGT].box(), *m_material); PxShape* sL = rgd->createShape(m_geometrys[BDR_ID_LFT].box(), *m_material); PxShape* sR = rgd->createShape(m_geometrys[BDR_ID_RGT].box(), *m_material); // Set Local Poses sT->setLocalPose(p_top); sBl->setLocalPose(p_bottom_lft); sBr->setLocalPose(p_bottom_rgt); sL->setLocalPose(p_left); sR->setLocalPose(p_right); // Set Global Pose Transform t = const_cast<Board*>(P::board)->Get().staticActor->getGlobalPose(); rgd->setGlobalPose(P::board->Pose() * Transform(0, m_height*2, 0)); m_actor.staticActor = rgd; m_actor.staticActor->userData = &m_color; }
// Experiment specific functions called from ARSS.cpp void CreateExperiment() { // This is how you turn on the grid display. (There is also an XY Grid.) gDebug.bXZGridOn=true; // This is how you create a ground plane (and save its address in gExp.VIPs). CreateGroundPlane(); // This is how you create a compound, multi-shape, static actor. PxRigidStatic* basket = gPhysX.mPhysics->createRigidStatic(PxTransform(PxVec3(0))); if (!basket) ncc__error("basket fail!"); PxMaterial* defmat=gPhysX.mDefaultMaterial; PxBoxGeometry base(0.5,0.1,0.5); PxBoxGeometry pole(0.05,1,0.05); PxBoxGeometry board(0.5,0.5,0.01); PxBoxGeometry hoopel(0.01,0.01,0.15); basket->createShape(base,*defmat,PxTransform(PxVec3(0,0.1,0))); basket->createShape(pole,*defmat,PxTransform(PxVec3(0,1,0))); PxShape* sboard = basket->createShape(board,*defmat,PxTransform(PxVec3(0,2,0.05))); PxShape* shoopel1 = basket->createShape(hoopel,*defmat,PxTransform(PxVec3(-0.15,2,0.15+0.06))); PxShape* shoopel2 = basket->createShape(hoopel,*defmat,PxTransform(PxVec3(+0.15,2,0.15+0.06))); PxShape* shoopel3 = basket->createShape(hoopel,*defmat,PxTransform(PxVec3(+0.00,2,0.30+0.05),PxQuat(PxPi/2,PxVec3(0,1,0)))); gPhysX.mScene->addActor(*basket); // We saved the pointers to the shapes we wish to color separately, with a call to the convenience function... ColorShape(sboard, ncc::rgb::yLightYellow); // ... or manually (in case we wish to be efficient with duplicate colors). gColors.colorBucket.push_back(vector<GLubyte>(3)); gColors.colorBucket.back()[0]=ncc::rgb::grBlack[0]; gColors.colorBucket.back()[1]=ncc::rgb::grBlack[1]; gColors.colorBucket.back()[2]=ncc::rgb::grBlack[2]; shoopel1->userData=&(gColors.colorBucket.back()[0]); shoopel2->userData=&(gColors.colorBucket.back()[0]); shoopel3->userData=&(gColors.colorBucket.back()[0]); // We signal that the experiment is ready for simulation by setting this flag. gSim.isRunning = true; }
void CPhysics::Init() { bool recordMemoryAllocations = true; static PxDefaultErrorCallback gDefaultErrorCallback; static PxDefaultAllocator gDefaultAllocatorCallback; m_SDK = PxCreatePhysics(PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback, physx::PxTolerancesScale(), recordMemoryAllocations ); if(!m_SDK) _CrtDbgBreak(); if (!PxInitExtensions(*m_SDK)) _CrtDbgBreak(); m_Cooking = PxCreateCooking(PX_PHYSICS_VERSION, &m_SDK->getFoundation(), PxCookingParams()); if (!m_Cooking) _CrtDbgBreak(); PxSceneDesc sceneDesc(m_SDK->getTolerancesScale()); sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f); //customizeSceneDesc(sceneDesc); if(!sceneDesc.cpuDispatcher) { unsigned int Threads = 1; m_CpuDispatcher = PxDefaultCpuDispatcherCreate(Threads); if(!m_CpuDispatcher) _CrtDbgBreak(); sceneDesc.cpuDispatcher = static_cast<physx::pxtask::CpuDispatcher*>(m_CpuDispatcher); } if(!sceneDesc.filterShader) //sceneDesc.filterShader = &PxDefaultSimulationFilterShader; sceneDesc.filterShader = &ButterflyFilterShader; /* #ifdef PX_WINDOWS if (true) { pxtask::CudaContextManagerDesc cudaContextManagerDesc; mCudaContextManager = pxtask::createCudaContextManager(cudaContextManagerDesc, &mSDK->getProfileZoneManager()); } if(!sceneDesc.gpuDispatcher && mCudaContextManager) { sceneDesc.gpuDispatcher = mCudaContextManager->getGpuDispatcher(); } #endif*/ m_Scene = m_SDK->createScene(sceneDesc); if (!m_Scene) _CrtDbgBreak(); // Basicowy material m_Material = m_SDK->createMaterial(0.5f, 0.5f, 0.1f); //static friction, dynamic friction, restitution if(!m_Material) _CrtDbgBreak(); m_Scene->setSimulationEventCallback(new CCollisionCallback); // PVD if (m_SDK->getPvdConnectionManager() == NULL) _CrtDbgBreak(); //The connection flags state overall what data is to be sent to PVD. Currently //the Debug connection flag requires support from the implementation (don't send //the data when debug isn't set) but the other two flags, profile and memory //are taken care of by the PVD SDK. //PVD::TConnectionFlagsType theConnectionFlags( PVD::PvdConnectionType::Debug | PVD::PvdConnectionType::Profile | PVD::PvdConnectionType::Memory ); //Use these flags for a clean profile trace with minimal overhead PVD::TConnectionFlagsType theConnectionFlags( PVD::PvdConnectionType::Profile | PVD::PvdConnectionType::Debug); //Create a pvd connection that writes data straight to the filesystem. This is //the fastest connection on windows for various reasons. First, the transport is quite fast as //pvd writes data in blocks and filesystems work well with that abstraction. //Second, you don't have the PVD application parsing data and using CPU and memory bandwidth //while your application is running. //return mSDK->getPvdConnectionManager()->connect("c:\\temp.pxd2", true, theConnectionFlags); //The normal way to connect to pvd. PVD needs to be running at the time this function is called. //We don't worry about the return value because we are already registered as a listener for connections //and thus our onPvdConnected call will take care of setting up our basic connection state. PVD::PvdConnection* Conn = PxExtensionVisualDebugger::connect(m_SDK->getPvdConnectionManager(), "127.0.0.1", 5425, 10, true, PxDebuggerConnectionFlags( (PxU32)theConnectionFlags) ); // Test plane PxReal d = 0.0f; PxU32 axis = 1; PxTransform pose; #pragma region Testowe obiekty if(axis == 0) pose = PxTransform(PxVec3(d, 0.0f, 0.0f)); else if(axis == 1) pose = PxTransform(PxVec3(0.0f, d, 0.0f),PxQuat(PxHalfPi, PxVec3(0.0f, 0.0f, 1.0f))); else if(axis == 2) pose = PxTransform(PxVec3(0.0f, 0.0f, d), PxQuat(-PxHalfPi, PxVec3(0.0f, 1.0f, 0.0f))); PxRigidStatic* plane = m_SDK->createRigidStatic(pose); if (!plane) _CrtDbgBreak(); PxShape* shape = plane->createShape(PxPlaneGeometry(), *m_Material); if (!shape) _CrtDbgBreak(); m_Scene->addActor(*plane); PxReal density = 1.0f; PxTransform transform(PxVec3(50.0f, 50.0f, 50.0f), PxQuat::createIdentity()); PxVec3 dimensions(1.0f, 1.0f, 1.0f); PxBoxGeometry geometry(dimensions); PxRigidDynamic *actor = PxCreateDynamic(*m_SDK, transform, geometry, *m_Material, density); if (!actor) _CrtDbgBreak(); m_Scene->addActor(*actor); //physx::repx::RepXCollection* collection = physx::repx::createCollection("file.xml"); //physx::repx::addObjectsToScene(collection, m_SDK, m_Cooking, m_Scene, 0); #pragma endregion }
PhysicsSystemPhysX::PhysicsSystemPhysX() : PhysicsSystem() { Log("HELLO PHYSX"); static PxDefaultErrorCallback gDefaultErrorCallback; static PxDefaultAllocator gDefaultAllocatorCallback; PxFoundation* mFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback); if (!mFoundation) Log("PxCreateFoundation failed!"); PxProfileZoneManager* mProfileZoneManager = &PxProfileZoneManager::createProfileZoneManager(mFoundation); if (!mProfileZoneManager) Log("PxProfileZoneManager::createProfileZoneManager failed!"); bool recordMemoryAllocations = true; mPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *mFoundation, PxTolerancesScale(), recordMemoryAllocations, mProfileZoneManager); if (!mPhysics) Log("PxCreatePhysics failed!"); if (!PxInitExtensions(*mPhysics)) Log("PxInitExtensions failed!"); // static PxDefaultSimulationFilterShader gDefaultFilterShader; //static PxFilterFlags gDefaultFilterShader = PxSceneDesc sceneDesc(mPhysics->getTolerancesScale()); sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f); sceneDesc.gravity = PxVec3(0.0f, -19.81f, 0.0f); //sceneDesc. //customizeSceneDesc(sceneDesc); if (!sceneDesc.cpuDispatcher) { PxDefaultCpuDispatcher* mCpuDispatcher = PxDefaultCpuDispatcherCreate(1); if (!mCpuDispatcher) Log("PxDefaultCpuDispatcherCreate failed!"); sceneDesc.cpuDispatcher = mCpuDispatcher; } if (!sceneDesc.filterShader) sceneDesc.filterShader = PxDefaultSimulationFilterShader; /* #ifdef PX_WINDOWS if(!sceneDesc.gpuDispatcher && mCudaContextManager) { sceneDesc.gpuDispatcher = mCudaContextManager->getGpuDispatcher(); } #endif*/ mScene = mPhysics->createScene(sceneDesc); if (!mScene) Log("createScene failed!"); PxMaterial* mMaterial; mMaterial = mPhysics->createMaterial(0.5f, 0.5f, 0.1f); //static friction, dynamic friction, restitution if (!mMaterial) Log("createMaterial failed!"); aSphereActor = mPhysics->createRigidDynamic(PxTransform(0, 30, 0)); PxShape* aSphereShape = aSphereActor->createShape(PxSphereGeometry(1), *mMaterial); PxRigidBodyExt::updateMassAndInertia(*aSphereActor, 2); mScene->addActor(*aSphereActor); aSphereActor->setLinearVelocity(PxVec3(1, 1, 1)); PxRigidStatic* groundPlaneActor = mPhysics->createRigidStatic(PxTransform(0.f, -10.f, 0.f)); PxShape* groundShape = groundPlaneActor->createShape(PxBoxGeometry(150.f, 5.f, 150.f), *mMaterial); mScene->addActor(*groundPlaneActor); manager = PxCreateControllerManager(*mScene); }
void PhysXRigidManager::addStaticBody(const std::string & scene, physx::PxScene * world, physx::PxCooking * mCooking, nau::physics::IPhysics::BoundingVolume shape, physx::PxMaterial * material) { PxPhysics *gPhysics = &(world->getPhysics()); PxRigidStatic * staticActor; PxTransform trans = PxTransform(PxMat44(rigidBodies[scene].info.extInfo.transform)); switch (shape.sceneShape) { case nau::physics::IPhysics::BOX: { staticActor = PxCreateStatic( world->getPhysics(), trans, PxBoxGeometry(shape.max[0], shape.max[1], shape.max[2]), *material ); } break; case nau::physics::IPhysics::SPHERE: { staticActor = PxCreateStatic( world->getPhysics(), trans, PxSphereGeometry(shape.max[0]), *material ); } break; case nau::physics::IPhysics::CAPSULE: { staticActor = PxCreateStatic( world->getPhysics(), trans, PxCapsuleGeometry( shape.max[0], shape.max[1] ), *material ); } break; default: { if (scene.compare("plane") == 0) { staticActor = PxCreatePlane( world->getPhysics(), PxPlane(0.0f, 1.0f, 0.0f, 0.0f), *material ); } else { staticActor = gPhysics->createRigidStatic(trans); PxTriangleMeshGeometry triGeom(gPhysics->createTriangleMesh(*getTriangleMeshGeo(world, mCooking, rigidBodies[scene].info.extInfo, true))); //triGeom.triangleMesh = gPhysics->createTriangleMesh(*getTriangleMeshGeo(world, mCooking, rigidBodies[scene].extInfo, true)); staticActor->createShape(triGeom, *material); } } break; } staticActor->userData = static_cast<void*> (new std::string(scene)); world->addActor(*staticActor); rigidBodies[scene].info.actor = staticActor; }
void PhsXWorld::_addRigid(float mass, float friction, float restitution, std::shared_ptr<nau::scene::IScene> &aScene, std::string name, nau::math::vec3 aVec) { PxPhysics *gPhysics = &(m_pDynamicsWorld->getPhysics()); if (mass == 0.0f) { PxRigidStatic* staticActor; if (name.compare("plane") == 0) { staticActor = PxCreatePlane(*gPhysics, PxPlane(0.0f, 1.0f, 0.0f, 0.0f), *(gPhysics->createMaterial(friction, friction, restitution)) ); } else { /*if (name.compare("box") == 0) { staticActor = PxCreateStatic(*gPhysics, PxTransform(PxMat44(const_cast<float*> (aScene->getTransform().getMatrix()))), PxBoxGeometry(1.0f,1.0f,1.0f), *(gPhysics->createMaterial(1.0f, 1.0f, 0.6f)) ); } else {*/ staticActor = gPhysics->createRigidStatic(PxTransform(PxMat44(const_cast<float*> (aScene->getTransform().getMatrix())))); PxTriangleMeshGeometry triGeom; triGeom.triangleMesh = gPhysics->createTriangleMesh(getTriangleMeshGeo(m_pDynamicsWorld, aScene)); staticActor->createShape(triGeom, *(gPhysics->createMaterial(friction, friction, restitution))); //} } staticActor->userData = aScene.get(); m_pDynamicsWorld->addActor(*staticActor); } else { PxRigidDynamic* dynamic; //if (name.compare("ball") == 0) { // dynamic = PxCreateDynamic(*gPhysics, // PxTransform(PxMat44(const_cast<float*> (aScene->getTransform().getMatrix()))), // PxSphereGeometry(1), // *(gPhysics->createMaterial(0.5f, 0.5f, 0.6f)), // 10.0f // ); // //dynamic->setLinearVelocity(PxVec3(0, -50, -100)); //} //else { PxTransform trans = PxTransform(PxMat44(const_cast<float*> (aScene->getTransform().getMatrix()))); dynamic = gPhysics->createRigidDynamic(trans); PxConvexMesh * convexMesh = gPhysics->createConvexMesh(getTriangleMeshGeo(m_pDynamicsWorld, aScene, false)); PxConvexMeshGeometry convGeom(convexMesh); //PxConvexMeshGeometry convGeom(convexMesh, PxMeshScale(0.5f)); //convGeom.convexMesh = gPhysics->createConvexMesh(getTriangleMeshGeo(m_pDynamicsWorld, aScene, false)); //PxShape *shape = dynamic->createShape(convGeom, *(gPhysics->createMaterial(0.5f, 0.5f, 0.6f)), PxShapeFlag::eSIMULATION_SHAPE | PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSCENE_QUERY_SHAPE); PxShape *shape = dynamic->createShape(convGeom, *(gPhysics->createMaterial(friction, friction, restitution))); //shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, true); //dynamic->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, false); //} dynamic->userData = aScene.get(); //dynamic->setAngularDamping(0.5f); //dynamic->setLinearVelocity(velocity); m_pDynamicsWorld->addActor(*dynamic); } }
FDbool BuildingSystem::searchForHit(PhysicsSystem& physicsSystem, Ray r, PxGeometry& pixelFrustum, SearchContext& searchContext) { // Cast the ray into the scene. Quit if no intersection at all. PxQueryFilterData qFilterData; qFilterData.flags |= PxQueryFlag::ePREFILTER | PxQueryFlag::ePOSTFILTER; FDbool rayStatus = physicsSystem.scene->raycast( r.position, r.direction, 100, searchContext.hitBuffer, PxHitFlag::ePOSITION | PxHitFlag::eDISTANCE | PxHitFlag::eNORMAL, qFilterData, &CustomPhysicsQueryFilter()); /* Demo-ing to a friend showed that it can be confusing to try to connect * up an existing point that lies on the guide plane, since part of it will * be behind the guide plane, which the ray-cast will see as being closer. * To remedy this, I treat the GuidePlane as a "touching" rather than * "blocking hit" and give some priority to points. */ if (rayStatus && searchContext.hitBuffer.hasBlock) { // In this case, we know we hit something other than the guide plane. searchContext.hitActor = searchContext.hitBuffer.block.actor; searchContext.rayHit = &searchContext.hitBuffer.block; FDreal blockDistance = searchContext.rayHit->distance; searchContext.setHit(&searchContext.hitBuffer.block); // If the guide plane was also hit, see if it is closer. if (searchContext.hitBuffer.nbTouches > 0) { float guidePlaneDistance = searchContext.hitBuffer.getTouch(0). distance; // If the point intersects the plane, prefer it. if (searchContext.hitActor == pointActor) { FDUint i = (FDUint)searchContext.rayHit->shape->userData; Vector3 pointPos = *pointAuthor->getAttribute<Vector3>(i, 0); float pointRadius = 0.2; Vector3 guidePlaneNormal = searchContext.hitBuffer. getTouch(0).normal; Plane p = Plane(searchContext.hitBuffer.getTouch(0).position, guidePlaneNormal); // We know the point (modeled as a sphere) intersects the // plane if the point is within 1 sphere radius. float pointPlaneDistance = p.distance(pointPos); if (abs(pointPlaneDistance) <= pointRadius) { blockDistance = 0; } } if (guidePlaneDistance < blockDistance) { searchContext.hitActor = searchContext.hitBuffer.getTouch(0). actor; searchContext.setHit(&searchContext.hitBuffer.getTouch(0)); } } } else if (rayStatus) { // Only the guide plane was hit. searchContext.hitActor = searchContext.hitBuffer.getTouch(0).actor; searchContext.setHit(&searchContext.hitBuffer.getTouch(0)); } // Try overlap test for other geometry. Quaternion q = fdmath::getRotationBetween(Vector3(0, 0, 1), r.direction); Vector3 obo = q.rotate(Vector3(0, 0, 1)); PxTransform pose(r.position, q); PxQueryFilterData qPixelFilterData; qPixelFilterData.flags |= PxQueryFlag::ePREFILTER; physicsSystem.scene->overlap(pixelFrustum, pose, searchContext.overlapBuffer, qPixelFilterData, &PixelQueryFilter()); for (FDUint i = 0; i < searchContext.overlapBuffer.nbTouches; i++) { PxRigidStatic* thisActor = (PxRigidStatic*)searchContext.overlapBuffer. touches[i].actor; PxShape* thisShape = searchContext.overlapBuffer.touches[i].shape; // Get the closet point on the line to the ray. Transform lineTransform = thisActor->getGlobalPose() * thisShape->getLocalPose(); Vector3 lineAxisPoint = lineTransform.transform(Vector3(1, 0, 0)); Vector3 centerPos = lineTransform.p; Vector3 lineAxis = (lineAxisPoint - centerPos).getNormalized(); Vector3 uAxis = lineAxis.cross(r.direction); uAxis.normalize(); Plane p(centerPos, lineAxisPoint, centerPos + uAxis); Vector3 intersectionPoint; FDbool intersects = r.intersect(p, intersectionPoint); FD_ASSERT(intersects, "Ray did not intersect line's plane."); FDreal y = lineAxis.dot(intersectionPoint) - lineAxis.dot(centerPos); Vector3 closestPoint = centerPos + lineAxis * y; FDreal dist = (closestPoint - r.position).magnitude(); if (dist < searchContext.hitDist) { searchContext.setHit(&searchContext.overlapBuffer.touches[i], closestPoint, -r.direction, dist); searchContext.hitActor = thisActor; } } return searchContext.hitHappened; }
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); }