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; }
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(); } }
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(); }
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); } }
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(); }
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); }
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(); } }
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()); } }
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()); }
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)); }
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; }