Exemple #1
0
	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);
	}
}
Exemple #8
0
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();
}