00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef NVBLASTGEOMETRY_H
00030 #define NVBLASTGEOMETRY_H
00031
00032 #include "NvBlastTypes.h"
00033 #include "NvBlastMath.h"
00034 #include "NvBlastAssert.h"
00035
00036 #include <limits>
00037
00038
00039 namespace Nv {
00040 namespace Blast{
00041
00042
00062 NV_FORCE_INLINE uint32_t findClosestNode(const float point[4],
00063 const uint32_t firstGraphNodeIndex, const uint32_t* familyGraphNodeIndexLinks,
00064 const uint32_t* adjacencyPartition, const uint32_t* adjacentNodeIndices, const uint32_t* adjacentBondIndices,
00065 const NvBlastBond* assetBonds, const float* bondHealths,
00066 const NvBlastChunk* assetChunks, const float* supportChunkHealths, const uint32_t* chunkIndices)
00067 {
00068
00069
00070 uint32_t nodeIndex = firstGraphNodeIndex;
00071
00072
00073 uint32_t closestNode = nodeIndex;
00074 float minDist = std::numeric_limits<float>().max();
00075
00076
00077 while (!Nv::Blast::isInvalidIndex(nodeIndex))
00078 {
00079 if (supportChunkHealths[nodeIndex] > 0.0f)
00080 {
00081 uint32_t chunkIndex = chunkIndices[nodeIndex];
00082 if (!isInvalidIndex(chunkIndex))
00083 {
00084 const NvBlastChunk& chunk = assetChunks[chunkIndex];
00085 const float* centroid = chunk.centroid;
00086
00087 float d[3]; VecMath::sub(point, centroid, d);
00088 float dist = VecMath::dot(d, d);
00089
00090 if (dist < minDist)
00091 {
00092 minDist = dist;
00093 closestNode = nodeIndex;
00094 }
00095 }
00096 }
00097 nodeIndex = familyGraphNodeIndexLinks[nodeIndex];
00098 }
00099
00100
00101 NVBLAST_ASSERT(!isInvalidIndex(chunkIndices[closestNode]));
00102
00103 bool iterateOnBonds = true;
00104 if (iterateOnBonds)
00105 {
00106
00107
00108
00109 nodeIndex = closestNode;
00110 minDist = std::numeric_limits<float>().max();
00111
00112 const uint32_t startIndex = adjacencyPartition[nodeIndex];
00113 const uint32_t stopIndex = adjacencyPartition[nodeIndex + 1];
00114
00115 for (uint32_t adjacentIndex = startIndex; adjacentIndex < stopIndex; adjacentIndex++)
00116 {
00117 const uint32_t neighbourIndex = adjacentNodeIndices[adjacentIndex];
00118 const uint32_t neighbourChunk = chunkIndices[neighbourIndex];
00119 if (!isInvalidIndex(neighbourChunk))
00120 {
00121 const uint32_t bondIndex = adjacentBondIndices[adjacentIndex];
00122
00123 if (bondHealths[bondIndex] > 0.0f && supportChunkHealths[neighbourIndex] > 0.0f)
00124 {
00125 const NvBlastBond& bond = assetBonds[bondIndex];
00126
00127 const float* centroid = bond.centroid;
00128 float d[3]; VecMath::sub(point, centroid, d);
00129 float dist = VecMath::dot(d, d);
00130
00131 if (dist < minDist)
00132 {
00133 minDist = dist;
00134 float s = VecMath::dot(d, bond.normal);
00135 if (nodeIndex < neighbourIndex)
00136 {
00137 closestNode = s < 0.0f ? nodeIndex : neighbourIndex;
00138 }
00139 else
00140 {
00141 closestNode = s < 0.0f ? neighbourIndex : nodeIndex;
00142 }
00143 }
00144 }
00145 }
00146 }
00147 }
00148
00149 return closestNode;
00150 }
00151
00152
00171 NV_FORCE_INLINE uint32_t findClosestNode(const float point[4],
00172 const uint32_t firstGraphNodeIndex, const uint32_t* familyGraphNodeIndexLinks,
00173 const uint32_t* adjacencyPartition, const uint32_t* adjacentNodeIndices, const uint32_t* adjacentBondIndices,
00174 const NvBlastBond* bonds, const float* bondHealths, const uint32_t* chunkIndices)
00175 {
00176
00177
00178 uint32_t nodeIndex = firstGraphNodeIndex;
00179
00180
00181 uint32_t closestNode = nodeIndex;
00182 float minDist = std::numeric_limits<float>().max();
00183
00184 while (!Nv::Blast::isInvalidIndex(nodeIndex))
00185 {
00186 const uint32_t startIndex = adjacencyPartition[nodeIndex];
00187 const uint32_t stopIndex = adjacencyPartition[nodeIndex + 1];
00188
00189 for (uint32_t adjacentIndex = startIndex; adjacentIndex < stopIndex; adjacentIndex++)
00190 {
00191 const uint32_t neighbourIndex = adjacentNodeIndices[adjacentIndex];
00192 if (nodeIndex < neighbourIndex)
00193 {
00194 const uint32_t bondIndex = adjacentBondIndices[adjacentIndex];
00195 if (bondHealths[bondIndex] > 0.0f)
00196 {
00197 const NvBlastBond& bond = bonds[bondIndex];
00198
00199 const float* centroid = bond.centroid;
00200 float d[3]; VecMath::sub(point, centroid, d);
00201 float dist = VecMath::dot(d, d);
00202
00203 if (dist < minDist)
00204 {
00205 minDist = dist;
00206
00207 if (isInvalidIndex(chunkIndices[neighbourIndex]))
00208 {
00209 closestNode = nodeIndex;
00210 }
00211 else if (isInvalidIndex(chunkIndices[nodeIndex]))
00212 {
00213 closestNode = neighbourIndex;
00214 }
00215 else
00216 {
00217 float s = VecMath::dot(d, bond.normal);
00218 closestNode = s < 0 ? nodeIndex : neighbourIndex;
00219 }
00220 }
00221 }
00222 }
00223 }
00224 nodeIndex = familyGraphNodeIndexLinks[nodeIndex];
00225 }
00226
00227
00228 NVBLAST_ASSERT(!isInvalidIndex(chunkIndices[closestNode]));
00229 return closestNode;
00230 }
00231
00232
00233 }
00234 }
00235
00236
00237 #endif // NVBLASTGEOMETRY_H