HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SIM_SweptCollisionUtility.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  */
7 
8 #ifndef __SIM_SweptCollisionUtility_h__
9 #define __SIM_SweptCollisionUtility_h__
10 
11 #include "SIM_API.h"
12 #include "SIM_SweptCollisionData.h"
13 #include <UT/UT_VectorTypes.h>
14 #include <GA/GA_PageHandle.h>
15 #include <GU/GU_DetailHandle.h>
16 #include <vector>
17 
18 class SIM_Engine;
19 class SIM_Object;
20 class SIM_Impacts;
21 class SIM_Geometry;
22 class SIM_GeometryCopy;
23 class SIM_Time;
24 class GU_Detail;
25 class GU_PrimPacked;
26 
27 //////////////////////////////////////////////////////////////////////////////
28 //
29 // Data structures for merging geometry from an array of SIM_Objects
30 //
31 //////////////////////////////////////////////////////////////////////////////
32 
33 inline bool SIMisValidIndex(const int i, const int n)
34 {
35  return (0 <= i) && (i < n);
36 }
37 
38 // Identifies a point:
39 // the object index it belongs to and the point-id for that geometry
41 {
43  myIndexObject(-1),
44  myPid(-1)
45  {
46  }
47 
48  // Index in std::vector of SIM_Object
50  // point-id relative to object
51  int myPid;
52 };
53 
54 // MergedPoints represents a set of points that belong to a sequence of objects
56 {
57 public:
58  // default construct: merge map for zero objects
60  myIdentities(),
61  myRanges()
62  {
63  }
64 
65  // Number of merged points (total for all objects)
66  inline int getNumPointsMerged() const
67  {
68  return myIdentities.size();
69  }
70 
71  // For a merged point, obtain the object index and object point index (pid)
72  void getObjectAndPid(int& index_object, int& pid, const int p) const
73  {
74  UT_ASSERT( (0 <= p) && (p < myIdentities.size()) );
75 
76  const SIM_MergedIdentityPoint& id(myIdentities[p]);
77  index_object = id.myIndexObject;
78  pid = id.myPid;
79  }
80 
81  // Return the number of objects for this merge map.
82  // Each object index for this merge map lies in the half-open range
83  // [0, getNumObjects() - 1)
84  inline int getNumObjects() const
85  {
86  return myRanges.size();
87  }
88 
89  // Number of points for a object, given the object index
90  inline int getNumPointsObject(const int index_object) const
91  {
92  if( !SIMisValidIndex(index_object, myRanges.size()) )
93  {
94  UT_ASSERT( !"not a valid object index!" );
95  return 0;
96  }
97 
98  const std::pair< int, int >& object_range(myRanges[index_object]);
99 
100  const int num_points_range(object_range.second - object_range.first);
101 
102  UT_ASSERT( num_points_range >= 0 );
103 
104  return num_points_range;
105  }
106 
107 private:
108  // Joint array of point identities for object sequence
109  std::vector<SIM_MergedIdentityPoint> myIdentities;
110  // Contiguous sub-range [begin, end) of indices into myIdentities
111  // for each geometry index
112  std::vector< std::pair< int, int > > myRanges;
113 
114  friend void SIM_API
116  SIM_MergeMap& merged_points,
117  const UT_Array<const GU_Detail *> &gdps
118  );
119 
120  friend class SIM_MergeMapObject;
121 
122  // Disallow
123  SIM_MergeMap(const SIM_MergeMap&);
124  SIM_MergeMap& operator=(const SIM_MergeMap&);
125 };
126 
127 // Get a map for a fixed object that maps local point indices (pids)
128 // to indices for the merged points.
129 // This map is valid only as long as the SIM_MergeMap object
130 // that it was created from exists unchanged.
132 {
133 public:
135  const SIM_MergeMap& merged_points,
136  const int index_object
137  ) :
138  myIdentities(merged_points.myIdentities),
139  myBegin(merged_points.myRanges[index_object].first),
140  myEnd(merged_points.myRanges[index_object].second)
141  {
142  UT_ASSERT( 0 <= index_object );
143  UT_ASSERT( SIMisValidIndex(index_object, merged_points.myRanges.size()) );
144  }
145 
146  // Get merged point index from object point index (pid)
147  // Return -1 if the pid isn't merged.
148  inline int getP(const int pid) const
149  {
150  UT_ASSERT( (0 <= pid) && (pid < myEnd - myBegin) );
151 
152  return myBegin + pid;
153  }
154 
155  inline int getNumPointsObject() const
156  {
157  return myEnd - myBegin;
158  }
159 
160  inline int getNumPointsMerged() const
161  {
162  return myEnd - myBegin;
163  }
164 
165 private:
166  const std::vector<SIM_MergedIdentityPoint>& myIdentities;
167  const int myBegin;
168  const int myEnd;
169 
170  // Disallow
172  SIM_MergeMapObject operator=(const SIM_MergeMapObject&);
173 };
174 
175 /// Unpacks any packed primitives in the given SIM_Geometry and stores the
176 /// original primitive index of each primitive (e.g. for correctly recording
177 /// impacts).
179 {
180 public:
182  SIM_UnpackedGeometry(const GU_Detail &gdp);
183  SIM_UnpackedGeometry(const SIM_Geometry &simgeo);
184 
185  /// Returns the unpacked geometry.
187  {
188  return myGeo;
189  }
190 
191  /// Returns the primitive index in the source geometry that the given
192  /// primitive in the unpacked geometry corresponds to.
194  {
195  return myOriginalPrims(i);
196  }
197 
198 private:
199  void setGeometry(const GU_ConstDetailHandle &gdh);
200 
201  GU_ConstDetailHandle myGeo;
202  GA_IndexArray myOriginalPrims;
203 };
204 
205 //////////////////////////////////////////////////////////////////////////////
206 //
207 // Extract merged position, velocity, mass and thickness from
208 // an array of SIM_Objects
209 //
210 //////////////////////////////////////////////////////////////////////////////
211 
212 // Construct merged array of points for an array of geometries.
213 void SIM_API
215  SIM_MergeMap& merged_points,
216  const UT_Array<const GU_Detail *> &gdps
217 );
218 
219 /// Extract the triangle connectivity for a single object.
220 void SIM_API
222  SIM_TriangleConnectivity &triangles,
223  const SIM_MergeMapObject &merged_points,
224  const SIM_UnpackedGeometry &unpacked_geometry,
225  const char *geopath
226 );
227 
228 // Extract the geometry and the corresponding transform from an object.
229 // The resulting (transform, geometry) pairs can be used with
230 // SIMextractPositionPoints and SIMextractPositionTriangles
231 extern bool SIM_API
233  const SIM_Geometry*& geometry,
234  UT_DMatrix4& geometry_to_sim,
235  const SIM_Object& object
236 );
237 
238 // Extract the geometry and the corresponding transform
239 // that correspond to time t. Return false if this information
240 // couldn't be extracted from updated_object.
241 // This assumes that substep objects are set up correctly.
242 // (This is not the case for particle fluid objects, which
243 // store the substep positions in the final end state object).
244 // The resulting (transform, geometry) pairs can be used with
245 // SIMextractPositionPoints and SIMextractPositionTriangles
246 extern bool SIM_API
248  const SIM_Geometry*& geometry,
249  UT_DMatrix4& geometry_to_sim,
250  const SIM_Engine& engine,
251  const SIM_Object& undated_object,
252  const SIM_Time& t
253 );
254 
255 // Extract merged point thickness array for a set of point-set objects
256 // (e.g., particle objects). The thickness is taken from the "pscale"
257 // attribute, if this attribute is present. If there is no "pscale" attribute,
258 // then default_thickness is used.
259 extern void SIM_API
261  std::vector<fpreal32>& thickness_points,
262  const SIM_MergeMap& merged_points,
263  const UT_Array<const GU_Detail *> &gdps_end,
264  const fpreal default_thickness
265 );
266 
267 // Read the bounce parameter for an object
268 extern fpreal SIM_API
270  const SIM_Object& object,
271  const fpreal default_bounce
272 );
273 
274 // Read the friction parameter for an object
275 extern fpreal SIM_API
277  const SIM_Object& object,
278  const fpreal default_friction
279 );
280 
281 // Read the bounceforward parameter for an object
282 extern fpreal SIM_API
284  const SIM_Object& object,
285  const fpreal default_bounceforward
286 );
287 
288 //////////////////////////////////////////////////////////////////////////////
289 //
290 // Extract merged swept-collision state from an array of SIM_Objects
291 //
292 //////////////////////////////////////////////////////////////////////////////
293 
294 class SIM_Position;
295 class SIM_Object;
296 class SIM_Engine;
297 
298 //
299 // SIMreadSweptState reads from a set of objects all the topological and
300 // spatial data that is needed to perform swept-collision detection for
301 // all these objects.
302 // The data returned by this functions matches the geometry's end topology
303 // (the topology associated with t_end).
304 // (points and primitives may be added/deleted between t_begin and t_end).
305 // The "id" point-attribute will be used to carry over position data between
306 // the possibly different start and end topologies.
307 //
308 // This function will work correctly *only* if the substep objects have been
309 // set up correctly:
310 // It assumes that
311 // engine.getObjectAtTime(object, t_start) and
312 // engine.getObjectAtTime(object, t_end)
313 // return the correct states for the substep times t_start and t_end,
314 // respectively.
315 // (This assumption is broken by the particle fluid solver, which
316 // stores the substep state in the end state for optimization purposes.
317 // Therefore, the particle fluid solver does not use this function;
318 // it has a special code path to get the right information.)
319 //
320 // The topological and spatial data that is returned by SIMreadSweptState
321 // can be used as inputs for the function SIMdetectAndResolveCollisions,
322 // which detects and resolves collisions between two merged sets
323 // of geometry.
324 // The "pscale" attribute is used to initialize the thickness for each point.
325 // If this attribute is absent, then default_thickness is used
326 //
327 extern void SIM_API
329  SIM_MergeMap& merged_points,
330  std::vector<SIM_UnpackedGeometry> &unpacked_geometries_end,
331  std::vector<int>& id_objects,
332  std::vector<fpreal32> *thickness_points,
333  std::vector<fpreal32> *bounce_points,
334  std::vector<fpreal32> *friction_points,
335  std::vector<fpreal32> *bounceforward_points,
336  SIM_PositionPoints& position_points_start,
337  SIM_PositionPoints& position_points_end,
338  SIM_VelocityPoints *velocity_points_end,
339  const SIM_Engine& engine,
340  const std::vector<const SIM_Object*>& objects,
341  const fpreal default_thickness,
342  const fpreal64 t_start,
343  const fpreal64 t_end
344 );
345 
346 // This version reads from geometry.
347 extern void SIM_API
349  SIM_MergeMap& merged_points,
350  SIM_UnpackedGeometry &unpacked_geo_end,
351  std::vector<fpreal32> *thickness_points,
352  SIM_PositionPoints& position_points_start,
353  SIM_PositionPoints& position_points_end,
354  SIM_VelocityPoints *velocity_points_end,
355  const GU_Detail *gdp_start,
356  const UT_DMatrix4 &geoxform_start,
357  const GU_Detail *gdp_end,
358  const UT_DMatrix4 &geoxform_end,
359  const fpreal default_thickness,
360  const fpreal64 t_start,
361  const fpreal64 t_end
362 );
363 
364 // This version reads from a live object. It uses the previous
365 // position attribute to get the start positions rather than
366 // relying on the cache.
367 // You should provide arange. The page handles will be set up
368 // for you.
369 template <typename FLOAT>
370 extern bool SIM_API
372  const SIM_Object *object,
373  GU_Detail *gdp,
374  GA_Range &arange,
375  typename GA_PageHandleScalar<FLOAT>::ROType *thickness_points,
376  typename GA_PageHandleScalar<FLOAT>::ROType *bounce_points,
377  typename GA_PageHandleScalar<FLOAT>::ROType *friction_points,
378  typename GA_PageHandleScalar<FLOAT>::ROType *dynamicfriction_points,
379  typename GA_PageHandleScalar<FLOAT>::ROType *bounceforward_points,
380  typename GA_PageHandleScalar<FLOAT>::ROType *mass_points,
381  typename GA_PageHandleV<UT_Vector3T<FLOAT>>::RWType &position_points_start,
382  typename GA_PageHandleV<UT_Vector3T<FLOAT>>::RWType &position_points_end,
383  typename GA_PageHandleV<UT_Vector3T<FLOAT>>::RWType *velocity_points_end,
384  fpreal default_thickness);
385 
386 /// Extract the triangle connectivity for a set of objects.
387 extern void SIM_API
389  SIM_TriangleConnectivity& triangles,
390  const SIM_MergeMap& merged_points,
391  const std::vector<SIM_UnpackedGeometry>& unpacked_geometries,
392  const std::vector<const SIM_Object*>& objects
393 );
394 
395 //////////////////////////////////////////////////////////////////////////////
396 //
397 // Read/Write merged position and merged velocity for an array
398 // of SIM_Objects
399 //
400 //////////////////////////////////////////////////////////////////////////////
401 
402 // Read the merged position sequence for a set of points
403 // that belong to geometries.
404 extern void SIM_API
406  SIM_PositionPoints& position_points,
407  const SIM_MergeMap& merged_points,
408  const std::vector<UT_DMatrix4>& transforms,
409  const UT_Array<const GU_Detail *> &gdps
410 );
411 
412 // Read the merged velocity sequence
413 // for a set of points that belong to geometries.
414 // Use the velocity attribute for this
415 extern void SIM_API
417  SIM_VelocityPoints& velocity_points,
418  const SIM_MergeMap& merged_points,
419  const std::vector<UT_DMatrix4>& transforms,
420  const UT_Array<const GU_Detail*> &gdps
421 );
422 
423 // Set the position and velocity for all points in an array of geometries.
424 // position_points is written to the point positions
425 // velocity_points is written to the velocity attribute "v"
426 // it is assumed that for geometry[i], the map from object space to
427 // world simulation space is given by transforms[i].
428 // The a merged positions and velocities are transformed into
429 // the geometry's object space when they're applied to a point.
430 extern void SIM_API
432  const std::vector<SIM_GeometryCopy*>& geometries,
433  const SIM_MergeMap& merged_points,
434  const SIM_PositionPoints& position_points,
435  const SIM_VelocityPoints& velocity_points,
436  const std::vector<UT_DMatrix4>& transforms
437 );
438 
439 // Read the previous positions for all objects from the previous-position
440 // attribute. The attribute stores the position in world coordinates
441 // (no transform). Elements in r_points for points that don't have
442 // the attribute will retain the values from before the call.
443 extern void SIM_API
445  SIM_PositionPoints& position_points,
446  const SIM_MergeMap& merge_map,
447  const std::vector<const SIM_Geometry*>& geometries_end
448 );
449 
450 // Store the previous positions for all objects to the previous-position
451 // attribute. The attribute stores the position in world coordinates
452 // (no transform). Elements in r_points for points that don't have
453 // the attribute will not have their values written.
454 extern void SIM_API
456  std::vector<SIM_GeometryCopy*>& geometries_end,
457  const SIM_MergeMap& merge_map,
458  const SIM_PositionPoints& position_points
459 );
460 
461 // Copy the given position attribute into the previous position
462 // attribute wherever the exist flag is false. Then set the exist
463 // flag to true everywhere.
464 // pos_ph should be initialized to your position attribute.
465 // prevpos_ph will be created to point to the previous position.
466 template <typename FLOAT>
467 extern void SIM_API
469  GU_Detail *gdp,
470  typename GA_PageHandleV<UT_Vector3T<FLOAT>>::RWType &prevppos_ph,
471  typename GA_PageHandleV<UT_Vector3T<FLOAT>>::RWType &pos_ph
472 );
473 
474 // Copies the given position attribute blindly into the
475 // previous position attribute.
476 template <typename FLOAT>
477 extern void SIM_API
479  GU_Detail *gdp,
480  typename GA_PageHandleV<UT_Vector3T<FLOAT>>::RWType &prevppos_ph,
481  typename GA_PageHandleV<UT_Vector3T<FLOAT>>::RWType &pos_ph
482 );
483 
484 //////////////////////////////////////////////////////////////////////////////
485 //
486 // Detect collisions, resolve collisions, and generate impacts for
487 // an array of SIM_Objects.
488 //
489 //////////////////////////////////////////////////////////////////////////////
490 
491 // This function detects collisions and generates impacts for
492 // a pair of objects (a, b).
493 // that aim to resolve the collisions.
494 extern bool SIM_API
496  SIM_Impacts* impacts_a,
497  SIM_Impacts* impacts_b,
498  const SIM_Engine& engine,
499  SIM_Object*const undated_object_a,
500  const SIM_Object*const undated_object_b,
501  const SIM_Time& t_start,
502  const SIM_Time& t_end,
503  const int impact_flags,
504  const bool pscaleisradius
505 );
506 
507 #endif
fpreal SIM_API SIMreadBounceForwardParameterObject(const SIM_Object &object, const fpreal default_bounceforward)
GLint first
Definition: glcorearb.h:405
int getNumPointsObject(const int index_object) const
void SIM_API SIMextractTriangleConnectivityMerged(SIM_TriangleConnectivity &triangles, const SIM_MergeMapObject &merged_points, const SIM_UnpackedGeometry &unpacked_geometry, const char *geopath)
Extract the triangle connectivity for a single object.
int getNumPointsMerged() const
void getObjectAndPid(int &index_object, int &pid, const int p) const
bool SIMisValidIndex(const int i, const int n)
void SIM_API SIMreadPositionPoints(SIM_PositionPoints &position_points, const SIM_MergeMap &merged_points, const std::vector< UT_DMatrix4 > &transforms, const UT_Array< const GU_Detail * > &gdps)
void SIM_API SIMreadSweptState(SIM_MergeMap &merged_points, std::vector< SIM_UnpackedGeometry > &unpacked_geometries_end, std::vector< int > &id_objects, std::vector< fpreal32 > *thickness_points, std::vector< fpreal32 > *bounce_points, std::vector< fpreal32 > *friction_points, std::vector< fpreal32 > *bounceforward_points, SIM_PositionPoints &position_points_start, SIM_PositionPoints &position_points_end, SIM_VelocityPoints *velocity_points_end, const SIM_Engine &engine, const std::vector< const SIM_Object * > &objects, const fpreal default_thickness, const fpreal64 t_start, const fpreal64 t_end)
fpreal SIM_API SIMreadBounceParameterObject(const SIM_Object &object, const fpreal default_bounce)
void SIM_API SIMreadPreviousPositionAttribute(SIM_PositionPoints &position_points, const SIM_MergeMap &merge_map, const std::vector< const SIM_Geometry * > &geometries_end)
3D Vector class.
A range of elements in an index-map.
Definition: GA_Range.h:42
double fpreal64
Definition: SYS_Types.h:201
GLdouble n
Definition: glcorearb.h:2008
void SIM_API SIMwritePreviousPositionAttribute(std::vector< SIM_GeometryCopy * > &geometries_end, const SIM_MergeMap &merge_map, const SIM_PositionPoints &position_points)
void SIM_API SIMreadThicknessPoints(std::vector< fpreal32 > &thickness_points, const SIM_MergeMap &merged_points, const UT_Array< const GU_Detail * > &gdps_end, const fpreal default_thickness)
bool SIM_API SIMgetGeometryAndTransformAtTime(const SIM_Geometry *&geometry, UT_DMatrix4 &geometry_to_sim, const SIM_Engine &engine, const SIM_Object &undated_object, const SIM_Time &t)
void SIM_API SIMwritePositionAndVelocityPoints(const std::vector< SIM_GeometryCopy * > &geometries, const SIM_MergeMap &merged_points, const SIM_PositionPoints &position_points, const SIM_VelocityPoints &velocity_points, const std::vector< UT_DMatrix4 > &transforms)
int getNumObjects() const
GU_ConstDetailHandle getGeometry() const
Returns the unpacked geometry.
SIM_MergeMapObject(const SIM_MergeMap &merged_points, const int index_object)
GLuint id
Definition: glcorearb.h:655
void SIM_API SIMmergePoints(SIM_MergeMap &merged_points, const UT_Array< const GU_Detail * > &gdps)
GA_Size GA_Index
Define the strictness of GA_Offset/GA_Index.
Definition: GA_Types.h:635
void SIM_API SIMcopyAttribute(GU_Detail *gdp, typename GA_PageHandleV< UT_Vector3T< FLOAT >>::RWType &prevppos_ph, typename GA_PageHandleV< UT_Vector3T< FLOAT >>::RWType &pos_ph)
GLdouble t
Definition: glad.h:2397
int getP(const int pid) const
bool SIM_API SIMdetectCollisionsAndGenerateImpulses(SIM_Impacts *impacts_a, SIM_Impacts *impacts_b, const SIM_Engine &engine, SIM_Object *const undated_object_a, const SIM_Object *const undated_object_b, const SIM_Time &t_start, const SIM_Time &t_end, const int impact_flags, const bool pscaleisradius)
fpreal64 fpreal
Definition: SYS_Types.h:277
void SIM_API SIMcreatePreviousPositionAttribute(GU_Detail *gdp, typename GA_PageHandleV< UT_Vector3T< FLOAT >>::RWType &prevppos_ph, typename GA_PageHandleV< UT_Vector3T< FLOAT >>::RWType &pos_ph)
#define SIM_API
Definition: SIM_API.h:12
std::vector< SIM_PositionPoint > SIM_PositionPoints
void SIM_API SIMreadVelocityPointsFromAttribute(SIM_VelocityPoints &velocity_points, const SIM_MergeMap &merged_points, const std::vector< UT_DMatrix4 > &transforms, const UT_Array< const GU_Detail * > &gdps)
bool SIM_API SIMgetGeometryAndTransform(const SIM_Geometry *&geometry, UT_DMatrix4 &geometry_to_sim, const SIM_Object &object)
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
std::vector< SIM_VelocityPoint > SIM_VelocityPoints
GA_Index getOriginalPrimIndex(GA_Index i) const
fpreal SIM_API SIMreadFrictionParameterObject(const SIM_Object &object, const fpreal default_friction)
This implements a SIM_Geometry that copies the source geometry.