405 lines
9.7 KiB
C++
405 lines
9.7 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-2025 NVIDIA Corporation. All rights reserved.
|
|
|
|
#include "PxPvdUserRenderImpl.h"
|
|
#include "PxPvdInternalByteStreams.h"
|
|
#include "PxPvdBits.h"
|
|
#include <stdarg.h>
|
|
|
|
using namespace physx;
|
|
using namespace physx::pvdsdk;
|
|
|
|
namespace
|
|
{
|
|
|
|
template <typename TStreamType>
|
|
struct RenderWriter : public RenderSerializer
|
|
{
|
|
TStreamType& mStream;
|
|
RenderWriter(TStreamType& stream) : mStream(stream)
|
|
{
|
|
}
|
|
template <typename TDataType>
|
|
void write(const TDataType* val, uint32_t count)
|
|
{
|
|
uint32_t numBytes = count * sizeof(TDataType);
|
|
mStream.write(reinterpret_cast<const uint8_t*>(val), numBytes);
|
|
}
|
|
template <typename TDataType>
|
|
void write(const TDataType& val)
|
|
{
|
|
write(&val, 1);
|
|
}
|
|
|
|
template <typename TDataType>
|
|
void writeRef(DataRef<TDataType>& val)
|
|
{
|
|
uint32_t amount = val.size();
|
|
write(amount);
|
|
if(amount)
|
|
write(val.begin(), amount);
|
|
}
|
|
|
|
virtual void streamify(uint64_t& val)
|
|
{
|
|
write(val);
|
|
}
|
|
virtual void streamify(uint32_t& val)
|
|
{
|
|
write(val);
|
|
}
|
|
virtual void streamify(float& val)
|
|
{
|
|
write(val);
|
|
}
|
|
virtual void streamify(uint8_t& val)
|
|
{
|
|
write(val);
|
|
}
|
|
virtual void streamify(DataRef<uint8_t>& val)
|
|
{
|
|
writeRef(val);
|
|
}
|
|
|
|
virtual void streamify(PxDebugText& val)
|
|
{
|
|
write(val.color);
|
|
write(val.position);
|
|
write(val.size);
|
|
|
|
uint32_t amount = static_cast<uint32_t>(strlen(val.string)) + 1;
|
|
write(amount);
|
|
if(amount)
|
|
write(val.string, amount);
|
|
}
|
|
|
|
virtual void streamify(DataRef<PxDebugPoint>& val)
|
|
{
|
|
writeRef(val);
|
|
}
|
|
virtual void streamify(DataRef<PxDebugLine>& val)
|
|
{
|
|
writeRef(val);
|
|
}
|
|
virtual void streamify(DataRef<PxDebugTriangle>& val)
|
|
{
|
|
writeRef(val);
|
|
}
|
|
|
|
virtual uint32_t hasData()
|
|
{
|
|
return false;
|
|
}
|
|
virtual bool isGood()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
RenderWriter& operator=(const RenderWriter&);
|
|
};
|
|
|
|
struct UserRenderer : public PvdUserRenderer
|
|
{
|
|
ForwardingMemoryBuffer mBuffer;
|
|
uint32_t mBufferCapacity;
|
|
RendererEventClient* mClient;
|
|
|
|
UserRenderer(uint32_t bufferFullAmount)
|
|
: mBuffer("UserRenderBuffer"), mBufferCapacity(bufferFullAmount), mClient(NULL)
|
|
{
|
|
}
|
|
virtual ~UserRenderer()
|
|
{
|
|
}
|
|
virtual void release()
|
|
{
|
|
PVD_DELETE(this);
|
|
}
|
|
|
|
template <typename TEventType>
|
|
void handleEvent(TEventType evt)
|
|
{
|
|
RenderWriter<ForwardingMemoryBuffer> _writer(mBuffer);
|
|
RenderSerializer& writer(_writer);
|
|
|
|
PvdUserRenderTypes::Enum evtType(getPvdRenderTypeFromType<TEventType>());
|
|
writer.streamify(evtType);
|
|
evt.serialize(writer);
|
|
if(mBuffer.size() >= mBufferCapacity)
|
|
flushRenderEvents();
|
|
}
|
|
virtual void setInstanceId(const void* iid)
|
|
{
|
|
handleEvent(SetInstanceIdRenderEvent(PVD_POINTER_TO_U64(iid)));
|
|
}
|
|
// Draw these points associated with this instance
|
|
virtual void drawPoints(const PxDebugPoint* points, uint32_t count)
|
|
{
|
|
handleEvent(PointsRenderEvent(points, count));
|
|
}
|
|
// Draw these lines associated with this instance
|
|
virtual void drawLines(const PxDebugLine* lines, uint32_t count)
|
|
{
|
|
handleEvent(LinesRenderEvent(lines, count));
|
|
}
|
|
// Draw these triangles associated with this instance
|
|
virtual void drawTriangles(const PxDebugTriangle* triangles, uint32_t count)
|
|
{
|
|
handleEvent(TrianglesRenderEvent(triangles, count));
|
|
}
|
|
|
|
virtual void drawText(const PxDebugText& text)
|
|
{
|
|
handleEvent(TextRenderEvent(text));
|
|
}
|
|
|
|
virtual void drawRenderbuffer(const PxDebugPoint* pointData, uint32_t pointCount, const PxDebugLine* lineData,
|
|
uint32_t lineCount, const PxDebugTriangle* triangleData, uint32_t triangleCount)
|
|
{
|
|
handleEvent(DebugRenderEvent(pointData, pointCount, lineData, lineCount, triangleData, triangleCount));
|
|
}
|
|
|
|
// Constraint visualization routines
|
|
virtual void visualizeJointFrames(const PxTransform& parent, const PxTransform& child) PX_OVERRIDE
|
|
{
|
|
handleEvent(JointFramesRenderEvent(parent, child));
|
|
}
|
|
virtual void visualizeLinearLimit(const PxTransform& t0, const PxTransform& t1, float value) PX_OVERRIDE
|
|
{
|
|
handleEvent(LinearLimitRenderEvent(t0, t1, value, true));
|
|
}
|
|
virtual void visualizeAngularLimit(const PxTransform& t0, float lower, float upper) PX_OVERRIDE
|
|
{
|
|
handleEvent(AngularLimitRenderEvent(t0, lower, upper, true));
|
|
}
|
|
virtual void visualizeLimitCone(const PxTransform& t, float tanQSwingY, float tanQSwingZ) PX_OVERRIDE
|
|
{
|
|
handleEvent(LimitConeRenderEvent(t, tanQSwingY, tanQSwingZ, true));
|
|
}
|
|
virtual void visualizeDoubleCone(const PxTransform& t, float angle) PX_OVERRIDE
|
|
{
|
|
handleEvent(DoubleConeRenderEvent(t, angle, true));
|
|
}
|
|
// Clear the immedate buffer.
|
|
virtual void flushRenderEvents()
|
|
{
|
|
if(mClient)
|
|
mClient->handleBufferFlush(mBuffer.begin(), mBuffer.size());
|
|
mBuffer.clear();
|
|
}
|
|
|
|
virtual void setClient(RendererEventClient* client)
|
|
{
|
|
mClient = client;
|
|
}
|
|
|
|
private:
|
|
UserRenderer& operator=(const UserRenderer&);
|
|
};
|
|
|
|
template <bool swapBytes>
|
|
struct RenderReader : public RenderSerializer
|
|
{
|
|
MemPvdInputStream mStream;
|
|
ForwardingMemoryBuffer& mBuffer;
|
|
|
|
RenderReader(ForwardingMemoryBuffer& buf) : mBuffer(buf)
|
|
{
|
|
}
|
|
void setData(DataRef<const uint8_t> data)
|
|
{
|
|
mStream.setup(const_cast<uint8_t*>(data.begin()), const_cast<uint8_t*>(data.end()));
|
|
}
|
|
virtual void streamify(uint32_t& val)
|
|
{
|
|
mStream >> val;
|
|
}
|
|
virtual void streamify(uint64_t& val)
|
|
{
|
|
mStream >> val;
|
|
}
|
|
virtual void streamify(float& val)
|
|
{
|
|
mStream >> val;
|
|
}
|
|
virtual void streamify(uint8_t& val)
|
|
{
|
|
mStream >> val;
|
|
}
|
|
template <typename TDataType>
|
|
void readRef(DataRef<TDataType>& val)
|
|
{
|
|
uint32_t count;
|
|
mStream >> count;
|
|
uint32_t numBytes = sizeof(TDataType) * count;
|
|
|
|
TDataType* dataPtr = reinterpret_cast<TDataType*>(mBuffer.growBuf(numBytes));
|
|
mStream.read(reinterpret_cast<uint8_t*>(dataPtr), numBytes);
|
|
val = DataRef<TDataType>(dataPtr, count);
|
|
}
|
|
|
|
virtual void streamify(DataRef<PxDebugPoint>& val)
|
|
{
|
|
readRef(val);
|
|
}
|
|
virtual void streamify(DataRef<PxDebugLine>& val)
|
|
{
|
|
readRef(val);
|
|
}
|
|
virtual void streamify(DataRef<PxDebugTriangle>& val)
|
|
{
|
|
readRef(val);
|
|
}
|
|
virtual void streamify(PxDebugText& val)
|
|
{
|
|
mStream >> val.color;
|
|
mStream >> val.position;
|
|
mStream >> val.size;
|
|
|
|
uint32_t len = 0;
|
|
mStream >> len;
|
|
|
|
uint8_t* dataPtr = mBuffer.growBuf(len);
|
|
mStream.read(dataPtr, len);
|
|
val.string = reinterpret_cast<const char*>(dataPtr);
|
|
}
|
|
virtual void streamify(DataRef<uint8_t>& val)
|
|
{
|
|
readRef(val);
|
|
}
|
|
virtual bool isGood()
|
|
{
|
|
return mStream.isGood();
|
|
}
|
|
virtual uint32_t hasData()
|
|
{
|
|
return uint32_t(mStream.size() > 0);
|
|
}
|
|
|
|
private:
|
|
RenderReader& operator=(const RenderReader&);
|
|
};
|
|
|
|
template <>
|
|
struct RenderReader<true> : public RenderSerializer
|
|
{
|
|
MemPvdInputStream mStream;
|
|
ForwardingMemoryBuffer& mBuffer;
|
|
RenderReader(ForwardingMemoryBuffer& buf) : mBuffer(buf)
|
|
{
|
|
}
|
|
void setData(DataRef<const uint8_t> data)
|
|
{
|
|
mStream.setup(const_cast<uint8_t*>(data.begin()), const_cast<uint8_t*>(data.end()));
|
|
}
|
|
|
|
template <typename TDataType>
|
|
void read(TDataType& val)
|
|
{
|
|
mStream >> val;
|
|
swapBytes(val);
|
|
}
|
|
virtual void streamify(uint64_t& val)
|
|
{
|
|
read(val);
|
|
}
|
|
virtual void streamify(uint32_t& val)
|
|
{
|
|
read(val);
|
|
}
|
|
virtual void streamify(float& val)
|
|
{
|
|
read(val);
|
|
}
|
|
virtual void streamify(uint8_t& val)
|
|
{
|
|
read(val);
|
|
}
|
|
template <typename TDataType>
|
|
void readRef(DataRef<TDataType>& val)
|
|
{
|
|
uint32_t count;
|
|
mStream >> count;
|
|
swapBytes(count);
|
|
uint32_t numBytes = sizeof(TDataType) * count;
|
|
|
|
TDataType* dataPtr = reinterpret_cast<TDataType*>(mBuffer.growBuf(numBytes));
|
|
PVD_FOREACH(idx, count)
|
|
RenderSerializerMap<TDataType>().serialize(*this, dataPtr[idx]);
|
|
val = DataRef<TDataType>(dataPtr, count);
|
|
}
|
|
|
|
virtual void streamify(DataRef<PxDebugPoint>& val)
|
|
{
|
|
readRef(val);
|
|
}
|
|
virtual void streamify(DataRef<PxDebugLine>& val)
|
|
{
|
|
readRef(val);
|
|
}
|
|
virtual void streamify(DataRef<PxDebugTriangle>& val)
|
|
{
|
|
readRef(val);
|
|
}
|
|
virtual void streamify(PxDebugText& val)
|
|
{
|
|
mStream >> val.color;
|
|
mStream >> val.position;
|
|
mStream >> val.size;
|
|
|
|
uint32_t len = 0;
|
|
mStream >> len;
|
|
|
|
uint8_t* dataPtr = mBuffer.growBuf(len);
|
|
mStream.read(dataPtr, len);
|
|
val.string = reinterpret_cast<const char*>(dataPtr);
|
|
}
|
|
virtual void streamify(DataRef<uint8_t>& val)
|
|
{
|
|
readRef(val);
|
|
}
|
|
virtual bool isGood()
|
|
{
|
|
return mStream.isGood();
|
|
}
|
|
virtual uint32_t hasData()
|
|
{
|
|
return uint32_t(mStream.size() > 0);
|
|
}
|
|
|
|
private:
|
|
RenderReader& operator=(const RenderReader&);
|
|
};
|
|
|
|
}
|
|
|
|
PvdUserRenderer* PvdUserRenderer::create(uint32_t bufferSize)
|
|
{
|
|
return PVD_NEW(UserRenderer)(bufferSize);
|
|
}
|
|
|