Newton Dynamics  4.00
ndShapeInstance.h
1 /* Copyright (c) <2003-2022> <Julio Jerez, Newton Game Dynamics>
2 *
3 * This software is provided 'as-is', without any express or implied
4 * warranty. In no event will the authors be held liable for any damages
5 * arising from the use of this software.
6 *
7 * Permission is granted to anyone to use this software for any purpose,
8 * including commercial applications, and to alter it and redistribute it
9 * freely, subject to the following restrictions:
10 *
11 * 1. The origin of this software must not be misrepresented; you must not
12 * claim that you wrote the original software. If you use this software
13 * in a product, an acknowledgment in the product documentation would be
14 * appreciated but is not required.
15 *
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 *
19 * 3. This notice may not be removed or altered from any source distribution.
20 */
21 
22 #ifndef __ND_SHAPE_INSTANCE_H__
23 #define __ND_SHAPE_INSTANCE_H__
24 
25 #define D_MAX_SHAPE_AABB_PADDING ndFloat32 (1.0f / 16.0f)
26 
27 #include "ndShape.h"
28 
29 class ndBody;
30 class ndScene;
31 class ndShapeInfo;
32 class ndContactPoint;
33 class ndShapeInstance;
34 class ndRayCastNotify;
35 
36 D_MSV_NEWTON_ALIGN_32
38 {
39  public:
40  enum ndEdgeType
41  {
42  m_shared,
43  m_open,
44  };
45 
47  :m_instance(nullptr)
48  {
49  }
50 
51  virtual ~ndShapeDebugNotify()
52  {
53  }
54 
55  virtual void DrawPolygon(ndInt32 vertexCount, const ndVector* const faceArray, const ndEdgeType* const edgeType) = 0;
56 
57  const ndShapeInstance* m_instance;
58 } D_GCC_NEWTON_ALIGN_32;
59 
60 D_MSV_NEWTON_ALIGN_32
61 class ndShapeInstance: public ndContainersFreeListAlloc<ndShapeInstance>
62 {
63  public:
65  {
66  public:
67  ndDistanceCalculator(ndScene* const scene)
68  {
69  m_scene = scene;
70  }
71 
72  ndDistanceCalculator(ndScene* const scene,
73  ndShapeInstance* const shape0, const ndMatrix& matrix0,
74  ndShapeInstance* const shape1, const ndMatrix& matrix1)
75  :m_matrix0(matrix0)
76  ,m_matrix1(matrix1)
77  ,m_point0(ndVector::m_wOne)
78  ,m_point1(ndVector::m_wOne)
79  ,m_normal(ndVector::m_zero)
80  ,m_scene(scene)
81  ,m_shape0(shape0)
82  ,m_shape1(shape1)
83  {
84  }
85 
86  D_COLLISION_API bool ClosestPoint();
87 
88  ndMatrix m_matrix0;
89  ndMatrix m_matrix1;
90  ndVector m_point0;
91  ndVector m_point1;
92  ndVector m_normal;
93  ndScene* m_scene;
94  ndShapeInstance* m_shape0;
95  ndShapeInstance* m_shape1;
96  };
97 
98  enum ndScaleType
99  {
100  m_unit,
101  m_uniform,
102  m_nonUniform,
103  m_global,
104  };
105 
106  D_COLLISION_API ndShapeInstance(ndShape* const shape);
107  D_COLLISION_API ndShapeInstance(const ndShapeInstance& instance);
108  D_COLLISION_API ndShapeInstance(const ndShapeInstance& instance, ndShape* const shape);
109  D_COLLISION_API ndShapeInstance(const nd::TiXmlNode* const xmlNode, const ndShapeLoaderCache& shapesMap);
110  D_COLLISION_API ~ndShapeInstance();
111 
112  D_COLLISION_API ndShapeInstance& operator=(const ndShapeInstance& src);
113 
114  D_COLLISION_API ndMatrix CalculateInertia() const;
115  D_COLLISION_API void CalculateObb(ndVector& origin, ndVector& size) const;
116  D_COLLISION_API void CalculateAabb(const ndMatrix& matrix, ndVector& minP, ndVector& maxP) const;
117  D_COLLISION_API void DebugShape(const ndMatrix& matrix, ndShapeDebugNotify& debugCallback) const;
118  D_COLLISION_API ndFloat32 RayCast(ndRayCastNotify& callback, const ndVector& localP0, const ndVector& localP1, const ndBody* const body, ndContactPoint& contactOut) const;
119 
120  //D_COLLISION_API ndInt32 ClosestPoint(const ndMatrix& matrix, const ndVector& point, ndVector& contactPoint) const;
121 
122  D_COLLISION_API ndShapeInfo GetShapeInfo() const;
123  D_COLLISION_API void Save(const ndLoadSaveBase::ndSaveDescriptor& desc) const;
124  D_COLLISION_API ndFloat32 CalculateBuoyancyCenterOfPresure(ndVector& com, const ndMatrix& matrix, const ndVector& fluidPlane) const;
125 
126  D_COLLISION_API static ndVector GetBoxPadding();
127 
128  D_COLLISION_API void SavePLY(const char* const fileName) const;
129 
130  ndShape* GetShape();
131  const ndShape* GetShape() const;
132  void SetShape(ndShape* const shape);
133  ndVector SupportVertex(const ndVector& dir) const;
134  ndMatrix GetScaledTransform(const ndMatrix& matrix) const;
135  ndVector SupportVertexSpecial(const ndVector& dir, ndInt32* const vertexIndex) const;
136  ndVector SupportVertexSpecialProjectPoint(const ndVector& point, const ndVector& dir) const;
137 
138  const ndMatrix& GetLocalMatrix() const;
139  void SetLocalMatrix(const ndMatrix& matrix);
140 
141  const ndMatrix& GetGlobalMatrix() const;
142  void SetGlobalMatrix(const ndMatrix& scale);
143 
144  bool GetCollisionMode() const;
145  void SetCollisionMode(bool mode);
146  ndInt32 GetConvexVertexCount() const;
147 
148  ndShapeMaterial GetMaterial() const;
149  void SetMaterial(const ndShapeMaterial& material);
150 
151  const ndVector& GetScale() const;
152  const ndVector& GetInvScale() const;
153  const ndMatrix& GetAlignmentMatrix() const;
154 
155  D_COLLISION_API void SetScale(const ndVector& scale);
156  D_COLLISION_API void SetGlobalScale(const ndVector& scale);
157  D_COLLISION_API void SetGlobalScale(const ndMatrix& scaleMatrix);
158  D_COLLISION_API ndInt32 CalculatePlaneIntersection(const ndVector& normal, const ndVector& point, ndVector* const contactsOut) const;
159 
160  ndFloat32 GetVolume() const;
161  ndFloat32 GetBoxMinRadius() const;
162  ndFloat32 GetBoxMaxRadius() const;
163 
164  ndScaleType GetScaleType() const;
165  ndFloat32 GetUmbraClipSize() const;
166  ndUnsigned64 GetUserDataID() const;
167 
168  ndMatrix m_globalMatrix;
169  ndMatrix m_localMatrix;
170  ndMatrix m_alignmentMatrix;
171  ndVector m_scale;
172  ndVector m_invScale;
173  ndVector m_maxScale;
174 
175  ndShapeMaterial m_shapeMaterial;
176  const ndShape* m_shape;
177  const ndBody* m_ownerBody;
178  const void* m_subCollisionHandle;
179  const ndShapeInstance* m_parent;
180  ndFloat32 m_skinMargin;
181  ndScaleType m_scaleType;
182  bool m_collisionMode;
183 
184  private:
185  static ndVector m_padding;
186 } D_GCC_NEWTON_ALIGN_32 ;
187 
188 inline ndShape* ndShapeInstance::GetShape()
189 {
190  return (ndShape*)m_shape;
191 }
192 
193 inline const ndShape* ndShapeInstance::GetShape() const
194 {
195  return m_shape;
196 }
197 
198 inline const ndMatrix& ndShapeInstance::GetAlignmentMatrix() const
199 {
200  return m_alignmentMatrix;
201 }
202 
203 inline const ndMatrix& ndShapeInstance::GetLocalMatrix() const
204 {
205  return m_localMatrix;
206 }
207 
208 inline void ndShapeInstance::SetLocalMatrix(const ndMatrix& matrix)
209 {
210  m_localMatrix = matrix;
211 }
212 
213 inline const ndMatrix& ndShapeInstance::GetGlobalMatrix() const
214 {
215  return m_globalMatrix;
216 }
217 
218 inline void ndShapeInstance::SetGlobalMatrix(const ndMatrix& matrix)
219 {
220  m_globalMatrix = matrix;
221 }
222 
223 inline ndMatrix ndShapeInstance::GetScaledTransform(const ndMatrix& matrix) const
224 {
225  ndMatrix scale(ndGetIdentityMatrix());
226  scale[0][0] = m_scale.m_x;
227  scale[1][1] = m_scale.m_y;
228  scale[2][2] = m_scale.m_z;
229  return m_alignmentMatrix * scale * m_localMatrix * matrix;
230 }
231 
232 inline ndInt32 ndShapeInstance::GetConvexVertexCount() const
233 {
234  return m_shape->GetConvexVertexCount();
235 }
236 
237 inline ndVector ndShapeInstance::SupportVertex(const ndVector& inDir) const
238 {
239  const ndVector dir(inDir & ndVector::m_triplexMask);
240  ndAssert(dir.m_w == ndFloat32(0.0f));
241  ndAssert(ndAbs(dir.DotProduct(dir).GetScalar() - ndFloat32(1.0f)) < ndFloat32(1.0e-2f));
242  switch (m_scaleType)
243  {
244  case m_unit:
245  {
246  return m_shape->SupportVertex(dir, nullptr);
247  }
248  case m_uniform:
249  {
250  return m_scale * m_shape->SupportVertex(dir, nullptr);
251  }
252  case m_nonUniform:
253  {
254  // support((p * S), n) = S * support (p, n * transp(S))
255  const ndVector dir1((m_scale * dir).Normalize());
256  return m_scale * m_shape->SupportVertex(dir1, nullptr);
257  }
258 
259  case m_global:
260  default:
261  {
262  const ndVector dir1(m_alignmentMatrix.UnrotateVector((m_scale * dir).Normalize()));
263  return m_scale * m_alignmentMatrix.TransformVector(m_shape->SupportVertex(dir1, nullptr));
264  }
265  }
266 }
267 
268 inline ndVector ndShapeInstance::SupportVertexSpecial(const ndVector& inDir, ndInt32* const vertexIndex) const
269 {
270  const ndVector dir(inDir & ndVector::m_triplexMask);
271  ndAssert(dir.m_w == ndFloat32(0.0f));
272  ndAssert(ndAbs(dir.DotProduct(dir).GetScalar() - ndFloat32(1.0f)) < ndFloat32(1.0e-2f));
273  switch (m_scaleType)
274  {
275  case m_unit:
276  {
277  return m_shape->SupportVertexSpecial(dir, m_skinMargin, vertexIndex);
278  }
279  case m_uniform:
280  {
281  return m_scale * m_shape->SupportVertexSpecial(dir, m_skinMargin, vertexIndex);
282  }
283 
284  case m_global:
285  case m_nonUniform:
286  default:
287  return SupportVertex(dir);
288  }
289 }
290 
291 inline ndVector ndShapeInstance::SupportVertexSpecialProjectPoint(const ndVector& point, const ndVector& inDir) const
292 {
293  const ndVector dir(inDir & ndVector::m_triplexMask);
294  ndAssert(dir.m_w == ndFloat32(0.0f));
295  ndAssert(ndAbs(dir.DotProduct(dir).GetScalar() - ndFloat32(1.0f)) < ndFloat32(1.0e-2f));
296  switch (m_scaleType)
297  {
298  case m_unit:
299  {
300  return m_shape->SupportVertexSpecialProjectPoint(point, dir);
301  }
302  case m_uniform:
303  {
304  return m_scale * m_shape->SupportVertexSpecialProjectPoint(point * m_invScale, dir);
305  }
306 
307  case m_global:
308  case m_nonUniform:
309  default:
310  return point;
311 
312 #if 0
313  case m_nonUniform:
314  {
315  // support((p * S), n) = S * support (p/S, n * transp(S))
316  dVector dir1((m_scale * dir).Normalize());
317  return m_scale * m_shape->SupportVertexSpecialProjectPoint(point * m_invScale, dir1);
318  }
319 
320  case m_global:
321  default:
322  {
323  dVector dir1(m_alignmentMatrix.UnrotateVector((m_scale * dir).Normalize()));
324  return m_scale * m_alignmentMatrix.TransformVector(m_shape->SupportVertexSpecialProjectPoint(m_alignmentMatrix.UntransformVector(point * m_invScale), dir1));
325  }
326 #endif
327  }
328 }
329 
330 inline bool ndShapeInstance::GetCollisionMode() const
331 {
332  return m_collisionMode;
333 }
334 
335 inline void ndShapeInstance::SetCollisionMode(bool mode)
336 {
337  m_collisionMode = mode;
338 }
339 
340 inline const ndVector& ndShapeInstance::GetScale() const
341 {
342  return m_scale;
343 }
344 
345 inline const ndVector& ndShapeInstance::GetInvScale() const
346 {
347  return m_invScale;
348 }
349 
350 inline ndFloat32 ndShapeInstance::GetBoxMinRadius() const
351 {
352  return m_shape->GetBoxMinRadius() * m_maxScale.m_x;
353 }
354 
355 inline ndFloat32 ndShapeInstance::GetBoxMaxRadius() const
356 {
357  return m_shape->GetBoxMaxRadius() * m_maxScale.m_x;
358 }
359 
360 inline ndFloat32 ndShapeInstance::GetVolume() const
361 {
362  return m_shape->GetVolume() * m_scale.m_x * m_scale.m_y * m_scale.m_z;
363 }
364 
365 inline ndShapeMaterial ndShapeInstance::GetMaterial() const
366 {
367  return m_shapeMaterial;
368 }
369 
370 inline void ndShapeInstance::SetMaterial(const ndShapeMaterial& material)
371 {
372  m_shapeMaterial = material;
373 }
374 
375 inline ndShapeInstance::ndScaleType ndShapeInstance::GetScaleType() const
376 {
377  return m_scaleType;
378 }
379 
380 inline ndFloat32 ndShapeInstance::GetUmbraClipSize() const
381 {
382  return m_shape->GetUmbraClipSize() * m_maxScale.m_x;
383 }
384 
385 inline ndUnsigned64 ndShapeInstance::GetUserDataID() const
386 {
387  return ndUnsigned64 (m_shapeMaterial.m_userId);
388 }
389 
390 inline void ndShapeInstance::SetShape(ndShape* const shape)
391 {
392  if (m_shape)
393  {
394  m_shape->Release();
395  }
396  m_shape = shape ? shape->AddRef() : shape;
397 }
398 #endif
399 
400 
ndClassAlloc
Base class for providing memory allocation for all other engine classes.
Definition: ndClassAlloc.h:30
ndShapeLoaderCache
Definition: ndSaveLoadSytem.h:40
nd::TiXmlNode
The parent class for everything in the Document Object Model.
Definition: tinyxml.h:437
ndScene
Definition: ndScene.h:59
ndBody
Definition: ndBody.h:43
ndShapeMaterial
Definition: ndShape.h:80
ndShapeInstance::ndDistanceCalculator
Definition: ndShapeInstance.h:65
ndShape
Definition: ndShape.h:209
ndRayCastNotify
Definition: ndRayCastNotify.h:31
ndContactPoint
Definition: ndContact.h:39
ndMatrix
Definition: ndMatrix.h:42
ndShapeDebugNotify
Definition: ndShapeInstance.h:38
ndShapeInfo
Definition: ndShape.h:182
ndContainersFreeListAlloc
Definition: ndContainersAlloc.h:60
ndShapeInstance
Definition: ndShapeInstance.h:62
ndLoadSaveBase::ndSaveDescriptor
Definition: ndSaveLoadSytem.h:93
ndVector
Definition: ndVectorArmNeon.h:41