Beispiel #1
0
PxArticulationLink*	NpArticulation::createLink(PxArticulationLink* parent, const PxTransform& pose)
{
	PX_CHECK_AND_RETURN_NULL(pose.isSane(), "NpArticulation::createLink pose is not valid.");
	
	NP_WRITE_CHECK(getOwnerScene());
	
	if(parent && mArticulationLinks.empty())
	{
		Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "Root articulation link must have NULL parent pointer!");
		return NULL;
	}

	if(!parent && !mArticulationLinks.empty())
	{
		Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "Non-root articulation link must have valid parent pointer!");
		return NULL;
	}

	NpArticulationLink* parentLink = static_cast<NpArticulationLink*>(parent);

	NpArticulationLink* link = static_cast<NpArticulationLink*>(NpFactory::getInstance().createArticulationLink(*this, parentLink, pose.getNormalized()));

	if(link)
	{
		NpScene* scene = getAPIScene();
		if(scene)
			scene->addArticulationLink(*link);
	}
	return link;
}
Beispiel #2
0
void VisualDebugger::sendEntireSDK()
{
	NpPhysics& npPhysics = NpPhysics::getInstance();
	mPvdConnection->createInstance( (PxPhysics*)&npPhysics );
	npPhysics.getPvdConnectionManager()->setIsTopLevelUIElement( &npPhysics, true );
	mMetaDataBinding.sendAllProperties( *mPvdConnection, npPhysics );

#define SEND_BUFFER_GROUP( type, name ) {					\
		Ps::Array<type*> buffers;							\
		PxU32 numBuffers = npPhysics.getNb##name();			\
		buffers.resize(numBuffers);							\
		npPhysics.get##name(buffers.begin(), numBuffers);	\
		for(PxU32 i = 0; i < numBuffers; i++)				\
			increaseReference(buffers[i]);					\
	}

	SEND_BUFFER_GROUP( PxMaterial, Materials );
	SEND_BUFFER_GROUP( PxTriangleMesh, TriangleMeshes );
	SEND_BUFFER_GROUP( PxConvexMesh, ConvexMeshes );
	SEND_BUFFER_GROUP( PxHeightField, HeightFields );

#if PX_USE_CLOTH_API
	SEND_BUFFER_GROUP( PxClothFabric, ClothFabrics );
#endif

	mPvdConnection->flush();
	PxU32 numScenes = npPhysics.getNbScenes();
	for(PxU32 i = 0; i < numScenes; i++)
	{
		NpScene* npScene = npPhysics.getScene(i);
		Scb::Scene& scbScene = npScene->getScene();

		scbScene.getSceneVisualDebugger().sendEntireScene();
	}
}
Beispiel #3
0
void NpArticulation::release()
{
	NP_WRITE_CHECK(getOwnerScene());

	NpPhysics::getInstance().notifyDeletionListenersUserRelease(this, userData);

	//!!!AL TODO: Order should not matter in this case. Optimize by having a path which does not restrict release to leaf links or
	//      by using a more advanced data structure
	PxU32 idx = 0;
	while(mArticulationLinks.size())
	{
		idx = idx % mArticulationLinks.size();

		if (mArticulationLinks[idx]->getNbChildren() == 0)
		{
			mArticulationLinks[idx]->releaseInternal();  // deletes joint, link and removes link from list
		}
		else
		{
			idx++;
		}
	}

	NpScene* npScene = getAPIScene();
	if(npScene)
	{
		npScene->getScene().removeArticulation(getArticulation());

		npScene->removeFromArticulationList(*this);
	}

	mArticulationLinks.clear();

	mArticulation.destroy();
}
Beispiel #4
0
void NpArticulation::wakeUpInternal(bool forceWakeUp, bool autowake)
{
	NpScene* scene = getAPIScene();
	PX_ASSERT(scene);
	PxReal wakeCounterResetValue = scene->getWakeCounterResetValueInteral();

	Scb::Articulation& a = getArticulation();
	PxReal wakeCounter = a.getWakeCounter();

	bool needsWakingUp = isSleeping() && (autowake || forceWakeUp);
	if (autowake && (wakeCounter < wakeCounterResetValue))
	{
		wakeCounter = wakeCounterResetValue;
		needsWakingUp = true;
	}

	if (needsWakingUp)
	{
		for(PxU32 i=0; i < mArticulationLinks.size(); i++)
		{
			mArticulationLinks[i]->getScbBodyFast().wakeUpInternal(wakeCounter);
		}

		a.wakeUpInternal(wakeCounter);
	}
}
Beispiel #5
0
NpMaterial* NpPhysics::addMaterial(NpMaterial* m)
{
	if(!m)
		return NULL;

	Ps::Mutex::ScopedLock lock(mSceneAndMaterialMutex);

	//the handle is set inside the setMaterial method
	if(mMasterMaterialManager.setMaterial(*m))
	{
		// Let all scenes know of the new material
		for(PxU32 i=0; i < mSceneArray.size(); i++)
		{
			NpScene* s = getScene(i);
			s->addMaterial(*m);
		}
		return m;
	}
	else
	{
#ifdef PX_CHECKED
#ifdef PX_PS3
		Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "Cannot create material: There is a limit of 127 user created materials on PS3.");
#endif
#endif
		m->release();
		return NULL;
	}
}
void NpRigidDynamic::setGlobalPose(const PxTransform& pose, bool autowake)
{
    NpScene* scene = NpActor::getAPIScene(*this);

#ifdef PX_CHECKED
    if(scene)
        scene->checkPositionSanity(*this, pose, "PxRigidDynamic::setGlobalPose");
#endif

    PX_CHECK_AND_RETURN(pose.isSane(), "NpRigidDynamic::setGlobalPose: pose is not valid.");
    NP_WRITE_CHECK(NpActor::getOwnerScene(*this));

    PxTransform p = pose.getNormalized();

    if(scene)
    {
        updateDynamicSceneQueryShapes(mShapeManager, scene->getSceneQueryManagerFast());
    }

    PxTransform newPose = p;
    newPose.q.normalize(); //AM: added to fix 1461 where users read and write orientations for no reason.

    Scb::Body& b = getScbBodyFast();
    PxTransform body2World = newPose * b.getBody2Actor();
    b.setBody2World(body2World, false);

    if(scene && autowake && !(b.getActorFlags() & PxActorFlag::eDISABLE_SIMULATION))
        wakeUpInternal();
}
void NpCloth::setClothFlags(PxClothFlags flags)
{
	NP_WRITE_CHECK(NpActor::getOwnerScene(*this));

	mCloth.setClothFlags(flags);
	sendPvdSimpleProperties();

	NpScene* scene = NpActor::getAPIScene(*this);
	if (scene)
		scene->updatePhysXIndicator();
}
Beispiel #8
0
void VisualDebugger::updateScenesPvdConnection()
{
	NpPhysics& npPhysics = NpPhysics::getInstance();
	PxU32 numScenes = npPhysics.getNbScenes();
	for(PxU32 i = 0; i < numScenes; i++)
	{
		NpScene* npScene = npPhysics.getScene(i);
		Scb::Scene& scbScene = npScene->getScene();
		setupSceneConnection(scbScene);
	}
}
void NpPhysics::updateMaterial(NpMaterial& m)
{
	Ps::Mutex::ScopedLock lock(mSceneAndMaterialMutex);

	// Let all scenes know of the updated material
	for(PxU32 i=0; i < mSceneArray.size(); i++)
	{
		NpScene* s = getScene(i);
		s->updateMaterial(m);
	}
	mMasterMaterialManager.updateMaterial(m);
}
Beispiel #10
0
void VisualDebugger::updateScenesPvdConnection()
{
	NpPhysics& npPhysics = NpPhysics::getInstance();
	PxU32 numScenes = npPhysics.getNbScenes();
	for(PxU32 i = 0; i < numScenes; i++)
	{
		NpScene* npScene = npPhysics.getScene(i);
		Scb::Scene& scbScene = npScene->getScene();
		setupSceneConnection(scbScene);
		npScene->getSingleSqCollector().clearGeometryArrays();
		npScene->getBatchedSqCollector().clearGeometryArrays();
	}
}
Beispiel #11
0
void VisualDebugger::setCreateContactReports(bool value)
{
	if ( isConnected() )
	{
		NpPhysics& npPhysics = NpPhysics::getInstance();
		PxU32 numScenes = npPhysics.getNbScenes();
		for(PxU32 i = 0; i < numScenes; i++)
		{
			NpScene* npScene = npPhysics.getScene(i);
			Scb::Scene& scbScene = npScene->getScene();
			scbScene.getSceneVisualDebugger().setCreateContactReports(value);
		}
	}
}
PX_FORCE_INLINE void NpRigidDynamic::setKinematicTargetInternal(const PxTransform& targetPose)
{
    // The target is actor related. Transform to body related target
    PxTransform bodyTarget = targetPose * getScbBodyFast().getBody2Actor();

    Scb::Body& b = getScbBodyFast();
    b.setKinematicTarget(bodyTarget);

    NpScene* scene = NpActor::getAPIScene(*this);
    if ((b.getFlags() & PxRigidBodyFlag::eUSE_KINEMATIC_TARGET_FOR_SCENE_QUERIES) && scene)
    {
        updateDynamicSceneQueryShapes(mShapeManager, scene->getSceneQueryManagerFast());
    }
}
Beispiel #13
0
void NpArticulation::wakeUp()
{
	NpScene* scene = getAPIScene();

	NP_WRITE_CHECK(getOwnerScene());  // don't use the API scene, since it will be NULL on pending removal
	PX_CHECK_AND_RETURN(scene, "Articulation::wakeUp: articulation must be in a scene.");

	for(PxU32 i=0; i < mArticulationLinks.size(); i++)
	{
		mArticulationLinks[i]->getScbBodyFast().wakeUpInternal(scene->getWakeCounterResetValueInteral());
	}

	getArticulation().wakeUp();
}
void NpCloth::release()
{
	NP_WRITE_CHECK(NpActor::getOwnerScene(*this));

	NpPhysics::getInstance().notifyDeletionListenersUserRelease(this, userData);

// PX_AGGREGATE
	// initially no support for aggregates
	//NpClothT::release();	// PT: added for PxAggregate
//~PX_AGGREGATE

	NpScene* npScene = NpActor::getAPIScene(*this);
	if(npScene) // scene is 0 after scheduling for remove
		npScene->removeCloth(*this);

	mCloth.destroy();
}
void NpRigidDynamic::wakeUpInternalNoKinematicTest(Scb::Body& body, bool forceWakeUp, bool autowake)
{
    NpScene* scene = NpActor::getOwnerScene(*this);
    PX_ASSERT(scene);
    PxReal wakeCounterResetValue = scene->getWakeCounterResetValueInteral();

    PxReal wakeCounter = body.getWakeCounter();

    bool needsWakingUp = body.isSleeping() && (autowake || forceWakeUp);
    if (autowake && (wakeCounter < wakeCounterResetValue))
    {
        wakeCounter = wakeCounterResetValue;
        needsWakingUp = true;
    }

    if (needsWakingUp)
        body.wakeUpInternal(wakeCounter);
}
PxScene* NpPhysics::createScene(const PxSceneDesc& desc)
{
	PX_CHECK_AND_RETURN_NULL(desc.isValid(), "Physics::createScene: desc.isValid() is false!");

	const PxTolerancesScale& scale = mPhysics.getTolerancesScale();
	const PxTolerancesScale& descScale = desc.getTolerancesScale();
	PX_UNUSED(scale);
	PX_UNUSED(descScale);
	PX_CHECK_AND_RETURN_NULL((descScale.length == scale.length) && (descScale.mass == scale.mass) && (descScale.speed == scale.speed), "Physics::createScene: PxTolerancesScale must be the same as used for creation of PxPhysics!");

	Ps::Mutex::ScopedLock lock(mSceneAndMaterialMutex);  // done here because scene constructor accesses profiling manager of the SDK

	NpScene* npScene = PX_NEW (NpScene)(desc);
	if(!npScene)
	{
		Ps::getFoundation().error(PxErrorCode::eINTERNAL_ERROR, __FILE__, __LINE__, "Unable to create scene.");
		return NULL;
	}
	if(!npScene->getTaskManager())
	{
		Ps::getFoundation().error(PxErrorCode::eINTERNAL_ERROR, __FILE__, __LINE__, "Unable to create scene. Task manager creation failed.");
		return NULL;
	}

	npScene->loadFromDesc(desc);

#if PX_SUPPORT_PVD
	if(mPvd)
	{
		npScene->mScene.getScenePvdClient().setPsPvd(mPvd);		
		mPvd->addClient(&npScene->mScene.getScenePvdClient());
	}
#endif

	if (!sendMaterialTable(*npScene) || !npScene->getScene().isValid())
	{
		PX_DELETE(npScene);
		Ps::getFoundation().error(PxErrorCode::eOUT_OF_MEMORY, __FILE__, __LINE__, "Unable to create scene.");
		return NULL;
	}

	mSceneArray.pushBack(npScene);
	return npScene;
}
void NpArticulationLink::setGlobalPose(const PxTransform& pose, bool autowake)
{
	NpScene* scene = NpActor::getOwnerScene(*this);

	PX_CHECK_AND_RETURN(pose.isValid(), "NpArticulationLink::setGlobalPose pose is not valid.");

	NP_WRITE_CHECK(scene);
	
#if PX_CHECKED
	if(scene)
		scene->checkPositionSanity(*this, pose, "PxArticulationLink::setGlobalPose");
#endif

	PxTransform body2World = pose * getScbBodyFast().getBody2Actor();
	getScbBodyFast().setBody2World(body2World, false);

	if (scene && autowake)
		mRoot->wakeUpInternal(false, true);
}
bool NpPhysics::sendMaterialTable(NpScene& scene)
{
	// note: no lock here because this method gets only called at scene creation and there we do lock

	NpMaterialManagerIterator iter(mMasterMaterialManager);
	NpMaterial* mat;
	while(iter.getNextMaterial(mat))
		scene.addMaterial(*mat);

	return true;
}
void NpConstraint::release()
{
	NpScene* npScene = getNpScene();
	NP_WRITE_CHECK(npScene);

	NpPhysics::getInstance().notifyDeletionListenersUserRelease(this, NULL);

	if(mActor0)
		NpActor::getFromPxActor(*mActor0).removeConnector(*mActor0, NpConnectorType::eConstraint, this, "PxConstraint: Add to rigid actor 0: Constraint already added");
	if(mActor1)
		NpActor::getFromPxActor(*mActor1).removeConnector(*mActor1, NpConnectorType::eConstraint, this, "PxConstraint: Add to rigid actor 1: Constraint already added");

	if (npScene)
	{
		npScene->removeFromConstraintList(*this);
		npScene->getScene().removeConstraint(getScbConstraint());
	}

	mConstraint.destroy();
}
void NpShapeManager::attachShape(NpShape& shape, PxRigidActor& actor)
{
	PX_ASSERT(!mPruningStructure);

	Cm::PtrTableStorageManager& sm = NpFactory::getInstance().getPtrTableStorageManager();

	const PxU32 index = getNbShapes();
	mShapes.add(&shape, sm);	
	mSceneQueryData.add(reinterpret_cast<void*>(size_t(SQ_INVALID_PRUNER_DATA)), sm);

	NpScene* scene = NpActor::getAPIScene(actor);		
	if(scene && isSceneQuery(shape))
		setupSceneQuery(scene->getSceneQueryManagerFast(), actor, index);

	Scb::RigidObject& ro = static_cast<Scb::RigidObject&>(NpActor::getScbFromPxActor(actor));
	ro.onShapeAttach(shape.getScbShape());	

	PX_ASSERT(!shape.isExclusive() || shape.getActor()==NULL);
	shape.onActorAttach(actor);
}
void NpArticulationLink::releaseInternal()
{
	NpPhysics::getInstance().notifyDeletionListenersUserRelease(this, userData);

	NpArticulationLinkT::release();

	mRoot->removeLinkFromList(*this);

	if (mParent)
		mParent->removeFromChildList(*this);

	if (mInboundJoint)
		mInboundJoint->release();

	NpScene* npScene = NpActor::getAPIScene(*this);
	if (npScene)
		npScene->getScene().removeActor(mBody, true, false);

	mBody.destroy();
}
void VisualDebugger::sendEntireSDK()
{
	PVD::PvdCommLayerError error;
	error = mPvdConnection->beginFrame();
	
	NpPhysics& npPhysics = NpPhysics::getInstance();
	error = mPvdConnection->createInstance(PvdClassKeys::PhysicsSDK+1, PX_PROFILE_POINTER_TO_U64(&npPhysics), PVD::EInstanceUIFlags::TopLevel);
	mMetaDataBinding.sendAllProperties( mPvdConnection, &npPhysics );
	createGroups();

#define SEND_BUFFER_GROUP( type, name ) {					\
		Ps::Array<type*> buffers;							\
		PxU32 numBuffers = npPhysics.getNb##name();			\
		buffers.resize(numBuffers);							\
		npPhysics.get##name(buffers.begin(), numBuffers);	\
		for(PxU32 i = 0; i < numBuffers; i++)				\
			increaseReference(buffers[i]);					\
	}
	SEND_BUFFER_GROUP( PxTriangleMesh, TriangleMeshes );
	SEND_BUFFER_GROUP( PxConvexMesh, ConvexMeshes );
	SEND_BUFFER_GROUP( PxHeightField, HeightFields );
	SEND_BUFFER_GROUP( PxHeightField, HeightFields );


	
	//Ensure that all the instances and class descriptions created so far
	//are available to the rest of the system.
	error = mPvdConnection->flush();

	PxU32 numScenes = npPhysics.getNbScenes();
	for(PxU32 i = 0; i < numScenes; i++)
	{
		NpScene* npScene = npPhysics.getScene(i);
		Scb::Scene& scbScene = npScene->getScene();

		scbScene.getSceneVisualDebugger().sendEntireScene();
	}

	error = mPvdConnection->endFrame();
	error = mPvdConnection->flush();
}
NpConstraint::NpConstraint(PxRigidActor* actor0, PxRigidActor* actor1, PxConstraintConnector& connector, const PxConstraintShaderTable& shaders, PxU32 dataSize)
:	PxConstraint(PxConcreteType::eCONSTRAINT, PxBaseFlag::eOWNS_MEMORY)
,	mActor0		(actor0)
,	mActor1		(actor1)
,	mConstraint	(connector, shaders, dataSize)
,	mIsDirty	(true)
{
	
	mConstraint.setFlags(shaders.flag);
	if(actor0)
		NpActor::getFromPxActor(*actor0).addConnector(NpConnectorType::eConstraint, this, "PxConstraint: Add to rigid actor 0: Constraint already added");
	if(actor1)
		NpActor::getFromPxActor(*actor1).addConnector(NpConnectorType::eConstraint, this, "PxConstraint: Add to rigid actor 1: Constraint already added");

	NpScene* s = getSceneFromActors(actor0, actor1);
	if (s)
	{
		s->addToConstraintList(*this);
		s->getScene().addConstraint(mConstraint);
	}
}
void NpShapeManager::detachShape(NpShape& s, PxRigidActor& actor, bool wakeOnLostTouch)
{
	PX_ASSERT(!mPruningStructure);

	Cm::PtrTableStorageManager& sm = NpFactory::getInstance().getPtrTableStorageManager();

	const PxU32 index = mShapes.find(&s);
	PX_ASSERT(index!=0xffffffff);

	Scb::RigidObject& ro = static_cast<Scb::RigidObject&>(NpActor::getScbFromPxActor(actor));

	NpScene* scene = NpActor::getAPIScene(actor);
	if(scene && isSceneQuery(s))
		scene->getSceneQueryManagerFast().removePrunerShape(getPrunerData(index));

	Scb::Shape& scbShape = s.getScbShape();
	ro.onShapeDetach(scbShape, wakeOnLostTouch, (s.getRefCount() == 1));
	mShapes.replaceWithLast(index, sm);
	mSceneQueryData.replaceWithLast(index, sm);
	
	s.onActorDetach();
}
void NpRigidDynamic::setKinematicTarget(const PxTransform& destination)
{
    PX_CHECK_AND_RETURN(destination.isSane(), "NpRigidDynamic::setKinematicTarget: destination is not valid.");

    NpScene* scene = NpActor::getAPIScene(*this);
    PX_UNUSED(scene);
    NP_WRITE_CHECK(NpActor::getOwnerScene(*this));

#ifdef PX_CHECKED
    if(scene)
        scene->checkPositionSanity(*this, destination, "PxRigidDynamic::setKinematicTarget");
#endif

    Scb::Body& b = getScbBodyFast();
    PX_UNUSED(b);

    //0) make sure this is kinematic
    PX_CHECK_AND_RETURN((b.getFlags() & PxRigidBodyFlag::eKINEMATIC), "RigidDynamic::setKinematicTarget: Body must be kinematic!");
    PX_CHECK_AND_RETURN(scene, "RigidDynamic::setKinematicTarget: Body must be in a scene!");
    PX_CHECK_AND_RETURN(!(b.getActorFlags() & PxActorFlag::eDISABLE_SIMULATION), "RigidDynamic::setKinematicTarget: Not allowed if PxActorFlag::eDISABLE_SIMULATION is set!");

    setKinematicTargetInternal(destination.getNormalized());
}
Beispiel #26
0
void VisualDebugger::setVisualDebuggerFlag(PxVisualDebuggerFlags::Enum flag, bool value)
{
	if(value)
		mFlags |= PxU32(flag);
	else
		mFlags &= ~PxU32(flag);
	//This has been a bug against the debugger for some time,
	//changing this flag doesn't always change the sending-contact-reports behavior.
	if ( flag == PxVisualDebuggerFlags::eTRANSMIT_CONTACTS )
	{
		if ( isConnected() )
		{
			NpPhysics& npPhysics = NpPhysics::getInstance();
			PxU32 numScenes = npPhysics.getNbScenes();
			for(PxU32 i = 0; i < numScenes; i++)
			{
				NpScene* npScene = npPhysics.getScene(i);
				Scb::Scene& scbScene = npScene->getScene();
				scbScene.getSceneVisualDebugger().setCreateContactReports(value);
			}
		}
	}
}
NpMaterial* NpPhysics::addMaterial(NpMaterial* m)
{
	if(!m)
		return NULL;

	Ps::Mutex::ScopedLock lock(mSceneAndMaterialMutex);

	//the handle is set inside the setMaterial method
	if(mMasterMaterialManager.setMaterial(*m))
	{
		// Let all scenes know of the new material
		for(PxU32 i=0; i < mSceneArray.size(); i++)
		{
			NpScene* s = getScene(i);
			s->addMaterial(*m);
		}
		return m;
	}
	else
	{
		m->release();
		return NULL;
	}
}
void NpConstraint::setConstraintFunctions(PxConstraintConnector& n, const PxConstraintShaderTable& shaders)
{
	mConstraint.getScConstraint().setConstraintFunctions(n, shaders);
	
	//update mConnectorArray, since mActor0 or mActor1 should be in external reference
	bool bNeedUpdate = false;
	if(mActor0)
	{
		NpActor& npActor = NpActor::getFromPxActor(*mActor0);
		if(npActor.findConnector(NpConnectorType::eConstraint, this) == 0xffffffff)
		{
			bNeedUpdate = true;	
			npActor.addConnector(NpConnectorType::eConstraint, this, "PxConstraint: Add to rigid actor 0: Constraint already added");
		}
	}

	if(mActor1)
	{
		NpActor& npActor = NpActor::getFromPxActor(*mActor1);
		if(npActor.findConnector(NpConnectorType::eConstraint, this) == 0xffffffff)
		{
			bNeedUpdate = true;	
			npActor.addConnector(NpConnectorType::eConstraint, this, "PxConstraint: Add to rigid actor 1: Constraint already added");
		}
	}

	if(bNeedUpdate)
	{
		NpScene* newScene = getSceneFromActors(mActor0, mActor1);
		NpScene* oldScene = getNpScene();

		if (oldScene != newScene)
		{
			if (oldScene)
			{
				oldScene->removeFromConstraintList(*this);
				oldScene->getScene().removeConstraint(getScbConstraint());
			}
			if (newScene)
			{
				newScene->addToConstraintList(*this);
				newScene->getScene().addConstraint(getScbConstraint());
			}
		}
	}
}
void NpConstraint::setActors(PxRigidActor* actor0, PxRigidActor* actor1)
{
	NP_WRITE_CHECK(getNpScene());

	PX_CHECK_AND_RETURN((actor0 && !actor0->is<PxRigidStatic>()) || (actor1 && !actor1->is<PxRigidStatic>()), "PxConstraint: at least one actor must be non-static");
	PX_SIMD_GUARD;

	if(mActor0)
		NpActor::getFromPxActor(*mActor0).removeConnector(*mActor0, NpConnectorType::eConstraint, this, "PxConstraint: Add to rigid actor 0: Constraint already added");
	if(mActor1)
		NpActor::getFromPxActor(*mActor1).removeConnector(*mActor1, NpConnectorType::eConstraint, this, "PxConstraint: Add to rigid actor 1: Constraint already added");

	if(actor0)
		NpActor::getFromPxActor(*actor0).addConnector(NpConnectorType::eConstraint, this, "PxConstraint: Add to rigid actor 0: Constraint already added");
	if(actor1)
		NpActor::getFromPxActor(*actor1).addConnector(NpConnectorType::eConstraint, this, "PxConstraint: Add to rigid actor 1: Constraint already added");

	mActor0 = actor0;
	mActor1 = actor1;

	NpScene* newScene = getSceneFromActors(actor0, actor1);
	NpScene* oldScene = getNpScene();

	if (oldScene != newScene)
	{
		if (oldScene)
		{
			oldScene->removeFromConstraintList(*this);
			oldScene->getScene().removeConstraint(getScbConstraint());
		}

		getScbConstraint().setBodies(getScbRigidObject(actor0), getScbRigidObject(actor1));

		if (newScene)
		{
			newScene->addToConstraintList(*this);
			newScene->getScene().addConstraint(getScbConstraint());
		}
	}
	else
		getScbConstraint().setBodies(getScbRigidObject(actor0), getScbRigidObject(actor1));
}
Beispiel #30
0
PxScene* NpPhysics::createScene(const PxSceneDesc& desc)
{
	PX_CHECK_AND_RETURN_NULL(desc.isValid(), "Physics::createScene: desc.isValid() is false!");

	const PxTolerancesScale& scale = mPhysics.getTolerancesScale();
	const PxTolerancesScale& descScale = desc.getTolerancesScale();
	PX_UNUSED(scale);
	PX_UNUSED(descScale);
	PX_CHECK_AND_RETURN_NULL((descScale.length == scale.length) && (descScale.mass == scale.mass) && (descScale.speed == scale.speed), "Physics::createScene: PxTolerancesScale must be the same as used for creation of PxPhysics!");

	Ps::Mutex::ScopedLock lock(mSceneAndMaterialMutex);  // done here because scene constructor accesses profiling manager of the SDK

	NpScene* npScene = PX_NEW (NpScene)(desc);
	if(!npScene)
	{
		Ps::getFoundation().error(PxErrorCode::eINTERNAL_ERROR, __FILE__, __LINE__, "Unable to create scene.");
		return NULL;
	}
	if(!npScene->getTaskManager())
	{
		Ps::getFoundation().error(PxErrorCode::eINTERNAL_ERROR, __FILE__, __LINE__, "Unable to create scene. Task manager creation failed.");
		return NULL;
	}

	npScene->loadFromDesc(desc);

#if PX_SUPPORT_VISUAL_DEBUGGER
	if(mVisualDebugger->isConnected(true))
	{
		mVisualDebugger->setupSceneConnection(npScene->getScene());
		npScene->getScene().getSceneVisualDebugger().sendEntireScene();
	}
#endif

#ifdef PX_PS3
	for(PxU32 i=0;i<CmPS3ConfigInternal::SCENE_PARAM_SPU_MAX;i++)
	{
		npScene->getScene().setSceneParamInt((PxPS3ConfigParam::Enum)i, g_iPhysXSPUCount);
	}

	const PxU32 numFrictionBlocks = desc.nbContactDataBlocks/8;
	const PxU32 numNpCacheBlocks = desc.nbContactDataBlocks/8;
	const PxU32 numContactStreamBlocks = desc.nbContactDataBlocks/16;
	const PxU32 numConstraintBlocks = desc.nbContactDataBlocks - (numFrictionBlocks + numContactStreamBlocks + numNpCacheBlocks);

	npScene->getScene().setSceneParamInt(PxPS3ConfigParam::eMEM_CONSTRAINT_BLOCKS, numConstraintBlocks);
	npScene->getScene().setSceneParamInt(PxPS3ConfigParam::eMEM_FRICTION_BLOCKS, numFrictionBlocks);
	npScene->getScene().setSceneParamInt(PxPS3ConfigParam::eMEM_CONTACT_STREAM_BLOCKS, numContactStreamBlocks);
	npScene->getScene().setSceneParamInt(PxPS3ConfigParam::eMEM_NP_CACHE_BLOCKS, numNpCacheBlocks);
#endif

	if (!sendMaterialTable(*npScene) || !npScene->getScene().isValid())
	{
		PX_DELETE(npScene);
		Ps::getFoundation().error(PxErrorCode::eOUT_OF_MEMORY, __FILE__, __LINE__, "Unable to create scene.");
		return NULL;
	}

	mSceneArray.pushBack(npScene);
	return npScene;
}