void Picking::grabActor(const PxVec3& worldImpact, const PxVec3& rayOrigin) { if(!mSelectedActor || (mSelectedActor->getType() != PxActorType::eRIGID_DYNAMIC && mSelectedActor->getType() != PxActorType::eARTICULATION_LINK)) return; PxScene& scene = mFrame.getActiveScene(); PxPhysics& physics = scene.getPhysics(); //create a shape less actor for the mouse { mMouseActor = physics.createRigidDynamic(PxTransform(worldImpact, PxQuat::createIdentity())); mMouseActor->setRigidDynamicFlag(PxRigidDynamicFlag::eKINEMATIC, true); mMouseActor->setMass(1.0f); mMouseActor->setMassSpaceInertiaTensor(PxVec3(1.0f, 1.0f, 1.0f)); scene.addActor(*mMouseActor); mFrame.addPhysicsActors(mMouseActor); } PxRigidActor* pickedActor = static_cast<PxRigidActor*>(mSelectedActor); #if USE_D6_JOINT_FOR_MOUSE mMouseJoint = PxD6JointCreate( physics, mMouseActor, PxTransform::createIdentity(), pickedActor, PxTransform(pickedActor->getGlobalPose().transformInv(worldImpact))); #elif USE_SPHERICAL_JOINT_FOR_MOUSE mMouseJoint = PxSphericalJointCreate(physics, mMouseActor, PxTransform::createIdentity(), pickedActor, PxTransform(pickedActor->getGlobalPose().transformInv(worldImpact))); #else mMouseJoint = PxDistanceJointCreate(physics, mMouseActor, PxTransform::createIdentity(), pickedActor, PxTransform(pickedActor->getGlobalPose().transformInv(worldImpact))); mMouseJoint->setMaxDistance(0.0f); mMouseJoint->setMinDistance(0.0f); mMouseJoint->setDistanceJointFlags(PxDistanceJointFlag::eMAX_DISTANCE_ENABLED); #endif mDistanceToPicked = (worldImpact - rayOrigin).magnitude(); }
osg::Matrix PhysXInterface::getMatrix( int id ) { PxRigidActor* actor = _actors[id]; if ( actor ) { float m[16]; PxMat44 pxMat( actor->getGlobalPose() ); for ( int i=0; i<16; ++i ) m[i] = *(pxMat.front() + i); return osg::Matrix(&m[0]); } return osg::Matrix(); }
PxBounds3 NpShapeManager::getWorldBounds(const PxRigidActor& actor) const { PxBounds3 bounds(PxBounds3::empty()); const PxU32 nbShapes = getNbShapes(); PxTransform actorPose = actor.getGlobalPose(); NpShape*const* PX_RESTRICT shapes = getShapes(); for(PxU32 i=0;i<nbShapes;i++) bounds.include(Gu::computeBounds(shapes[i]->getScbShape().getGeometry(), actorPose * shapes[i]->getLocalPoseFast(), !physx::gUnifiedHeightfieldCollision)); return bounds; }
bool Picking::pick(int x, int y) { PxScene& scene = mFrame.getActiveScene(); PxVec3 rayOrig, rayDir, pickOrig; computeCameraRay(rayOrig, rayDir, pickOrig, x, y); // raycast rigid bodies in scene PxRaycastHit hit; hit.shape = NULL; PxRaycastBuffer hit1; scene.raycast(rayOrig, rayDir, PX_MAX_F32, hit1, PxHitFlag::ePOSITION); hit = hit1.block; if(hit.shape) { const char* shapeName = hit.shape->getName(); if(shapeName) printf("Picked shape name: %s\n", shapeName); PxRigidActor* actor = hit.actor; PX_ASSERT(actor); mSelectedActor = static_cast<PxRigidActor*>(actor->is<PxRigidDynamic>()); if(!mSelectedActor) mSelectedActor = static_cast<PxRigidActor*>(actor->is<PxArticulationLink>()); //ML::this is very useful to debug some collision problem PxTransform t = actor->getGlobalPose(); // printf("id = %i\n PxTransform transform(PxVec3(%f, %f, %f), PxQuat(%f, %f, %f, %f))\n", (int)actor->userData, t.p.x, t.p.y, t.p.z, t.q.x, t.q.y, t.q.z, t.q.w); } else { mSelectedActor = 0; } if(mSelectedActor) { printf("Actor '%s' picked! (userData: %p)\n", mSelectedActor->getName(), mSelectedActor->userData); //if its a dynamic rigid body, joint it for dragging purposes: grabActor(hit.position, rayOrig); } #ifdef VISUALIZE_PICKING_RAYS Ray ray; ray.origin = rayOrig; ray.dir = rayDir; mRays.push_back(ray); #endif return true; }
bool CreateGeometryFromPhysxActor(PxActor *a, LevelGeometry::Mesh &mesh) { bool rv = false; if (!a) return rv; PxRigidActor *ra = a->isRigidActor(); if (!ra) return rv; GameObject* gameObj = NULL; PhysicsCallbackObject* userData = static_cast<PhysicsCallbackObject*>(ra->userData); if(userData) gameObj = userData->isGameObject(); r3dCSHolder block(g_pPhysicsWorld->GetConcurrencyGuard()); PxU32 nbShapes = ra->getNbShapes(); for (PxU32 i = 0; i < nbShapes; ++i) { PxShape *s = 0; ra->getShapes(&s, 1, i); PxGeometryType::Enum gt = s->getGeometryType(); switch(gt) { case PxGeometryType::eTRIANGLEMESH: { PxTriangleMeshGeometry g; s->getTriangleMeshGeometry(g); PxTransform t = s->getLocalPose().transform(ra->getGlobalPose()); rv = CreateGeometryFromPhysxGeometry(g, t, mesh); break; } default: r3dArtBug("buildNavigation: Unsupported physx mesh type %d, obj: %s\n", gt, gameObj ? gameObj->Name.c_str() : "<unknown>"); } } return rv; }
void NpShapeManager::visualize(Cm::RenderOutput& out, NpScene* scene, const PxRigidActor& actor) { const PxU32 nbShapes = getNbShapes(); NpShape*const* PX_RESTRICT shapes = getShapes(); PxTransform actorPose = actor.getGlobalPose(); const bool visualizeCompounds = (nbShapes>1) && scene->getVisualizationParameter(PxVisualizationParameter::eCOLLISION_COMPOUNDS)!=0.0f; PxBounds3 compoundBounds(PxBounds3::empty()); for(PxU32 i=0;i<nbShapes;i++) { Scb::Shape& shape = shapes[i]->getScbShape(); if(shape.getFlags() & PxShapeFlag::eVISUALIZATION) { shapes[i]->visualize(out, actor); if(visualizeCompounds) compoundBounds.include(Gu::computeBounds(shape.getGeometry(), actorPose*shapes[i]->getLocalPose(), !physx::gUnifiedHeightfieldCollision)); } } if(visualizeCompounds && !compoundBounds.isEmpty()) out << PxU32(PxDebugColor::eARGB_MAGENTA) << PxMat44(PxIdentity) << Cm::DebugBox(compoundBounds); }
PR PhysX3::GetWorldTransform(PintObjectHandle handle) { PxTransform Pose; PxRigidActor* RigidActor = GetActorFromHandle(handle); if(RigidActor) { Pose = RigidActor->getGlobalPose(); } else { PxShape* Shape = GetShapeFromHandle(handle); ASSERT(Shape); #ifdef SUPPORT_SHARED_SHAPES ASSERT(Shape->getActor()); Pose = PxShapeExt::getGlobalPose(*Shape, *Shape->getActor()); #else Pose = PxShapeExt::getGlobalPose(*Shape); #endif } return PR(ToPoint(Pose.p), ToQuat(Pose.q)); }