aboutsummaryrefslogtreecommitdiff
path: root/PhysX_3.4/Source/PhysX/src/buffering/ScbScenePvdClient.cpp
diff options
context:
space:
mode:
authorgit perforce import user <a@b>2016-10-25 12:29:14 -0600
committerSheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees>2016-10-25 18:56:37 -0500
commit3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch)
treefa6485c169e50d7415a651bf838f5bcd0fd3bfbd /PhysX_3.4/Source/PhysX/src/buffering/ScbScenePvdClient.cpp
downloadphysx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz
physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip
Initial commit:
PhysX 3.4.0 Update @ 21294896 APEX 1.4.0 Update @ 21275617 [CL 21300167]
Diffstat (limited to 'PhysX_3.4/Source/PhysX/src/buffering/ScbScenePvdClient.cpp')
-rw-r--r--PhysX_3.4/Source/PhysX/src/buffering/ScbScenePvdClient.cpp1240
1 files changed, 1240 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/PhysX/src/buffering/ScbScenePvdClient.cpp b/PhysX_3.4/Source/PhysX/src/buffering/ScbScenePvdClient.cpp
new file mode 100644
index 00000000..03161149
--- /dev/null
+++ b/PhysX_3.4/Source/PhysX/src/buffering/ScbScenePvdClient.cpp
@@ -0,0 +1,1240 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#if PX_SUPPORT_PVD
+#include "NpCast.h"
+#include "ScbScenePvdClient.h"
+#include "PxActor.h"
+#include "PxRenderBuffer.h"
+#include "ScbScene.h"
+#include "ScbNpDeps.h"
+#include "PxPhysics.h"
+#include "ScMaterialCore.h"
+#include "PxsMaterialManager.h"
+#include "ScBodySim.h"
+#include "ScConstraintSim.h"
+#include "ScParticleSystemCore.h"
+#include "ScParticleSystemSim.h"
+
+#include "PxConstraintDesc.h"
+#include "ScConstraintCore.h"
+#include "PvdTypeNames.h"
+
+#include "gpu/PxParticleGpu.h"
+#include "PxPvdUserRenderer.h"
+#include "PxvNphaseImplementationContext.h"
+
+using namespace physx;
+using namespace physx::Vd;
+using namespace physx::pvdsdk;
+using namespace Scb;
+
+
+namespace
+{
+ PX_FORCE_INLINE PxU64 getContextId(Scb::Scene& scene) { return scene.getContextId(); }
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ // Sc-to-Np
+ PX_FORCE_INLINE static NpConstraint* getNpConstraint(Sc::ConstraintCore* scConstraint)
+ {
+ const size_t scOffset = reinterpret_cast<size_t>(&(reinterpret_cast<Scb::Constraint*>(0)->getScConstraint()));
+ const size_t scbOffset = reinterpret_cast<size_t>(&(reinterpret_cast<NpConstraint*>(0)->getScbConstraint()));
+ return reinterpret_cast<NpConstraint*>(reinterpret_cast<char*>(scConstraint) - scOffset - scbOffset);
+ }
+
+#if PX_USE_PARTICLE_SYSTEM_API
+
+ // Sc-to-Scb
+ PX_FORCE_INLINE static Scb::ParticleSystem* getScbParticleSystem(Sc::ParticleSystemCore* scParticleSystem)
+ {
+ const size_t offset = reinterpret_cast<size_t>(&(reinterpret_cast<Scb::ParticleSystem*>(0)->getScParticleSystem()));
+ return reinterpret_cast<Scb::ParticleSystem*>(reinterpret_cast<char*>(scParticleSystem) - offset);
+ }
+
+#endif
+
+ ///////////////////////////////////////////////////////////////////////////////
+
+ PX_FORCE_INLINE static const PxActor* getPxActor(const Scb::Actor* scbActor)
+ {
+ const PxActorType::Enum type = scbActor->getActorCore().getActorCoreType();
+ if(type == PxActorType::eRIGID_DYNAMIC)
+ {
+ return getNpRigidDynamic(static_cast<const Scb::Body*>(scbActor));
+ }
+ else if(type == PxActorType::eRIGID_STATIC)
+ {
+ return getNpRigidStatic(static_cast<const Scb::RigidStatic*>(scbActor));
+ }
+#if PX_USE_PARTICLE_SYSTEM_API
+ else if(type == PxActorType::ePARTICLE_SYSTEM)
+ {
+ return getNpParticleSystem(static_cast<const Scb::ParticleSystem*>(scbActor));
+ }
+ else if(type == PxActorType::ePARTICLE_FLUID)
+ {
+ return getNpParticleFluid(static_cast<const Scb::ParticleSystem*>(scbActor));
+ }
+#endif
+ else if(type == PxActorType::eARTICULATION_LINK)
+ {
+ return getNpArticulationLink(static_cast<const Scb::Body*>(scbActor));
+ }
+#if PX_USE_CLOTH_API
+ else if(type == PxActorType::eCLOTH)
+ {
+ return getNpCloth(const_cast<Scb::Cloth*>(static_cast<const Scb::Cloth*>(scbActor)));
+ }
+#endif
+
+ return NULL;
+ }
+
+ struct CreateOp
+ {
+ CreateOp& operator=(const CreateOp&);
+ physx::pvdsdk::PvdDataStream& mStream;
+ PvdMetaDataBinding& mBinding;
+ PsPvd* mPvd;
+ PxScene& mScene;
+ CreateOp(physx::pvdsdk::PvdDataStream& str, PvdMetaDataBinding& bind, PsPvd* pvd, PxScene& scene)
+ : mStream(str), mBinding(bind), mPvd(pvd), mScene(scene)
+ {
+ }
+ template <typename TDataType>
+ void operator()(const TDataType& dtype)
+ {
+ mBinding.createInstance(mStream, dtype, mScene, mPvd);
+ }
+ void operator()(const PxArticulationLink&)
+ {
+ }
+#if PX_USE_PARTICLE_SYSTEM_API
+ void operator()(const PxParticleSystem& dtype)
+ {
+ mBinding.createInstance(mStream, dtype, mScene);
+ }
+ void operator()(const PxParticleFluid& dtype)
+ {
+ mBinding.createInstance(mStream, dtype, mScene);
+ }
+#endif
+ };
+
+ struct UpdateOp
+ {
+ UpdateOp& operator=(const UpdateOp&);
+ physx::pvdsdk::PvdDataStream& mStream;
+ PvdMetaDataBinding& mBinding;
+ UpdateOp(physx::pvdsdk::PvdDataStream& str, PvdMetaDataBinding& bind) : mStream(str), mBinding(bind)
+ {
+ }
+ template <typename TDataType>
+ void operator()(const TDataType& dtype)
+ {
+ mBinding.sendAllProperties(mStream, dtype);
+ }
+ };
+
+ struct DestroyOp
+ {
+ DestroyOp& operator=(const DestroyOp&);
+ physx::pvdsdk::PvdDataStream& mStream;
+ PvdMetaDataBinding& mBinding;
+ PxScene& mScene;
+ DestroyOp(physx::pvdsdk::PvdDataStream& str, PvdMetaDataBinding& bind, PxScene& scene)
+ : mStream(str), mBinding(bind), mScene(scene)
+ {
+ }
+ template <typename TDataType>
+ void operator()(const TDataType& dtype)
+ {
+ mBinding.destroyInstance(mStream, dtype, mScene);
+ }
+ void operator()(const PxArticulationLink& dtype)
+ {
+ mBinding.destroyInstance(mStream, dtype);
+ }
+#if PX_USE_PARTICLE_SYSTEM_API
+ void operator()(const PxParticleSystem& dtype)
+ {
+ mBinding.destroyInstance(mStream, dtype, mScene);
+ }
+ void operator()(const PxParticleFluid& dtype)
+ {
+ mBinding.destroyInstance(mStream, dtype, mScene);
+ }
+#endif
+ };
+
+ template <typename TOperator>
+ inline void BodyTypeOperation(const Scb::Body* scbBody, TOperator op)
+ {
+ bool isArticulationLink = scbBody->getActorType() == PxActorType::eARTICULATION_LINK;
+ if(isArticulationLink)
+ {
+ const NpArticulationLink* link = getNpArticulationLink(scbBody);
+ op(*static_cast<const PxArticulationLink*>(link));
+ }
+ else
+ {
+ const NpRigidDynamic* npRigidDynamic = getNpRigidDynamic(scbBody);
+ op(*static_cast<const PxRigidDynamic*>(npRigidDynamic));
+ }
+ }
+
+ template <typename TOperator>
+ inline void ActorTypeOperation(const PxActor* actor, TOperator op)
+ {
+ switch(actor->getType())
+ {
+ case PxActorType::eRIGID_STATIC:
+ op(*static_cast<const PxRigidStatic*>(actor));
+ break;
+ case PxActorType::eRIGID_DYNAMIC:
+ op(*static_cast<const PxRigidDynamic*>(actor));
+ break;
+ case PxActorType::eARTICULATION_LINK:
+ op(*static_cast<const PxArticulationLink*>(actor));
+ break;
+#if PX_USE_PARTICLE_SYSTEM_API
+ case PxActorType::ePARTICLE_SYSTEM:
+ op(*static_cast<const PxParticleSystem*>(actor));
+ break;
+ case PxActorType::ePARTICLE_FLUID:
+ op(*static_cast<const PxParticleFluid*>(actor));
+ break;
+#endif
+#if PX_USE_CLOTH_API
+ case PxActorType::eCLOTH:
+ op(*static_cast<const PxCloth*>(actor));
+ break;
+#endif
+ case PxActorType::eACTOR_COUNT:
+ case PxActorType::eACTOR_FORCE_DWORD:
+ PX_ASSERT(false);
+ break;
+ };
+ }
+
+ namespace
+ {
+ struct PvdConstraintVisualizer : public PxConstraintVisualizer
+ {
+ PX_NOCOPY(PvdConstraintVisualizer)
+ public:
+ physx::pvdsdk::PvdUserRenderer& mRenderer;
+ PvdConstraintVisualizer(const void* id, physx::pvdsdk::PvdUserRenderer& r) : mRenderer(r)
+ {
+ mRenderer.setInstanceId(id);
+ }
+ virtual void visualizeJointFrames(const PxTransform& parent, const PxTransform& child)
+ {
+ mRenderer.visualizeJointFrames(parent, child);
+ }
+
+ virtual void visualizeLinearLimit(const PxTransform& t0, const PxTransform& t1, PxReal value, bool active)
+ {
+ mRenderer.visualizeLinearLimit(t0, t1, PxF32(value), active);
+ }
+
+ virtual void visualizeAngularLimit(const PxTransform& t0, PxReal lower, PxReal upper, bool active)
+ {
+ mRenderer.visualizeAngularLimit(t0, PxF32(lower), PxF32(upper), active);
+ }
+
+ virtual void visualizeLimitCone(const PxTransform& t, PxReal ySwing, PxReal zSwing, bool active)
+ {
+ mRenderer.visualizeLimitCone(t, PxF32(ySwing), PxF32(zSwing), active);
+ }
+
+ virtual void visualizeDoubleCone(const PxTransform& t, PxReal angle, bool active)
+ {
+ mRenderer.visualizeDoubleCone(t, PxF32(angle), active);
+ }
+ };
+ }
+
+ class SceneRendererClient : public RendererEventClient, public physx::shdfnd::UserAllocated
+ {
+ PX_NOCOPY(SceneRendererClient)
+ public:
+ SceneRendererClient(PvdUserRenderer* renderer, PxPvd* pvd):mRenderer(renderer)
+ {
+ mStream = PvdDataStream::create(pvd);
+ mStream->createInstance(renderer);
+ }
+
+ ~SceneRendererClient()
+ {
+ mStream->destroyInstance(mRenderer);
+ mStream->release();
+ }
+
+ virtual void handleBufferFlush(const uint8_t* inData, uint32_t inLength)
+ {
+ mStream->setPropertyValue(mRenderer, "events", inData, inLength);
+ }
+
+ private:
+
+ PvdUserRenderer* mRenderer;
+ PvdDataStream* mStream;
+ };
+
+} // namespace
+
+ScbScenePvdClient::ScbScenePvdClient(Scb::Scene& scene)
+ : mPvd(NULL), mScbScene(scene), mPvdDataStream(NULL), mUserRender(NULL), mRenderClient(NULL), mIsConnected(false)
+{
+}
+
+ScbScenePvdClient::~ScbScenePvdClient()
+{
+ if(mPvd)
+ mPvd->removeClient(this);
+}
+
+void ScbScenePvdClient::updateCamera(const char* name, const PxVec3& origin, const PxVec3& up, const PxVec3& target)
+{
+ if(mIsConnected)
+ mPvdDataStream->updateCamera(name, origin, up, target);
+}
+
+void ScbScenePvdClient::drawPoints(const PvdDebugPoint* points, PxU32 count)
+{
+ if(mUserRender)
+ mUserRender->drawPoints(points, count);
+}
+
+void ScbScenePvdClient::drawLines(const PvdDebugLine* lines, PxU32 count)
+{
+ if(mUserRender)
+ mUserRender->drawLines(lines, count);
+}
+
+void ScbScenePvdClient::drawTriangles(const PvdDebugTriangle* triangles, PxU32 count)
+{
+ if(mUserRender)
+ mUserRender->drawTriangles(triangles, count);
+}
+
+void ScbScenePvdClient::drawText(const PvdDebugText& text)
+{
+ if(mUserRender)
+ mUserRender->drawText(text);
+}
+
+PvdUserRenderer* ScbScenePvdClient::getUserRender()
+{
+ return mUserRender;
+}
+
+
+PsPvd* ScbScenePvdClient::getPsPvd()
+{
+ return mPvd;
+}
+
+void ScbScenePvdClient::setPsPvd(PsPvd* pvd)
+{
+ mPvd = pvd;
+}
+
+physx::pvdsdk::PvdClient* ScbScenePvdClient::getClientInternal()
+{
+ return this;
+}
+
+void ScbScenePvdClient::setScenePvdFlag(PxPvdSceneFlag::Enum flag, bool value)
+{
+ if(value)
+ mFlags |= flag;
+ else
+ mFlags &= ~flag;
+}
+
+void ScbScenePvdClient::setScenePvdFlags(PxPvdSceneFlags flags)
+{
+ mFlags = flags;
+}
+
+PxPvdSceneFlags ScbScenePvdClient::getScenePvdFlags() const
+{
+ return mFlags;
+}
+
+bool ScbScenePvdClient::isConnected() const
+{
+ return mIsConnected;
+}
+
+void ScbScenePvdClient::onPvdConnected()
+{
+ if(mIsConnected || !mPvd)
+ return;
+
+ mIsConnected = true;
+
+
+ mPvdDataStream = PvdDataStream::create(mPvd);
+
+ mUserRender = PvdUserRenderer::create();
+ mRenderClient = PX_NEW(SceneRendererClient)(mUserRender, mPvd);
+ mUserRender->setClient(mRenderClient);
+ sendEntireScene();
+}
+
+void ScbScenePvdClient::onPvdDisconnected()
+{
+ if(!mIsConnected)
+ return;
+ mIsConnected = false;
+
+ PX_DELETE(mRenderClient);
+ mRenderClient = NULL;
+ mUserRender->release();
+ mUserRender = NULL;
+ mPvdDataStream->release();
+ mPvdDataStream = NULL;
+}
+
+void ScbScenePvdClient::flush()
+{
+}
+
+PvdDataStream* ScbScenePvdClient::getDataStream()
+{
+ return mPvdDataStream;
+}
+
+PvdMetaDataBinding* ScbScenePvdClient::getMetaDataBinding()
+{
+ return &mMetaDataBinding;
+}
+
+void ScbScenePvdClient::updatePvdProperties()
+{
+ mMetaDataBinding.sendAllProperties(*mPvdDataStream, *mScbScene.getPxScene());
+}
+
+void ScbScenePvdClient::releasePvdInstance()
+{
+ if(mPvdDataStream)
+ {
+ PxScene* theScene = mScbScene.getPxScene();
+ // remove from parent
+ mPvdDataStream->removeObjectRef(&PxGetPhysics(), "Scenes", theScene);
+ mPvdDataStream->destroyInstance(theScene);
+ }
+}
+
+// PT: this is only called once, from "onPvdConnected"
+void ScbScenePvdClient::sendEntireScene()
+{
+ NpScene* npScene = static_cast<NpScene*>(mScbScene.getPxScene());
+
+ if(npScene->getFlagsFast() & PxSceneFlag::eREQUIRE_RW_LOCK) // getFlagsFast() will trigger a warning of lock check
+ npScene->lockRead(__FILE__, __LINE__);
+
+ {
+ PxScene* theScene = mScbScene.getPxScene();
+ mPvdDataStream->createInstance(theScene);
+ updatePvdProperties();
+
+ PxPhysics* physics = &PxGetPhysics();
+ // Create parent/child relationship.
+ mPvdDataStream->setPropertyValue(theScene, "Physics", reinterpret_cast<const void*>(physics));
+ mPvdDataStream->pushBackObjectRef(physics, "Scenes", theScene);
+ }
+
+ // materials:
+ {
+ PxsMaterialManager& manager = mScbScene.getScScene().getMaterialManager();
+ PxsMaterialManagerIterator iter(manager);
+ PxsMaterialCore* mat;
+ while(iter.getNextMaterial(mat))
+ {
+ const PxMaterial* theMaterial = mat->getNxMaterial();
+ if(mPvd->registerObject(theMaterial))
+ mMetaDataBinding.createInstance(*mPvdDataStream, *theMaterial, PxGetPhysics());
+ };
+ }
+
+ if(mPvd->getInstrumentationFlags() & PxPvdInstrumentationFlag::eDEBUG)
+ {
+ Ps::Array<PxActor*> actorArray;
+
+ // RBs
+ // static:
+ {
+ PxU32 numActors = npScene->getNbActors(PxActorTypeFlag::eRIGID_STATIC | PxActorTypeFlag::eRIGID_DYNAMIC);
+ actorArray.resize(numActors);
+ npScene->getActors(PxActorTypeFlag::eRIGID_STATIC | PxActorTypeFlag::eRIGID_DYNAMIC, actorArray.begin(),
+ actorArray.size());
+ for(PxU32 i = 0; i < numActors; i++)
+ {
+ PxActor* pxActor = actorArray[i];
+ if(pxActor->is<PxRigidStatic>())
+ mMetaDataBinding.createInstance(*mPvdDataStream, *static_cast<PxRigidStatic*>(pxActor), *npScene, mPvd);
+ else
+ mMetaDataBinding.createInstance(*mPvdDataStream, *static_cast<PxRigidDynamic*>(pxActor), *npScene, mPvd);
+ }
+ }
+ // articulations & links
+ {
+ Ps::Array<PxArticulation*> articulations;
+ PxU32 numArticulations = npScene->getNbArticulations();
+ articulations.resize(numArticulations);
+ npScene->getArticulations(articulations.begin(), articulations.size());
+ for(PxU32 i = 0; i < numArticulations; i++)
+ mMetaDataBinding.createInstance(*mPvdDataStream, *articulations[i], *npScene, mPvd);
+ }
+
+#if PX_USE_PARTICLE_SYSTEM_API
+ // particle systems & fluids:
+ {
+ PxU32 nbParticleSystems = mScbScene.getScScene().getNbParticleSystems();
+ Sc::ParticleSystemCore* const* particleSystems = mScbScene.getScScene().getParticleSystems();
+ for(PxU32 i = 0; i < nbParticleSystems; i++)
+ {
+ Sc::ParticleSystemCore* scParticleSystem = particleSystems[i];
+ createPvdInstance(scParticleSystem->getPxParticleBase());
+ }
+ }
+#endif
+
+#if PX_USE_CLOTH_API
+ // cloth
+ {
+ Ps::Array<PxActor*> cloths;
+ PxU32 numActors = npScene->getNbActors(PxActorTypeFlag::eCLOTH);
+ cloths.resize(numActors);
+ npScene->getActors(PxActorTypeFlag::eCLOTH, cloths.begin(), cloths.size());
+ for(PxU32 i = 0; i < numActors; i++)
+ {
+ Scb::Cloth* scbCloth = &static_cast<NpCloth*>(cloths[i])->getScbCloth();
+ createPvdInstance(scbCloth);
+ }
+ }
+#endif
+
+ // joints
+ {
+ Sc::ConstraintCore*const * constraints = mScbScene.getScScene().getConstraints();
+ PxU32 nbConstraints = mScbScene.getScScene().getNbConstraints();
+ for(PxU32 i = 0; i < nbConstraints; i++)
+ {
+ updateConstraint(*constraints[i], PxPvdUpdateType::CREATE_INSTANCE);
+ updateConstraint(*constraints[i], PxPvdUpdateType::UPDATE_ALL_PROPERTIES);
+ }
+ }
+ }
+
+ if(npScene->getFlagsFast() & PxSceneFlag::eREQUIRE_RW_LOCK)
+ npScene->unlockRead();
+}
+
+void ScbScenePvdClient::updateConstraint(const Sc::ConstraintCore& scConstraint, PxU32 updateType)
+{
+ PxConstraintConnector* conn = scConstraint.getPxConnector();
+ if(conn && checkPvdDebugFlag())
+ conn->updatePvdProperties(*mPvdDataStream, scConstraint.getPxConstraint(), PxPvdUpdateType::Enum(updateType));
+}
+
+void ScbScenePvdClient::createPvdInstance(const PxActor* actor)
+{
+ if(checkPvdDebugFlag())
+ ActorTypeOperation(actor, CreateOp(*mPvdDataStream, mMetaDataBinding, mPvd, *mScbScene.getPxScene()));
+}
+
+void ScbScenePvdClient::updatePvdProperties(const PxActor* actor)
+{
+ if(checkPvdDebugFlag())
+ ActorTypeOperation(actor, UpdateOp(*mPvdDataStream, mMetaDataBinding));
+}
+
+void ScbScenePvdClient::releasePvdInstance(const PxActor* actor)
+{
+ if(checkPvdDebugFlag())
+ ActorTypeOperation(actor, DestroyOp(*mPvdDataStream, mMetaDataBinding, *mScbScene.getPxScene()));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void ScbScenePvdClient::createPvdInstance(const Scb::Actor* actor)
+{
+ // PT: why not UPDATE_PVD_PROPERTIES_CHECK() here?
+ createPvdInstance(getPxActor(actor));
+}
+
+void ScbScenePvdClient::updatePvdProperties(const Scb::Actor* actor)
+{
+ // PT: why not UPDATE_PVD_PROPERTIES_CHECK() here?
+ updatePvdProperties(getPxActor(actor));
+}
+
+void ScbScenePvdClient::releasePvdInstance(const Scb::Actor* actor)
+{
+ // PT: why not UPDATE_PVD_PROPERTIES_CHECK() here?
+ releasePvdInstance(getPxActor(actor));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void ScbScenePvdClient::createPvdInstance(const Scb::Body* body)
+{
+ if(checkPvdDebugFlag() && body->getActorType() != PxActorType::eARTICULATION_LINK)
+ BodyTypeOperation(body, CreateOp(*mPvdDataStream, mMetaDataBinding, mPvd, *mScbScene.getPxScene()));
+}
+
+void ScbScenePvdClient::updatePvdProperties(const Scb::Body* body)
+{
+ if(checkPvdDebugFlag())
+ BodyTypeOperation(body, UpdateOp(*mPvdDataStream, mMetaDataBinding));
+}
+
+void ScbScenePvdClient::updateKinematicTarget(const Scb::Body* body, const PxTransform& p)
+{
+ if(checkPvdDebugFlag())
+ mPvdDataStream->setPropertyValue(getNpRigidDynamic(body), "KinematicTarget", p);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void ScbScenePvdClient::createPvdInstance(const Scb::RigidStatic* rigidStatic)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.createInstance(*mPvdDataStream, *getNpRigidStatic(rigidStatic), *mScbScene.getPxScene(), mPvd);
+}
+
+void ScbScenePvdClient::updatePvdProperties(const Scb::RigidStatic* rigidStatic)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.sendAllProperties(*mPvdDataStream, *getNpRigidStatic(rigidStatic));
+}
+
+void ScbScenePvdClient::releasePvdInstance(const Scb::RigidObject* rigidObject)
+{
+ releasePvdInstance(getPxActor(rigidObject));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void ScbScenePvdClient::createPvdInstance(const Scb::Constraint* constraint)
+{
+ if(checkPvdDebugFlag())
+ updateConstraint(constraint->getScConstraint(), PxPvdUpdateType::CREATE_INSTANCE);
+}
+
+void ScbScenePvdClient::updatePvdProperties(const Scb::Constraint* constraint)
+{
+ if(checkPvdDebugFlag())
+ updateConstraint(constraint->getScConstraint(), PxPvdUpdateType::UPDATE_ALL_PROPERTIES);
+}
+
+void ScbScenePvdClient::releasePvdInstance(const Scb::Constraint* constraint)
+{
+ const Sc::ConstraintCore& scConstraint = constraint->getScConstraint();
+ PxConstraintConnector* conn;
+ if(checkPvdDebugFlag() && (conn = scConstraint.getPxConnector()) != NULL)
+ conn->updatePvdProperties(*mPvdDataStream, scConstraint.getPxConstraint(), PxPvdUpdateType::RELEASE_INSTANCE);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void ScbScenePvdClient::createPvdInstance(const Scb::Articulation* articulation)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.createInstance(*mPvdDataStream, *getNpArticulation(articulation), *mScbScene.getPxScene(), mPvd);
+}
+
+void ScbScenePvdClient::updatePvdProperties(const Scb::Articulation* articulation)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.sendAllProperties(*mPvdDataStream, *getNpArticulation(articulation));
+}
+
+void ScbScenePvdClient::releasePvdInstance(const Scb::Articulation* articulation)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.destroyInstance(*mPvdDataStream, *getNpArticulation(articulation), *mScbScene.getPxScene());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void ScbScenePvdClient::createPvdInstance(const Scb::ArticulationJoint* articulationJoint)
+{
+ PX_UNUSED(articulationJoint);
+}
+
+void ScbScenePvdClient::updatePvdProperties(const Scb::ArticulationJoint* articulationJoint)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.sendAllProperties(*mPvdDataStream, *getNpArticulationJoint(articulationJoint));
+}
+
+void ScbScenePvdClient::releasePvdInstance(const Scb::ArticulationJoint* articulationJoint)
+{
+ PX_UNUSED(articulationJoint);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void ScbScenePvdClient::createPvdInstance(const Sc::MaterialCore* materialCore)
+{
+ if(checkPvdDebugFlag())
+ {
+ const PxMaterial* theMaterial = materialCore->getNxMaterial();
+ if(mPvd->registerObject(theMaterial))
+ mMetaDataBinding.createInstance(*mPvdDataStream, *theMaterial, PxGetPhysics());
+ }
+}
+
+void ScbScenePvdClient::updatePvdProperties(const Sc::MaterialCore* materialCore)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.sendAllProperties(*mPvdDataStream, *materialCore->getNxMaterial());
+}
+
+void ScbScenePvdClient::releasePvdInstance(const Sc::MaterialCore* materialCore)
+{
+ if(checkPvdDebugFlag() && mPvd->unRegisterObject(materialCore->getNxMaterial() ) )
+ mMetaDataBinding.destroyInstance(*mPvdDataStream, *materialCore->getNxMaterial(), PxGetPhysics());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void ScbScenePvdClient::createPvdInstance(const Scb::Shape* shape, PxActor& owner)
+{
+ if(checkPvdDebugFlag())
+ {
+ PX_PROFILE_ZONE("PVD.createPVDInstance", getContextId(mScbScene));
+ const PxShape* npShape = getNpShape(shape);
+ mMetaDataBinding.createInstance(*mPvdDataStream, *npShape, static_cast<PxRigidActor&>(owner), mPvd);
+ }
+}
+
+static void addShapesToPvd(PxU32 nbShapes, void* const* shapes, const size_t offset, PxActor& pxActor, PsPvd* pvd, PvdDataStream& stream, PvdMetaDataBinding& binding)
+{
+ for(PxU32 i=0;i<nbShapes;i++)
+ {
+ const Scb::Shape* shape = reinterpret_cast<Scb::Shape*>(reinterpret_cast<char*>(shapes[i]) + offset);
+ const PxShape* npShape = getNpShape(shape);
+ binding.createInstance(stream, *npShape, static_cast<PxRigidActor&>(pxActor), pvd);
+ }
+}
+
+void ScbScenePvdClient::addBodyAndShapesToPvd(Scb::Body& b)
+{
+ if(checkPvdDebugFlag())
+ {
+ PX_PROFILE_ZONE("PVD.createPVDInstance", getContextId(mScbScene));
+ createPvdInstance(&b);
+
+ const size_t offset = NpShapeGetScPtrOffset() - Scb::Shape::getScOffset();
+ PxActor& pxActor = *b.getScBody().getPxActor();
+
+ void* const* shapes;
+ const PxU32 nbShapes = NpRigidDynamicGetShapes(b, shapes);
+ addShapesToPvd(nbShapes, shapes, offset, pxActor, mPvd, *mPvdDataStream, mMetaDataBinding);
+ }
+}
+
+void ScbScenePvdClient::addStaticAndShapesToPvd(Scb::RigidStatic& s)
+{
+ if(checkPvdDebugFlag())
+ {
+ PX_PROFILE_ZONE("PVD.createPVDInstance", getContextId(mScbScene));
+ createPvdInstance(&s);
+
+ const size_t offset = NpShapeGetScPtrOffset() - Scb::Shape::getScOffset();
+ PxActor& pxActor = *s.getScStatic().getPxActor();
+
+ void* const* shapes;
+ const PxU32 nbShapes = NpRigidStaticGetShapes(s, shapes);
+ addShapesToPvd(nbShapes, shapes, offset, pxActor, mPvd, *mPvdDataStream, mMetaDataBinding);
+ }
+}
+
+void ScbScenePvdClient::updateMaterials(const Scb::Shape* shape)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.updateMaterials(*mPvdDataStream, *getNpShape(const_cast<Scb::Shape*>(shape)), mPvd);
+}
+
+void ScbScenePvdClient::updatePvdProperties(const Scb::Shape* shape)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.sendAllProperties(*mPvdDataStream, *getNpShape(const_cast<Scb::Shape*>(shape)));
+}
+
+void ScbScenePvdClient::releaseAndRecreateGeometry(const Scb::Shape* shape)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.releaseAndRecreateGeometry(*mPvdDataStream, *getNpShape(const_cast<Scb::Shape*>(shape)),
+ NpPhysics::getInstance(), mPvd);
+}
+
+void ScbScenePvdClient::releasePvdInstance(const Scb::Shape* shape, PxActor& owner)
+{
+ if(checkPvdDebugFlag())
+ {
+ PX_PROFILE_ZONE("PVD.releasePVDInstance", getContextId(mScbScene));
+
+ const NpShape* npShape = getNpShape(shape);
+ mMetaDataBinding.destroyInstance(*mPvdDataStream, *npShape, static_cast<PxRigidActor&>(owner));
+
+ const PxU32 numMaterials = npShape->getNbMaterials();
+ PX_ALLOCA(materialPtr, PxMaterial*, numMaterials);
+ npShape->getMaterials(materialPtr, numMaterials);
+
+ for(PxU32 idx = 0; idx < numMaterials; ++idx)
+ releasePvdInstance(&(static_cast<NpMaterial*>(materialPtr[idx])->getScMaterial()));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void ScbScenePvdClient::originShift(PxVec3 shift)
+{
+ mMetaDataBinding.originShift(*mPvdDataStream, mScbScene.getPxScene(), shift);
+}
+
+template <typename TPropertyType>
+void ScbScenePvdClient::sendArray(const void* instance, const char* propName, const Cm::BitMap* bitMap,
+ PxU32 nbValidParticles, PxStrideIterator<const TPropertyType>& iterator)
+{
+ PX_ASSERT(nbValidParticles > 0);
+ if(!iterator.ptr())
+ return;
+
+ // setup the pvd array PxParticleFlags
+ pvdsdk::DataRef<const PxU8> propData;
+ Ps::Array<PxU8> mTempU8Array;
+ mTempU8Array.resize(nbValidParticles * sizeof(TPropertyType));
+ TPropertyType* tmpArray = reinterpret_cast<TPropertyType*>(mTempU8Array.begin());
+ propData = pvdsdk::DataRef<const PxU8>(mTempU8Array.begin(), mTempU8Array.size());
+
+ PxU32 tIdx = 0;
+ Cm::BitMap::Iterator it(*bitMap);
+ for(PxU32 index = it.getNext(); index != Cm::BitMap::Iterator::DONE; index = it.getNext())
+ {
+ tmpArray[tIdx++] = iterator[index];
+ }
+ PX_ASSERT(tIdx == nbValidParticles);
+
+ mPvdDataStream->setPropertyValue(instance, propName, propData,
+ pvdsdk::getPvdNamespacedNameForType<TPropertyType>());
+}
+
+void ScbScenePvdClient::sendStateDatas(Sc::ParticleSystemCore* psCore)
+{
+ PX_UNUSED(psCore);
+#if PX_USE_PARTICLE_SYSTEM_API
+
+ if(!checkPvdDebugFlag())
+ return;
+
+ Scb::ParticleSystem* scbParticleSystem = getScbParticleSystem(psCore);
+ bool doProcess = scbParticleSystem->getFlags() & PxParticleBaseFlag::eENABLED;
+#if PX_SUPPORT_GPU_PHYSX
+ doProcess &= (scbParticleSystem->getDeviceExclusiveAccessGpu() == NULL);
+#endif
+ if(doProcess)
+ {
+ Sc::ParticleSystemSim* particleSystem = psCore->getSim();
+ Pt::ParticleSystemStateDataDesc stateData;
+ particleSystem->getParticleState().getParticlesV(stateData, true, false);
+ Pt::ParticleSystemSimDataDesc simParticleData;
+ particleSystem->getSimParticleData(simParticleData, false);
+
+ const PxActor* pxActor = getPxActor(scbParticleSystem);
+
+ // mPvdDataStream->setPropertyValue( pxActor, "WorldBounds", psCore->getWorldBounds());
+ mPvdDataStream->setPropertyValue(pxActor, "NbParticles", stateData.numParticles);
+ mPvdDataStream->setPropertyValue(pxActor, "ValidParticleRange", stateData.validParticleRange);
+
+ if(stateData.validParticleRange > 0)
+ {
+ mPvdDataStream->setPropertyValue(pxActor, "ValidParticleBitmap", stateData.bitMap->getWords(),
+ (stateData.validParticleRange >> 5) + 1);
+ sendArray<PxVec3>(pxActor, "Positions", stateData.bitMap, stateData.numParticles, stateData.positions);
+ sendArray<PxVec3>(pxActor, "Velocities", stateData.bitMap, stateData.numParticles, stateData.velocities);
+ sendArray<PxF32>(pxActor, "RestOffsets", stateData.bitMap, stateData.numParticles, stateData.restOffsets);
+ sendArray<PxVec3>(pxActor, "CollisionNormals", stateData.bitMap, stateData.numParticles,
+ simParticleData.collisionNormals);
+ sendArray<PxF32>(pxActor, "Densities", stateData.bitMap, stateData.numParticles, simParticleData.densities);
+ // todo: twoway data if need more particle retrieval
+
+ { // send PxParticleFlags, we have Pt::ParticleFlags here
+ pvdsdk::DataRef<const PxU8> propData;
+ Ps::Array<PxU8> mTempU8Array;
+ mTempU8Array.resize(stateData.numParticles * sizeof(PxU16));
+ PxU16* tmpArray = reinterpret_cast<PxU16*>(mTempU8Array.begin());
+ propData = pvdsdk::DataRef<const PxU8>(mTempU8Array.begin(), mTempU8Array.size());
+
+ PxU32 tIdx = 0;
+ PxStrideIterator<const Pt::ParticleFlags>& iterator = stateData.flags;
+ Cm::BitMap::Iterator it(*stateData.bitMap);
+ for(PxU32 index = it.getNext(); index != Cm::BitMap::Iterator::DONE; index = it.getNext())
+ {
+ tmpArray[tIdx++] = iterator[index].api;
+ }
+
+ mPvdDataStream->setPropertyValue(pxActor, "Flags", propData,
+ pvdsdk::getPvdNamespacedNameForType<PxU16>());
+ }
+ }
+ }
+#endif
+}
+
+void ScbScenePvdClient::frameStart(PxReal simulateElapsedTime)
+{
+ PX_PROFILE_ZONE("Basic.pvdFrameStart", mScbScene.getContextId());
+
+ if(!mIsConnected)
+ return;
+
+ mPvdDataStream->flushPvdCommand();
+ mMetaDataBinding.sendBeginFrame(*mPvdDataStream, mScbScene.getPxScene(), simulateElapsedTime);
+}
+
+void ScbScenePvdClient::frameEnd()
+{
+ PX_PROFILE_ZONE("Basic.pvdFrameEnd", mScbScene.getContextId());
+
+ if(!mIsConnected)
+ {
+ if(mPvd)
+ mPvd->flush(); // Even if we aren't connected, we may need to flush buffered events.
+ return;
+ }
+
+ PxScene* theScene = mScbScene.getPxScene();
+
+ // Send the statistics for last frame.
+ void* tmp = NULL;
+#if PX_SUPPORT_GPU_PHYSX
+ if(mScbScene.getScScene().getSceneGpu())
+ {
+ NpPhysics& npPhysics = static_cast<NpPhysics&>(theScene->getPhysics());
+ PxTriangleMeshCacheStatistics triMeshCacheStats =
+ npPhysics.getNpPhysicsGpu().getTriangleMeshCacheStatistics(*theScene);
+ tmp = &triMeshCacheStats;
+ }
+#endif
+ mMetaDataBinding.sendStats(*mPvdDataStream, theScene, tmp);
+
+ if(mPvd->getInstrumentationFlags() & PxPvdInstrumentationFlag::eDEBUG)
+ {
+#if PX_USE_PARTICLE_SYSTEM_API
+ // particle systems & fluids:
+ {
+ PX_PROFILE_ZONE("PVD.updatePariclesAndFluids", getContextId(mScbScene));
+ PxU32 nbParticleSystems = mScbScene.getScScene().getNbParticleSystems();
+ Sc::ParticleSystemCore* const* particleSystems = mScbScene.getScScene().getParticleSystems();
+ for(PxU32 i = 0; i < nbParticleSystems; i++)
+ {
+ sendStateDatas(particleSystems[i]);
+ }
+ }
+#endif
+
+#if PX_USE_CLOTH_API
+ {
+ PX_PROFILE_ZONE("PVD.updateCloths", getContextId(mScbScene));
+ mMetaDataBinding.updateCloths(*mPvdDataStream, *theScene);
+ }
+#endif
+ }
+
+ // flush our data to the main connection
+ mPvd->flush();
+
+ // End the frame *before* we send the dynamic object current data.
+ // This ensures that contacts end up synced with the rest of the system.
+ // Note that contacts were sent much earler in NpScene::fetchResults.
+ mMetaDataBinding.sendEndFrame(*mPvdDataStream, mScbScene.getPxScene());
+
+ if(mPvd->getInstrumentationFlags() & PxPvdInstrumentationFlag::eDEBUG)
+ {
+ PvdVisualizer* vizualizer = NULL;
+ const bool visualizeJoints = getScenePvdFlags() & PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS;
+ if(visualizeJoints)
+ vizualizer = this;
+
+ PX_PROFILE_ZONE("PVD.sceneUpdate", getContextId(mScbScene));
+ mMetaDataBinding.updateDynamicActorsAndArticulations(*mPvdDataStream, theScene, vizualizer);
+ }
+
+ // frame end moved to update contacts to have them in the previous frame.
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void ScbScenePvdClient::createPvdInstance(const Scb::Aggregate* aggregate)
+{
+ if(checkPvdDebugFlag())
+ {
+ PX_PROFILE_ZONE("PVD.createPVDInstance", getContextId(mScbScene));
+ const NpAggregate* npAggregate = getNpAggregate(aggregate);
+ mMetaDataBinding.createInstance(*mPvdDataStream, *npAggregate, *mScbScene.getPxScene());
+ }
+}
+
+void ScbScenePvdClient::updatePvdProperties(const Scb::Aggregate* aggregate)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.sendAllProperties(*mPvdDataStream, *getNpAggregate(aggregate));
+}
+
+void ScbScenePvdClient::attachAggregateActor(const Scb::Aggregate* aggregate, Scb::Actor* actor)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.attachAggregateActor(*mPvdDataStream, *getNpAggregate(aggregate), *getPxActor(actor));
+}
+
+void ScbScenePvdClient::detachAggregateActor(const Scb::Aggregate* aggregate, Scb::Actor* actor)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.detachAggregateActor(*mPvdDataStream, *getNpAggregate(aggregate), *getPxActor(actor));
+}
+
+void ScbScenePvdClient::releasePvdInstance(const Scb::Aggregate* aggregate)
+{
+ if(checkPvdDebugFlag())
+ {
+ PX_PROFILE_ZONE("PVD.releasePVDInstance", getContextId(mScbScene));
+ const NpAggregate* npAggregate = getNpAggregate(aggregate);
+ mMetaDataBinding.destroyInstance(*mPvdDataStream, *npAggregate, *mScbScene.getPxScene());
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if PX_USE_CLOTH_API
+static inline const PxCloth* toPx(const Scb::Cloth* cloth)
+{
+ const NpCloth* realCloth = getNpCloth(cloth);
+ return static_cast<const PxCloth*>(realCloth);
+}
+
+void ScbScenePvdClient::createPvdInstance(const Scb::Cloth* cloth)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.createInstance(*mPvdDataStream, *getNpCloth(cloth), *mScbScene.getPxScene(), mPvd);
+}
+
+void ScbScenePvdClient::sendSimpleProperties(const Scb::Cloth* cloth)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.sendSimpleProperties(*mPvdDataStream, *toPx(cloth));
+}
+
+void ScbScenePvdClient::sendMotionConstraints(const Scb::Cloth* cloth)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.sendMotionConstraints(*mPvdDataStream, *toPx(cloth));
+}
+
+void ScbScenePvdClient::sendSelfCollisionIndices(const Scb::Cloth* cloth)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.sendSelfCollisionIndices(*mPvdDataStream, *toPx(cloth));
+}
+
+void ScbScenePvdClient::sendRestPositions(const Scb::Cloth* cloth)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.sendRestPositions(*mPvdDataStream, *toPx(cloth));
+}
+
+void ScbScenePvdClient::sendSeparationConstraints(const Scb::Cloth* cloth)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.sendSeparationConstraints(*mPvdDataStream, *toPx(cloth));
+}
+
+void ScbScenePvdClient::sendCollisionSpheres(const Scb::Cloth* cloth)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.sendCollisionSpheres(*mPvdDataStream, *toPx(cloth));
+}
+
+void ScbScenePvdClient::sendCollisionCapsules(const Scb::Cloth* cloth)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.sendCollisionSpheres(*mPvdDataStream, *toPx(cloth), true);
+}
+
+void ScbScenePvdClient::sendCollisionTriangles(const Scb::Cloth* cloth)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.sendCollisionTriangles(*mPvdDataStream, *toPx(cloth));
+}
+
+void ScbScenePvdClient::sendParticleAccelerations(const Scb::Cloth* cloth)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.sendParticleAccelerations(*mPvdDataStream, *toPx(cloth));
+}
+
+void ScbScenePvdClient::sendVirtualParticles(const Scb::Cloth* cloth)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.sendVirtualParticles(*mPvdDataStream, *toPx(cloth));
+}
+
+void ScbScenePvdClient::releasePvdInstance(const Scb::Cloth* cloth)
+{
+ if(checkPvdDebugFlag())
+ mMetaDataBinding.destroyInstance(*mPvdDataStream, *toPx(cloth), *mScbScene.getPxScene());
+}
+#endif // PX_USE_CLOTH_API
+
+///////////////////////////////////////////////////////////////////////////////
+
+void ScbScenePvdClient::updateJoints()
+{
+ if(checkPvdDebugFlag())
+ {
+ const bool visualizeJoints = getScenePvdFlags() & PxPvdSceneFlag::eTRANSMIT_CONTACTS;
+
+ // joints
+ {
+ PX_PROFILE_ZONE("PVD.updateJoints", getContextId(mScbScene));
+ Sc::ConstraintCore*const * constraints = mScbScene.getScScene().getConstraints();
+ PxU32 nbConstraints = mScbScene.getScScene().getNbConstraints();
+ PxI64 constraintCount = 0;
+
+ for(PxU32 i = 0; i < nbConstraints; i++)
+ {
+ Sc::ConstraintCore* constraint = constraints[i];
+ PxPvdUpdateType::Enum updateType = getNpConstraint(constraint)->isDirty()
+ ? PxPvdUpdateType::UPDATE_ALL_PROPERTIES
+ : PxPvdUpdateType::UPDATE_SIM_PROPERTIES;
+ updateConstraint(*constraint, updateType);
+ PxConstraintConnector* conn = constraint->getPxConnector();
+ // visualization is updated here
+ {
+ PxU32 typeId = 0;
+ void* joint = NULL;
+ if(conn)
+ joint = conn->getExternalReference(typeId);
+ // visualize:
+ Sc::ConstraintSim* sim = constraint->getSim();
+ if(visualizeJoints && sim && sim->getConstantsLL() && joint && constraint->getVisualize())
+ {
+ Sc::BodySim* b0 = sim->getBody(0);
+ Sc::BodySim* b1 = sim->getBody(1);
+ PxTransform t0 = b0 ? b0->getBody2World() : PxTransform(PxIdentity);
+ PxTransform t1 = b1 ? b1->getBody2World() : PxTransform(PxIdentity);
+ PvdConstraintVisualizer viz(joint, *mUserRender);
+ (*constraint->getVisualize())(viz, sim->getConstantsLL(), t0, t1, 0xffffFFFF);
+ }
+ }
+ ++constraintCount;
+ }
+
+ mUserRender->flushRenderEvents();
+ }
+ }
+}
+
+void ScbScenePvdClient::updateContacts()
+{
+ if(!checkPvdDebugFlag())
+ return;
+
+ // if contacts are disabled, send empty array and return
+ const PxScene* theScene(mScbScene.getPxScene());
+ if(!(getScenePvdFlags() & PxPvdSceneFlag::eTRANSMIT_CONTACTS))
+ {
+ mMetaDataBinding.sendContacts(*mPvdDataStream, *theScene);
+ return;
+ }
+
+ PX_PROFILE_ZONE("PVD.updateContacts", getContextId(mScbScene));
+
+ PxsContactManagerOutputIterator outputIter;
+
+ Sc::ContactIterator contactIter;
+ mScbScene.getScScene().initContactsIterator(contactIter, outputIter);
+ Sc::ContactIterator::Pair* pair;
+ Sc::Contact* contact;
+ Ps::Array<Sc::Contact> contacts;
+ while ((pair = contactIter.getNextPair()) != NULL)
+ {
+ while ((contact = pair->getNextContact()) != NULL)
+ contacts.pushBack(*contact);
+ }
+
+ mMetaDataBinding.sendContacts(*mPvdDataStream, *theScene, contacts);
+}
+
+
+void ScbScenePvdClient::updateSceneQueries()
+{
+ // if contacts are disabled, send empty array and return
+ if(checkPvdDebugFlag() && (getScenePvdFlags() & PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES))
+ mMetaDataBinding.sendSceneQueries(*mPvdDataStream, *mScbScene.getPxScene(), mPvd);
+}
+
+void ScbScenePvdClient::setCreateContactReports(bool b)
+{
+ mScbScene.getScScene().setCreateContactReports(b);
+}
+
+void ScbScenePvdClient::visualize(PxArticulationLink& link)
+{
+ NpArticulationLink& npLink = static_cast<NpArticulationLink&>(link);
+ const void* itemId = npLink.getInboundJoint();
+ if(itemId && mUserRender)
+ {
+ PvdConstraintVisualizer viz(itemId, *mUserRender);
+ npLink.visualizeJoint(viz);
+ }
+}
+
+void ScbScenePvdClient::visualize(const PxRenderBuffer& debugRenderable)
+{
+ if(mUserRender)
+ {
+ mUserRender->drawRenderbuffer(reinterpret_cast<const PvdDebugPoint*>(debugRenderable.getPoints()), debugRenderable.getNbPoints(),
+ reinterpret_cast<const PvdDebugLine*>(debugRenderable.getLines()), debugRenderable.getNbLines(),
+ reinterpret_cast<const PvdDebugTriangle*>(debugRenderable.getTriangles()), debugRenderable.getNbTriangles());
+ mUserRender->flushRenderEvents();
+ }
+}
+
+#endif