Main Page   Class List   Class Members  

  • Main Page
  • User's Guide
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

sdk/extensions/authoringCommon/source/NvBlastExtAuthoringInternalCommon.h

Go to the documentation of this file.
00001 // This code contains NVIDIA Confidential Information and is disclosed to you
00002 // under a form of NVIDIA software license agreement provided separately to you.
00003 //
00004 // Notice
00005 // NVIDIA Corporation and its licensors retain all intellectual property and
00006 // proprietary rights in and to this software and related documentation and
00007 // any modifications thereto. Any use, reproduction, disclosure, or
00008 // distribution of this software and related documentation without an express
00009 // license agreement from NVIDIA Corporation is strictly prohibited.
00010 //
00011 // ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
00012 // NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
00013 // THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
00014 // MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
00015 //
00016 // Information and code furnished is believed to be accurate and reliable.
00017 // However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
00018 // information or for any infringement of patents or other rights of third parties that may
00019 // result from its use. No license is granted by implication or otherwise under any patent
00020 // or patent rights of NVIDIA Corporation. Details are subject to change without notice.
00021 // This code supersedes and replaces all information previously supplied.
00022 // NVIDIA Corporation products are not authorized for use as critical
00023 // components in life support devices or systems without express written approval of
00024 // NVIDIA Corporation.
00025 //
00026 // Copyright (c) 2020 NVIDIA Corporation. All rights reserved.
00027 
00028 
00029 #ifndef NVBLASTINTERNALCOMMON_H
00030 #define NVBLASTINTERNALCOMMON_H
00031 #include "NvBlastExtAuthoringTypes.h"
00032 #include "NvBlastPxSharedHelpers.h"
00033 #include <PxVec2.h>
00034 #include <PxVec3.h>
00035 #include <PxPlane.h>
00036 #include <PxBounds3.h>
00037 #include <PxMath.h>
00038 #include <algorithm>
00039 
00040 namespace Nv
00041 {
00042 namespace Blast
00043 {
00044 
00048 struct EdgeWithParent
00049 {
00050     uint32_t s, e; // Starting and ending vertices
00051     uint32_t parent; // Parent facet index
00052     EdgeWithParent() : s(0), e(0), parent(0) {}
00053     EdgeWithParent(uint32_t s, uint32_t e, uint32_t p) : s(s), e(e), parent(p) {}
00054 };
00055 
00056 
00060 struct EdgeComparator
00061 {
00062     bool operator()(const EdgeWithParent& a, const EdgeWithParent& b) const
00063     {
00064         if (a.parent == b.parent)
00065         {
00066             if (a.s == b.s)
00067             {
00068                 return a.e < b.e;
00069             }
00070             else
00071             {
00072                 return a.s < b.s;
00073             }
00074         }
00075         else
00076         {
00077             return a.parent < b.parent;
00078         }
00079     }
00080 };
00081 
00082 inline bool operator<(const Edge& a, const Edge& b)
00083 {
00084     if (a.s == b.s)
00085         return a.e < b.e;
00086     else
00087         return a.s < b.s;
00088 }
00089 
00093 enum ProjectionDirections
00094 {
00095     YZ_PLANE = 1 << 1,
00096     XY_PLANE = 1 << 2,
00097     ZX_PLANE = 1 << 3,
00098 
00099     OPPOSITE_WINDING = 1 << 4
00100 };
00101 
00105 NV_FORCE_INLINE ProjectionDirections getProjectionDirection(const physx::PxVec3& normal)
00106 {
00107     float maxv = std::max(std::abs(normal.x), std::max(std::abs(normal.y), std::abs(normal.z)));
00108     ProjectionDirections retVal;
00109     if (maxv == std::abs(normal.x))
00110     {
00111         retVal = YZ_PLANE;
00112         if (normal.x < 0) retVal = (ProjectionDirections)((int)retVal | (int)OPPOSITE_WINDING);
00113         return retVal;
00114     }
00115     if (maxv == std::abs(normal.y))
00116     {
00117         retVal = ZX_PLANE;
00118         if (normal.y > 0) retVal = (ProjectionDirections)((int)retVal | (int)OPPOSITE_WINDING);
00119         return retVal;
00120     }
00121     retVal = XY_PLANE;
00122     if (normal.z < 0) retVal = (ProjectionDirections)((int)retVal | (int)OPPOSITE_WINDING);
00123     return retVal;
00124 }
00125 
00126 
00130 NV_FORCE_INLINE physx::PxVec2 getProjectedPoint(const physx::PxVec3& point, ProjectionDirections dir)
00131 {
00132     if (dir & YZ_PLANE)
00133     {
00134         return physx::PxVec2(point.y, point.z);
00135     }
00136     if (dir & ZX_PLANE)
00137     {
00138         return physx::PxVec2(point.x, point.z);
00139     }
00140     return physx::PxVec2(point.x, point.y);
00141 }
00142 
00143 NV_FORCE_INLINE physx::PxVec2 getProjectedPoint(const NvcVec3& point, ProjectionDirections dir)
00144 {
00145     return getProjectedPoint((const physx::PxVec3&)point, dir);
00146 }
00147 
00151 NV_FORCE_INLINE physx::PxVec2 getProjectedPointWithWinding(const physx::PxVec3& point, ProjectionDirections dir)
00152 {
00153     if (dir & YZ_PLANE)
00154     {
00155         if (dir & OPPOSITE_WINDING)
00156         {
00157             return physx::PxVec2(point.z, point.y);
00158         }
00159         else
00160         return physx::PxVec2(point.y, point.z);
00161     }
00162     if (dir & ZX_PLANE)
00163     {
00164         if (dir & OPPOSITE_WINDING)
00165         {
00166             return physx::PxVec2(point.z, point.x);
00167         }
00168         return physx::PxVec2(point.x, point.z);
00169     }
00170     if (dir & OPPOSITE_WINDING)
00171     {
00172         return physx::PxVec2(point.y, point.x);
00173     }
00174     return physx::PxVec2(point.x, point.y);
00175 }
00176 
00177 
00178 
00179 #define MAXIMUM_EXTENT 1000 * 1000 * 1000
00180 #define BBOX_TEST_EPS 1e-5f 
00181 
00185 NV_INLINE bool  weakBoundingBoxIntersection(const physx::PxBounds3& aBox, const physx::PxBounds3& bBox)
00186 {
00187     if (std::max(aBox.minimum.x, bBox.minimum.x) > std::min(aBox.maximum.x, bBox.maximum.x) + BBOX_TEST_EPS)
00188         return false;
00189     if (std::max(aBox.minimum.y, bBox.minimum.y) > std::min(aBox.maximum.y, bBox.maximum.y) + BBOX_TEST_EPS)
00190         return false;
00191     if (std::max(aBox.minimum.z, bBox.minimum.z) > std::min(aBox.maximum.z, bBox.maximum.z) + BBOX_TEST_EPS)
00192         return false;
00193     return true;
00194 }
00195 
00196 
00197 
00201 NV_INLINE bool getPlaneSegmentIntersection(const physx::PxPlane& pl, const physx::PxVec3& a, const physx::PxVec3& b,
00202                                            physx::PxVec3& result)
00203 {
00204     float div = (b - a).dot(pl.n);
00205     if (physx::PxAbs(div) < 0.0001f)
00206     {
00207         if (pl.contains(a))
00208         {
00209             result = a;
00210             return true;
00211         }
00212         else
00213         {
00214             return false;
00215         }
00216     }
00217     float t = (-a.dot(pl.n) - pl.d) / div;
00218     if (t < 0.0f || t > 1.0f)
00219     {
00220         return false;
00221     }
00222     result = (b - a) * t + a;
00223     return true;
00224 }
00225 
00226 
00227 #define POS_COMPARISON_OFFSET 1e-5f
00228 #define NORM_COMPARISON_OFFSET 1e-3f
00229 
00232 struct VrtComp
00233 {
00234     bool operator()(const Vertex& a, const Vertex& b) const
00235     {
00236         if (a.p.x + POS_COMPARISON_OFFSET < b.p.x) return true;
00237         if (a.p.x - POS_COMPARISON_OFFSET > b.p.x) return false;
00238         if (a.p.y + POS_COMPARISON_OFFSET < b.p.y) return true;
00239         if (a.p.y - POS_COMPARISON_OFFSET > b.p.y) return false;
00240         if (a.p.z + POS_COMPARISON_OFFSET < b.p.z) return true;
00241         if (a.p.z - POS_COMPARISON_OFFSET > b.p.z) return false;
00242 
00243         if (a.n.x + NORM_COMPARISON_OFFSET < b.n.x) return true;
00244         if (a.n.x - NORM_COMPARISON_OFFSET > b.n.x) return false;
00245         if (a.n.y + NORM_COMPARISON_OFFSET < b.n.y) return true;
00246         if (a.n.y - NORM_COMPARISON_OFFSET > b.n.y) return false;
00247         if (a.n.z + NORM_COMPARISON_OFFSET < b.n.z) return true;
00248         if (a.n.z - NORM_COMPARISON_OFFSET > b.n.z) return false;
00249 
00250 
00251         if (a.uv[0].x + NORM_COMPARISON_OFFSET < b.uv[0].x) return true;
00252         if (a.uv[0].x - NORM_COMPARISON_OFFSET > b.uv[0].x) return false;
00253         if (a.uv[0].y + NORM_COMPARISON_OFFSET < b.uv[0].y) return true;
00254         return false;
00255     };
00256 };
00257 
00261 struct VrtPositionComparator
00262 {
00263     bool operator()(const NvcVec3& a, const NvcVec3& b) const
00264     {
00265         if (a.x + POS_COMPARISON_OFFSET < b.x) return true;
00266         if (a.x - POS_COMPARISON_OFFSET > b.x) return false;
00267         if (a.y + POS_COMPARISON_OFFSET < b.y) return true;
00268         if (a.y - POS_COMPARISON_OFFSET > b.y) return false;
00269         if (a.z + POS_COMPARISON_OFFSET < b.z) return true;
00270         if (a.z - POS_COMPARISON_OFFSET > b.z) return false;
00271         return false;
00272     };
00273     bool operator()(const Vertex& a, const Vertex& b) const
00274     {
00275         return operator()(a.p, b.p);
00276     };
00277 };
00278 
00279 
00280 NV_INLINE float calculateCollisionHullVolume(const CollisionHull& hull)
00281 {
00282     if (hull.pointsCount == 0)
00283     {
00284         return 0.0f;
00285     }
00286 
00287     // Find an approximate centroid for a more accurate calculation
00288     NvcVec3 centroid = { 0.0f, 0.0f, 0.0f };
00289     for (uint32_t i = 0; i < hull.pointsCount; ++i)
00290     {
00291         centroid = centroid + hull.points[i];
00292     }
00293     centroid = centroid / hull.pointsCount;
00294 
00295     float volume = 0.0f;
00296 
00297     for (uint32_t i = 0; i < hull.polygonDataCount; ++i)
00298     {
00299         const HullPolygon& poly = hull.polygonData[i];
00300         if (poly.vertexCount < 3)
00301         {
00302             continue;
00303         }
00304         const uint32_t i0 = hull.indices[poly.indexBase];
00305         uint32_t i1 = hull.indices[poly.indexBase + 1];
00306         for (uint32_t j = 2; j < poly.vertexCount; ++j)
00307         {
00308             const uint32_t i2 = hull.indices[poly.indexBase + j];
00309             const NvcVec3 a = hull.points[i0] - centroid;
00310             const NvcVec3 b = hull.points[i1] - centroid;
00311             const NvcVec3 c = hull.points[i2] - centroid;
00312             volume +=
00313                 (a.x * b.y * c.z - a.x * b.z * c.y - a.y * b.x * c.z + a.y * b.z * c.x + a.z * b.x * c.y - a.z * b.y * c.x);
00314             i1 = i2;
00315         }
00316     }
00317     return (1.0f / 6.0f) * std::abs(volume);
00318 }
00319 
00320 }   // namespace Blast
00321 }   // namespace Nv
00322 
00323 #endif
Copyright © 2015-2017 NVIDIA Corporation, 2701 San Tomas Expressway, Santa Clara, CA 95050 U.S.A. All rights reserved. www.nvidia.com