diff --git a/Gems/EMotionFX/Code/MCore/Source/PlaneEq.cpp b/Gems/EMotionFX/Code/MCore/Source/PlaneEq.cpp deleted file mode 100644 index fd64974fb1..0000000000 --- a/Gems/EMotionFX/Code/MCore/Source/PlaneEq.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -// include required headers -#include "PlaneEq.h" - -namespace MCore -{ - // clip points against the plane - bool PlaneEq::Clip(const AZStd::vector& pointsIn, AZStd::vector& pointsOut) const - { - size_t numPoints = pointsIn.size(); - - MCORE_ASSERT(&pointsIn != &pointsOut); - MCORE_ASSERT(numPoints >= 2); - - size_t vert1 = numPoints - 1; - float firstDist = CalcDistanceTo(pointsIn[vert1]); - float nextDist = firstDist; - bool firstIn = (firstDist >= 0.0f); - bool nextIn = firstIn; - - pointsOut.clear(); - - if (numPoints == 2) - { - numPoints = 1; - } - - for (int32 vert2 = 0; vert2 < numPoints; vert2++) - { - float dist = nextDist; - bool in = nextIn; - - nextDist = CalcDistanceTo(pointsIn[vert2]); - nextIn = (nextDist >= 0.0f); - - if (in) - { - pointsOut.emplace_back(pointsIn[vert1]); - } - - if ((in != nextIn) && (dist != 0.0f) && (nextDist != 0.0f)) - { - AZ::Vector3 dir = (pointsIn[vert2] - pointsIn[vert1]); - - float frac = dist / (dist - nextDist); - if ((frac > 0.0f) && (frac < 1.0f)) - { - pointsOut.emplace_back(pointsIn[vert1] + frac * dir); - } - } - - vert1 = vert2; - } - - //if (numPoints == 1) - // return (pointsOut.GetLength() > 1); - - return (pointsOut.size() > 1); - } - - - // clip a set of vectors to this plane - bool PlaneEq::Clip(AZStd::vector& points) const - { - AZStd::vector pointsOut; - if (Clip(points, pointsOut)) - { - points = pointsOut; - return true; - } - - return false; - } -} // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/PlaneEq.h b/Gems/EMotionFX/Code/MCore/Source/PlaneEq.h index df8738a1ee..3c8954a29a 100644 --- a/Gems/EMotionFX/Code/MCore/Source/PlaneEq.h +++ b/Gems/EMotionFX/Code/MCore/Source/PlaneEq.h @@ -147,43 +147,6 @@ namespace MCore */ MCORE_INLINE float GetDist() const { return m_dist; } - /** - * Checks if a given axis aligned bounding box (AABB) is partially above (aka in front) this plane or not. - * The Frustum class uses this method to check if a box is partially inside a the frustum or not. - * @param box The axis aligned bounding box to perform the test with. - * @result Returns true when 'box' is partially (or completely) above the plane or not. - */ - MCORE_INLINE bool PartiallyAbove(const AABB& box) const; - - /** - * Check if a given axis aligned bounding box (AABB) is completely above (aka in front) this plane or not. - * The Frustum class uses this method to check if a box is completely inside a the frustum or not. - * @param box The axis aligned bounding box to perform the test with. - * @result Returns true when 'box' is completely above the plane or not. - */ - MCORE_INLINE bool CompletelyAbove(const AABB& box) const; - - /** - * Clips a set of 3D points to this plane. - * Actually these are not just points, but edges. The edges go from point 0 to 1, from 1 to 2, etc. - * Beware that the clipped number of points can be higher as the ones you input to this method. - * This method can be used to pretty easily clip polygon data against the plane. - * @param pointsIn The array of points (and edges) to be clipped to the planes. - * @param pointsOut The array of clipped points (and edges). Note that (pointsOut.GetLength() > pointsIn.GetLength()) can be true. - * @result Returns true when the points have been clipped. False is returned when the clipping resulted in 0 output points. - */ - bool Clip(const AZStd::vector& pointsIn, AZStd::vector& pointsOut) const; - - /** - * Clip a set of 3D points to this plane. - * Actually these are not just points, but edges. The edges go from point 0 to 1, from 1 to 2, etc. - * Beware that the clipped number of points can be higher as the ones you input to this method. - * This method can be used to pretty easily clip polygon data against the plane. - * @param points The set of points (or edges) to clip. When done, points contains the clipped points. - * @result Returns true when the points have been clipped. False is returned when the clipping resulted in 0 points. In that last case 'points' won't be effected and contains just the original input points. - */ - bool Clip(AZStd::vector& points) const; - /** * Project a vector onto the plane. * @param vectorToProject The vector you wish to project onto the plane. @@ -197,6 +160,4 @@ namespace MCore float m_dist; /**< The D in the plane equation (Ax + By + Cz + D = 0). */ }; - // include the inline code -#include "PlaneEq.inl" } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/PlaneEq.inl b/Gems/EMotionFX/Code/MCore/Source/PlaneEq.inl deleted file mode 100644 index 62ccb19551..0000000000 --- a/Gems/EMotionFX/Code/MCore/Source/PlaneEq.inl +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - - -// check if the box is partially above the plane -MCORE_INLINE bool PlaneEq::PartiallyAbove(const AABB& box) const -{ - const AZ::Vector3 minVec = box.GetMin(); - const AZ::Vector3 maxVec = box.GetMax(); - const AZ::Vector3 testPoint(IsNegative(float(m_normal.GetX())) ? minVec.GetX() : maxVec.GetX(), - IsNegative(static_cast(m_normal.GetY())) ? minVec.GetY() : maxVec.GetY(), - IsNegative(static_cast(m_normal.GetZ())) ? minVec.GetZ() : maxVec.GetZ()); - - return IsPositive(m_normal.Dot(testPoint) + m_dist); -} - - -// check if the box is completely above the plane -MCORE_INLINE bool PlaneEq::CompletelyAbove(const AABB& box) const -{ - const AZ::Vector3 minVec = box.GetMin(); - const AZ::Vector3 maxVec = box.GetMax(); - const AZ::Vector3 testPoint(IsPositive(m_normal.GetX()) ? minVec.GetX() : maxVec.GetX(), - IsPositive(m_normal.GetY()) ? minVec.GetY() : maxVec.GetY(), - IsPositive(m_normal.GetZ()) ? minVec.GetZ() : maxVec.GetZ()); - - return IsPositive(m_normal.Dot(testPoint) + m_dist); -} diff --git a/Gems/EMotionFX/Code/MCore/Source/TriangleListOptimizer.h b/Gems/EMotionFX/Code/MCore/Source/TriangleListOptimizer.h deleted file mode 100644 index 38e5df8de4..0000000000 --- a/Gems/EMotionFX/Code/MCore/Source/TriangleListOptimizer.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include -#include - -namespace MCore -{ - /** - * The triangle list optimizer. - * This can be used to improve cache efficiency. It reorders the index buffers to maximize the number of cache hits. - */ - template - class TriangleListOptimizer - { - public: - /** - * The constructor. - * @param numCacheEntries The cache size in number of elements. Smaller values often result in better optimizations. - */ - TriangleListOptimizer(size_t numCacheEntries = 8); - - /** - * Optimizes an index buffer. - * This will modify the input triangle list index buffer. - * Each triangle needs three indices. - * @param triangleList The index buffer. - * @param numIndices The number of indices inside the specified index buffer. - */ - void OptimizeIndexBuffer(IndexType* triangleList, size_t numIndices); - - /** - * Calculate the number of cache hits that the a given triange list would get. - * Higher values will be better than lower values. - * @param triangleList The index buffer, with three indices per triangle. - * @param numIndices The number of indices. - * @result The number of cache hits. - */ - size_t CalcNumCacheHits(IndexType* triangleList, size_t numIndices); - - private: - AZStd::vector m_entries{}; - size_t m_numUsedEntries = 0; /**< The number of used cache entries. */ - size_t m_oldestEntry = 0; /**< The index to the oldest entry, which will be overwritten first when the cache is full. */ - - void Flush(); - - /** - * Calculate the number of cache hits for a given triangle. - * @param indexA The first vertex index. - * @param indexB The second vertex index. - * @param indexC The third vertex index. - * @result The number of cache hits that this triangle would give. - */ - size_t CalcNumCacheHits(IndexType indexA, IndexType indexB, IndexType indexC) const; - - /** - * Add an index value to the cache. - * @param vertexIndex The vertex index value. - */ - void AddToCache(IndexType vertexIndex); - }; - - template - TriangleListOptimizer::TriangleListOptimizer(size_t numCacheEntries) - { - // We never push more items than this capacity. The vector stores the - // max number of entries for us in its capacity() method. - m_entries.set_capacity(numCacheEntries); - } - - template - void TriangleListOptimizer::OptimizeIndexBuffer(IndexType* triangleList, size_t numIndices) - { - Flush(); - - // create a temporary buffer - AZStd::vector newBuffer(numIndices); - size_t maxIndices = numIndices; - - // for all triangles in the triangle list - for (size_t f = 0; f < numIndices; f += 3) - { - size_t mostEfficient = 0; - size_t mostHits = 0; - - for (size_t i = 0; i < maxIndices; i += 3) - { - // get the triangle indices - const IndexType indexA = triangleList[i]; - const IndexType indexB = triangleList[i + 1]; - const IndexType indexC = triangleList[i + 2]; - - // calculate how many hits this triangle would give - size_t numHits = CalcNumCacheHits(indexA, indexB, indexC); - - // if the number of hits is the maximum hits we can score, use this triangle - if (numHits == 3) - { - mostHits = numHits; - mostEfficient = i; - break; - } - - // check if this gives more hits than any other triangle we tested before - if (numHits > mostHits) - { - mostHits = numHits; - mostEfficient = i; - } - } - - // insert the triangle that gave most cache hits to the new triangle list - AddToCache(triangleList[mostEfficient]); - AddToCache(triangleList[mostEfficient + 1]); - AddToCache(triangleList[mostEfficient + 2]); - newBuffer[f] = triangleList[mostEfficient]; - newBuffer[f + 1] = triangleList[mostEfficient + 1]; - newBuffer[f + 2] = triangleList[mostEfficient + 2]; - - // remove the triangle from the old list, so that we don't test it anymore next time, since we already inserted it inside the new optimized list - AZStd::move( - /*input first*/ triangleList + mostEfficient + 3, - /*input last*/ triangleList + maxIndices, - /*output first*/ triangleList + mostEfficient); - - // we need to test one less triangle next time, since we just added one of the triangles to the new list - // so there is one less left - maxIndices -= 3; - } - - // copy the results - AZStd::copy(begin(newBuffer), end(newBuffer), triangleList); - } - - // calculate the number of cache hits - template - size_t TriangleListOptimizer::CalcNumCacheHits(IndexType* triangleList, size_t numIndices) - { - // clear the cache - Flush(); - - size_t totalHits = 0; - - // for all triangles in the triangle list - for (size_t f = 0; f < numIndices; f += 3) - { - const IndexType indexA = triangleList[f]; - const IndexType indexB = triangleList[f + 1]; - const IndexType indexC = triangleList[f + 2]; - - totalHits += CalcNumCacheHits(indexA, indexB, indexC); - - AddToCache(indexA); - AddToCache(indexB); - AddToCache(indexC); - } - - return totalHits; - } - - template - void TriangleListOptimizer::Flush() - { - m_numUsedEntries = 0; - m_oldestEntry = 0; - m_entries.clear(); - } - - // calculate the number of cache hits for a triangle - template - size_t TriangleListOptimizer::CalcNumCacheHits(IndexType indexA, IndexType indexB, IndexType indexC) const - { - size_t total = 0; - - // check all cache entries - for (IndexType entryValue : m_entries) - { - if (entryValue == indexA || entryValue == indexB || entryValue == indexC) - { - total++; - } - if (total == 3) - { - break; - } - } - - return total; - } - - // get a value from the cache - template - void TriangleListOptimizer::AddToCache(IndexType vertexIndex) - { - // check if this entry is already in the cache, if so we have a cache hit and can quit - const auto entryIt = AZStd::find(m_entries.begin(), m_entries.end(), vertexIndex); - if (entryIt != m_entries.end()) - { - return; - } - - // the entry is not inside the cache and the cache is not full yet, we can simply insert the cache entry and return - if (m_numUsedEntries < m_entries.capacity()) - { - m_entries.emplace_back(vertexIndex); - ++m_numUsedEntries; - return; - } - - // the cache is full, remove one of the entries - // since we simulate a FIFO cache, we have to remove the oldest entry - m_entries[m_oldestEntry] = vertexIndex; - ++m_oldestEntry %= m_entries.capacity(); - } -} // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/mcore_files.cmake b/Gems/EMotionFX/Code/MCore/mcore_files.cmake index c1203cb72e..7468b4f60d 100644 --- a/Gems/EMotionFX/Code/MCore/mcore_files.cmake +++ b/Gems/EMotionFX/Code/MCore/mcore_files.cmake @@ -91,9 +91,7 @@ set(FILES Source/MemoryTracker.cpp Source/MemoryTracker.h Source/MultiThreadManager.h - Source/PlaneEq.cpp Source/PlaneEq.h - Source/PlaneEq.inl Source/Random.cpp Source/Random.h Source/Ray.cpp @@ -109,6 +107,5 @@ set(FILES Source/StringIdPool.h Source/ReflectionSerializer.cpp Source/ReflectionSerializer.h - Source/TriangleListOptimizer.h Source/Vector.h )