diff options
Diffstat (limited to 'PhysX_3.4/Source/GeomUtils/src/convex')
18 files changed, 2779 insertions, 0 deletions
diff --git a/PhysX_3.4/Source/GeomUtils/src/convex/GuBigConvexData.cpp b/PhysX_3.4/Source/GeomUtils/src/convex/GuBigConvexData.cpp new file mode 100644 index 00000000..7874c526 --- /dev/null +++ b/PhysX_3.4/Source/GeomUtils/src/convex/GuBigConvexData.cpp @@ -0,0 +1,203 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#include "PsIntrinsics.h" +#include "PsUserAllocated.h" +#include "GuSerialize.h" +#include "GuBigConvexData2.h" +#include "GuCubeIndex.h" +#include "PsIntrinsics.h" +#include "CmUtils.h" +#include "PsUtilities.h" +#include "PsAllocator.h" + +using namespace physx; +using namespace Gu; + +BigConvexData::BigConvexData() : mVBuffer(NULL) +{ + mData.mSubdiv = 0; + mData.mNbSamples = 0; + mData.mSamples = NULL; + + ////// + + mData.mNbVerts = 0; + mData.mNbAdjVerts = 0; + mData.mValencies = NULL; + mData.mAdjacentVerts = NULL; +} + +BigConvexData::~BigConvexData() +{ + PX_FREE(mData.mSamples); + + /////////// + + if(mVBuffer) + { + PX_FREE(mVBuffer); + } + else + { + // Allocated from somewhere else!! + PX_FREE(mData.mValencies); + PX_FREE(mData.mAdjacentVerts); + } +} + +void BigConvexData::CreateOffsets() +{ + // Create offsets (radix style) + mData.mValencies[0].mOffset = 0; + for(PxU32 i=1;i<mData.mNbVerts;i++) + mData.mValencies[i].mOffset = PxU16(mData.mValencies[i-1].mOffset + mData.mValencies[i-1].mCount); +} + +bool BigConvexData::VLoad(PxInputStream& stream) +{ + // Import header + PxU32 Version; + bool Mismatch; + if(!ReadHeader('V', 'A', 'L', 'E', Version, Mismatch, stream)) + return false; + + mData.mNbVerts = readDword(Mismatch, stream); + mData.mNbAdjVerts = readDword(Mismatch, stream); + + PX_FREE(mVBuffer); + + // PT: align Gu::Valency? + const PxU32 numVerts = (mData.mNbVerts+3)&~3; + const PxU32 TotalSize = sizeof(Gu::Valency)*numVerts + sizeof(PxU8)*mData.mNbAdjVerts; + mVBuffer = PX_ALLOC(TotalSize, "BigConvexData data"); + mData.mValencies = reinterpret_cast<Gu::Valency*>(mVBuffer); + mData.mAdjacentVerts = (reinterpret_cast<PxU8*>(mVBuffer)) + sizeof(Gu::Valency)*numVerts; + + PX_ASSERT(0 == (size_t(mData.mAdjacentVerts) & 0xf)); + PX_ASSERT(Version==2); + + { + PxU16* temp = reinterpret_cast<PxU16*>(mData.mValencies); + + PxU32 MaxIndex = readDword(Mismatch, stream); + ReadIndices(Ps::to16(MaxIndex), mData.mNbVerts, temp, stream, Mismatch); + + // We transform from: + // + // |5555|4444|3333|2222|1111|----|----|----|----|----| + // + // to: + // + // |5555|4444|4444|2222|3333|----|2222|----|1111|----| + // + for(PxU32 i=0;i<mData.mNbVerts;i++) + mData.mValencies[mData.mNbVerts-i-1].mCount = temp[mData.mNbVerts-i-1]; + } + stream.read(mData.mAdjacentVerts, mData.mNbAdjVerts); + + // Recreate offsets + CreateOffsets(); + + return true; +} + +PxU32 BigConvexData::ComputeOffset(const PxVec3& dir) const +{ + return ComputeCubemapOffset(dir, mData.mSubdiv); +} + +PxU32 BigConvexData::ComputeNearestOffset(const PxVec3& dir) const +{ + return ComputeCubemapNearestOffset(dir, mData.mSubdiv); +} + +bool BigConvexData::Load(PxInputStream& stream) +{ + // Import header + PxU32 Version; + bool Mismatch; + if(!ReadHeader('S', 'U', 'P', 'M', Version, Mismatch, stream)) + return false; + + // Load base gaussmap +// if(!GaussMap::Load(stream)) return false; + + // Import header + if(!ReadHeader('G', 'A', 'U', 'S', Version, Mismatch, stream)) + return false; + + // Import basic info + mData.mSubdiv = Ps::to16(readDword(Mismatch, stream)); + mData.mNbSamples = Ps::to16(readDword(Mismatch, stream)); + + // Load map data + mData.mSamples = reinterpret_cast<PxU8*>(PX_ALLOC(sizeof(PxU8)*mData.mNbSamples*2, "BigConvex Samples Data")); + + // These byte buffers shouldn't need converting + stream.read(mData.mSamples, sizeof(PxU8)*mData.mNbSamples*2); + + //load the valencies + return VLoad(stream); +} + +// PX_SERIALIZATION +void BigConvexData::exportExtraData(PxSerializationContext& stream) +{ + if(mData.mSamples) + { + stream.alignData(PX_SERIAL_ALIGN); + stream.writeData(mData.mSamples, sizeof(PxU8)*mData.mNbSamples*2); + } + + if(mData.mValencies) + { + stream.alignData(PX_SERIAL_ALIGN); + PxU32 numVerts = (mData.mNbVerts+3)&~3; + const PxU32 TotalSize = sizeof(Gu::Valency)*numVerts + sizeof(PxU8)*mData.mNbAdjVerts; + stream.writeData(mData.mValencies, TotalSize); + } +} + +void BigConvexData::importExtraData(PxDeserializationContext& context) +{ + if(mData.mSamples) + mData.mSamples = context.readExtraData<PxU8, PX_SERIAL_ALIGN>(PxU32(mData.mNbSamples*2)); + + if(mData.mValencies) + { + context.alignExtraData(); + PxU32 numVerts = (mData.mNbVerts+3)&~3; + mData.mValencies = context.readExtraData<Gu::Valency>(numVerts); + mData.mAdjacentVerts = context.readExtraData<PxU8>(mData.mNbAdjVerts); + + } +} +//~PX_SERIALIZATION + diff --git a/PhysX_3.4/Source/GeomUtils/src/convex/GuBigConvexData.h b/PhysX_3.4/Source/GeomUtils/src/convex/GuBigConvexData.h new file mode 100644 index 00000000..835f463b --- /dev/null +++ b/PhysX_3.4/Source/GeomUtils/src/convex/GuBigConvexData.h @@ -0,0 +1,98 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef GU_BIG_CONVEX_DATA_H +#define GU_BIG_CONVEX_DATA_H + +#include "foundation/PxSimpleTypes.h" + +namespace physx +{ + +class BigConvexDataBuilder; +class PxcHillClimb; +class BigConvexData; + +// Data + +namespace Gu +{ + +struct Valency +{ +//= ATTENTION! ===================================================================================== +// Changing the data layout of this class breaks the binary serialization format. See comments for +// PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData +// function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION +// accordingly. +//================================================================================================== + + PxU16 mCount; + PxU16 mOffset; +}; +PX_COMPILE_TIME_ASSERT(sizeof(Gu::Valency) == 4); + +struct BigConvexRawData +{ +//= ATTENTION! ===================================================================================== +// Changing the data layout of this class breaks the binary serialization format. See comments for +// PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData +// function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION +// accordingly. +//================================================================================================== + + // Support vertex map + PxU16 mSubdiv; // "Gaussmap" subdivision + PxU16 mNbSamples; // Total #samples in gaussmap PT: this is not even needed at runtime! + + PxU8* mSamples; + PX_FORCE_INLINE const PxU8* getSamples2() const + { + return mSamples + mNbSamples; + } + //~Support vertex map + + // Valencies data + PxU32 mNbVerts; //!< Number of vertices + PxU32 mNbAdjVerts; //!< Total number of adjacent vertices ### PT: this is useless at runtime and should not be stored here + Gu::Valency* mValencies; //!< A list of mNbVerts valencies (= number of neighbors) + PxU8* mAdjacentVerts; //!< List of adjacent vertices + //~Valencies data +}; +#if PX_P64_FAMILY +PX_COMPILE_TIME_ASSERT(sizeof(Gu::BigConvexRawData) == 40); +#else +PX_COMPILE_TIME_ASSERT(sizeof(Gu::BigConvexRawData) == 24); +#endif + +} // namespace Gu + +} + +#endif diff --git a/PhysX_3.4/Source/GeomUtils/src/convex/GuBigConvexData2.h b/PhysX_3.4/Source/GeomUtils/src/convex/GuBigConvexData2.h new file mode 100644 index 00000000..be2e8a50 --- /dev/null +++ b/PhysX_3.4/Source/GeomUtils/src/convex/GuBigConvexData2.h @@ -0,0 +1,95 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef GU_BIG_CONVEX_DATA2_H +#define GU_BIG_CONVEX_DATA2_H + +#include "GuBigConvexData.h" +#include "PxMetaData.h" + +namespace physx +{ + class PxSerializationContext; + class PxDeserializationContext; + + class PX_PHYSX_COMMON_API BigConvexData : public Ps::UserAllocated + { + //= ATTENTION! ===================================================================================== + // Changing the data layout of this class breaks the binary serialization format. See comments for + // PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData + // function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION + // accordingly. + //================================================================================================== + public: +// PX_SERIALIZATION + BigConvexData(const PxEMPTY) {} + static void getBinaryMetaData(PxOutputStream& stream); +//~PX_SERIALIZATION + BigConvexData(); + ~BigConvexData(); + // Support vertex map + bool Load(PxInputStream& stream); + + PxU32 ComputeOffset(const PxVec3& dir) const; + PxU32 ComputeNearestOffset(const PxVec3& dir) const; + + // Data access + PX_INLINE PxU32 GetSubdiv() const { return mData.mSubdiv; } + PX_INLINE PxU32 GetNbSamples() const { return mData.mNbSamples; } + //~Support vertex map + + // Valencies + // Data access + PX_INLINE PxU32 GetNbVerts() const { return mData.mNbVerts; } + PX_INLINE const Gu::Valency* GetValencies() const { return mData.mValencies; } + PX_INLINE PxU16 GetValency(PxU32 i) const { return mData.mValencies[i].mCount; } + PX_INLINE PxU16 GetOffset(PxU32 i) const { return mData.mValencies[i].mOffset; } + PX_INLINE const PxU8* GetAdjacentVerts() const { return mData.mAdjacentVerts; } + + PX_INLINE PxU16 GetNbNeighbors(PxU32 i) const { return mData.mValencies[i].mCount; } + PX_INLINE const PxU8* GetNeighbors(PxU32 i) const { return &mData.mAdjacentVerts[mData.mValencies[i].mOffset]; } + +// PX_SERIALIZATION + void exportExtraData(PxSerializationContext& stream); + void importExtraData(PxDeserializationContext& context); +//~PX_SERIALIZATION + Gu::BigConvexRawData mData; + protected: + void* mVBuffer; + // Internal methods + void CreateOffsets(); + bool VLoad(PxInputStream& stream); + //~Valencies + friend class BigConvexDataBuilder; + }; + +} + +#endif // BIG_CONVEX_DATA_H + diff --git a/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexEdgeFlags.h b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexEdgeFlags.h new file mode 100644 index 00000000..66f55ace --- /dev/null +++ b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexEdgeFlags.h @@ -0,0 +1,56 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef GU_CONVEX_EDGE_FLAGS_H +#define GU_CONVEX_EDGE_FLAGS_H + +#include "CmPhysXCommon.h" + +namespace physx +{ +namespace Gu +{ + enum ExtraTrigDataFlag + { + ETD_CONVEX_EDGE_01 = (1<<3), // PT: important value, don't change + ETD_CONVEX_EDGE_12 = (1<<4), // PT: important value, don't change + ETD_CONVEX_EDGE_20 = (1<<5), // PT: important value, don't change + + ETD_CONVEX_EDGE_ALL = ETD_CONVEX_EDGE_01|ETD_CONVEX_EDGE_12|ETD_CONVEX_EDGE_20 + }; + + // PT: helper function to make sure we use the proper default flags everywhere + PX_FORCE_INLINE PxU8 getConvexEdgeFlags(const PxU8* extraTrigData, PxU32 triangleIndex) + { + return extraTrigData ? extraTrigData[triangleIndex] : PxU8(ETD_CONVEX_EDGE_ALL); + } +} +} + +#endif diff --git a/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexHelper.cpp b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexHelper.cpp new file mode 100644 index 00000000..48bd7641 --- /dev/null +++ b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexHelper.cpp @@ -0,0 +1,137 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#include "GuConvexHelper.h" +#include "GuGeometryUnion.h" +#include "GuInternal.h" +#include "PsUtilities.h" + +using namespace physx; +using namespace Gu; + +// PT: we can't call alloca in a function and we want to avoid defines or duplicating the code. This makes it a bit tricky to write. +void Gu::getScaledConvex( PxVec3*& scaledVertices, PxU8*& scaledIndices, PxVec3* dstVertices, PxU8* dstIndices, + bool idtConvexScale, const PxVec3* srcVerts, const PxU8* srcIndices, PxU32 nbVerts, const Cm::FastVertex2ShapeScaling& convexScaling) +{ + //pretransform convex polygon if we have scaling! + if(idtConvexScale) // PT: the scale is always 1 for boxes so no need to test the type + { + scaledVertices = const_cast<PxVec3*>(srcVerts); + scaledIndices = const_cast<PxU8*>(srcIndices); + } + else + { + scaledIndices = dstIndices; + scaledVertices = dstVertices; + for(PxU32 i=0; i<nbVerts; i++) + { + scaledIndices[i] = Ps::to8(i); //generate trivial indexing. + scaledVertices[i] = convexScaling * srcVerts[srcIndices[i]]; + } + } +} + +bool Gu::getConvexData(const Gu::GeometryUnion& shape, Cm::FastVertex2ShapeScaling& scaling, PxBounds3& bounds, PolygonalData& polyData) +{ + const PxConvexMeshGeometryLL& shapeConvex = shape.get<const PxConvexMeshGeometryLL>(); + + const bool idtScale = shapeConvex.scale.isIdentity(); + if(!idtScale) + scaling.init(shapeConvex.scale); + + // PT: this version removes all the FCMPs and almost all LHS. This is temporary until + // the legacy 3x3 matrix totally vanishes but meanwhile do NOT do useless matrix conversions, + // it's a perfect recipe for LHS. + PX_ASSERT(!shapeConvex.hullData->mAABB.isEmpty()); + bounds = shapeConvex.hullData->mAABB.transformFast(scaling.getVertex2ShapeSkew()); + + getPolygonalData_Convex(&polyData, shapeConvex.hullData, scaling); + + // PT: non-uniform scaling invalidates the "internal objects" optimization, since our internal sphere + // might become an ellipsoid or something. Just disable the optimization if scaling is used... + if(!idtScale) + polyData.mInternal.reset(); + + return idtScale; +} + +PxU32 Gu::findUniqueConvexEdges(PxU32 maxNbEdges, ConvexEdge* PX_RESTRICT edges, PxU32 numPolygons, const Gu::HullPolygonData* PX_RESTRICT polygons, const PxU8* PX_RESTRICT vertexData) +{ + PxU32 nbEdges = 0; + + while(numPolygons--) + { + const HullPolygonData& polygon = *polygons++; + const PxU8* vRefBase = vertexData + polygon.mVRef8; + PxU32 numEdges = polygon.mNbVerts; + + PxU32 a = numEdges - 1; + PxU32 b = 0; + while(numEdges--) + { + PxU8 vi0 = vRefBase[a]; + PxU8 vi1 = vRefBase[b]; + + if(vi1 < vi0) + { + PxU8 tmp = vi0; + vi0 = vi1; + vi1 = tmp; + } + + bool found=false; + for(PxU32 i=0;i<nbEdges;i++) + { + if(edges[i].vref0==vi0 && edges[i].vref1==vi1) + { + found = true; + edges[i].normal += polygon.mPlane.n; + break; + } + } + if(!found) + { + if(nbEdges==maxNbEdges) + { + PX_ALWAYS_ASSERT_MESSAGE("Internal error: max nb edges reached. This shouldn't be possible..."); + return nbEdges; + } + + edges[nbEdges].vref0 = vi0; + edges[nbEdges].vref1 = vi1; + edges[nbEdges].normal = polygon.mPlane.n; + nbEdges++; + } + + a = b; + b++; + } + } + return nbEdges; +} diff --git a/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexHelper.h b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexHelper.h new file mode 100644 index 00000000..5e93eab2 --- /dev/null +++ b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexHelper.h @@ -0,0 +1,66 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef GU_CONVEXHELPER_H +#define GU_CONVEXHELPER_H + +#include "GuShapeConvex.h" + +namespace physx +{ +namespace Gu +{ + class GeometryUnion; + + /////////////////////////////////////////////////////////////////////////// + + PX_PHYSX_COMMON_API void getScaledConvex( PxVec3*& scaledVertices, PxU8*& scaledIndices, PxVec3* dstVertices, PxU8* dstIndices, + bool idtConvexScale, const PxVec3* srcVerts, const PxU8* srcIndices, PxU32 nbVerts, const Cm::FastVertex2ShapeScaling& convexScaling); + + // PT: calling this correctly isn't trivial so let's macroize it. At least we limit the damage since it immediately calls a real function. + #define GET_SCALEX_CONVEX(scaledVertices, stackIndices, idtScaling, nbVerts, scaling, srcVerts, srcIndices) \ + getScaledConvex(scaledVertices, stackIndices, \ + idtScaling ? NULL : reinterpret_cast<PxVec3*>(PxAlloca(nbVerts * sizeof(PxVec3))), \ + idtScaling ? NULL : reinterpret_cast<PxU8*>(PxAlloca(nbVerts * sizeof(PxU8))), \ + idtScaling, srcVerts, srcIndices, nbVerts, scaling); + + PX_PHYSX_COMMON_API bool getConvexData(const Gu::GeometryUnion& shape, Cm::FastVertex2ShapeScaling& scaling, PxBounds3& bounds, PolygonalData& polyData); + + struct ConvexEdge + { + PxU8 vref0; + PxU8 vref1; + PxVec3 normal; // warning: non-unit vector! + }; + + PX_PHYSX_COMMON_API PxU32 findUniqueConvexEdges(PxU32 maxNbEdges, ConvexEdge* PX_RESTRICT edges, PxU32 numPolygons, const Gu::HullPolygonData* PX_RESTRICT polygons, const PxU8* PX_RESTRICT vertexData); +} +} + +#endif diff --git a/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexMesh.cpp b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexMesh.cpp new file mode 100644 index 00000000..53d67504 --- /dev/null +++ b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexMesh.cpp @@ -0,0 +1,456 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + + +#include "PxVisualizationParameter.h" +#include "PsIntrinsics.h" +#include "CmPhysXCommon.h" +#include "CmRenderOutput.h" +#include "PsMathUtils.h" +#include "GuConvexMesh.h" +#include "GuTriangle32.h" +#include "GuBigConvexData2.h" +#include "GuSerialize.h" +#include "GuMeshFactory.h" +#include "CmUtils.h" +#include "PxMeshScale.h" +#include "PsAllocator.h" +#include "PsFoundation.h" + +using namespace physx; +using namespace Gu; + +// PX_SERIALIZATION +#include "PsIntrinsics.h" +//~PX_SERIALIZATION + +bool Gu::ConvexMesh::getPolygonData(PxU32 i, PxHullPolygon& data) const +{ + if(i>=mHullData.mNbPolygons) + return false; + + const HullPolygonData& poly = mHullData.mPolygons[i]; + data.mPlane[0] = poly.mPlane.n.x; + data.mPlane[1] = poly.mPlane.n.y; + data.mPlane[2] = poly.mPlane.n.z; + data.mPlane[3] = poly.mPlane.d; + data.mNbVerts = poly.mNbVerts; + data.mIndexBase = poly.mVRef8; + return true; +} + +/// ====================================== + +static void initConvexHullData(Gu::ConvexHullData& data) +{ + data.mAABB.setEmpty(); + data.mCenterOfMass = PxVec3(0); + data.mNbEdges = PxBitAndWord(); + data.mNbHullVertices = 0; + data.mNbPolygons = 0; + data.mPolygons = NULL; + data.mBigConvexRawData = NULL; + data.mInternal.mRadius = 0.0f; + data.mInternal.mExtents[0] = data.mInternal.mExtents[1] = data.mInternal.mExtents[2] = 0.0f; +} + +Gu::ConvexMesh::ConvexMesh() +: PxConvexMesh(PxConcreteType::eCONVEX_MESH, PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE) +, mNb (0) +, mBigConvexData (NULL) +, mMass (0) +, mInertia (PxMat33(PxIdentity)) +{ + initConvexHullData(mHullData); +} + +Gu::ConvexMesh::ConvexMesh(GuMeshFactory& factory, ConvexHullData& data) +: PxConvexMesh(PxConcreteType::eCONVEX_MESH, PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE) +, mNb(0) +, mBigConvexData(NULL) +, mMass(0) +, mInertia(PxMat33(PxIdentity)) +, mMeshFactory(&factory) +{ + mHullData = data; +} + +Gu::ConvexMesh::~ConvexMesh() +{ +// PX_SERIALIZATION + if(getBaseFlags()&PxBaseFlag::eOWNS_MEMORY) +//~PX_SERIALIZATION + { + PX_DELETE_POD(mHullData.mPolygons); + PX_DELETE_AND_RESET(mBigConvexData); + } +} + +bool Gu::ConvexMesh::isGpuCompatible() const +{ + return mHullData.mNbHullVertices <= 64 && + mHullData.mPolygons[0].mNbVerts < 32 && + mHullData.mNbEdges.isBitSet(); +} + +// PX_SERIALIZATION +void Gu::ConvexMesh::exportExtraData(PxSerializationContext& stream) +{ + stream.alignData(PX_SERIAL_ALIGN); + const PxU32 bufferSize = computeBufferSize(mHullData, getNb()); + stream.writeData(mHullData.mPolygons, bufferSize); + + if(mBigConvexData) + { + stream.alignData(PX_SERIAL_ALIGN); + stream.writeData(mBigConvexData, sizeof(BigConvexData)); + + mBigConvexData->exportExtraData(stream); + } +} + +void Gu::ConvexMesh::importExtraData(PxDeserializationContext& context) +{ + const PxU32 bufferSize = computeBufferSize(mHullData, getNb()); + mHullData.mPolygons = reinterpret_cast<Gu::HullPolygonData*>(context.readExtraData<PxU8, PX_SERIAL_ALIGN>(bufferSize)); + + if(mBigConvexData) + { + mBigConvexData = context.readExtraData<BigConvexData, PX_SERIAL_ALIGN>(); + new(mBigConvexData)BigConvexData(PxEmpty); + mBigConvexData->importExtraData(context); + mHullData.mBigConvexRawData = &mBigConvexData->mData; + } +} + +Gu::ConvexMesh* Gu::ConvexMesh::createObject(PxU8*& address, PxDeserializationContext& context) +{ + ConvexMesh* obj = new (address) ConvexMesh(PxBaseFlag::eIS_RELEASABLE); + address += sizeof(ConvexMesh); + obj->importExtraData(context); + obj->resolveReferences(context); + return obj; +} + +static bool convexHullLoad(Gu::ConvexHullData& data, PxInputStream& stream, PxBitAndDword& bufferSize) +{ + PxU32 version; + bool Mismatch; + if(!ReadHeader('C', 'L', 'H', 'L', version, Mismatch, stream)) + return false; + + if(!ReadHeader('C', 'V', 'H', 'L', version, Mismatch, stream)) + return false; + + PxU32 Nb; + + // Import figures + { + PxU32 tmp[4]; + ReadDwordBuffer(tmp, 4, Mismatch, stream); + data.mNbHullVertices = Ps::to8(tmp[0]); + data.mNbEdges = Ps::to16(tmp[1]); + data.mNbPolygons = Ps::to8(tmp[2]); + Nb = tmp[3]; + } + + //AM: In practice the old aligner approach wastes 20 bytes and there is no reason to 20 byte align this data. + //I changed the code to just 4 align for the time being. + //On consoles if anything we will need to make this stuff 16 byte align vectors to have any sense, which will have to be done by padding data structures. + PX_ASSERT(sizeof(Gu::HullPolygonData) % sizeof(PxReal) == 0); //otherwise please pad it. + PX_ASSERT(sizeof(PxVec3) % sizeof(PxReal) == 0); + + PxU32 bytesNeeded = computeBufferSize(data, Nb); + + PX_FREE(data.mPolygons); // Load() can be called for an existing convex mesh. In that case we need to free + // the memory first. + + bufferSize = Nb; + void* mDataMemory = PX_ALLOC(bytesNeeded, "ConvexHullData data"); + + PxU8* address = reinterpret_cast<PxU8*>(mDataMemory); + + data.mPolygons = reinterpret_cast<Gu::HullPolygonData*>(address); address += sizeof(Gu::HullPolygonData) * data.mNbPolygons; + PxVec3* mDataHullVertices = reinterpret_cast<PxVec3*>(address); address += sizeof(PxVec3) * data.mNbHullVertices; + PxU8* mDataFacesByEdges8 = address; address += sizeof(PxU8) * data.mNbEdges * 2; + PxU8* mDataFacesByVertices8 = address; address += sizeof(PxU8) * data.mNbHullVertices * 3; + PxU16* mEdges = reinterpret_cast<PxU16*>(address); address += data.mNbEdges.isBitSet() ? (sizeof(PxU16) * data.mNbEdges * 2) : 0; + PxU8* mDataVertexData8 = address; address += sizeof(PxU8) * Nb; // PT: leave that one last, so that we don't need to serialize "Nb" + + PX_ASSERT(!(size_t(mDataHullVertices) % sizeof(PxReal))); + PX_ASSERT(!(size_t(data.mPolygons) % sizeof(PxReal))); + PX_ASSERT(size_t(address)<=size_t(mDataMemory)+bytesNeeded); + + // Import vertices + readFloatBuffer(&mDataHullVertices->x, PxU32(3*data.mNbHullVertices), Mismatch, stream); + + if(version<=6) + { + PxU16 useUnquantizedNormals = readWord(Mismatch, stream); + PX_UNUSED(useUnquantizedNormals); + } + + // Import polygons + stream.read(data.mPolygons, data.mNbPolygons*sizeof(Gu::HullPolygonData)); + + if(Mismatch) + { + for(PxU32 i=0;i<data.mNbPolygons;i++) + flipData(data.mPolygons[i]); + } + + stream.read(mDataVertexData8, Nb); + stream.read(mDataFacesByEdges8, PxU32(data.mNbEdges*2)); + if(version <= 5) + { + //KS - we need to compute faces-by-vertices here + + bool noPlaneShift = false; + for(PxU32 i=0; i< data.mNbHullVertices; ++i) + { + PxU32 count = 0; + PxU8 inds[3]; + for(PxU32 j=0; j<data.mNbPolygons; ++j) + { + Gu::HullPolygonData& polygon = data.mPolygons[j]; + for(PxU32 k=0; k< polygon.mNbVerts; ++k) + { + PxU8 index = mDataVertexData8[polygon.mVRef8 + k]; + if(i == index) + { + //Found a polygon + inds[count++] = Ps::to8(j); + break; + } + } + if(count == 3) + break; + } + //We have 3 indices + //PX_ASSERT(count == 3); + //Do something here + if(count == 3) + { + mDataFacesByVertices8[i*3+0] = inds[0]; + mDataFacesByVertices8[i*3+1] = inds[1]; + mDataFacesByVertices8[i*3+2] = inds[2]; + } + else + { + noPlaneShift = true; + break; + } + } + + + if(noPlaneShift) + { + for(PxU32 a = 0; a < data.mNbHullVertices; ++a) + { + mDataFacesByVertices8[a*3] = 0xFF; + mDataFacesByVertices8[a*3+1] = 0xFF; + mDataFacesByVertices8[a*3+2] = 0xFF; + } + } + + } + else + stream.read(mDataFacesByVertices8, PxU32(data.mNbHullVertices * 3)); + + if (data.mNbEdges.isBitSet()) + { + if (version <= 7) + { + for (PxU32 a = 0; a < PxU32(data.mNbEdges * 2); ++a) + { + mEdges[a] = 0xFFFF; + } + } + else + { + readWordBuffer(mEdges, PxU32(data.mNbEdges * 2), Mismatch, stream); + } + } + return true; +} + +bool Gu::ConvexMesh::load(PxInputStream& stream) +{ + // Import header + PxU32 version; + bool mismatch; + if(!readHeader('C', 'V', 'X', 'M', version, mismatch, stream)) + return false; + + // Check if old (incompatible) mesh format is loaded + if (version < PX_CONVEX_VERSION) + { + Ps::getFoundation().error(PxErrorCode::eINTERNAL_ERROR, __FILE__, __LINE__, "Loading convex mesh failed: " + "Deprecated mesh cooking format."); + return false; + } + + // Import serialization flags + PxU32 serialFlags = readDword(mismatch, stream); + PX_UNUSED(serialFlags); + + if(!convexHullLoad(mHullData, stream, mNb)) + return false; + + // Import local bounds + float tmp[8]; + readFloatBuffer(tmp, 8, mismatch, stream); +// geomEpsilon = tmp[0]; + mHullData.mAABB = PxBounds3(PxVec3(tmp[1], tmp[2], tmp[3]), PxVec3(tmp[4],tmp[5],tmp[6])); + + // Import mass info + mMass = tmp[7]; + if(mMass!=-1.0f) + { + readFloatBuffer(&mInertia(0,0), 9, mismatch, stream); + readFloatBuffer(&mHullData.mCenterOfMass.x, 3, mismatch, stream); + } + + // Import gaussmaps + PxF32 gaussMapFlag = readFloat(mismatch, stream); + if(gaussMapFlag != -1.0f) + { + PX_ASSERT(gaussMapFlag == 1.0f); //otherwise file is corrupt + + PX_DELETE_AND_RESET(mBigConvexData); + PX_NEW_SERIALIZED(mBigConvexData,BigConvexData); + + if(mBigConvexData) + { + mBigConvexData->Load(stream); + mHullData.mBigConvexRawData = &mBigConvexData->mData; + } + } + +/* + printf("\n\n"); + printf("COM: %f %f %f\n", massInfo.centerOfMass.x, massInfo.centerOfMass.y, massInfo.centerOfMass.z); + printf("BND: %f %f %f\n", mHullData.aabb.getCenter().x, mHullData.aabb.getCenter().y, mHullData.aabb.getCenter().z); + printf("CNT: %f %f %f\n", mHullData.mCenterxx.x, mHullData.mCenterxx.y, mHullData.mCenterxx.z); + printf("COM-BND: %f BND-CNT: %f, CNT-COM: %f\n", (massInfo.centerOfMass - mHullData.aabb.getCenter()).magnitude(), (mHullData.aabb.getCenter() - mHullData.mCenterxx).magnitude(), (mHullData.mCenterxx - massInfo.centerOfMass).magnitude()); +*/ + +// TEST_INTERNAL_OBJECTS + mHullData.mInternal.mRadius = readFloat(mismatch, stream); + mHullData.mInternal.mExtents[0] = readFloat(mismatch, stream); + mHullData.mInternal.mExtents[1] = readFloat(mismatch, stream); + mHullData.mInternal.mExtents[2] = readFloat(mismatch, stream); + + PX_ASSERT(PxVec3(mHullData.mInternal.mExtents[0], mHullData.mInternal.mExtents[1], mHullData.mInternal.mExtents[2]).isFinite()); + PX_ASSERT(mHullData.mInternal.mExtents[0] != 0.0f); + PX_ASSERT(mHullData.mInternal.mExtents[1] != 0.0f); + PX_ASSERT(mHullData.mInternal.mExtents[2] != 0.0f); +//~TEST_INTERNAL_OBJECTS + return true; +} + + + +void Gu::ConvexMesh::release() +{ + decRefCount(); +} + +void Gu::ConvexMesh::onRefCountZero() +{ + if ((!getBufferSize()) || mMeshFactory->removeConvexMesh(*this)) // when the mesh failed to load properly, it will not have been added to the convex array + { + GuMeshFactory* mf = mMeshFactory; + Cm::deletePxBase(this); + mf->notifyFactoryListener(this, PxConcreteType::eCONVEX_MESH); + return; + } + + // PT: if we reach this point, we didn't find the mesh in the Physics object => don't delete! + // This prevents deleting the object twice. + Ps::getFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "Gu::ConvexMesh::release: double deletion detected!"); +} + +void Gu::ConvexMesh::acquireReference() +{ + incRefCount(); +} + +PxU32 Gu::ConvexMesh::getReferenceCount() const +{ + return getRefCount(); +} + +void Gu::ConvexMesh::getMassInformation(PxReal& mass, PxMat33& localInertia, PxVec3& localCenterOfMass) const +{ + mass = Gu::ConvexMesh::getMass(); + localInertia = Gu::ConvexMesh::getInertia(); + localCenterOfMass = Gu::ConvexMesh::getHull().mCenterOfMass; +} + +PxBounds3 Gu::ConvexMesh::getLocalBounds() const +{ + PX_ASSERT(mHullData.mAABB.isValid()); + return PxBounds3::centerExtents(mHullData.mAABB.mCenter, mHullData.mAABB.mExtents); +} + + +#if PX_ENABLE_DEBUG_VISUALIZATION +#include "CmMatrix34.h" +#include "GuDebug.h" +void Gu::ConvexMesh::debugVisualize(Cm::RenderOutput& out, const PxTransform& pose, const PxMeshScale& scale) const +{ + const PxU32 scolor = PxU32(PxDebugColor::eARGB_MAGENTA); + + const PxVec3* vertices = mHullData.getHullVertices(); + const PxU8* indexBuffer = mHullData.getVertexData8(); + const PxU32 nbPolygons = getNbPolygonsFast(); + + const PxMat44 m44(PxMat33(pose.q) * scale.toMat33(), pose.p); + + out << m44 << scolor; // PT: no need to output this for each segment! + + for (PxU32 i = 0; i < nbPolygons; i++) + { + const PxU32 pnbVertices = mHullData.mPolygons[i].mNbVerts; + + PxVec3 begin = m44.transform(vertices[indexBuffer[0]]); // PT: transform it only once before the loop starts + for (PxU32 j = 1; j < pnbVertices; j++) + { + PxVec3 end = m44.transform(vertices[indexBuffer[j]]); + out.outputSegment(begin, end); + begin = end; + } + out.outputSegment(begin, m44.transform(vertices[indexBuffer[0]])); + + indexBuffer += pnbVertices; + } +} + +#endif diff --git a/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexMesh.h b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexMesh.h new file mode 100644 index 00000000..cf75ec31 --- /dev/null +++ b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexMesh.h @@ -0,0 +1,189 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef GU_COLLISION_CONVEXMESH_H +#define GU_COLLISION_CONVEXMESH_H + +#include "foundation/PxBitAndData.h" +#include "PxConvexMesh.h" +#include "CmPhysXCommon.h" +#include "PsUserAllocated.h" +#include "CmRefCountable.h" +#include "GuConvexMeshData.h" + +// PX_SERIALIZATION +#include "PxMetaData.h" +#include "CmRenderOutput.h" +//~PX_SERIALIZATION + +namespace physx +{ + +class BigConvexData; +class GuMeshFactory; +class PxMeshScale; + + +namespace Gu +{ + struct HullPolygonData; + + PX_INLINE PxU32 computeBufferSize(const Gu::ConvexHullData& data, PxU32 nb) + { + PxU32 bytesNeeded = sizeof(Gu::HullPolygonData) * data.mNbPolygons; + bytesNeeded += sizeof(PxVec3) * data.mNbHullVertices; + bytesNeeded += sizeof(PxU8) * data.mNbEdges * 2; // mFacesByEdges8 + bytesNeeded += sizeof(PxU8) * data.mNbHullVertices * 3; // mFacesByVertices8; + bytesNeeded += data.mNbEdges.isBitSet() ? (sizeof(PxU16) * data.mNbEdges * 2) : 0; // mEdges; + bytesNeeded += sizeof(PxU8) * nb; // mVertexData8 + + //4 align the whole thing! + const PxU32 mod = bytesNeeded % sizeof(PxReal); + if (mod) + bytesNeeded += sizeof(PxReal) - mod; + return bytesNeeded; + } + + // 0: includes raycast map + // 1: discarded raycast map + // 2: support map not always there + // 3: support stackless trees for non-recursive collision queries + // 4: no more opcode model + // 5: valencies table and gauss map combined, only exported over a vertex count treshold that depends on the platform cooked for. + // 6: removed support for edgeData16. + // 7: removed support for edge8Data. + // 8: removed support for triangles. + + // 9: removed local sphere. + //10: removed geometric center. + //11: removed mFlags, and mERef16 from Poly; nbVerts is just a byte. + //12: removed explicit minimum, maximum from Poly + //13: internal objects + #define PX_CONVEX_VERSION 13 + + class ConvexMesh : public PxConvexMesh, public Ps::UserAllocated, public Cm::RefCountable + { + //= ATTENTION! ===================================================================================== + // Changing the data layout of this class breaks the binary serialization format. See comments for + // PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData + // function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION + // accordingly. + //================================================================================================== + public: + // PX_SERIALIZATION + PX_PHYSX_COMMON_API ConvexMesh(PxBaseFlags baseFlags) : PxConvexMesh(baseFlags), Cm::RefCountable(PxEmpty), mHullData(PxEmpty), mNb(PxEmpty) + { + mNb.setBit(); + } + + PX_PHYSX_COMMON_API virtual void exportExtraData(PxSerializationContext& stream); + PX_PHYSX_COMMON_API void importExtraData(PxDeserializationContext& context); + PX_PHYSX_COMMON_API virtual void onRefCountZero(); + PX_PHYSX_COMMON_API static ConvexMesh* createObject(PxU8*& address, PxDeserializationContext& context); + PX_PHYSX_COMMON_API static void getBinaryMetaData(PxOutputStream& stream); + void resolveReferences(PxDeserializationContext&) {} + virtual void requires(PxProcessPxBaseCallback&){} + //~PX_SERIALIZATION + PX_PHYSX_COMMON_API ConvexMesh(); + + ConvexMesh(GuMeshFactory& factory, ConvexHullData& data); + + PX_PHYSX_COMMON_API bool load(PxInputStream& stream); + + // PxConvexMesh + PX_PHYSX_COMMON_API virtual void release(); + PX_PHYSX_COMMON_API virtual PxU32 getNbVertices() const { return mHullData.mNbHullVertices; } + PX_PHYSX_COMMON_API virtual const PxVec3* getVertices() const { return mHullData.getHullVertices(); } + PX_PHYSX_COMMON_API virtual const PxU8* getIndexBuffer() const { return mHullData.getVertexData8(); } + PX_PHYSX_COMMON_API virtual PxU32 getNbPolygons() const { return mHullData.mNbPolygons; } + PX_PHYSX_COMMON_API virtual bool getPolygonData(PxU32 i, PxHullPolygon& data) const; + PX_PHYSX_COMMON_API virtual bool isGpuCompatible() const; + PX_PHYSX_COMMON_API virtual PxU32 getReferenceCount() const; + PX_PHYSX_COMMON_API virtual void acquireReference(); + + PX_PHYSX_COMMON_API virtual void getMassInformation(PxReal& mass, PxMat33& localInertia, PxVec3& localCenterOfMass) const; + PX_PHYSX_COMMON_API virtual PxBounds3 getLocalBounds() const; + //~PxConvexMesh + + PX_FORCE_INLINE PxU32 getNbVerts() const { return mHullData.mNbHullVertices; } + PX_FORCE_INLINE const PxVec3* getVerts() const { return mHullData.getHullVertices(); } + PX_FORCE_INLINE PxU32 getNbPolygonsFast() const { return mHullData.mNbPolygons; } + PX_FORCE_INLINE const HullPolygonData& getPolygon(PxU32 i) const { return mHullData.mPolygons[i]; } + PX_FORCE_INLINE const HullPolygonData* getPolygons() const { return mHullData.mPolygons; } + PX_FORCE_INLINE PxU32 getNbEdges() const { return mHullData.mNbEdges; } + + PX_FORCE_INLINE const ConvexHullData& getHull() const { return mHullData; } + PX_FORCE_INLINE ConvexHullData& getHull() { return mHullData; } + PX_FORCE_INLINE const CenterExtents& getLocalBoundsFast() const { return mHullData.mAABB; } + PX_FORCE_INLINE PxReal getMass() const { return mMass; } + PX_FORCE_INLINE void setMass(PxReal mass) { mMass = mass; } + PX_FORCE_INLINE const PxMat33& getInertia() const { return mInertia; } + PX_FORCE_INLINE void setInertia(const PxMat33& inertia) { mInertia = inertia; } + + PX_FORCE_INLINE BigConvexData* getBigConvexData() const { return mBigConvexData; } + PX_FORCE_INLINE void setBigConvexData(BigConvexData* bcd) { mBigConvexData = bcd; } + + PX_FORCE_INLINE PxU32 getBufferSize() const { return computeBufferSize(mHullData, getNb()); } + + PX_PHYSX_COMMON_API virtual ~ConvexMesh(); + + PX_FORCE_INLINE void setMeshFactory(GuMeshFactory* f) { mMeshFactory = f; } + + protected: + ConvexHullData mHullData; + PxBitAndDword mNb; // ### PT: added for serialization. Try to remove later? + + BigConvexData* mBigConvexData; //!< optional, only for large meshes! PT: redundant with ptr in chull data? Could also be end of other buffer + PxReal mMass; //this is mass assuming a unit density that can be scaled by instances! + PxMat33 mInertia; //in local space of mesh! +private: + GuMeshFactory* mMeshFactory; // PT: changed to pointer for serialization + + PX_FORCE_INLINE PxU32 getNb() const { return mNb; } + PX_FORCE_INLINE PxU32 ownsMemory() const { return PxU32(!mNb.isBitSet()); } + +#if PX_ENABLE_DEBUG_VISUALIZATION +public: + /** + \brief Perform convex mesh geometry debug visualization + + \param out Debug renderer. + \param pose World position. + \param scale Scale to apply. + */ + void debugVisualize( Cm::RenderOutput& out, const PxTransform& pose, const PxMeshScale& scale) const; + +#endif + }; + +} // namespace Gu + +} + +#endif diff --git a/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexMeshData.h b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexMeshData.h new file mode 100644 index 00000000..60558b05 --- /dev/null +++ b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexMeshData.h @@ -0,0 +1,215 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef GU_CONVEX_MESH_DATA_H +#define GU_CONVEX_MESH_DATA_H + +#include "foundation/PxPlane.h" +#include "PsIntrinsics.h" +#include "GuSerialize.h" +#include "GuCenterExtents.h" +#include "foundation/PxBitAndData.h" + +// Data definition + +namespace physx +{ +namespace Gu +{ + struct BigConvexRawData; + + struct HullPolygonData + { + //= ATTENTION! ===================================================================================== + // Changing the data layout of this class breaks the binary serialization format. See comments for + // PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData + // function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION + // accordingly. + //================================================================================================== + + // PT: this structure won't be allocated with PX_NEW because polygons aren't allocated alone (with a dedicated alloc). + // Instead they are part of a unique allocation/buffer containing all data for the ConvexHullData class (polygons, followed by + // hull vertices, edge data, etc). As a result, ctors for embedded classes like PxPlane won't be called. + + PxPlane mPlane; //!< Plane equation for this polygon //Could drop 4th elem as it can be computed from any vertex as: d = - p.dot(n); + PxU16 mVRef8; //!< Offset of vertex references in hull vertex data (CS: can we assume indices are tightly packed and offsets are ascending?? DrawObjects makes and uses this assumption) + PxU8 mNbVerts; //!< Number of vertices/edges in the polygon + PxU8 mMinIndex; //!< Index of the polygon vertex that has minimal projection along this plane's normal. + + PX_FORCE_INLINE PxReal getMin(const PxVec3* PX_RESTRICT hullVertices) const //minimum of projection of the hull along this plane normal + { + return mPlane.n.dot(hullVertices[mMinIndex]); + } + + PX_FORCE_INLINE PxReal getMax() const { return -mPlane.d; } //maximum of projection of the hull along this plane normal + }; + + PX_FORCE_INLINE void flipData(Gu::HullPolygonData& data) + { + flip(data.mPlane.n.x); + flip(data.mPlane.n.y); + flip(data.mPlane.n.z); + flip(data.mPlane.d); + flip(data.mVRef8); + } + // PT: if this one breaks, please make sure the 'flipData' function is properly updated. + PX_COMPILE_TIME_ASSERT(sizeof(Gu::HullPolygonData) == 20); + +// TEST_INTERNAL_OBJECTS + struct InternalObjectsData + { + //= ATTENTION! ===================================================================================== + // Changing the data layout of this class breaks the binary serialization format. See comments for + // PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData + // function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION + // accordingly. + //================================================================================================== + PxReal mRadius; + PxReal mExtents[3]; + + PX_FORCE_INLINE void reset() + { + mRadius = 0.0f; + mExtents[0] = 0.0f; + mExtents[1] = 0.0f; + mExtents[2] = 0.0f; + } + }; + PX_COMPILE_TIME_ASSERT(sizeof(Gu::InternalObjectsData) == 16); +//~TEST_INTERNAL_OBJECTS + + struct ConvexHullData + { + //= ATTENTION! ===================================================================================== + // Changing the data layout of this class breaks the binary serialization format. See comments for + // PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData + // function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION + // accordingly. + //================================================================================================== + + // PT: WARNING: bounds must be followed by at least 32bits of data for safe SIMD loading + CenterExtents mAABB; //!< bounds TODO: compute this on the fly from first 6 vertices in the vertex array. We'll of course need to sort the most extreme ones to the front. + PxVec3 mCenterOfMass; //in local space of mesh! + + // PT: WARNING: mNbHullVertices *must* appear before mBigConvexRawData for ConvX to be able to do "big raw data" surgery + + PxBitAndWord mNbEdges; //!<the highest bit indicate whether we have grb data, the other 15 bits indicate the number of edges in this convex hull + + PxU8 mNbHullVertices; //!< Number of vertices in the convex hull + PxU8 mNbPolygons; //!< Number of planar polygons composing the hull + + HullPolygonData* mPolygons; //!< Array of mNbPolygons structures + BigConvexRawData* mBigConvexRawData; //!< Hill climbing data, only for large convexes! else NULL. + +// TEST_INTERNAL_OBJECTS + InternalObjectsData mInternal; +//~TEST_INTERNAL_OBJECTS + + PX_FORCE_INLINE ConvexHullData(const PxEMPTY) : mNbEdges(PxEmpty) + { + } + + PX_FORCE_INLINE ConvexHullData() + { + } + + PX_FORCE_INLINE const CenterExtentsPadded& getPaddedBounds() const + { + // PT: see compile-time assert at the end of file + return static_cast<const CenterExtentsPadded&>(mAABB); + } + + PX_FORCE_INLINE const PxVec3* getHullVertices() const //!< Convex hull vertices + { + const char* tmp = reinterpret_cast<const char*>(mPolygons); + tmp += sizeof(Gu::HullPolygonData) * mNbPolygons; + return reinterpret_cast<const PxVec3*>(tmp); + } + + PX_FORCE_INLINE const PxU8* getFacesByEdges8() const //!< for each edge, gives 2 adjacent polygons; used by convex-convex code to come up with all the convex' edge normals. + { + const char* tmp = reinterpret_cast<const char*>(mPolygons); + tmp += sizeof(Gu::HullPolygonData) * mNbPolygons; + tmp += sizeof(PxVec3) * mNbHullVertices; + return reinterpret_cast<const PxU8*>(tmp); + } + + PX_FORCE_INLINE const PxU8* getFacesByVertices8() const //!< for each edge, gives 2 adjacent polygons; used by convex-convex code to come up with all the convex' edge normals. + { + const char* tmp = reinterpret_cast<const char*>(mPolygons); + tmp += sizeof(Gu::HullPolygonData) * mNbPolygons; + tmp += sizeof(PxVec3) * mNbHullVertices; + tmp += sizeof(PxU8) * mNbEdges * 2; + return reinterpret_cast<const PxU8*>(tmp); + } + + //If we don't build the convex hull with grb data, we will return NULL pointer + PX_FORCE_INLINE const PxU16* getVerticesByEdges16() const //!< Vertex indices indexed by unique edges + { + if (mNbEdges.isBitSet()) + { + const char* tmp = reinterpret_cast<const char*>(mPolygons); + tmp += sizeof(Gu::HullPolygonData) * mNbPolygons; + tmp += sizeof(PxVec3) * mNbHullVertices; + tmp += sizeof(PxU8) * mNbEdges * 2; + tmp += sizeof(PxU8) * mNbHullVertices * 3; + return reinterpret_cast<const PxU16*>(tmp); + } + return NULL; + } + + PX_FORCE_INLINE const PxU8* getVertexData8() const //!< Vertex indices indexed by hull polygons + { + const char* tmp = reinterpret_cast<const char*>(mPolygons); + tmp += sizeof(Gu::HullPolygonData) * mNbPolygons; + tmp += sizeof(PxVec3) * mNbHullVertices; + tmp += sizeof(PxU8) * mNbEdges * 2; + tmp += sizeof(PxU8) * mNbHullVertices * 3; + if (mNbEdges.isBitSet()) + tmp += sizeof(PxU16) * mNbEdges * 2; + return reinterpret_cast<const PxU8*>(tmp); + } + + }; + #if PX_P64_FAMILY + PX_COMPILE_TIME_ASSERT(sizeof(Gu::ConvexHullData) == 72); + #else + PX_COMPILE_TIME_ASSERT(sizeof(Gu::ConvexHullData) == 64); + #endif + + // PT: 'getPaddedBounds()' is only safe if we make sure the bounds member is followed by at least 32bits of data + PX_COMPILE_TIME_ASSERT(PX_OFFSET_OF(Gu::ConvexHullData, mCenterOfMass)>=PX_OFFSET_OF(Gu::ConvexHullData, mAABB)+4); + +} // namespace Gu + +} + +//#pragma PX_POP_PACK + +#endif diff --git a/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexSupportTable.cpp b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexSupportTable.cpp new file mode 100644 index 00000000..912e5594 --- /dev/null +++ b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexSupportTable.cpp @@ -0,0 +1,44 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#include "GuVecBox.h" + +namespace physx +{ + const Ps::aos::BoolV boxVertexTable[8] = { + Ps::aos::BFFFF(),//--- + Ps::aos::BTFFF(),//+-- + Ps::aos::BFTFF(),//-+- + Ps::aos::BTTFF(),//++- + Ps::aos::BFFTF(),//--+ + Ps::aos::BTFTF(),//+-+ + Ps::aos::BFTTF(),//-++ + Ps::aos::BTTTF(),//+++ + }; +} diff --git a/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexSupportTable.h b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexSupportTable.h new file mode 100644 index 00000000..017dfc01 --- /dev/null +++ b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexSupportTable.h @@ -0,0 +1,162 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef GU_CONVEX_SUPPORT_TABLE_H +#define GU_CONVEX_SUPPORT_TABLE_H + +#include "GuVecConvex.h" +#include "PsVecTransform.h" +#include "PxPhysXCommonConfig.h" + +namespace physx +{ +namespace Gu +{ + + class TriangleV; + class CapsuleV; + class BoxV; + class ConvexHullV; + class ShrunkConvexHullV; + class ConvexHullNoScaleV; + class ShrunkConvexHullNoScaleV; + + +#if PX_VC + #pragma warning(push) + #pragma warning( disable : 4324 ) // Padding was added at the end of a structure because of a __declspec(align) value. +#endif + class SupportLocal + { + public: + Ps::aos::Vec3V shapeSpaceCenterOfMass; + const Ps::aos::PsTransformV& transform; + const Ps::aos::Mat33V& vertex2Shape; + const Ps::aos::Mat33V& shape2Vertex; + const bool isIdentityScale; + + SupportLocal(const Ps::aos::PsTransformV& _transform, const Ps::aos::Mat33V& _vertex2Shape, const Ps::aos::Mat33V& _shape2Vertex, const bool _isIdentityScale = true): transform(_transform), + vertex2Shape(_vertex2Shape), shape2Vertex(_shape2Vertex), isIdentityScale(_isIdentityScale) + { + } + + void setShapeSpaceCenterofMass(const Ps::aos::Vec3VArg _shapeSpaceCenterOfMass) + { + shapeSpaceCenterOfMass = _shapeSpaceCenterOfMass; + } + virtual ~SupportLocal() {} + virtual Ps::aos::Vec3V doSupport(const Ps::aos::Vec3VArg dir) const = 0; + virtual void doSupport(const Ps::aos::Vec3VArg dir, Ps::aos::FloatV& min, Ps::aos::FloatV& max) const = 0; + virtual void populateVerts(const PxU8* inds, PxU32 numInds, const PxVec3* originalVerts, Ps::aos::Vec3V* verts)const = 0; + + protected: + SupportLocal& operator=(const SupportLocal&); + }; +#if PX_VC + #pragma warning(pop) +#endif + + template <typename Convex> + class SupportLocalImpl : public SupportLocal + { + + public: + const Convex& conv; + SupportLocalImpl(const Convex& _conv, const Ps::aos::PsTransformV& _transform, const Ps::aos::Mat33V& _vertex2Shape, const Ps::aos::Mat33V& _shape2Vertex, const bool _isIdentityScale = true) : + SupportLocal(_transform, _vertex2Shape, _shape2Vertex, _isIdentityScale), conv(_conv) + { + } + + Ps::aos::Vec3V doSupport(const Ps::aos::Vec3VArg dir) const + { + //return conv.supportVertsLocal(dir); + return conv.supportLocal(dir); + } + + void doSupport(const Ps::aos::Vec3VArg dir, Ps::aos::FloatV& min, Ps::aos::FloatV& max) const + { + return conv.supportLocal(dir, min, max); + } + + + void populateVerts(const PxU8* inds, PxU32 numInds, const PxVec3* originalVerts, Ps::aos::Vec3V* verts) const + { + conv.populateVerts(inds, numInds, originalVerts, verts); + } + + PX_FORCE_INLINE void populateVertsFast(const PxU8* inds, PxU32 numInds, const PxVec3* originalVerts, Ps::aos::Vec3V* verts) const + { + conv.populateVerts(inds, numInds, originalVerts, verts); + } + + protected: + SupportLocalImpl& operator=(const SupportLocalImpl&); + + }; + + template <typename Convex, typename ShrunkConvex> + class SupportLocalShrunkImpl : public SupportLocal + { + SupportLocalShrunkImpl& operator=(const SupportLocalShrunkImpl&); + public: + const Convex& conv; + const ShrunkConvex& shrunkConvex; + SupportLocalShrunkImpl(const Convex& _conv, const Ps::aos::PsTransformV& _transform, const Ps::aos::Mat33V& _vertex2Shape, const Ps::aos::Mat33V& _shape2Vertex, const bool _isIdentityScale = true) : + SupportLocal(_transform, _vertex2Shape, _shape2Vertex, _isIdentityScale), conv(_conv), + shrunkConvex(static_cast<const ShrunkConvex&>(static_cast<const ConvexV&>(_conv))) //ML: The types may or may not be related but they will share the base class (ConvexV) so to avoid + //a compiler warning if we use reinterpret_cast unnecessarily, we static cast to base, then back up to + //the derived type. We guarantee that all types that are converted between are data compatible + { + } + + Ps::aos::Vec3V doSupport(const Ps::aos::Vec3VArg dir) const + { + //return conv.supportVertsLocal(dir); + return conv.supportLocal(dir); + } + + void doSupport(const Ps::aos::Vec3VArg dir, Ps::aos::FloatV& min, Ps::aos::FloatV& max) const + { + return conv.supportLocal(dir, min, max); + } + + void populateVerts(const PxU8* inds, PxU32 numInds, const PxVec3* originalVerts, Ps::aos::Vec3V* verts) const + { + conv.populateVerts(inds, numInds, originalVerts, verts); + } + + PX_COMPILE_TIME_ASSERT(sizeof(Convex) == sizeof(ShrunkConvex)); + + }; + +} + +} + +#endif diff --git a/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexUtilsInternal.cpp b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexUtilsInternal.cpp new file mode 100644 index 00000000..e7b6109f --- /dev/null +++ b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexUtilsInternal.cpp @@ -0,0 +1,78 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#include "GuConvexUtilsInternal.h" + +#include "foundation/PxBounds3.h" +#include "CmScaling.h" +#include "GuBoxConversion.h" +#include "PxConvexMeshGeometry.h" +#include "GuConvexMesh.h" + +using namespace physx; +using namespace Gu; + +void Gu::computeHullOBB(Box& hullOBB, const PxBounds3& hullAABB, float offset, + const Cm::Matrix34& convexPose, + const Cm::Matrix34& meshPose, const Cm::FastVertex2ShapeScaling& meshScaling, bool idtScaleMesh) +{ + // transform bounds = mesh space + Cm::Matrix34 m0to1 = meshPose.transformTranspose(convexPose); + + hullOBB.extents = hullAABB.getExtents() + PxVec3(offset); + hullOBB.center = m0to1.transform(hullAABB.getCenter()); + hullOBB.rot = m0to1.m; + + if(!idtScaleMesh) + meshScaling.transformQueryBounds(hullOBB.center, hullOBB.extents, hullOBB.rot); +} + +void Gu::computeVertexSpaceOBB(Box& dst, const Box& src, const PxTransform& meshPose, const PxMeshScale& meshScale) +{ + // AP scaffold failure in x64 debug in GuConvexUtilsInternal.cpp + //PX_ASSERT("Performance warning - this path shouldn't execute for identity mesh scale." && !meshScale.isIdentity()); + + dst = transform(meshScale.getInverse() * Cm::Matrix34(meshPose.getInverse()), src); +} + +void Gu::computeOBBAroundConvex( + Box& obb, const PxConvexMeshGeometry& convexGeom, const PxConvexMesh* cm, const PxTransform& convexPose) +{ + const CenterExtents& aabb = static_cast<const Gu::ConvexMesh*>(cm)->getLocalBoundsFast(); + + if(convexGeom.scale.isIdentity()) + { + const PxMat33 m(convexPose.q); + obb = Gu::Box(m.transform(aabb.mCenter) + convexPose.p, aabb.mExtents, m); + } + else + { + obb = transform(Cm::Matrix34(convexPose) * convexGeom.scale.toMat33(), Box(aabb.mCenter, aabb.mExtents, PxMat33(PxIdentity))); + } +} diff --git a/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexUtilsInternal.h b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexUtilsInternal.h new file mode 100644 index 00000000..533fa956 --- /dev/null +++ b/PhysX_3.4/Source/GeomUtils/src/convex/GuConvexUtilsInternal.h @@ -0,0 +1,67 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef GU_CONVEX_UTILS_INTERNALS_H +#define GU_CONVEX_UTILS_INTERNALS_H + +#include "PxPhysXCommonConfig.h" +#include "CmPhysXCommon.h" + +namespace physx +{ +class PxMeshScale; +class PxConvexMeshGeometry; +class PxConvexMesh; + +namespace Cm +{ + class Matrix34; + class FastVertex2ShapeScaling; +} + +namespace Gu +{ + class Box; + + void computeHullOBB( + Gu::Box& hullOBB, const PxBounds3& hullAABB, float offset, const Cm::Matrix34& world0, + const Cm::Matrix34& world1, const Cm::FastVertex2ShapeScaling& meshScaling, bool idtScaleMesh); + + // src = input + // computes a box in vertex space (including skewed scale) from src world box + void computeVertexSpaceOBB(Gu::Box& dst, const Gu::Box& src, const PxTransform& meshPose, const PxMeshScale& meshScale); + + PX_PHYSX_COMMON_API void computeOBBAroundConvex( + Gu::Box& obb, const PxConvexMeshGeometry& convexGeom, const PxConvexMesh* cm, const PxTransform& convexPose); + +} // namespace Gu + +} + +#endif diff --git a/PhysX_3.4/Source/GeomUtils/src/convex/GuCubeIndex.h b/PhysX_3.4/Source/GeomUtils/src/convex/GuCubeIndex.h new file mode 100644 index 00000000..dad4f7d2 --- /dev/null +++ b/PhysX_3.4/Source/GeomUtils/src/convex/GuCubeIndex.h @@ -0,0 +1,155 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef GU_CUBE_INDEX_H +#define GU_CUBE_INDEX_H + +#include "foundation/PxVec3.h" +#include "CmPhysXCommon.h" +#include "PsFPU.h" + +namespace physx +{ + + enum CubeIndex + { + CUBE_RIGHT, + CUBE_LEFT, + CUBE_TOP, + CUBE_BOTTOM, + CUBE_FRONT, + CUBE_BACK, + + CUBE_FORCE_DWORD = 0x7fffffff + }; + + /* + It's pretty straightforwards in concept (though the execution in hardware is + a bit crufty and complex). You use a 3D texture coord to look up a texel in + a cube map. First you find which of the axis has the largest value (i.e. + X,Y,Z), and then the sign of that axis decides which face you are going to + use. Which is why the faces are called +X, -X, +Y, -Y, +Z, -Z - after their + principle axis. Then you scale the vector so that the largest value is +/-1. + Then use the other two as 2D coords to look up your texel (with a 0.5 scale + & offset). + + For example, vector (0.4, -0.2, -0.5). Largest value is the Z axis, and it's + -ve, so we're reading from the -Z map. Scale so that this Z axis is +/-1, + and you get the vector (0.8, -0.4, -1.0). So now use the other two values to + look up your texel. So we look up texel (0.8, -0.4). The scale & offset move + the -1->+1 range into the usual 0->1 UV range, so we actually look up texel + (0.9, 0.3). The filtering is extremely complex, especially where three maps + meet, but that's a hardware problem :-) + */ + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /** + * Cubemap lookup function. + * + * To transform returned uvs into mapping coordinates : + * u += 1.0f; u *= 0.5f; + * v += 1.0f; v *= 0.5f; + * + * \fn CubemapLookup(const PxVec3& direction, float& u, float& v) + * \param direction [in] a direction vector + * \param u [out] impact coordinate on the unit cube, in [-1,1] + * \param v [out] impact coordinate on the unit cube, in [-1,1] + * \return cubemap texture index + */ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + PX_INLINE CubeIndex CubemapLookup(const PxVec3& direction, float& u, float& v); + + PX_INLINE PxU32 ComputeCubemapOffset(const PxVec3& dir, PxU32 subdiv) + { + float u,v; + const CubeIndex CI = CubemapLookup(dir, u, v); + + // Remap to [0, subdiv[ + const float Coeff = 0.5f * float(subdiv-1); + u += 1.0f; u *= Coeff; + v += 1.0f; v *= Coeff; + + // Compute offset + return PxU32(CI)*(subdiv*subdiv) + PxU32(u)*subdiv + PxU32(v); + } + + + PX_INLINE PxU32 ComputeCubemapNearestOffset(const PxVec3& dir, PxU32 subdiv) + { + float u,v; + const CubeIndex CI = CubemapLookup(dir, u, v); + + // Remap to [0, subdiv] + const float Coeff = 0.5f * float(subdiv-1); + u += 1.0f; u *= Coeff; + v += 1.0f; v *= Coeff; + + // Compute offset + return PxU32(CI)*(subdiv*subdiv) + PxU32(u + 0.5f)*subdiv + PxU32(v + 0.5f); + } + + + PX_INLINE CubeIndex CubemapLookup(const PxVec3& direction, float& u, float& v) + { + const PxU32* binary = reinterpret_cast<const PxU32*>(&direction.x); + + const PxU32 absPx = binary[0] & ~PX_SIGN_BITMASK; + const PxU32 absNy = binary[1] & ~PX_SIGN_BITMASK; + const PxU32 absNz = binary[2] & ~PX_SIGN_BITMASK; + + PxU32 Index1 = 0; //x biggest axis + PxU32 Index2 = 1; + PxU32 Index3 = 2; + if( (absNy > absPx) & (absNy > absNz)) + { + //y biggest + Index2 = 2; + Index3 = 0; + Index1 = 1; + } + else if(absNz > absPx) + { + //z biggest + Index2 = 0; + Index3 = 1; + Index1 = 2; + } + + const PxF32* data = &direction.x; + const float Coeff = 1.0f / fabsf(data[Index1]); + u = data[Index2] * Coeff; + v = data[Index3] * Coeff; + + const PxU32 Sign = binary[Index1]>>31; + return CubeIndex(Sign|(Index1+Index1)); + } + +} + +#endif diff --git a/PhysX_3.4/Source/GeomUtils/src/convex/GuHillClimbing.cpp b/PhysX_3.4/Source/GeomUtils/src/convex/GuHillClimbing.cpp new file mode 100644 index 00000000..c945385f --- /dev/null +++ b/PhysX_3.4/Source/GeomUtils/src/convex/GuHillClimbing.cpp @@ -0,0 +1,96 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#include "foundation/PxVec3.h" +#include "foundation/PxAssert.h" +#include "PsUserAllocated.h" +#include "CmPhysXCommon.h" +#include "GuHillClimbing.h" +#include "GuBigConvexData2.h" + +namespace physx +{ + +void localSearch(PxU32& id, const PxVec3& dir, const PxVec3* verts, const Gu::BigConvexRawData* val) +{ + // WARNING: there is a problem on x86 with a naive version of this code, where truncation + // of values from 80 bits to 32 bits as they're stored in memory means that iteratively moving to + // an adjacent vertex of greater support can go into an infinite loop. So we use a version which + // never vists a version twice. Note - this might not be enough for GJK, since local + // termination of the support function might not be enough to ensure convergence of GJK itself. + + // if we got here, we'd better have vertices and valencies + PX_ASSERT(verts && val); + + class TinyBitMap + { + public: + PxU32 m[8]; + PX_FORCE_INLINE TinyBitMap() { m[0] = m[1] = m[2] = m[3] = m[4] = m[5] = m[6] = m[7] = 0; } + PX_FORCE_INLINE void set(PxU8 v) { m[v>>5] |= 1<<(v&31); } + PX_FORCE_INLINE bool get(PxU8 v) const { return (m[v>>5] & 1<<(v&31)) != 0; } + }; + + TinyBitMap visited; + + const Gu::Valency* Valencies = val->mValencies; + const PxU8* Adj = val->mAdjacentVerts; + + PX_ASSERT(Valencies && Adj); + + // Get the initial value and the initial vertex + float MaxVal = dir.dot(verts[id]); + PxU32 NextVtx = id; + + do + { + PxU16 NbNeighbors = Valencies[NextVtx].mCount; + const PxU8* Run = Adj + Valencies[NextVtx].mOffset; + id = NextVtx; + while(NbNeighbors--) + { + const PxU8 Neighbor = *Run++; + + if(!visited.get(Neighbor)) + { + visited.set(Neighbor); + + const float CurVal = dir.dot(verts[Neighbor]); + + if(CurVal>MaxVal) + { + MaxVal = CurVal; + NextVtx = Neighbor; + } + } + } + } while(NextVtx!=id); +} + +} diff --git a/PhysX_3.4/Source/GeomUtils/src/convex/GuHillClimbing.h b/PhysX_3.4/Source/GeomUtils/src/convex/GuHillClimbing.h new file mode 100644 index 00000000..5eb9d31a --- /dev/null +++ b/PhysX_3.4/Source/GeomUtils/src/convex/GuHillClimbing.h @@ -0,0 +1,46 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef GU_HILL_CLIMBING_H +#define GU_HILL_CLIMBING_H + +#include "Ps.h" +#include "PxPhysXCommonConfig.h" + +namespace physx +{ + namespace Gu + { + struct BigConvexRawData; + } + + void localSearch(PxU32& id, const PxVec3& dir, const PxVec3* verts, const Gu::BigConvexRawData* val); +} + +#endif diff --git a/PhysX_3.4/Source/GeomUtils/src/convex/GuShapeConvex.cpp b/PhysX_3.4/Source/GeomUtils/src/convex/GuShapeConvex.cpp new file mode 100644 index 00000000..606cafab --- /dev/null +++ b/PhysX_3.4/Source/GeomUtils/src/convex/GuShapeConvex.cpp @@ -0,0 +1,516 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#include "GuShapeConvex.h" +#include "GuBigConvexData.h" +#include "GuEdgeListData.h" +#include "GuInternal.h" + +#include "CmMatrix34.h" +#include "GuHillClimbing.h" +#include "PsFPU.h" + +using namespace physx; +using namespace Gu; + +static PX_FORCE_INLINE PxU32 selectClosestPolygon(PxReal& maxDp_, PxU32 numPolygons, const Gu::HullPolygonData* polys, const PxVec3& axis) +{ + float maxDp = polys[0].mPlane.n.dot(axis); + PxU32 closest = 0; + + // Loop through polygons + for(PxU32 i=1; i <numPolygons; i++) + { + // Catch current polygon and test its plane + const PxReal dp = polys[i].mPlane.n.dot(axis); + if(dp>maxDp) + { + maxDp = dp; + closest = i; + } + } + maxDp_ = maxDp; + return closest; +} + +static PxU32 SelectClosestEdgeCB_Convex(const PolygonalData& data, const Cm::FastVertex2ShapeScaling& scaling, const PxVec3& localSpaceDirection) +{ + //vertex1TOShape1Skew is a symmetric matrix. + //it has the property that (vertex1TOShape1Skew * v)|localSpaceDirection == (vertex1TOShape1Skew * localSpaceDirection)|v + const PxVec3 vertexSpaceDirection = scaling * localSpaceDirection; + + const Gu::HullPolygonData* PX_RESTRICT polys = data.mPolygons; + + PxReal maxDp; + // ##might not be needed + PxU32 closest = ::selectClosestPolygon(maxDp, data.mNbPolygons, polys, vertexSpaceDirection); + + // Since the convex is closed, at least some poly must satisfy this + PX_ASSERT(maxDp>=0); + + const PxU32 numEdges = data.mNbEdges; + const PxU8* const edgeToFace = data.mFacesByEdges; + + //Loop through edges + PxU32 closestEdge = 0xffffffff; + PxReal maxDpSq = maxDp * maxDp; + for(PxU32 i=0; i < numEdges; i++) + { + const PxU8 f0 = edgeToFace[i*2]; + const PxU8 f1 = edgeToFace[i*2+1]; + + // unnormalized edge normal + const PxVec3 edgeNormal = polys[f0].mPlane.n + polys[f1].mPlane.n; + const PxReal enMagSq = edgeNormal.magnitudeSquared(); + //Test normal of current edge - squared test is valid if dp and maxDp both >= 0 + const float dp = edgeNormal.dot(vertexSpaceDirection); + if(dp>=0.0f && dp*dp>maxDpSq*enMagSq) + { + maxDpSq = dp*dp/enMagSq; + closestEdge = i; + } + } + + if(closestEdge!=0xffffffff) + { + const PxU8* FBE = edgeToFace; + + const PxU32 f0 = FBE[closestEdge*2]; + const PxU32 f1 = FBE[closestEdge*2+1]; + + const PxReal dp0 = polys[f0].mPlane.n.dot(vertexSpaceDirection); + const PxReal dp1 = polys[f1].mPlane.n.dot(vertexSpaceDirection); + if(dp0>dp1) + closest = f0; + else + closest = f1; + } + return closest; +} + +// Hull projection callback for "small" hulls +static void HullProjectionCB_SmallConvex(const PolygonalData& data, const PxVec3& dir, + const Cm::Matrix34& world, + const Cm::FastVertex2ShapeScaling& scaling, + PxReal& min, PxReal& max) +{ + const PxVec3 localSpaceDirection = world.rotateTranspose(dir); + //vertex1TOShape1Skew is a symmetric matrix. + //it has the property that (vertex1TOShape1Skew * v)|localSpaceDirection == (vertex1TOShape1Skew * localSpaceDirection)|v + const PxVec3 vertexSpaceDirection = scaling * localSpaceDirection; + + // PT: prevents aliasing + PxReal minimum = PX_MAX_REAL; + PxReal maximum = -PX_MAX_REAL; + + //brute-force, localspace + { + const PxVec3* PX_RESTRICT verts = data.mVerts; + PxU32 numVerts = data.mNbVerts; + while(numVerts--) + { + const PxReal dp = (*verts++).dot(vertexSpaceDirection); + minimum = physx::intrinsics::selectMin(minimum, dp); + maximum = physx::intrinsics::selectMax(maximum, dp); + } + + } + + const PxReal offset = world.p.dot(dir); + min = minimum + offset; + max = maximum + offset; +} + +static PxU32 computeNearestOffset(const PxU32 subdiv, const PxVec3& dir) +{ + // ComputeCubemapNearestOffset(const Point& dir, udword subdiv) + + // PT: ok so why exactly was the code duplicated here? + // PxU32 CI = CubemapLookup(dir,u,v) + + PxU32 index; + PxReal coeff; + // find largest axis + PxReal absNx = PxAbs(dir.x); + PxReal absNy = PxAbs(dir.y); + PxReal absNz = PxAbs(dir.z); + + if( absNy > absNx && + absNy > absNz) + { + //y biggest + index = 1; + coeff = 1.0f/absNy; + } + else if(absNz > absNx) + { + index = 2; + coeff = 1.0f/absNz; + } + else + { + index = 0; + coeff = 1.0f/absNx; + } + + union + { + PxU32 aU32; + PxReal aFloat; + } conv; + + conv.aFloat = dir[index]; + PxU32 sign = conv.aU32>>31; + + const PxU32 index2 = Ps::getNextIndex3(index); + const PxU32 index3 = Ps::getNextIndex3(index2); + PxReal u = dir[index2] * coeff; + PxReal v = dir[index3] * coeff; + + PxU32 CI = (sign | (index+index)); + + //Remap to [0, subdiv[ + coeff = 0.5f * PxReal(subdiv-1); + u += 1.0f; u *= coeff; + v += 1.0f; v *= coeff; + + //Round to nearest + PxU32 ui = PxU32(u); + PxU32 vi = PxU32(v); + + PxReal du = u - PxReal(ui); + PxReal dv = v - PxReal(vi); + if(du>0.5f) ui++; + if(dv>0.5f) vi++; + + //Compute offset + return CI*(subdiv*subdiv) + ui*subdiv + vi; +} + +// Hull projection callback for "big" hulls +static void HullProjectionCB_BigConvex(const PolygonalData& data, const PxVec3& dir, const Cm::Matrix34& world, const Cm::FastVertex2ShapeScaling& scaling, PxReal& minimum, PxReal& maximum) +{ + const PxVec3* PX_RESTRICT verts = data.mVerts; + + const PxVec3 localSpaceDirection = world.rotateTranspose(dir); + //vertex1TOShape1Skew is a symmetric matrix. + //it has the property that (vertex1TOShape1Skew * v)|localSpaceDirection == (vertex1TOShape1Skew * localSpaceDirection)|v + const PxVec3 vertexSpaceDirection = scaling * localSpaceDirection; //NB: triangles are always shape 1! eek! + + // This version is better for objects with a lot of vertices + const Gu::BigConvexRawData* bigData = data.mBigData; + PxU32 minID = 0, maxID = 0; + { + const PxU32 offset = computeNearestOffset(bigData->mSubdiv, -vertexSpaceDirection); + minID = bigData->mSamples[offset]; + maxID = bigData->getSamples2()[offset]; + } + + // Do hillclimbing! + localSearch(minID, -vertexSpaceDirection, verts, bigData); + localSearch(maxID, vertexSpaceDirection, verts, bigData); + + const PxReal offset = world.p.dot(dir); + minimum = offset + verts[minID].dot(vertexSpaceDirection); + maximum = offset + verts[maxID].dot(vertexSpaceDirection); + PX_ASSERT(maximum >= minimum); +} + +void Gu::getPolygonalData_Convex(PolygonalData* PX_RESTRICT dst, const Gu::ConvexHullData* PX_RESTRICT src, const Cm::FastVertex2ShapeScaling& scaling) +{ + dst->mCenter = scaling * src->mCenterOfMass; + dst->mNbVerts = src->mNbHullVertices; + dst->mNbPolygons = src->mNbPolygons; + dst->mNbEdges = src->mNbEdges; + dst->mPolygons = src->mPolygons; + dst->mVerts = src->getHullVertices(); + dst->mPolygonVertexRefs = src->getVertexData8(); + dst->mFacesByEdges = src->getFacesByEdges8(); + +// TEST_INTERNAL_OBJECTS + dst->mInternal = src->mInternal; +//~TEST_INTERNAL_OBJECTS + + dst->mBigData = src->mBigConvexRawData; + + // This threshold test doesnt cost much and many customers cook on PC and use this on 360. + // 360 has a much higher threshold than PC(and it makes a big difference) + // PT: the cool thing is that this test is now done once by contact generation call, not once by hull projection + if(!src->mBigConvexRawData) + dst->mProjectHull = HullProjectionCB_SmallConvex; + else + dst->mProjectHull = HullProjectionCB_BigConvex; + dst->mSelectClosestEdgeCB = SelectClosestEdgeCB_Convex; +} + +// Box emulating convex mesh + +// Face0: 0-1-2-3 +// Face1: 1-5-6-2 +// Face2: 5-4-7-6 +// Face3: 4-0-3-7 +// Face4; 3-2-6-7 +// Face5: 4-5-1-0 + +// 7+------+6 0 = --- +// /| /| 1 = +-- +// / | / | 2 = ++- +// / 4+---/--+5 3 = -+- +// 3+------+2 / y z 4 = --+ +// | / | / | / 5 = +-+ +// |/ |/ |/ 6 = +++ +// 0+------+1 *---x 7 = -++ + +static const PxU8 gPxcBoxPolygonData[] = { + 0, 1, 2, 3, + 1, 5, 6, 2, + 5, 4, 7, 6, + 4, 0, 3, 7, + 3, 2, 6, 7, + 4, 5, 1, 0, +}; + +#define INVSQRT2 0.707106781188f //!< 1 / sqrt(2) +static PxVec3 gPxcBoxEdgeNormals[] = +{ + PxVec3(0, -INVSQRT2, -INVSQRT2), // 0-1 + PxVec3(INVSQRT2, 0, -INVSQRT2), // 1-2 + PxVec3(0, INVSQRT2, -INVSQRT2), // 2-3 + PxVec3(-INVSQRT2, 0, -INVSQRT2), // 3-0 + + PxVec3(0, INVSQRT2, INVSQRT2), // 7-6 + PxVec3(INVSQRT2, 0, INVSQRT2), // 6-5 + PxVec3(0, -INVSQRT2, INVSQRT2), // 5-4 + PxVec3(-INVSQRT2, 0, INVSQRT2), // 4-7 + + PxVec3(INVSQRT2, -INVSQRT2, 0), // 1-5 + PxVec3(INVSQRT2, INVSQRT2, 0), // 6-2 + PxVec3(-INVSQRT2, INVSQRT2, 0), // 3-7 + PxVec3(-INVSQRT2, -INVSQRT2, 0) // 4-0 +}; +#undef INVSQRT2 + +// ### needs serious checkings + // Flags(16), Count(16), Offset(32); +static Gu::EdgeDescData gPxcBoxEdgeDesc[] = { + {Gu::PX_EDGE_ACTIVE, 2, 0}, + {Gu::PX_EDGE_ACTIVE, 2, 2}, + {Gu::PX_EDGE_ACTIVE, 2, 4}, + {Gu::PX_EDGE_ACTIVE, 2, 6}, + {Gu::PX_EDGE_ACTIVE, 2, 8}, + {Gu::PX_EDGE_ACTIVE, 2, 10}, + {Gu::PX_EDGE_ACTIVE, 2, 12}, + {Gu::PX_EDGE_ACTIVE, 2, 14}, + {Gu::PX_EDGE_ACTIVE, 2, 16}, + {Gu::PX_EDGE_ACTIVE, 2, 18}, + {Gu::PX_EDGE_ACTIVE, 2, 20}, + {Gu::PX_EDGE_ACTIVE, 2, 22}, +}; + +// ### needs serious checkings +static PxU8 gPxcBoxFaceByEdge[] = { + 0,5, // Edge 0-1 + 0,1, // Edge 1-2 + 0,4, // Edge 2-3 + 0,3, // Edge 3-0 + 2,4, // Edge 7-6 + 1,2, // Edge 6-5 + 2,5, // Edge 5-4 + 2,3, // Edge 4-7 + 1,5, // Edge 1-5 + 1,4, // Edge 6-2 + 3,4, // Edge 3-7 + 3,5, // Edge 4-0 +}; + +static PxU32 SelectClosestEdgeCB_Box(const PolygonalData& data, const Cm::FastVertex2ShapeScaling& scaling, const PxVec3& localDirection) +{ + PX_UNUSED(scaling); + + PxReal maxDp; + // ##might not be needed + PxU32 closest = ::selectClosestPolygon(maxDp, 6, data.mPolygons, localDirection); + + PxU32 numEdges = 12; + const PxVec3* PX_RESTRICT edgeNormals = gPxcBoxEdgeNormals; + + //Loop through edges + PxU32 closestEdge = 0xffffffff; + for(PxU32 i=0; i < numEdges; i++) + { + //Test normal of current edge + const float dp = edgeNormals[i].dot(localDirection); + if(dp>maxDp) + { + maxDp = dp; + closestEdge = i; + } + } + + if(closestEdge!=0xffffffff) + { + const Gu::EdgeDescData* PX_RESTRICT ED = gPxcBoxEdgeDesc; + const PxU8* PX_RESTRICT FBE = gPxcBoxFaceByEdge; + + PX_ASSERT(ED[closestEdge].Count==2); + const PxU32 f0 = FBE[ED[closestEdge].Offset]; + const PxU32 f1 = FBE[ED[closestEdge].Offset+1]; + + const PxReal dp0 = data.mPolygons[f0].mPlane.n.dot(localDirection); + const PxReal dp1 = data.mPolygons[f1].mPlane.n.dot(localDirection); + if(dp0>dp1) + closest = f0; + else + closest = f1; + } + + return closest; +} + +static PX_FORCE_INLINE void projectBox(PxVec3& p, const PxVec3& localDir, const PxVec3& extents) +{ + // PT: the original code didn't have branches or FPU comparisons. Why rewrite it ? +// p.x = (localDir.x >= 0) ? extents.x : -extents.x; +// p.y = (localDir.y >= 0) ? extents.y : -extents.y; +// p.z = (localDir.z >= 0) ? extents.z : -extents.z; + p.x = physx::intrinsics::fsel(localDir.x, extents.x, -extents.x); + p.y = physx::intrinsics::fsel(localDir.y, extents.y, -extents.y); + p.z = physx::intrinsics::fsel(localDir.z, extents.z, -extents.z); +} + +static void HullProjectionCB_Box(const PolygonalData& data, const PxVec3& dir, const Cm::Matrix34& world, const Cm::FastVertex2ShapeScaling& scaling, PxReal& minimum, PxReal& maximum) +{ + PX_UNUSED(scaling); + + const PxVec3 localDir = world.rotateTranspose(dir); + + PxVec3 p; + projectBox(p, localDir, *data.mHalfSide); + + const PxReal offset = world.p.dot(dir); + const PxReal tmp = p.dot(localDir); + maximum = offset + tmp; + minimum = offset - tmp; +} + +PolygonalBox::PolygonalBox(const PxVec3& halfSide) : mHalfSide(halfSide) +{ + //Precompute the convex data + // 7+------+6 0 = --- + // /| /| 1 = +-- + // / | / | 2 = ++- + // / 4+---/--+5 3 = -+- + // 3+------+2 / y z 4 = --+ + // | / | / | / 5 = +-+ + // |/ |/ |/ 6 = +++ + // 0+------+1 *---x 7 = -++ + + PxVec3 minimum = -mHalfSide; + PxVec3 maximum = mHalfSide; + // Generate 8 corners of the bbox + mVertices[0] = PxVec3(minimum.x, minimum.y, minimum.z); + mVertices[1] = PxVec3(maximum.x, minimum.y, minimum.z); + mVertices[2] = PxVec3(maximum.x, maximum.y, minimum.z); + mVertices[3] = PxVec3(minimum.x, maximum.y, minimum.z); + mVertices[4] = PxVec3(minimum.x, minimum.y, maximum.z); + mVertices[5] = PxVec3(maximum.x, minimum.y, maximum.z); + mVertices[6] = PxVec3(maximum.x, maximum.y, maximum.z); + mVertices[7] = PxVec3(minimum.x, maximum.y, maximum.z); + + //Setup the polygons + for(PxU8 i=0; i < 6; i++) + { + mPolygons[i].mNbVerts = 4; + mPolygons[i].mVRef8 = PxU16(i*4); + } + + // ### planes needs *very* careful checks + // X axis + mPolygons[1].mPlane.n = PxVec3(1.0f, 0.0f, 0.0f); + mPolygons[1].mPlane.d = -mHalfSide.x; + mPolygons[3].mPlane.n = PxVec3(-1.0f, 0.0f, 0.0f); + mPolygons[3].mPlane.d = -mHalfSide.x; + + mPolygons[1].mMinIndex = 0; + mPolygons[3].mMinIndex = 1; + +// mPolygons[1].mMinObsolete = -mHalfSide.x; +// mPolygons[3].mMinObsolete = -mHalfSide.x; + + PX_ASSERT(mPolygons[1].getMin(mVertices) == -mHalfSide.x); + PX_ASSERT(mPolygons[3].getMin(mVertices) == -mHalfSide.x); + + + // Y axis + mPolygons[4].mPlane.n = PxVec3(0.f, 1.0f, 0.0f); + mPolygons[4].mPlane.d = -mHalfSide.y; + mPolygons[5].mPlane.n = PxVec3(0.0f, -1.0f, 0.0f); + mPolygons[5].mPlane.d = -mHalfSide.y; + + mPolygons[4].mMinIndex = 0; + mPolygons[5].mMinIndex = 2; +// mPolygons[4].mMinObsolete = -mHalfSide.y; +// mPolygons[5].mMinObsolete = -mHalfSide.y; + + PX_ASSERT(mPolygons[4].getMin(mVertices) == -mHalfSide.y); + PX_ASSERT(mPolygons[5].getMin(mVertices) == -mHalfSide.y); + + // Z axis + mPolygons[2].mPlane.n = PxVec3(0.f, 0.0f, 1.0f); + mPolygons[2].mPlane.d = -mHalfSide.z; + mPolygons[0].mPlane.n = PxVec3(0.0f, 0.0f, -1.0f); + mPolygons[0].mPlane.d = -mHalfSide.z; + + mPolygons[2].mMinIndex = 0; + mPolygons[0].mMinIndex = 4; +// mPolygons[2].mMinObsolete = -mHalfSide.z; +// mPolygons[0].mMinObsolete = -mHalfSide.z; + PX_ASSERT(mPolygons[2].getMin(mVertices) == -mHalfSide.z); + PX_ASSERT(mPolygons[0].getMin(mVertices) == -mHalfSide.z); +} + +void PolygonalBox::getPolygonalData(PolygonalData* PX_RESTRICT dst) const +{ + dst->mCenter = PxVec3(0.0f, 0.0f, 0.0f); + dst->mNbVerts = 8; + dst->mNbPolygons = 6; + dst->mPolygons = mPolygons; + dst->mNbEdges = 0; + dst->mVerts = mVertices; + dst->mPolygonVertexRefs = gPxcBoxPolygonData; + dst->mFacesByEdges = NULL; + dst->mInternal.mRadius = 0.0f; + dst->mInternal.mExtents[0] = 0.0f; + dst->mInternal.mExtents[1] = 0.0f; + dst->mInternal.mExtents[2] = 0.0f; +// dst->mBigData = NULL; + dst->mHalfSide = &mHalfSide; + dst->mProjectHull = HullProjectionCB_Box; + dst->mSelectClosestEdgeCB = SelectClosestEdgeCB_Box; +} diff --git a/PhysX_3.4/Source/GeomUtils/src/convex/GuShapeConvex.h b/PhysX_3.4/Source/GeomUtils/src/convex/GuShapeConvex.h new file mode 100644 index 00000000..9906caf0 --- /dev/null +++ b/PhysX_3.4/Source/GeomUtils/src/convex/GuShapeConvex.h @@ -0,0 +1,100 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef GU_SHAPECONVEX_H +#define GU_SHAPECONVEX_H + +#include "GuConvexMeshData.h" +#include "CmScaling.h" + +namespace physx +{ +namespace Gu +{ + struct PolygonalData; + typedef void (*HullPrefetchCB) (PxU32 numVerts, const PxVec3* PX_RESTRICT verts); + typedef void (*HullProjectionCB) (const PolygonalData& data, const PxVec3& dir, const Cm::Matrix34& world2hull, const Cm::FastVertex2ShapeScaling& scaling, PxReal& minimum, PxReal& maximum); + typedef PxU32 (*SelectClosestEdgeCB) (const PolygonalData& data, const Cm::FastVertex2ShapeScaling& scaling, const PxVec3& localDirection); + + struct PolygonalData + { + // Data + PxVec3 mCenter; + PxU32 mNbVerts; + PxU32 mNbPolygons; + PxU32 mNbEdges; + const Gu::HullPolygonData* mPolygons; + const PxVec3* mVerts; + const PxU8* mPolygonVertexRefs; + const PxU8* mFacesByEdges; + const PxU16* mVerticesByEdges; + + Gu::InternalObjectsData mInternal; + union + { + const Gu::BigConvexRawData* mBigData; // Only for big convexes + const PxVec3* mHalfSide; // Only for boxes + }; + + // Code + HullProjectionCB mProjectHull; + SelectClosestEdgeCB mSelectClosestEdgeCB; + + PX_FORCE_INLINE const PxU8* getPolygonVertexRefs(const Gu::HullPolygonData& poly) const + { + return mPolygonVertexRefs + poly.mVRef8; + } + }; + +#if PX_VC + #pragma warning(push) + #pragma warning( disable : 4251 ) // class needs to have dll-interface to be used by clients of class +#endif + class PX_PHYSX_COMMON_API PolygonalBox + { + public: + PolygonalBox(const PxVec3& halfSide); + + void getPolygonalData(PolygonalData* PX_RESTRICT dst) const; + + const PxVec3& mHalfSide; + PxVec3 mVertices[8]; + Gu::HullPolygonData mPolygons[6]; + private: + PolygonalBox& operator=(const PolygonalBox&); + }; +#if PX_VC + #pragma warning(pop) +#endif + + void getPolygonalData_Convex(PolygonalData* PX_RESTRICT dst, const Gu::ConvexHullData* PX_RESTRICT src, const Cm::FastVertex2ShapeScaling& scaling); +} +} + +#endif |