NvBlastGeometry.h
Go to the documentation of this file.
1 // This code contains NVIDIA Confidential Information and is disclosed to you
2 // under a form of NVIDIA software license agreement provided separately to you.
3 //
4 // Notice
5 // NVIDIA Corporation and its licensors retain all intellectual property and
6 // proprietary rights in and to this software and related documentation and
7 // any modifications thereto. Any use, reproduction, disclosure, or
8 // distribution of this software and related documentation without an express
9 // license agreement from NVIDIA Corporation is strictly prohibited.
10 //
11 // ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
12 // NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
13 // THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
14 // MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
15 //
16 // Information and code furnished is believed to be accurate and reliable.
17 // However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
18 // information or for any infringement of patents or other rights of third parties that may
19 // result from its use. No license is granted by implication or otherwise under any patent
20 // or patent rights of NVIDIA Corporation. Details are subject to change without notice.
21 // This code supersedes and replaces all information previously supplied.
22 // NVIDIA Corporation products are not authorized for use as critical
23 // components in life support devices or systems without express written approval of
24 // NVIDIA Corporation.
25 //
26 // Copyright (c) 2016-2020 NVIDIA Corporation. All rights reserved.
27 
28 
29 #ifndef NVBLASTGEOMETRY_H
30 #define NVBLASTGEOMETRY_H
31 
32 #include "NvBlastTypes.h"
33 #include "NvBlastMath.h"
34 #include "NvBlastAssert.h"
35 
36 #include <limits>
37 
38 
39 namespace Nv {
40 namespace Blast{
41 
42 
62 NV_FORCE_INLINE uint32_t findClosestNode(const float point[4],
63  const uint32_t firstGraphNodeIndex, const uint32_t* familyGraphNodeIndexLinks,
64  const uint32_t* adjacencyPartition, const uint32_t* adjacentNodeIndices, const uint32_t* adjacentBondIndices,
65  const NvBlastBond* assetBonds, const float* bondHealths,
66  const NvBlastChunk* assetChunks, const float* supportChunkHealths, const uint32_t* chunkIndices)
67 {
68  // firstGraphNodeIndex could still be the world chunk, however
69  // there should be no way a single-node actor that is just the world chunk exists.
70  uint32_t nodeIndex = firstGraphNodeIndex;
71  // Since there should always be a regular chunk in the graph, it is possible to initialize closestNode
72  // as world chunk index but it would always evaluate to some meaningful node index eventually.
73  uint32_t closestNode = nodeIndex;
74  float minDist = std::numeric_limits<float>().max();
75 
76  // find the closest healthy chunk in the graph by its centroid to point distance
77  while (!Nv::Blast::isInvalidIndex(nodeIndex))
78  {
79  if (supportChunkHealths[nodeIndex] > 0.0f)
80  {
81  uint32_t chunkIndex = chunkIndices[nodeIndex];
82  if (!isInvalidIndex(chunkIndex)) // Invalid if this is the world chunk
83  {
84  const NvBlastChunk& chunk = assetChunks[chunkIndex];
85  const float* centroid = chunk.centroid;
86 
87  float d[3]; VecMath::sub(point, centroid, d);
88  float dist = VecMath::dot(d, d);
89 
90  if (dist < minDist)
91  {
92  minDist = dist;
93  closestNode = nodeIndex;
94  }
95  }
96  }
97  nodeIndex = familyGraphNodeIndexLinks[nodeIndex];
98  }
99 
100  // as long as the world chunk is not input as a single-node graph actor
101  NVBLAST_ASSERT(!isInvalidIndex(chunkIndices[closestNode]));
102 
103  bool iterateOnBonds = true;
104  if (iterateOnBonds)
105  {
106  // improve geometric accuracy by looking on which side of the closest bond the point lies
107  // expects bond normals to point from the smaller to the larger node index
108 
109  nodeIndex = closestNode;
110  minDist = std::numeric_limits<float>().max();
111 
112  const uint32_t startIndex = adjacencyPartition[nodeIndex];
113  const uint32_t stopIndex = adjacencyPartition[nodeIndex + 1];
114 
115  for (uint32_t adjacentIndex = startIndex; adjacentIndex < stopIndex; adjacentIndex++)
116  {
117  const uint32_t neighbourIndex = adjacentNodeIndices[adjacentIndex];
118  const uint32_t neighbourChunk = chunkIndices[neighbourIndex];
119  if (!isInvalidIndex(neighbourChunk)) // Invalid if neighbor is the world chunk
120  {
121  const uint32_t bondIndex = adjacentBondIndices[adjacentIndex];
122  // do not follow broken bonds, since it means that neighbor is not actually connected in the graph
123  if (bondHealths[bondIndex] > 0.0f && supportChunkHealths[neighbourIndex] > 0.0f)
124  {
125  const NvBlastBond& bond = assetBonds[bondIndex];
126 
127  const float* centroid = bond.centroid;
128  float d[3]; VecMath::sub(point, centroid, d);
129  float dist = VecMath::dot(d, d);
130 
131  if (dist < minDist)
132  {
133  minDist = dist;
134  float s = VecMath::dot(d, bond.normal);
135  if (nodeIndex < neighbourIndex)
136  {
137  closestNode = s < 0.0f ? nodeIndex : neighbourIndex;
138  }
139  else
140  {
141  closestNode = s < 0.0f ? neighbourIndex : nodeIndex;
142  }
143  }
144  }
145  }
146  }
147  }
148 
149  return closestNode;
150 }
151 
152 
171 NV_FORCE_INLINE uint32_t findClosestNode(const float point[4],
172  const uint32_t firstGraphNodeIndex, const uint32_t* familyGraphNodeIndexLinks,
173  const uint32_t* adjacencyPartition, const uint32_t* adjacentNodeIndices, const uint32_t* adjacentBondIndices,
174  const NvBlastBond* bonds, const float* bondHealths, const uint32_t* chunkIndices)
175 {
176  // firstGraphNodeIndex could still be the world chunk, however
177  // there should be no way a single-node actor that is just the world chunk exists.
178  uint32_t nodeIndex = firstGraphNodeIndex;
179  // Since there should always be a regular chunk in the graph, it is possible to initialize closestNode
180  // as world chunk index but it would always evaluate to some meaningful node index eventually.
181  uint32_t closestNode = nodeIndex;
182  float minDist = std::numeric_limits<float>().max();
183 
184  while (!Nv::Blast::isInvalidIndex(nodeIndex))
185  {
186  const uint32_t startIndex = adjacencyPartition[nodeIndex];
187  const uint32_t stopIndex = adjacencyPartition[nodeIndex + 1];
188 
189  for (uint32_t adjacentIndex = startIndex; adjacentIndex < stopIndex; adjacentIndex++)
190  {
191  const uint32_t neighbourIndex = adjacentNodeIndices[adjacentIndex];
192  if (nodeIndex < neighbourIndex)
193  {
194  const uint32_t bondIndex = adjacentBondIndices[adjacentIndex];
195  if (bondHealths[bondIndex] > 0.0f)
196  {
197  const NvBlastBond& bond = bonds[bondIndex];
198 
199  const float* centroid = bond.centroid;
200  float d[3]; VecMath::sub(point, centroid, d);
201  float dist = VecMath::dot(d, d);
202 
203  if (dist < minDist)
204  {
205  minDist = dist;
206  // if any of the nodes is the world chunk, use the valid one instead
207  if (isInvalidIndex(chunkIndices[neighbourIndex]))
208  {
209  closestNode = nodeIndex;
210  }
211  else if (isInvalidIndex(chunkIndices[nodeIndex]))
212  {
213  closestNode = neighbourIndex;
214  }
215  else
216  {
217  float s = VecMath::dot(d, bond.normal);
218  closestNode = s < 0 ? nodeIndex : neighbourIndex;
219  }
220  }
221  }
222  }
223  }
224  nodeIndex = familyGraphNodeIndexLinks[nodeIndex];
225  }
226 
227  // as long as the world chunk is not input as a single-node graph actor
228  NVBLAST_ASSERT(!isInvalidIndex(chunkIndices[closestNode]));
229  return closestNode;
230 }
231 
232 
233 } // namespace Blast
234 } // namespace Nv
235 
236 
237 #endif // NVBLASTGEOMETRY_H
Definition: NvBlastTypes.h:189
NV_INLINE float dist(const float a[3], const float b[3])
Definition: NvBlastMath.h:86
float normal[3]
Definition: NvBlastTypes.h:194
float centroid[3]
Definition: NvBlastTypes.h:157
NV_INLINE bool isInvalidIndex(T index)
Definition: NvBlastIndexFns.h:57
NV_INLINE void sub(const float a[3], const float b[3], float r[3])
Definition: NvBlastMath.h:67
#define NVBLAST_ASSERT(exp)
Definition: NvBlastAssert.h:37
float centroid[3]
Definition: NvBlastTypes.h:204
NV_FORCE_INLINE uint32_t findClosestNode(const float point[4], const uint32_t firstGraphNodeIndex, const uint32_t *familyGraphNodeIndexLinks, const uint32_t *adjacencyPartition, const uint32_t *adjacentNodeIndices, const uint32_t *adjacentBondIndices, const NvBlastBond *assetBonds, const float *bondHealths, const NvBlastChunk *assetChunks, const float *supportChunkHealths, const uint32_t *chunkIndices)
Definition: NvBlastGeometry.h:62
Definition: NvBlastTypes.h:152
NV_INLINE float dot(const float a[3], const float b[3])
Definition: NvBlastMath.h:73
Definition: NvBlastArray.h:37
#define NV_FORCE_INLINE
Definition: NvPreprocessor.h:365