Main Page Class List Class Members

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
NvBlastBond
Definition: NvBlastTypes.h:189
Nv::Blast::VecMath::dist
NV_INLINE float dist(const float a[3], const float b[3])
Definition: NvBlastMath.h:86
NvBlastTypes.h
NvBlastMath.h
NvBlastBond::normal
float normal[3]
Definition: NvBlastTypes.h:194
NvBlastChunk::centroid
float centroid[3]
Definition: NvBlastTypes.h:157
Nv::Blast::isInvalidIndex
NV_INLINE bool isInvalidIndex(T index)
Definition: NvBlastIndexFns.h:57
Nv::Blast::VecMath::sub
NV_INLINE void sub(const float a[3], const float b[3], float r[3])
Definition: NvBlastMath.h:67
NVBLAST_ASSERT
#define NVBLAST_ASSERT(exp)
Definition: NvBlastAssert.h:37
NvBlastBond::centroid
float centroid[3]
Definition: NvBlastTypes.h:204
Nv::Blast::findClosestNode
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
NvBlastChunk
Definition: NvBlastTypes.h:152
Nv::Blast::VecMath::dot
NV_INLINE float dot(const float a[3], const float b[3])
Definition: NvBlastMath.h:73
Nv
Definition: NvBlastArray.h:37
NvBlastAssert.h
NV_FORCE_INLINE
#define NV_FORCE_INLINE
Definition: NvPreprocessor.h:365