diff options
Diffstat (limited to 'sdk/extensions/authoringCommon/source/NvBlastExtAuthoringMeshImpl.cpp')
| -rw-r--r-- | sdk/extensions/authoringCommon/source/NvBlastExtAuthoringMeshImpl.cpp | 358 |
1 files changed, 358 insertions, 0 deletions
diff --git a/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringMeshImpl.cpp b/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringMeshImpl.cpp new file mode 100644 index 0000000..f0c9a84 --- /dev/null +++ b/sdk/extensions/authoringCommon/source/NvBlastExtAuthoringMeshImpl.cpp @@ -0,0 +1,358 @@ +// 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) 2016-2018 NVIDIA Corporation. All rights reserved. + +#define _CRT_SECURE_NO_WARNINGS + +#include "NvBlastExtAuthoringMeshImpl.h" +#include "NvBlastExtAuthoringTypes.h" +#include <NvBlastAssert.h> +#include "PxMath.h" +#include <cmath> +#include <string.h> +#include <vector> +#include <algorithm> + +using physx::PxVec2; +using physx::PxVec3; +using physx::PxBounds3; + + +namespace Nv +{ +namespace Blast +{ + +MeshImpl::MeshImpl(const PxVec3* position, const PxVec3* normals, const PxVec2* uv, uint32_t verticesCount, const uint32_t* indices, uint32_t indicesCount) +{ + + mVertices.resize(verticesCount); + for (uint32_t i = 0; i < mVertices.size(); ++i) + { + mVertices[i].p = position[i]; + } + if (normals != 0) + { + for (uint32_t i = 0; i < mVertices.size(); ++i) + { + mVertices[i].n = normals[i]; + } + + } + else + { + for (uint32_t i = 0; i < mVertices.size(); ++i) + { + mVertices[i].n = PxVec3(0, 0, 0); + } + } + if (uv != 0) + { + for (uint32_t i = 0; i < mVertices.size(); ++i) + { + mVertices[i].uv[0] = uv[i]; + } + } + else + { + for (uint32_t i = 0; i < mVertices.size(); ++i) + { + mVertices[i].uv[0] = PxVec2(0, 0); + } + } + mEdges.resize(indicesCount); + mFacets.resize(indicesCount / 3); + + + int32_t facetId = 0; + for (uint32_t i = 0; i < indicesCount; i += 3) + { + mEdges[i].s = indices[i]; + mEdges[i].e = indices[i + 1]; + + mEdges[i + 1].s = indices[i + 1]; + mEdges[i + 1].e = indices[i + 2]; + + mEdges[i + 2].s = indices[i + 2]; + mEdges[i + 2].e = indices[i]; + mFacets[facetId].firstEdgeNumber = i; + mFacets[facetId].edgesCount = 3; + mFacets[facetId].materialId = 0; + //Unassigned for now + mFacets[facetId].smoothingGroup = -1; + facetId++; + } + recalculateBoundingBox(); +} + +MeshImpl::MeshImpl(const Vertex* vertices, const Edge* edges, const Facet* facets, uint32_t posCount, uint32_t edgesCount, uint32_t facetsCount) +{ + mVertices.resize(posCount); + mEdges.resize(edgesCount); + mFacets.resize(facetsCount); + + memcpy(mVertices.data(), vertices, sizeof(Vertex) * posCount); + memcpy(mEdges.data(), edges, sizeof(Edge) * edgesCount); + memcpy(mFacets.data(), facets, sizeof(Facet) * facetsCount); + recalculateBoundingBox(); +} + +MeshImpl::MeshImpl(const Vertex* vertices, uint32_t count) +{ + mVertices = std::vector<Vertex>(vertices, vertices + count); + mEdges.resize(count); + mFacets.resize(count / 3); + uint32_t vp = 0; + for (uint32_t i = 0; i < count; i += 3) + { + mEdges[i].s = vp; + mEdges[i].e = vp + 1; + + mEdges[i + 1].s = vp + 1; + mEdges[i + 1].e = vp + 2; + + mEdges[i + 2].s = vp + 2; + mEdges[i + 2].e = vp; + vp += 3; + } + for (uint32_t i = 0; i < count / 3; ++i) + { + mFacets[i].edgesCount = 3; + mFacets[i].firstEdgeNumber = i * 3; + } + recalculateBoundingBox(); +} + +MeshImpl::MeshImpl(const Vertex* vertices, uint32_t count, uint32_t* indices, uint32_t indexCount, void* materials, uint32_t materialStride) +{ + mVertices = std::vector<Vertex>(vertices, vertices + count); + mEdges.resize(indexCount); + mFacets.resize(indexCount / 3); + + for (uint32_t i = 0; i < indexCount; i += 3) + { + mEdges[i].s = indices[i]; + mEdges[i].e = indices[i + 1]; + + mEdges[i + 1].s = indices[i + 1]; + mEdges[i + 1].e = indices[i + 2]; + + mEdges[i + 2].s = indices[i + 2]; + mEdges[i + 2].e = indices[i]; + } + for (uint32_t i = 0; i < indexCount / 3; ++i) + { + mFacets[i].edgesCount = 3; + mFacets[i].firstEdgeNumber = i * 3; + mFacets[i].userData = 0; + if (materials != nullptr) + { + mFacets[i].materialId = *(uint32_t*)((uint8_t*)materials + i * materialStride); + } + } + recalculateBoundingBox(); +} + + + +float MeshImpl::getMeshVolume() +{ + /** + Check if mesh boundary consist only of triangles + */ + for (uint32_t i = 0; i < mFacets.size(); ++i) + { + if (mFacets[i].edgesCount != 3) + { + return 0.0f; + } + } + + float volume = 0; + for (uint32_t i = 0; i < mFacets.size(); ++i) + { + int32_t offset = mFacets[i].firstEdgeNumber; + PxVec3& a = mVertices[mEdges[offset].s].p; + PxVec3& b = mVertices[mEdges[offset + 1].s].p; + PxVec3& c = mVertices[mEdges[offset + 2].s].p; + + volume += (a.x * b.y * c.z - a.x * b.z * c.y - a.y * b.x * c.z + a.y * b.z * c.x + a.z * b.x * c.y - a.z * b.y * c.x); + } + return (1.0f / 6.0f) * std::abs(volume); +} + + +uint32_t MeshImpl::getFacetCount() const +{ + return static_cast<uint32_t>(mFacets.size()); +} + +Vertex* MeshImpl::getVerticesWritable() +{ + return mVertices.data(); +} + +Edge* MeshImpl::getEdgesWritable() +{ + return mEdges.data(); +} + +const Vertex* MeshImpl::getVertices() const +{ + return mVertices.data(); +} + +const Edge* MeshImpl::getEdges() const +{ + return mEdges.data(); +} + +uint32_t MeshImpl::getEdgesCount() const +{ + return static_cast<uint32_t>(mEdges.size()); +} +uint32_t MeshImpl::getVerticesCount() const +{ + return static_cast<uint32_t>(mVertices.size()); +} +Facet* MeshImpl::getFacetsBufferWritable() +{ + return mFacets.data(); +} +const Facet* MeshImpl::getFacetsBuffer() const +{ + return mFacets.data(); +} +Facet* MeshImpl::getFacetWritable(int32_t facet) +{ + return &mFacets[facet]; +} +const Facet* MeshImpl::getFacet(int32_t facet) const +{ + return &mFacets[facet]; +} + +MeshImpl::~MeshImpl() +{ +} + +void MeshImpl::release() +{ + delete this; +} + +const PxBounds3& MeshImpl::getBoundingBox() const +{ + return mBounds; +} + +PxBounds3& MeshImpl::getBoundingBoxWritable() +{ + return mBounds; +} + + +void MeshImpl::recalculateBoundingBox() +{ + mBounds.setEmpty(); + for (uint32_t i = 0; i < mVertices.size(); ++i) + { + mBounds.include(mVertices[i].p); + } + calcPerFacetBounds(); +} + +const physx::PxBounds3* MeshImpl::getFacetBound(uint32_t index) const +{ + if (mPerFacetBounds.empty()) + { + return nullptr; + } + return &mPerFacetBounds[index]; +} + +void MeshImpl::calcPerFacetBounds() +{ + mPerFacetBounds.resize(mFacets.size()); + + for (uint32_t i = 0; i < mFacets.size(); ++i) + { + auto& fb = mPerFacetBounds[i]; + fb.setEmpty(); + + for (uint32_t v = 0; v < mFacets[i].edgesCount; ++v) + { + fb.include(mVertices[mEdges[mFacets[i].firstEdgeNumber + v].s].p); + fb.include(mVertices[mEdges[mFacets[i].firstEdgeNumber + v].e].p); + } + } +} + +void MeshImpl::setMaterialId(const int32_t* materialId) +{ + if (materialId != nullptr) + { + for (uint32_t i = 0; i < mFacets.size(); ++i) + { + mFacets[i].materialId = *materialId; + ++materialId; + } + } +} + +bool MeshImpl::isValid() const +{ + return mVertices.size() > 0 && mEdges.size() > 0 && mFacets.size() > 0; +} + + +void MeshImpl::replaceMaterialId(int32_t oldMaterialId, int32_t newMaterialId) +{ + for (uint32_t i = 0; i < mFacets.size(); ++i) + { + if (mFacets[i].materialId == oldMaterialId) + { + mFacets[i].materialId = newMaterialId; + } + } +} + +void MeshImpl::setSmoothingGroup(const int32_t* smoothingGroups) +{ + if (smoothingGroups != nullptr) + { + for (uint32_t i = 0; i < mFacets.size(); ++i) + { + mFacets[i].smoothingGroup = *smoothingGroups; + ++smoothingGroups; + } + } +} + + + +} // namespace Blast +} // namespace Nv |