Projekt_Grafika/dependencies/physx-4.1/source/physx/src/buffering/ScbScene.h

780 lines
27 KiB
C++

//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#ifndef PX_PHYSICS_SCB_SCENE
#define PX_PHYSICS_SCB_SCENE
#include "ScScene.h"
#include "ScbSceneBuffer.h"
#include "ScbType.h"
#include "PsFoundation.h"
#include "PsMutex.h"
#include "PsHashSet.h"
#if PX_SUPPORT_PVD
#include "PxPhysics.h"
#include "ScbScenePvdClient.h"
#endif
namespace physx
{
class NpMaterial;
namespace Sc
{
class BodyDesc;
}
namespace Gu
{
class BVHStructure;
}
namespace Scb
{
class Base;
class RigidObject;
class RigidStatic;
class Body;
class Actor;
class Shape;
class Constraint;
class Material;
class Articulation;
class ArticulationJoint;
class Aggregate;
struct ShapeBuffer;
/**
\brief Helper class to track inserted/removed/updated buffering objects.
*/
class ObjectTracker
{
public:
ObjectTracker() {}
/**
\brief An object has been inserted while the simulation was running -> track it for insertion at sync point
*/
void scheduleForInsert(Base& element);
/**
\brief An object has been removed while the simulation was running -> track it for removal at sync point
*/
void scheduleForRemove(Base& element);
/**
\brief An object has been changed while the simulation was running -> track it for update at sync point
*/
void scheduleForUpdate(Base& element);
/**
\brief Get the list of dirty objects that require processing at a sync point.
*/
Base*const * getBuffered() { return mBuffered.getEntries(); }
/**
\brief Get number of dirty objects that require processing at a sync point.
*/
PxU32 getBufferedCount() const { return mBuffered.size(); }
/**
\brief Cleanup dirty objects after sync point.
\li Transition pending insertion objects from eINSERT_PENDING to eIN_SCENE.
\li Transition pending removal objects from eREMOVE_PENDING to eNOT_IN_SCENE.
\li Destroy objects marked as eIS_RELEASED.
\li Clear dirty list.
*/
void clear();
void insert(Base& element);
void remove(Base& element);
private:
Ps::CoalescedHashSet<Base*> mBuffered;
};
typedef ObjectTracker ShapeManager;
typedef ObjectTracker RigidStaticManager;
typedef ObjectTracker BodyManager;
typedef ObjectTracker ArticulationManager;
typedef ObjectTracker ConstraintManager;
typedef ObjectTracker ArticulationJointManager;
typedef ObjectTracker AggregateManager;
enum MATERIAL_EVENT
{
MATERIAL_ADD,
MATERIAL_UPDATE,
MATERIAL_REMOVE
};
class MaterialEvent
{
public:
PX_FORCE_INLINE MaterialEvent(PxU16 handle, MATERIAL_EVENT type) : mHandle(handle), mType(type) {}
PX_FORCE_INLINE MaterialEvent() {}
PxU16 mHandle;//handle to the master material table
MATERIAL_EVENT mType;
};
class Scene : public Ps::UserAllocated
{
PX_NOCOPY(Scene)
public:
enum BufferFlag
{
BF_GRAVITY = (1 << 0),
BF_BOUNCETHRESHOLDVELOCITY = (1 << 1),
BF_FLAGS = (1 << 2),
BF_DOMINANCE_PAIRS = (1 << 3),
BF_SOLVER_BATCH_SIZE = (1 << 4),
BF_VISUALIZATION = (1 << 5),
BF_CULLING_BOX = (1 << 6),
BF_SOLVER_ARTIC_BATCH_SIZE = (1 << 7)
};
public:
Scene(const PxSceneDesc& desc, PxU64 contextID);
~Scene() {} //use release() plz.
//---------------------------------------------------------------------------------
// Wrapper for Sc::Scene interface
//---------------------------------------------------------------------------------
void release();
PxScene* getPxScene();
PX_INLINE void setGravity(const PxVec3& gravity);
PX_INLINE PxVec3 getGravity() const;
PX_INLINE void setBounceThresholdVelocity(const PxReal t);
PX_INLINE PxReal getBounceThresholdVelocity() const;
PX_INLINE void setFlags(PxSceneFlags flags);
PX_INLINE PxSceneFlags getFlags() const;
PX_INLINE void setFrictionType(PxFrictionType::Enum type) { mScene.setFrictionType(type); }
PX_INLINE PxFrictionType::Enum getFrictionType() const { return mScene.getFrictionType(); }
void addActor(Scb::RigidStatic&, bool noSim, PxBounds3* uninflatedBounds, const Gu::BVHStructure* bvhStructure);
void removeActor(Scb::RigidStatic&, bool wakeOnLostTouch, bool noSim);
void addActor(Scb::Body&, bool noSim, PxBounds3* uninflatedBounds, const Gu::BVHStructure* bvhStructure);
void removeActor(Scb::Body&, bool wakeOnLostTouch, bool noSim);
void addConstraint(Scb::Constraint&);
void removeConstraint(Scb::Constraint&);
void addArticulation(Scb::Articulation&);
void removeArticulation(Scb::Articulation&);
void addArticulationJoint(Scb::ArticulationJoint&);
void removeArticulationJoint(Scb::ArticulationJoint&);
void addAggregate(Scb::Aggregate&);
void removeAggregate(Scb::Aggregate&);
void addMaterial(const Sc::MaterialCore& mat);
void updateMaterial(const Sc::MaterialCore& mat);
void removeMaterial(const Sc::MaterialCore& mat);
void updateLowLevelMaterial(NpMaterial** masterMaterials);
// These methods are only to be called at fetchResults!
PX_INLINE PxU32 getNumActiveBodies() const { return mScene.getNumActiveBodies(); }
PX_INLINE Sc::BodyCore* const* getActiveBodiesArray() const { return mScene.getActiveBodiesArray(); }
PX_INLINE PxSimulationEventCallback* getSimulationEventCallback() const;
PX_INLINE void setSimulationEventCallback(PxSimulationEventCallback* callback);
PX_INLINE PxContactModifyCallback* getContactModifyCallback() const;
PX_INLINE void setContactModifyCallback(PxContactModifyCallback* callback);
PX_INLINE PxCCDContactModifyCallback* getCCDContactModifyCallback() const;
PX_INLINE void setCCDContactModifyCallback(PxCCDContactModifyCallback* callback);
PX_INLINE PxU32 getCCDMaxPasses() const;
PX_INLINE void setCCDMaxPasses(PxU32 ccdMaxPasses);
PX_INLINE void setBroadPhaseCallback(PxBroadPhaseCallback* callback);
PX_INLINE PxBroadPhaseCallback* getBroadPhaseCallback() const;
PxBroadPhaseType::Enum getBroadPhaseType() const;
bool getBroadPhaseCaps(PxBroadPhaseCaps& caps) const;
PxU32 getNbBroadPhaseRegions() const;
PxU32 getBroadPhaseRegions(PxBroadPhaseRegionInfo* userBuffer, PxU32 bufferSize, PxU32 startIndex) const;
PxU32 addBroadPhaseRegion(const PxBroadPhaseRegion& region, bool populateRegion);
bool removeBroadPhaseRegion(PxU32 handle);
// Collision filtering
PX_INLINE void setFilterShaderData(const void* data, PxU32 dataSize);
PX_INLINE const void* getFilterShaderData() const;
PX_INLINE PxU32 getFilterShaderDataSize() const;
PX_INLINE PxSimulationFilterShader getFilterShader() const;
PX_INLINE PxSimulationFilterCallback* getFilterCallback() const;
// Groups
PX_INLINE void setDominanceGroupPair(PxDominanceGroup group1, PxDominanceGroup group2, const PxDominanceGroupPair& dominance);
PX_INLINE PxDominanceGroupPair getDominanceGroupPair(PxDominanceGroup group1, PxDominanceGroup group2) const;
PX_INLINE void setSolverBatchSize(PxU32 solverBatchSize);
PX_INLINE PxU32 getSolverBatchSize() const;
PX_INLINE void setSolverArticulationBatchSize(PxU32 solverBatchSize);
PX_INLINE PxU32 getSolverArticulationBatchSize() const;
PX_INLINE void simulate(PxReal timeStep, PxBaseTask* continuation) { mScene.simulate(timeStep, continuation); }
PX_INLINE void collide(PxReal timeStep, PxBaseTask* continuation) { mScene.collide(timeStep, continuation); }
PX_INLINE void advance(PxReal timeStep, PxBaseTask* continuation) { mScene.advance(timeStep, continuation); }
PX_INLINE void endSimulation() { mScene.endSimulation(); }
PX_INLINE void flush(bool sendPendingReports);
PX_INLINE void fireBrokenConstraintCallbacks() { mScene.fireBrokenConstraintCallbacks(); }
PX_INLINE void fireTriggerCallbacks() { mScene.fireTriggerCallbacks(); }
PX_INLINE void fireQueuedContactCallbacks() { mScene.fireQueuedContactCallbacks(false); }
PX_INLINE const Ps::Array<PxContactPairHeader>&
getQueuedContactPairHeaders() { return mScene.getQueuedContactPairHeaders(); }
PX_FORCE_INLINE void postCallbacksPreSync() { mScene.postCallbacksPreSync(); } //cleanup tasks after the pre-sync callbacks have fired
PX_INLINE void fireCallBacksPostSync() { mScene.fireCallbacksPostSync(); } //callbacks that are fired on the core side, after the buffers get synced
PX_INLINE void postReportsCleanup();
PX_INLINE const PxSceneLimits& getLimits() const { return mScene.getLimits(); }
PX_INLINE void setLimits(const PxSceneLimits& limits) { mScene.setLimits(limits); }
PX_INLINE void getStats(PxSimulationStatistics& stats) const;
PX_INLINE void buildActiveActors(); //build the list of active actors
PX_INLINE void buildActiveAndFrozenActors(); //build the list of active and frozen actors
PX_INLINE PxActor** getActiveActors(PxU32& nbActorsOut);
PX_INLINE void setActiveActors(PxActor** actors, PxU32 nbActors);
PX_INLINE PxActor** getFrozenActors(PxU32& nbActorsOut);
PX_INLINE PxClientID createClient();
PX_INLINE void setVisualizationParameter(PxVisualizationParameter::Enum param, PxReal value);
PX_INLINE PxReal getVisualizationParameter(PxVisualizationParameter::Enum param) const;
PX_INLINE void setVisualizationCullingBox(const PxBounds3& box);
PX_INLINE const PxBounds3& getVisualizationCullingBox() const;
void shiftOrigin(const PxVec3& shift);
//---------------------------------------------------------------------------------
// Data synchronization
//---------------------------------------------------------------------------------
public:
void syncWriteThroughProperties();
void syncEntireScene();
void processPendingRemove();
PX_FORCE_INLINE PxU16* allocShapeMaterialBuffer(PxU32 count, PxU32& startIdx) { return allocArrayBuffer(mShapeMaterialBuffer, count, startIdx); }
PX_FORCE_INLINE const PxU16* getShapeMaterialBuffer(PxU32 startIdx) const { return &mShapeMaterialBuffer[startIdx]; }
PX_FORCE_INLINE Scb::Shape** allocShapeBuffer(PxU32 count, PxU32& startIdx) { return allocArrayBuffer(mShapePtrBuffer, count, startIdx); }
PX_FORCE_INLINE Scb::Shape** getShapeBuffer(PxU32 startIdx) { return &mShapePtrBuffer[startIdx]; }
PX_FORCE_INLINE Scb::Actor** allocActorBuffer(PxU32 count, PxU32& startIdx) { return allocArrayBuffer(mActorPtrBuffer, count, startIdx); }
PX_FORCE_INLINE Scb::Actor** getActorBuffer(PxU32 startIdx) { return &mActorPtrBuffer[startIdx]; }
void scheduleForUpdate(Scb::Base& object);
PxU8* getStream(ScbType::Enum type);
PX_FORCE_INLINE void removeShapeFromPendingUpdateList(Scb::Base& shape) { mShapeManager.remove(shape); }
PX_FORCE_INLINE const Sc::Scene& getScScene() const { return mScene; }
PX_FORCE_INLINE Sc::Scene& getScScene() { return mScene; }
PX_FORCE_INLINE void prepareOutOfBoundsCallbacks() { mScene.prepareOutOfBoundsCallbacks(); }
private:
void syncState();
PX_FORCE_INLINE Ps::IntBool isBuffered(BufferFlag f) const { return Ps::IntBool(mBufferFlags& f); }
PX_FORCE_INLINE void markUpdated(BufferFlag f) { mBufferFlags |= f; }
//---------------------------------------------------------------------------------
// Miscellaneous
//---------------------------------------------------------------------------------
public:
PX_FORCE_INLINE bool isPhysicsBuffering() const { return mIsBuffering; }
PX_FORCE_INLINE void setPhysicsBuffering(bool buffering) { mIsBuffering = buffering; }
PX_FORCE_INLINE Sc::SimulationStage::Enum getSimulationStage() const { return mScene.getSimulationStage(); }
PX_FORCE_INLINE void setSimulationStage(Sc::SimulationStage::Enum stage) { mScene.setSimulationStage(stage); }
PX_FORCE_INLINE bool isValid() const { return mScene.isValid(); }
PX_FORCE_INLINE PxReal getWakeCounterResetValue() const { return mWakeCounterResetValue; }
void switchRigidToNoSim(Scb::RigidObject&, bool isDynamic);
void switchRigidFromNoSim(Scb::RigidObject&, bool isDynamic);
static size_t getScOffset() { return reinterpret_cast<size_t>(&reinterpret_cast<Scene*>(0)->mScene); }
#if PX_SUPPORT_PVD
PX_FORCE_INLINE Vd::ScbScenePvdClient& getScenePvdClient() { return mScenePvdClient; }
PX_FORCE_INLINE const Vd::ScbScenePvdClient& getScenePvdClient() const { return mScenePvdClient; }
#endif
PX_FORCE_INLINE PxU64 getContextId() const { return mScene.getContextId(); }
private:
void addShapeInternal(Scb::Shape&);
void addShapesInternal(PxU32 nbShapes, PxShape** PX_RESTRICT shapes, size_t scbOffset, PxActor** PX_RESTRICT owners, PxU32 offsetNpToCore, bool isDynamic);
template<typename T> T* allocArrayBuffer(Ps::Array<T>& buffer, PxU32 count, PxU32& startIdx);
private:
template<bool TIsDynamic, class T>
PX_FORCE_INLINE void addActorT(T& actor, ObjectTracker& tracker, bool noSim, PxBounds3* uninflatedBounds, const Gu::BVHStructure* bvhStructure);
template<typename T> void add(T& v, ObjectTracker& tracker, PxBounds3* uninflatedBounds, const Gu::BVHStructure* bvhStructure);
template<typename T> void remove(T& v, ObjectTracker& tracker, bool wakeOnLostTouch = false);
template<bool TIsDynamic, typename T> void addRigidNoSim(T& v, ObjectTracker& tracker, const Gu::BVHStructure* bvhStructure);
template<bool TIsDynamic, typename T> void removeRigidNoSim(T& v, ObjectTracker& tracker);
template<typename T, typename S> void processSimUpdates(S*const * scObjects, PxU32 nbObjects);
template<typename T> void processUserUpdates(ObjectTracker& tracker);
template<typename T, bool syncOnRemove, bool wakeOnLostTouchCheck> void processRemoves(ObjectTracker& tracker);
template<typename T> void processShapeRemoves(ObjectTracker& tracker);
Sc::Scene mScene;
Ps::Array<MaterialEvent> mSceneMaterialBuffer;
Ps::Mutex mSceneMaterialBufferLock;
bool mSimulationRunning;
bool mIsBuffering;
Cm::FlushPool mStream; // Pool for temporarily buffering user changes on objects
ShapeManager mShapeManager;
Ps::Array<PxU16> mShapeMaterialBuffer; // Buffered setMaterial() call might need to track list of materials (for multi material shapes)
Ps::Array<Scb::Shape*> mShapePtrBuffer; // List of shape pointers to track buffered calls to resetFiltering(), for example
Ps::Array<Scb::Actor*> mActorPtrBuffer;
RigidStaticManager mRigidStaticManager;
BodyManager mBodyManager;
ConstraintManager mConstraintManager;
ArticulationManager mArticulationManager;
ArticulationJointManager mArticulationJointManager;
AggregateManager mAggregateManager;
#if PX_SUPPORT_PVD
Vd::ScbScenePvdClient mScenePvdClient;
#endif
PX_FORCE_INLINE void updatePvdProperties()
{
#if PX_SUPPORT_PVD
// PT: TODO: shouldn't we test PxPvdInstrumentationFlag::eDEBUG here?
if(mScenePvdClient.isConnected())
mScenePvdClient.updatePvdProperties();
#endif
}
PxReal mWakeCounterResetValue;
// note: If deletion of rigid objects is done before the sync of the simulation data then we
// might wanna consider having a separate list for deleted rigid objects (for performance
// reasons)
//---------------------------------------------------------------------------------
// On demand buffered data (simulation read-only data)
//---------------------------------------------------------------------------------
Scb::SceneBuffer mBufferedData;
PxU32 mBufferFlags;
};
} // namespace Scb
template<typename T>
T* Scb::Scene::allocArrayBuffer(Ps::Array<T>& buffer, PxU32 count, PxU32& startIdx)
{
PxU32 oldSize = buffer.size();
buffer.resize(oldSize + count);
startIdx = oldSize;
return &buffer[oldSize];
}
PX_INLINE void Scb::Scene::setGravity(const PxVec3& gravity)
{
if(!isPhysicsBuffering())
{
mScene.setGravity(gravity);
updatePvdProperties();
}
else
{
mBufferedData.mGravity = gravity;
markUpdated(BF_GRAVITY);
}
}
PX_INLINE PxVec3 Scb::Scene::getGravity() const
{
if(isBuffered(BF_GRAVITY))
return mBufferedData.mGravity;
else
return mScene.getGravity();
}
void Scb::Scene::setBounceThresholdVelocity(const PxReal t)
{
if(!isPhysicsBuffering())
{
mScene.setBounceThresholdVelocity(t);
updatePvdProperties();
}
else
{
mBufferedData.mBounceThresholdVelocity = t;
markUpdated(BF_BOUNCETHRESHOLDVELOCITY);
}
}
PxReal Scb::Scene::getBounceThresholdVelocity() const
{
if(isBuffered(BF_BOUNCETHRESHOLDVELOCITY))
return mBufferedData.mBounceThresholdVelocity;
else
return mScene.getBounceThresholdVelocity();
}
PX_INLINE void Scb::Scene::setFlags(PxSceneFlags flags)
{
if(!isPhysicsBuffering())
{
mScene.setPublicFlags(flags);
const bool pcm = (flags & PxSceneFlag::eENABLE_PCM);
mScene.setPCM(pcm);
const bool contactCache = !(flags & PxSceneFlag::eDISABLE_CONTACT_CACHE);
mScene.setContactCache(contactCache);
updatePvdProperties();
}
else
{
mBufferedData.mFlags = flags;
markUpdated(BF_FLAGS);
}
}
PX_INLINE PxSceneFlags Scb::Scene::getFlags() const
{
if(isBuffered(BF_FLAGS))
return mBufferedData.mFlags;
else
return mScene.getPublicFlags();
}
///////////////////////////////////////////////////////////////////////////////
PX_INLINE PxSimulationEventCallback* Scb::Scene::getSimulationEventCallback() const
{
return mScene.getSimulationEventCallback();
}
PX_INLINE void Scb::Scene::setSimulationEventCallback(PxSimulationEventCallback* callback)
{
if(!isPhysicsBuffering())
mScene.setSimulationEventCallback(callback);
else
Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "PxScene::setSimulationEventCallback() not allowed while simulation is running. Call will be ignored.");
}
PX_INLINE PxContactModifyCallback* Scb::Scene::getContactModifyCallback() const
{
return mScene.getContactModifyCallback();
}
PX_INLINE void Scb::Scene::setContactModifyCallback(PxContactModifyCallback* callback)
{
if(!isPhysicsBuffering())
mScene.setContactModifyCallback(callback);
else
Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "PxScene::setContactModifyCallback() not allowed while simulation is running. Call will be ignored.");
}
PX_INLINE PxCCDContactModifyCallback* Scb::Scene::getCCDContactModifyCallback() const
{
return mScene.getCCDContactModifyCallback();
}
PX_INLINE void Scb::Scene::setCCDContactModifyCallback(PxCCDContactModifyCallback* callback)
{
if(!isPhysicsBuffering())
mScene.setCCDContactModifyCallback(callback);
else
Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "PxScene::setCCDContactModifyCallback() not allowed while simulation is running. Call will be ignored.");
}
PX_INLINE PxU32 Scb::Scene::getCCDMaxPasses() const
{
return mScene.getCCDMaxPasses();
}
PX_INLINE void Scb::Scene::setCCDMaxPasses(PxU32 ccdMaxPasses)
{
if(!isPhysicsBuffering())
mScene.setCCDMaxPasses(ccdMaxPasses);
else
Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "PxScene::setCCDMaxPasses() not allowed while simulation is running. Call will be ignored.");
}
PX_INLINE PxBroadPhaseCallback* Scb::Scene::getBroadPhaseCallback() const
{
return mScene.getBroadPhaseCallback();
}
PX_INLINE void Scb::Scene::setBroadPhaseCallback(PxBroadPhaseCallback* callback)
{
if(!isPhysicsBuffering())
mScene.setBroadPhaseCallback(callback);
else
Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "PxScene::setBroadPhaseCallback() not allowed while simulation is running. Call will be ignored.");
}
///////////////////////////////////////////////////////////////////////////////
PX_INLINE void Scb::Scene::setFilterShaderData(const void* data, PxU32 dataSize)
{
if(!isPhysicsBuffering())
mScene.setFilterShaderData(data, dataSize);
else
Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "PxScene::setFilterShaderData() not allowed while simulation is running. Call will be ignored.");
}
PX_INLINE const void* Scb::Scene::getFilterShaderData() const
{
return mScene.getFilterShaderDataFast();
}
PX_INLINE PxU32 Scb::Scene::getFilterShaderDataSize() const
{
return mScene.getFilterShaderDataSizeFast();
}
PX_INLINE PxSimulationFilterShader Scb::Scene::getFilterShader() const
{
return mScene.getFilterShaderFast();
}
PX_INLINE PxSimulationFilterCallback* Scb::Scene::getFilterCallback() const
{
return mScene.getFilterCallbackFast();
}
PX_INLINE void Scb::Scene::flush(bool sendPendingReports)
{
PX_ASSERT(!isPhysicsBuffering());
mShapeMaterialBuffer.reset();
mShapePtrBuffer.reset();
mActorPtrBuffer.reset();
//!!! TODO: Clear all buffers used for double buffering changes (see ObjectTracker::mBufferPool)
mScene.flush(sendPendingReports);
}
PX_INLINE void Scb::Scene::postReportsCleanup()
{
PX_ASSERT(!isPhysicsBuffering());
mScene.postReportsCleanup();
}
PX_INLINE void Scb::Scene::setDominanceGroupPair(PxDominanceGroup group1, PxDominanceGroup group2, const PxDominanceGroupPair& dominance)
{
if(!isPhysicsBuffering())
{
mScene.setDominanceGroupPair(group1, group2, dominance);
updatePvdProperties();
}
else
{
mBufferedData.setDominancePair(group1, group2, dominance);
markUpdated(BF_DOMINANCE_PAIRS);
}
}
PX_INLINE PxDominanceGroupPair Scb::Scene::getDominanceGroupPair(PxDominanceGroup group1, PxDominanceGroup group2) const
{
if(isBuffered(BF_DOMINANCE_PAIRS))
{
PxDominanceGroupPair dominance(0, 0);
if(mBufferedData.getDominancePair(group1, group2, dominance))
return dominance;
}
return mScene.getDominanceGroupPair(group1, group2);
}
PX_INLINE void Scb::Scene::setSolverBatchSize(PxU32 solverBatchSize)
{
if(!isPhysicsBuffering())
{
mScene.setSolverBatchSize(solverBatchSize);
updatePvdProperties();
}
else
{
mBufferedData.mSolverBatchSize = solverBatchSize;
markUpdated(BF_SOLVER_BATCH_SIZE);
}
}
PX_INLINE PxU32 Scb::Scene::getSolverArticulationBatchSize() const
{
if(isBuffered(BF_SOLVER_ARTIC_BATCH_SIZE))
return mBufferedData.mSolverBatchSize;
else
return mScene.getSolverArticBatchSize();
}
PX_INLINE void Scb::Scene::setSolverArticulationBatchSize(PxU32 solverBatchSize)
{
if (!isPhysicsBuffering())
{
mScene.setSolverArticBatchSize(solverBatchSize);
updatePvdProperties();
}
else
{
mBufferedData.mSolverArticulationBatchSize = solverBatchSize;
markUpdated(BF_SOLVER_ARTIC_BATCH_SIZE);
}
}
PX_INLINE PxU32 Scb::Scene::getSolverBatchSize() const
{
if (isBuffered(BF_SOLVER_BATCH_SIZE))
return mBufferedData.mSolverBatchSize;
else
return mScene.getSolverBatchSize();
}
PX_INLINE void Scb::Scene::getStats(PxSimulationStatistics& stats) const
{
PX_ASSERT(!isPhysicsBuffering());
mScene.getStats(stats);
}
PX_INLINE void Scb::Scene::buildActiveActors()
{
PX_ASSERT(!isPhysicsBuffering());
mScene.buildActiveActors();
}
PX_INLINE void Scb::Scene::buildActiveAndFrozenActors()
{
PX_ASSERT(!isPhysicsBuffering());
mScene.buildActiveAndFrozenActors();
}
PX_INLINE PxActor** Scb::Scene::getActiveActors(PxU32& nbActorsOut)
{
if(!isPhysicsBuffering())
return mScene.getActiveActors(nbActorsOut);
else
{
Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "PxScene::getActiveActors() not allowed while simulation is running. Call will be ignored.");
nbActorsOut = 0;
return NULL;
}
}
PX_INLINE void Scb::Scene::setActiveActors(PxActor** actors, PxU32 nbActors)
{
mScene.setActiveActors(actors, nbActors);
}
PX_INLINE PxActor** Scb::Scene::getFrozenActors(PxU32& nbActorsOut)
{
if(!isPhysicsBuffering())
return mScene.getFrozenActors(nbActorsOut);
else
{
Ps::getFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "PxScene::getFrozenActors() not allowed while simulation is running. Call will be ignored.");
nbActorsOut = 0;
return NULL;
}
}
PX_INLINE PxClientID Scb::Scene::createClient()
{
if(!isPhysicsBuffering())
return mScene.createClient();
else
return PxClientID(mScene.getNbClients() + mBufferedData.mNumClientsCreated++);
}
PX_INLINE void Scb::Scene::setVisualizationParameter(PxVisualizationParameter::Enum param, PxReal value)
{
if(!isPhysicsBuffering())
mScene.setVisualizationParameter(param, value);
else
{
PX_ASSERT(param < PxVisualizationParameter::eNUM_VALUES);
mBufferedData.mVisualizationParamChanged[param] = 1;
mBufferedData.mVisualizationParam[param] = value;
markUpdated(BF_VISUALIZATION);
}
}
PX_INLINE PxReal Scb::Scene::getVisualizationParameter(PxVisualizationParameter::Enum param) const
{
PX_ASSERT(param < PxVisualizationParameter::eNUM_VALUES);
if(isBuffered(BF_VISUALIZATION) && mBufferedData.mVisualizationParamChanged[param])
return mBufferedData.mVisualizationParam[param];
else
return mScene.getVisualizationParameter(param);
}
PX_INLINE void Scb::Scene::setVisualizationCullingBox(const PxBounds3& box)
{
if(!isPhysicsBuffering())
mScene.setVisualizationCullingBox(box);
else
{
mBufferedData.mVisualizationCullingBox = box;
markUpdated(BF_CULLING_BOX);
}
}
PX_INLINE const PxBounds3& Scb::Scene::getVisualizationCullingBox() const
{
if(isBuffered(BF_CULLING_BOX))
return mBufferedData.mVisualizationCullingBox;
else
return mScene.getVisualizationCullingBox();
}
}
#endif