RavEngine
Loading...
Searching...
No Matches
PxRenderOutput.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2008-2022 NVIDIA Corporation. All rights reserved.
26// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
27// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
28
29#ifndef PX_RENDER_OUTPUT_H
30#define PX_RENDER_OUTPUT_H
31
32#include "foundation/PxMat44.h"
33#include "foundation/PxBasicTemplates.h"
34#include "PxRenderBuffer.h"
35
36#if !PX_DOXYGEN
37namespace physx
38{
39#endif
40
41#if PX_VC
42#pragma warning(push)
43#pragma warning( disable : 4251 ) // class needs to have dll-interface to be used by clients of class
44#endif
45
49 class PX_PHYSX_COMMON_API PxRenderOutput
50 {
51 public:
52
53 enum Primitive
54 {
55 POINTS,
56 LINES,
57 LINESTRIP,
58 TRIANGLES,
59 TRIANGLESTRIP
60 };
61
63 : mPrim(POINTS),
64 mColor(0),
65 mVertex0(0.0f),
66 mVertex1(0.0f),
67 mVertexCount(0),
68 mTransform(PxIdentity),
69 mBuffer(buffer)
70 {
71 }
72
73 PX_INLINE PxRenderOutput& operator<<(Primitive prim);
74
75 PX_INLINE PxRenderOutput& operator<<(PxU32 color) ;
76
77 PX_INLINE PxRenderOutput& operator<<(const PxMat44& transform);
78
79 PX_INLINE PxRenderOutput& operator<<(const PxTransform& t);
80
81 PX_INLINE PxRenderOutput& operator<<(const PxVec3& vertex); //AM: Don't use this! Slow! Deprecated!
82
83 PX_INLINE PxDebugLine* reserveSegments(PxU32 nbSegments);
84
85 PX_INLINE PxDebugPoint* reservePoints(PxU32 nbSegments);
86
87 PX_INLINE void outputSegment(const PxVec3& v0, const PxVec3& v1);
88
89 PX_INLINE PxRenderOutput& outputCapsule(PxF32 radius, PxF32 halfHeight, const PxMat44& absPose);
90
91 private:
92
93 PxRenderOutput& operator=(const PxRenderOutput&);
94
95 Primitive mPrim;
96 PxU32 mColor;
97 PxVec3 mVertex0, mVertex1;
98 PxU32 mVertexCount;
99 PxMat44 mTransform;
100 PxRenderBuffer& mBuffer;
101 };
102
104 {
105 explicit PxDebugBox(const PxVec3& extents, bool wireframe_ = true)
106 : minimum(-extents), maximum(extents), wireframe(wireframe_) {}
107
108 explicit PxDebugBox(const PxVec3& pos, const PxVec3& extents, bool wireframe_ = true)
109 : minimum(pos - extents), maximum(pos + extents), wireframe(wireframe_) {}
110
111 explicit PxDebugBox(const PxBounds3& bounds, bool wireframe_ = true)
112 : minimum(bounds.minimum), maximum(bounds.maximum), wireframe(wireframe_) {}
113
114 PxVec3 minimum, maximum;
115 bool wireframe;
116 };
117 PX_FORCE_INLINE PxRenderOutput& operator<<(PxRenderOutput& out, const PxDebugBox& box)
118 {
119 if (box.wireframe)
120 {
121 out << PxRenderOutput::LINESTRIP;
122 out << PxVec3(box.minimum.x, box.minimum.y, box.minimum.z);
123 out << PxVec3(box.maximum.x, box.minimum.y, box.minimum.z);
124 out << PxVec3(box.maximum.x, box.maximum.y, box.minimum.z);
125 out << PxVec3(box.minimum.x, box.maximum.y, box.minimum.z);
126 out << PxVec3(box.minimum.x, box.minimum.y, box.minimum.z);
127 out << PxVec3(box.minimum.x, box.minimum.y, box.maximum.z);
128 out << PxVec3(box.maximum.x, box.minimum.y, box.maximum.z);
129 out << PxVec3(box.maximum.x, box.maximum.y, box.maximum.z);
130 out << PxVec3(box.minimum.x, box.maximum.y, box.maximum.z);
131 out << PxVec3(box.minimum.x, box.minimum.y, box.maximum.z);
132 out << PxRenderOutput::LINES;
133 out << PxVec3(box.maximum.x, box.minimum.y, box.minimum.z);
134 out << PxVec3(box.maximum.x, box.minimum.y, box.maximum.z);
135 out << PxVec3(box.maximum.x, box.maximum.y, box.minimum.z);
136 out << PxVec3(box.maximum.x, box.maximum.y, box.maximum.z);
137 out << PxVec3(box.minimum.x, box.maximum.y, box.minimum.z);
138 out << PxVec3(box.minimum.x, box.maximum.y, box.maximum.z);
139 }
140 else
141 {
142 out << PxRenderOutput::TRIANGLESTRIP;
143 out << PxVec3(box.minimum.x, box.minimum.y, box.minimum.z); // 0
144 out << PxVec3(box.minimum.x, box.maximum.y, box.minimum.z); // 2
145 out << PxVec3(box.maximum.x, box.minimum.y, box.minimum.z); // 1
146 out << PxVec3(box.maximum.x, box.maximum.y, box.minimum.z); // 3
147 out << PxVec3(box.maximum.x, box.maximum.y, box.maximum.z); // 7
148 out << PxVec3(box.minimum.x, box.maximum.y, box.minimum.z); // 2
149 out << PxVec3(box.minimum.x, box.maximum.y, box.maximum.z); // 6
150 out << PxVec3(box.minimum.x, box.minimum.y, box.minimum.z); // 0
151 out << PxVec3(box.minimum.x, box.minimum.y, box.maximum.z); // 4
152 out << PxVec3(box.maximum.x, box.minimum.y, box.minimum.z); // 1
153 out << PxVec3(box.maximum.x, box.minimum.y, box.maximum.z); // 5
154 out << PxVec3(box.maximum.x, box.maximum.y, box.maximum.z); // 7
155 out << PxVec3(box.minimum.x, box.minimum.y, box.maximum.z); // 4
156 out << PxVec3(box.minimum.x, box.maximum.y, box.maximum.z); // 6
157 }
158 return out;
159 }
160
162 {
163 PxDebugArrow(const PxVec3& pos, const PxVec3& vec)
164 : base(pos), tip(pos + vec), headLength(vec.magnitude()*0.15f) {}
165
166 PxDebugArrow(const PxVec3& pos, const PxVec3& vec, PxReal headLength_)
167 : base(pos), tip(pos + vec), headLength(headLength_) {}
168
169 PxVec3 base, tip;
170 PxReal headLength;
171 };
172 PX_FORCE_INLINE void normalToTangents(const PxVec3& normal, PxVec3& tangent0, PxVec3& tangent1)
173 {
174 tangent0 = PxAbs(normal.x) < 0.70710678f ? PxVec3(0, -normal.z, normal.y) : PxVec3(-normal.y, normal.x, 0);
175 tangent0.normalize();
176 tangent1 = normal.cross(tangent0);
177 }
178 PX_FORCE_INLINE PxRenderOutput& operator<<(PxRenderOutput& out, const PxDebugArrow& arrow)
179 {
180 PxVec3 t0 = arrow.tip - arrow.base, t1, t2;
181
182 t0.normalize();
183 normalToTangents(t0, t1, t2);
184
185 const PxReal tipAngle = 0.25f;
186 t1 *= arrow.headLength * tipAngle;
187 t2 *= arrow.headLength * tipAngle * PxSqrt(3.0f);
188 PxVec3 headBase = arrow.tip - t0 * arrow.headLength;
189
190 out << PxRenderOutput::LINES;
191 out << arrow.base << arrow.tip;
192
193 out << PxRenderOutput::TRIANGLESTRIP;
194 out << arrow.tip;
195 out << headBase + t1 + t1;
196 out << headBase - t1 - t2;
197 out << headBase - t1 + t2;
198 out << arrow.tip;
199 out << headBase + t1 + t1;
200 return out;
201 }
202
204 {
205 PxDebugBasis(const PxVec3& ext, PxU32 cX = PxU32(PxDebugColor::eARGB_RED),
206 PxU32 cY = PxU32(PxDebugColor::eARGB_GREEN), PxU32 cZ = PxU32(PxDebugColor::eARGB_BLUE))
207 : extends(ext), colorX(cX), colorY(cY), colorZ(cZ) {}
208 PxVec3 extends;
209 PxU32 colorX, colorY, colorZ;
210 };
211 PX_FORCE_INLINE PxRenderOutput& operator<<(PxRenderOutput& out, const PxDebugBasis& basis)
212 {
213 const PxReal headLength = basis.extends.magnitude() * 0.15f;
214 out << basis.colorX << PxDebugArrow(PxVec3(0.0f), PxVec3(basis.extends.x, 0, 0), headLength);
215 out << basis.colorY << PxDebugArrow(PxVec3(0.0f), PxVec3(0, basis.extends.y, 0), headLength);
216 out << basis.colorZ << PxDebugArrow(PxVec3(0.0f), PxVec3(0, 0, basis.extends.z), headLength);
217 return out;
218 }
219
221 {
222 PxDebugCircle(PxU32 s, PxReal r)
223 : nSegments(s), radius(r) {}
224 PxU32 nSegments;
225 PxReal radius;
226 };
227 PX_FORCE_INLINE PxRenderOutput& operator<<(PxRenderOutput& out, const PxDebugCircle& circle)
228 {
229 const PxF32 step = PxTwoPi / circle.nSegments;
230 PxF32 angle = 0;
231 out << PxRenderOutput::LINESTRIP;
232 for (PxU32 i = 0; i < circle.nSegments; i++, angle += step)
233 out << PxVec3(circle.radius * PxSin(angle), circle.radius * PxCos(angle), 0);
234 out << PxVec3(0, circle.radius, 0);
235 return out;
236 }
237
239 {
240 PxDebugArc(PxU32 s, PxReal r, PxReal minAng, PxReal maxAng)
241 : nSegments(s), radius(r), minAngle(minAng), maxAngle(maxAng) {}
242 PxU32 nSegments;
243 PxReal radius;
244 PxReal minAngle, maxAngle;
245 };
246 PX_FORCE_INLINE PxRenderOutput& operator<<(PxRenderOutput& out, const PxDebugArc& arc)
247 {
248 const PxF32 step = (arc.maxAngle - arc.minAngle) / arc.nSegments;
249 PxF32 angle = arc.minAngle;
250 out << PxRenderOutput::LINESTRIP;
251 for (PxU32 i = 0; i < arc.nSegments; i++, angle += step)
252 out << PxVec3(arc.radius * PxSin(angle), arc.radius * PxCos(angle), 0);
253 out << PxVec3(arc.radius * PxSin(arc.maxAngle), arc.radius * PxCos(arc.maxAngle), 0);
254 return out;
255 }
256
257 PX_INLINE PxRenderOutput& PxRenderOutput::operator<<(Primitive prim)
258 {
259 mPrim = prim;
260 mVertexCount = 0;
261 return *this;
262 }
263
264 PX_INLINE PxRenderOutput& PxRenderOutput::operator<<(PxU32 color)
265 {
266 mColor = color;
267 return *this;
268 }
269
270 PX_INLINE PxRenderOutput& PxRenderOutput::operator<<(const PxMat44& transform)
271 {
272 mTransform = transform;
273 return *this;
274 }
275
276 PX_INLINE PxRenderOutput& PxRenderOutput::operator<<(const PxTransform& t)
277 {
278 mTransform = PxMat44(t);
279 return *this;
280 }
281
282 PX_INLINE PxRenderOutput& PxRenderOutput::operator<<(const PxVec3& vertexIn)
283 {
284 // apply transformation
285 const PxVec3 vertex = mTransform.transform(vertexIn);
286 ++mVertexCount;
287
288 // add primitive to render buffer
289 switch (mPrim)
290 {
291 case POINTS:
292 mBuffer.addPoint(PxDebugPoint(vertex, mColor)); break;
293 case LINES:
294 if (mVertexCount == 2)
295 {
296 mBuffer.addLine(PxDebugLine(mVertex0, vertex, mColor));
297 mVertexCount = 0;
298 }
299 break;
300 case LINESTRIP:
301 if (mVertexCount >= 2)
302 mBuffer.addLine(PxDebugLine(mVertex0, vertex, mColor));
303 break;
304 case TRIANGLES:
305 if (mVertexCount == 3)
306 {
307 mBuffer.addTriangle(PxDebugTriangle(mVertex1, mVertex0, vertex, mColor));
308 mVertexCount = 0;
309 }
310 break;
311 case TRIANGLESTRIP:
312 if (mVertexCount >= 3)
313 mBuffer.addTriangle(PxDebugTriangle(
314 (mVertexCount & 0x1) ? mVertex0 : mVertex1,
315 (mVertexCount & 0x1) ? mVertex1 : mVertex0, vertex, mColor));
316 break;
317 }
318
319 // cache the last 2 vertices (for strips)
320 if (1 < mVertexCount)
321 {
322 mVertex1 = mVertex0;
323 mVertex0 = vertex;
324 }
325 else
326 {
327 mVertex0 = vertex;
328 }
329 return *this;
330 }
331
332 PX_INLINE PxDebugLine* PxRenderOutput::reserveSegments(PxU32 nbSegments)
333 {
334 return mBuffer.reserveLines(nbSegments);
335 }
336
337 PX_INLINE PxDebugPoint* PxRenderOutput::reservePoints(PxU32 nbPoints)
338 {
339 return mBuffer.reservePoints(nbPoints);
340 }
341
342 // PT: using the operators is just too slow.
343 PX_INLINE void PxRenderOutput::outputSegment(const PxVec3& v0, const PxVec3& v1)
344 {
345 PxDebugLine* segment = mBuffer.reserveLines(1);
346 segment->pos0 = v0;
347 segment->pos1 = v1;
348 segment->color0 = segment->color1 = mColor;
349 }
350
351 PX_INLINE PxRenderOutput& PxRenderOutput::outputCapsule(PxF32 radius, PxF32 halfHeight, const PxMat44& absPose)
352 {
353 PxRenderOutput& out = *this;
354
355 const PxVec3 vleft2(-halfHeight, 0.0f, 0.0f);
356 PxMat44 left2 = absPose;
357 left2.column3 += PxVec4(left2.rotate(vleft2), 0.0f);
358 out << left2 << PxDebugArc(100, radius, PxPi, PxTwoPi);
359
360 PxMat44 rotPose = left2;
361 PxSwap(rotPose.column1, rotPose.column2);
362 rotPose.column1 = -rotPose.column1;
363 out << rotPose << PxDebugArc(100, radius, PxPi, PxTwoPi);
364
365 PxSwap(rotPose.column0, rotPose.column2);
366 rotPose.column0 = -rotPose.column0;
367 out << rotPose << PxDebugCircle(100, radius);
368
369 const PxVec3 vright2(halfHeight, 0.0f, 0.0f);
370 PxMat44 right2 = absPose;
371 right2.column3 += PxVec4(right2.rotate(vright2), 0.0f);
372 out << right2 << PxDebugArc(100, radius, 0.0f, PxPi);
373
374 rotPose = right2;
375 PxSwap(rotPose.column1, rotPose.column2);
376 rotPose.column1 = -rotPose.column1;
377 out << rotPose << PxDebugArc(100, radius, 0.0f, PxPi);
378
379 PxSwap(rotPose.column0, rotPose.column2);
380 rotPose.column0 = -rotPose.column0;
381 out << rotPose << PxDebugCircle(100, radius);
382
383 out << absPose;
384 out.outputSegment(absPose.transform(PxVec3(-halfHeight, radius, 0)),
385 absPose.transform(PxVec3(halfHeight, radius, 0)));
386 out.outputSegment(absPose.transform(PxVec3(-halfHeight, -radius, 0)),
387 absPose.transform(PxVec3(halfHeight, -radius, 0)));
388 out.outputSegment(absPose.transform(PxVec3(-halfHeight, 0, radius)),
389 absPose.transform(PxVec3(halfHeight, 0, radius)));
390 out.outputSegment(absPose.transform(PxVec3(-halfHeight, 0, -radius)),
391 absPose.transform(PxVec3(halfHeight, 0, -radius)));
392
393 return *this;
394 }
395
396#if PX_VC
397#pragma warning(pop)
398#endif
399
400#if !PX_DOXYGEN
401} // namespace physx
402#endif
403
404#endif
Class representing 3D range or axis aligned bounding box.
Definition PxBounds3.h:58
4x4 matrix class
Definition PxMat44.h:55
PX_CUDA_CALLABLE PX_INLINE const PxVec4 transform(const PxVec4 &other) const
Transform vector by matrix, equal to v' = M*v.
Definition PxMat44.h:279
Interface for points, lines, triangles, and text buffer.
Definition PxRenderBuffer.h:136
Definition PxRenderOutput.h:50
class representing a rigid euclidean transform as a quaternion and a vector
Definition PxTransform.h:49
PX_CUDA_CALLABLE PX_FORCE_INLINE Type normalize()
normalizes the vector in place
Definition PxVec3.h:297
3 Element vector class.
Definition PxVec3.h:50
PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 cross(const PxVec3 &v) const
cross product
Definition PxVec3.h:284
PX_CUDA_CALLABLE PX_FORCE_INLINE float normalize()
normalizes the vector in place
Definition PxVec3.h:300
PX_CUDA_CALLABLE PX_FORCE_INLINE float magnitude() const
returns the magnitude
Definition PxVec3.h:183
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
#define PX_INLINE
Definition PxPreprocessor.h:320
transform(pattern)
Definition docopt.py:72
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39
PX_CUDA_CALLABLE PX_FORCE_INLINE float PxCos(float a)
Cosine of an angle (Unit: Radians)
Definition PxMath.h:190
PX_CUDA_CALLABLE PX_FORCE_INLINE float PxAbs(float a)
abs returns the absolute value of its argument.
Definition PxMath.h:109
PX_CUDA_CALLABLE PX_FORCE_INLINE float PxSqrt(float a)
Square root.
Definition PxMath.h:146
PX_CUDA_CALLABLE PX_FORCE_INLINE float PxSin(float a)
trigonometry – all angles are in radians.
Definition PxMath.h:178
Definition PxRenderOutput.h:239
Definition PxRenderOutput.h:162
Definition PxRenderOutput.h:204
Definition PxRenderOutput.h:104
Definition PxRenderOutput.h:221
Used to store a single line and colour for debug rendering.
Definition PxRenderBuffer.h:85
Used to store a single point and colour for debug rendering.
Definition PxRenderBuffer.h:73