PxShape* AttachShape_AssumesLocked(const PxGeometry& PGeom, const PxTransform& PLocalPose, const float ContactOffset, PxShapeFlags PShapeFlags = PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSCENE_QUERY_SHAPE | PxShapeFlag::eSIMULATION_SHAPE) const { const PxMaterial* PMaterial = GetDefaultPhysMaterial(); PxShape* PNewShape = bShapeSharing ? GPhysXSDK->createShape(PGeom, *PMaterial, /*isExclusive =*/ false, PShapeFlags) : PDestActor->createShape(PGeom, *PMaterial, PShapeFlags); if (PNewShape) { PNewShape->setLocalPose(PLocalPose); if (NewShapes) { NewShapes->Add(PNewShape); } PNewShape->setContactOffset(ContactOffset); const bool bSyncFlags = bShapeSharing || SceneType == PST_Sync; const FShapeFilterData& Filters = ShapeData.FilterData; const bool bComplexShape = PNewShape->getGeometryType() == PxGeometryType::eTRIANGLEMESH; PNewShape->setQueryFilterData(bComplexShape ? Filters.QueryComplexFilter : Filters.QuerySimpleFilter); PNewShape->setFlags( (bSyncFlags ? ShapeData.SyncShapeFlags : ShapeData.AsyncShapeFlags) | (bComplexShape ? ShapeData.ComplexShapeFlags : ShapeData.SimpleShapeFlags)); PNewShape->setSimulationFilterData(Filters.SimFilter); FBodyInstance::ApplyMaterialToShape_AssumesLocked(PNewShape, SimpleMaterial, ComplexMaterials, bShapeSharing); if(bShapeSharing) { PDestActor->attachShape(*PNewShape); PNewShape->release(); } } return PNewShape; }
void PhysXMeshCollider::setGeometry(const PxGeometry& geometry) { PxShape* shape = getInternal()->_getShape(); if (shape->getGeometryType() != geometry.getType()) { PxShape* newShape = gPhysX().getPhysX()->createShape(geometry, *gPhysX().getDefaultMaterial(), true); getInternal()->_setShape(newShape); } else getInternal()->_getShape()->setGeometry(geometry); }
bool BoxController::updateKinematicProxy() { // Set extents for kinematic proxy if(mKineActor) { PxShape* shape = getKineShape(); PX_ASSERT(shape->getGeometryType() == PxGeometryType::eBOX); PxBoxGeometry bg; shape->getBoxGeometry(bg); bg.halfExtents = CCTtoProxyExtents(mHalfHeight, mHalfSideExtent, mHalfForwardExtent, mProxyScaleCoeff); shape->setGeometry(bg); } return true; }
bool CapsuleController::setRadius(PxF32 r) { // Set radius for CCT volume mRadius = r; // Set radius for kinematic proxy if(mKineActor) { PxShape* shape = getKineShape(); PX_ASSERT(shape->getGeometryType() == PxGeometryType::eCAPSULE); PxCapsuleGeometry cg; shape->getCapsuleGeometry(cg); cg.radius = CCTtoProxyRadius(r, mProxyScaleCoeff); shape->setGeometry(cg); } return true; }
bool CapsuleController::setHeight(PxF32 h) { // Set height for CCT volume mHeight = h; // Set height for kinematic proxy if(mKineActor) { PxShape* shape = getKineShape(); PX_ASSERT(shape->getGeometryType() == PxGeometryType::eCAPSULE); PxCapsuleGeometry cg; shape->getCapsuleGeometry(cg); cg.halfHeight = CCTtoProxyHeight(h, mProxyScaleCoeff); shape->setGeometry(cg); } 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 Cct::findTouchedGeometry( const InternalCBData_FindTouchedGeom* userData, const PxExtendedBounds3& worldBounds, // ### we should also accept other volumes TriArray& worldTriangles, IntArray& triIndicesArray, IntArray& geomStream, const CCTFilter& filter, const CCTParams& params) { PX_ASSERT(userData); const PxInternalCBData_FindTouchedGeom* internalData = static_cast<const PxInternalCBData_FindTouchedGeom*>(userData); PxScene* scene = internalData->scene; Cm::RenderBuffer* renderBuffer = internalData->renderBuffer; PxExtendedVec3 Origin; // Will be TouchedGeom::mOffset getCenter(worldBounds, Origin); // Find touched *boxes* i.e. touched objects' AABBs in the world // We collide against dynamic shapes too, to get back dynamic boxes/etc // TODO: add active groups in interface! PxSceneQueryFilterFlags sqFilterFlags; if(filter.mStaticShapes) sqFilterFlags |= PxSceneQueryFilterFlag::eSTATIC; if(filter.mDynamicShapes) sqFilterFlags |= PxSceneQueryFilterFlag::eDYNAMIC; if(filter.mFilterCallback) { if(filter.mPreFilter) sqFilterFlags |= PxSceneQueryFilterFlag::ePREFILTER; if(filter.mPostFilter) sqFilterFlags |= PxSceneQueryFilterFlag::ePOSTFILTER; } // ### this one is dangerous const PxBounds3 tmpBounds(toVec3(worldBounds.minimum), toVec3(worldBounds.maximum)); // LOSS OF ACCURACY // PT: unfortunate conversion forced by the PxGeometry API PxVec3 center = tmpBounds.getCenter(), extents = tmpBounds.getExtents(); PxShape* hits[100]; PxU32 size = 100; const PxSceneQueryFilterData sceneQueryFilterData = filter.mFilterData ? PxSceneQueryFilterData(*filter.mFilterData, sqFilterFlags) : PxSceneQueryFilterData(sqFilterFlags); PxI32 numberHits = scene->overlapMultiple(PxBoxGeometry(extents), PxTransform(center), hits, size, sceneQueryFilterData, filter.mFilterCallback); for(PxI32 i = 0; i < numberHits; i++) { PxShape* shape = hits[i]; if(shape == NULL) continue; // Filtering // Discard all CCT shapes, i.e. kinematic actors we created ourselves. We don't need to collide with them since they're surrounded // by the real CCT volume - and collisions with those are handled elsewhere. We use the userData field for filtering because that's // really our only valid option (filtering groups are already used by clients and we don't have control over them, clients might // create other kinematic actors that we may want to keep here, etc, etc) if(internalData->cctShapeHashSet->contains(shape)) continue; // Ubi (EA) : Discarding Triggers : if(shape->getFlags() & PxShapeFlag::eTRIGGER_SHAPE) continue; // PT: here you might want to disable kinematic objects. // Output shape to stream const PxTransform globalPose = getShapeGlobalPose(*shape); const PxGeometryType::Enum type = shape->getGeometryType(); // ### VIRTUAL! if(type==PxGeometryType::eSPHERE) outputSphereToStream(shape, globalPose, geomStream, Origin); else if(type==PxGeometryType::eCAPSULE) outputCapsuleToStream(shape, globalPose, geomStream, Origin); else if(type==PxGeometryType::eBOX) outputBoxToStream(shape, globalPose, geomStream, worldTriangles, triIndicesArray, Origin, tmpBounds, params, renderBuffer); else if(type==PxGeometryType::eTRIANGLEMESH) outputMeshToStream(shape, globalPose, geomStream, worldTriangles, triIndicesArray, Origin, tmpBounds, params, renderBuffer); else if(type==PxGeometryType::eHEIGHTFIELD) outputHeightFieldToStream(shape, globalPose, geomStream, worldTriangles, triIndicesArray, Origin, tmpBounds, params, renderBuffer); else if(type==PxGeometryType::eCONVEXMESH) outputConvexToStream(shape, globalPose, geomStream, worldTriangles, triIndicesArray, Origin, tmpBounds); else if(type==PxGeometryType::ePLANE) outputPlaneToStream(shape, globalPose, geomStream, worldTriangles, triIndicesArray, Origin, tmpBounds, params, renderBuffer); } }
osg::Node* createNodeForActor( PxRigidActor* actor ) { if ( !actor ) return NULL; std::vector<PxShape*> shapes( actor->getNbShapes() ); osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform; transform->setMatrix( toMatrix(PxMat44(actor->getGlobalPose())) ); osg::ref_ptr<osg::Geode> geode = new osg::Geode; transform->addChild( geode.get() ); PxU32 num = actor->getShapes( &(shapes[0]), actor->getNbShapes() ); for ( PxU32 i=0; i<num; ++i ) { PxShape* shape = shapes[i]; osg::Matrix localMatrix = toMatrix( PxMat44(actor->getGlobalPose()) ); osg::Vec3 localPos = toVec3( shape->getLocalPose().p ); osg::Quat localQuat(shape->getLocalPose().q.x, shape->getLocalPose().q.y, shape->getLocalPose().q.z, shape->getLocalPose().q.w); switch ( shape->getGeometryType() ) { case PxGeometryType::eSPHERE: { PxSphereGeometry sphere; shape->getSphereGeometry( sphere ); osg::Sphere* sphereShape = new osg::Sphere(localPos, sphere.radius); geode->addDrawable( new osg::ShapeDrawable(sphereShape) ); } break; case PxGeometryType::ePLANE: // TODO break; case PxGeometryType::eCAPSULE: { PxCapsuleGeometry capsule; shape->getCapsuleGeometry( capsule ); osg::Capsule* capsuleShape = new osg::Capsule( localPos, capsule.radius, capsule.halfHeight * 2.0f); capsuleShape->setRotation( localQuat ); geode->addDrawable( new osg::ShapeDrawable(capsuleShape) ); } break; case PxGeometryType::eBOX: { PxBoxGeometry box; shape->getBoxGeometry( box ); osg::Box* boxShape = new osg::Box(localPos, box.halfExtents[0] * 2.0f, box.halfExtents[1] * 2.0f, box.halfExtents[2] * 2.0f); boxShape->setRotation( localQuat ); geode->addDrawable( new osg::ShapeDrawable(boxShape) ); } break; case PxGeometryType::eCONVEXMESH: { PxConvexMeshGeometry convexMeshGeom; shape->getConvexMeshGeometry( convexMeshGeom ); // TODO: consider convexMeshGeom.scale PxConvexMesh* convexMesh = convexMeshGeom.convexMesh; if ( convexMesh ) { /*for ( unsigned int i=0; i<convexMesh->getNbPolygons(); ++i ) { }*/ // TODO } } break; case PxGeometryType::eTRIANGLEMESH: { PxTriangleMeshGeometry triangleMeshGeom; shape->getTriangleMeshGeometry( triangleMeshGeom ); // TODO: consider triangleMeshGeom.scale PxTriangleMesh* triangleMesh = triangleMeshGeom.triangleMesh; if ( triangleMesh ) { osg::ref_ptr<osg::Vec3Array> va = new osg::Vec3Array( triangleMesh->getNbVertices() ); for ( unsigned int i=0; i<va->size(); ++i ) (*va)[i] = toVec3( *(triangleMesh->getVertices() + i) ) * localMatrix; osg::ref_ptr<osg::DrawElements> de; if ( triangleMesh->getTriangleMeshFlags()&PxTriangleMeshFlag::eHAS_16BIT_TRIANGLE_INDICES ) { osg::DrawElementsUShort* de16 = new osg::DrawElementsUShort(GL_TRIANGLES); de = de16; const PxU16* indices = (const PxU16*)triangleMesh->getTriangles(); for ( unsigned int i=0; i<triangleMesh->getNbTriangles(); ++i ) { de16->push_back( indices[3 * i + 0] ); de16->push_back( indices[3 * i + 1] ); de16->push_back( indices[3 * i + 2] ); } } else { osg::DrawElementsUInt* de32 = new osg::DrawElementsUInt(GL_TRIANGLES); de = de32; const PxU32* indices = (const PxU32*)triangleMesh->getTriangles(); for ( unsigned int i=0; i<triangleMesh->getNbTriangles(); ++i ) { de32->push_back( indices[3 * i + 0] ); de32->push_back( indices[3 * i + 1] ); de32->push_back( indices[3 * i + 2] ); } } geode->addDrawable( createGeometry(va.get(), NULL, NULL, de.get()) ); } } break; case PxGeometryType::eHEIGHTFIELD: { PxHeightFieldGeometry hfGeom; shape->getHeightFieldGeometry( hfGeom ); // TODO: consider hfGeom.*scale PxHeightField* heightField = hfGeom.heightField; if ( heightField ) { // TODO } } break; } } return transform.release(); }