void PhysXMeshCollider::applyGeometry() { if (!mMesh.isLoaded()) { setGeometry(PxSphereGeometry(0.01f)); // Dummy return; } FPhysXMesh* physxMesh = static_cast<FPhysXMesh*>(mMesh->_getInternal()); if (mMesh->getType() == PhysicsMeshType::Convex) { PxConvexMeshGeometry geometry; geometry.scale = PxMeshScale(toPxVector(getScale()), PxIdentity); geometry.convexMesh = physxMesh->_getConvex(); setGeometry(geometry); } else // Triangle { PxTriangleMeshGeometry geometry; geometry.scale = PxMeshScale(toPxVector(getScale()), PxIdentity); geometry.triangleMesh = physxMesh->_getTriangle(); setGeometry(geometry); } }
int RayCastManagerImpl::CastSweep(const XMFLOAT3& p_origin, XMFLOAT3& p_direction, float p_width, const float& p_range, int& o_flag) { if(p_range <= 0.0f) { cout << "Physcs. Raytracer. Sweep. Range of sweep was zero or below" << endl; return -1; } // Cast directx things to physx PxVec3 origin = PxVec3(p_origin.x, p_origin.y, p_origin.z); PxVec3 direction = PxVec3(p_direction.x, p_direction.y, p_direction.z); direction.normalize(); PxSweepBuffer hit; // Used to save the hit /// Paramters for the sweep // PxGeometry* geometry bool status = m_utils.m_worldScene->sweep(PxSphereGeometry(p_width), PxTransform(origin), direction, p_range, hit, PxHitFlag::eMESH_BOTH_SIDES); // hit.block.position; if(!status && !hit.hasBlock) { // No hit detected, return -1 TODOKO Maybee i should return something better? return -1; } // Start with checking static and dynamic rigid bodies unordered_map<PxRigidActor*, int> idsByRigidBody = m_utils.m_rigidBodyManager->GetIDsByBodies(); if(idsByRigidBody.find(hit.block.actor) != idsByRigidBody.end()) { PxRigidActor* actorAsRigic = (PxRigidActor*)hit.block.actor; if(actorAsRigic->isRigidDynamic()) { PxRigidDynamic* actorsAsDynamic = (PxRigidDynamic*)hit.block.actor; if(actorsAsDynamic->getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC) { o_flag = 0; } } else if(actorAsRigic->isRigidStatic()) { o_flag = 3; } return idsByRigidBody.find(hit.block.actor)->second; } else { // Nothing } // Now comes the difficult task of checking vs character controllers unordered_map<PxController*, int> idsByCharacterController = m_utils.m_characterControlManager->GetIdsByControllers(); for(auto pairs : idsByCharacterController) // Loop through every pair in the list { if(pairs.first->getActor() == hit.block.actor) // The first part contains the actor pointer { o_flag = 1; return pairs.second; // If this is true we found a hit vs character controller, second contains ID } } return -1; }
// add a bullet in the scene void AddBullet(const PxVec3& pos, const PxVec3& v) { PxShape *shape = gPhysics->createShape(PxSphereGeometry(0.3f), *gMaterial); PxTransform localTmS(pos); PxRigidDynamic *body = gPhysics->createRigidDynamic(localTmS); body->attachShape(*shape); PxRigidBodyExt::updateMassAndInertia(*body, 100.0f); body->setLinearVelocity(v); gScene->addActor(*body); shape->release(); }
bool ParticleChain::checkPenetration(const Ogre::Vector3 &position, Ogre::Vector3 &closestSurfacePos, Ogre::Vector3 &collisionNormal) { PxShape *hit = nullptr; PxVec3 pxPos = Convert::toPx(position); if (mPhysXScene->getPxScene()->overlapAny(PxSphereGeometry(0.05f), PxTransform(pxPos), hit)) { PxVec3 actorCenter = hit->getActor().getWorldBounds().getCenter(); PxVec3 rayDir = actorCenter - pxPos; rayDir.normalize(); PxVec3 rayOrigin = pxPos - rayDir.multiply(PxVec3(0.2f, 0.2f, 0.2f)); if (mPhysXScene->getPxScene()->overlapAny(PxSphereGeometry(0.05f), PxTransform(rayOrigin), hit)) return false; PxRaycastHit rayHit; if (mPhysXScene->getPxScene()->raycastSingle(rayOrigin, rayDir, 0.2f, PxSceneQueryFlag::eIMPACT|PxSceneQueryFlag::eNORMAL|PxSceneQueryFlag::eDISTANCE, rayHit)) { closestSurfacePos = Convert::toOgre(rayHit.impact); collisionNormal = Convert::toOgre(rayHit.normal); return true; } } return false; }
// add some physics objects into the scene void AddPhyObjects() { PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0, 1, 0, 0), *gMaterial); gScene->addActor(*groundPlane); PxShape* shape = gPhysics->createShape(PxBoxGeometry(1.0f, 1.0f, 1.0f), *gMaterial); PxTransform localTm(PxVec3(-3.0f, 5.0f, 0.f)); PxRigidDynamic* body = gPhysics->createRigidDynamic(localTm); body->attachShape(*shape); PxRigidBodyExt::updateMassAndInertia(*body, 10.0f); gScene->addActor(*body); shape->release(); shape = gPhysics->createShape(PxSphereGeometry(1.0f), *gMaterial); PxTransform localTmS(PxVec3(3.0f, 5.0f, 0.f)); body = gPhysics->createRigidDynamic(localTmS); body->attachShape(*shape); PxRigidBodyExt::updateMassAndInertia(*body, 10.0f); gScene->addActor(*body); shape->release(); PxRigidDynamic* dynamic = PxCreateDynamic(*gPhysics, PxTransform(PxVec3(0, 20, 20)), PxSphereGeometry(1), *gMaterial, 10.0f); dynamic->setAngularDamping(0.5f); dynamic->setLinearVelocity(PxVec3(0, -5, -10)); gScene->addActor(*dynamic); // add capsule into the scene shape = gPhysics->createShape(PxCapsuleGeometry(1.0f, 3.0f), *gMaterial); PxTransform localTmC(PxVec3(3.0f, 5.0f, -3.f)); body = gPhysics->createRigidDynamic(localTmC); body->attachShape(*shape); PxRigidBodyExt::updateMassAndInertia(*body, 10.0f); gScene->addActor(*body); // add a static box as the trigger shape = gPhysics->createShape(PxBoxGeometry(1.0f, 1.0f, 1.0f), *gMaterial); PxTransform localTmTrigger(PxVec3(0.0f, 1.0f, -10.f)); body = gPhysics->createRigidDynamic(localTmTrigger); shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false); shape->setFlag(PxShapeFlag::eTRIGGER_SHAPE, true); body->attachShape(*shape); body->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true); gScene->addActor(*body); shape->release(); }
PxActor* World::addSphere(const float size, const ofVec3f& pos, const ofQuaternion& rot, float mass) { assert(inited); return createRigidBody(PxSphereGeometry(size), mass, pos, rot); }
/** * Method is used to add new dynamic actor to physics scene. * @param entity is pointer to scene entity which will be added to physics simulation. * @param type is enumeration of shape type. * @param filterGroup is actor own id. * @param filterMask is mask to filter pairs that trigger a contact callback. */ void PhysicsManager::addDynamicActor(SceneEntity* entity, ShapeType type, PxU32 filterGroup, PxU32 filterMask) { PxRigidDynamic* actor = nullptr; PxVec3 position = PxVec3(entity->entityState.position[0],entity->entityState.position[1],entity->entityState.position[2]); PxQuat orientation = PxQuat(entity->entityState.orientation[0],entity->entityState.orientation[1],entity->entityState.orientation[2],entity->entityState.orientation[3]); PxReal density = 1.0f; PxTransform transformation = PxTransform(position,orientation); if(type == BOX) { float x = (entity->entityGeometry.geometryBox->max.x() - entity->entityGeometry.geometryBox->min.x())*entity->entityState.scale.x()*0.5f; float y = (entity->entityGeometry.geometryBox->max.y() - entity->entityGeometry.geometryBox->min.y())*entity->entityState.scale.y()*0.5f; float z = (entity->entityGeometry.geometryBox->max.z() - entity->entityGeometry.geometryBox->min.z())*entity->entityState.scale.z()*0.5f; PxVec3 dimensions(x,y,z); actor = PxCreateDynamic(*physicsSDK,transformation,PxBoxGeometry(dimensions),*materials[0].second,density); PxRigidBodyExt::updateMassAndInertia(*actor, density); } else if(type == SPHERE) { float radius = entity->entityGeometry.geometrySphere->sphereRadius; actor = PxCreateDynamic(*physicsSDK,transformation,PxSphereGeometry(radius),*materials[0].second,density); } else if(type == CAPSULE) { float radius = entity->entityGeometry.geometrySphere->sphereRadius; actor = PxCreateDynamic(*physicsSDK,transformation,PxCapsuleGeometry(radius/2, radius),*materials[0].second,density); } else if(type == CONVEX) { /*int vertsCount = entity->entityGeometry.geometryMesh->getVerticesAmount(); AyumiUtils::Vertex<>* verts = entity->entityGeometry.geometryMesh->getVertices(); PxVec3* convexVerts = new PxVec3[vertsCount]; for(int i = 0; i < vertsCount; ++i) convexVerts[i] = PxVec3(verts[i].x,verts[i].y,verts[i].z); PxConvexMeshDesc convexDesc; convexDesc.points.count = entity->entityGeometry.geometryMesh->getVerticesAmount(); convexDesc.points.stride = sizeof(PxVec3); convexDesc.points.data = convexVerts; convexDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX; MemoryWriteBuffer buf; if(cooking->cookConvexMesh(convexDesc, buf)) { PxConvexMesh* convexMesh = physicsSDK->createConvexMesh(MemoryReadBuffer(buf.data)); actor = PxCreateDynamic(*physicsSDK,transformation,PxConvexMeshGeometry(convexMesh,PxMeshScale()),*materials[0].second,density); } else { Logger::getInstance()->saveLog(Log<string>("Convex Mesh creation error occurred!")); return; }*/ //delete[] convexVerts; } else { Logger::getInstance()->saveLog(Log<string>("Dynamic Actor shape creation error occurred!")); return; } if(!actor) Logger::getInstance()->saveLog(Log<string>("Static Actor creation error occurred!")); PxRigidBodyExt::updateMassAndInertia(*actor, density); actor->setAngularDamping(0.75); actor->setLinearVelocity(PxVec3(0,0,0)); actor->setName(entity->entityName.c_str()); setupFiltering(actor,filterGroup,filterMask); scene->addActor(*actor); DynamicActor* d = new DynamicActor(); d->entityLogic = entity; d->entityPhysics = actor; d->shapesAmount = actor->getNbShapes(); d->shapes = new PxShape*[d->shapesAmount]; dynamicActors.push_back(d); }
void PhysXPhysics::VAddSphere(float radius, Actor* gameActor, const std::string& densityStr, const std::string& physicsMaterial, bool gravityEnabled, float linearDamping, float angularDamping, Mat4x4 relativeTransform, const std::string& bodyType) { float density = LookupDensity(densityStr); AddShape(gameActor, &PxSphereGeometry(radius), density, physicsMaterial, gravityEnabled, linearDamping, angularDamping, bodyType); }