feat: updated engine version to 4.4-rc1
This commit is contained in:
parent
ee00efde1f
commit
21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions
67
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitter.cpp
vendored
Normal file
67
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitter.cpp
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
|
||||
#include <Jolt/TriangleSplitter/TriangleSplitter.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
TriangleSplitter::TriangleSplitter(const VertexList &inVertices, const IndexedTriangleList &inTriangles) :
|
||||
mVertices(inVertices),
|
||||
mTriangles(inTriangles)
|
||||
{
|
||||
mSortedTriangleIdx.resize(inTriangles.size());
|
||||
mCentroids.resize(inTriangles.size());
|
||||
|
||||
for (uint t = 0; t < inTriangles.size(); ++t)
|
||||
{
|
||||
// Initially triangles start unsorted
|
||||
mSortedTriangleIdx[t] = t;
|
||||
|
||||
// Calculate centroid
|
||||
inTriangles[t].GetCentroid(inVertices).StoreFloat3(&mCentroids[t]);
|
||||
}
|
||||
}
|
||||
|
||||
bool TriangleSplitter::SplitInternal(const Range &inTriangles, uint inDimension, float inSplit, Range &outLeft, Range &outRight)
|
||||
{
|
||||
// Divide triangles
|
||||
uint start = inTriangles.mBegin, end = inTriangles.mEnd;
|
||||
while (start < end)
|
||||
{
|
||||
// Search for first element that is on the right hand side of the split plane
|
||||
while (start < end && mCentroids[mSortedTriangleIdx[start]][inDimension] < inSplit)
|
||||
++start;
|
||||
|
||||
// Search for the first element that is on the left hand side of the split plane
|
||||
while (start < end && mCentroids[mSortedTriangleIdx[end - 1]][inDimension] >= inSplit)
|
||||
--end;
|
||||
|
||||
if (start < end)
|
||||
{
|
||||
// Swap the two elements
|
||||
std::swap(mSortedTriangleIdx[start], mSortedTriangleIdx[end - 1]);
|
||||
++start;
|
||||
--end;
|
||||
}
|
||||
}
|
||||
JPH_ASSERT(start == end);
|
||||
|
||||
#ifdef JPH_ENABLE_ASSERTS
|
||||
// Validate division algorithm
|
||||
JPH_ASSERT(inTriangles.mBegin <= start);
|
||||
JPH_ASSERT(start <= inTriangles.mEnd);
|
||||
for (uint i = inTriangles.mBegin; i < start; ++i)
|
||||
JPH_ASSERT(mCentroids[mSortedTriangleIdx[i]][inDimension] < inSplit);
|
||||
for (uint i = start; i < inTriangles.mEnd; ++i)
|
||||
JPH_ASSERT(mCentroids[mSortedTriangleIdx[i]][inDimension] >= inSplit);
|
||||
#endif
|
||||
|
||||
outLeft = Range(inTriangles.mBegin, start);
|
||||
outRight = Range(start, inTriangles.mEnd);
|
||||
return outLeft.Count() > 0 && outRight.Count() > 0;
|
||||
}
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
84
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitter.h
vendored
Normal file
84
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitter.h
vendored
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Jolt/Geometry/IndexedTriangle.h>
|
||||
#include <Jolt/Core/NonCopyable.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
/// A class that splits a triangle list into two parts for building a tree
|
||||
class JPH_EXPORT TriangleSplitter : public NonCopyable
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
TriangleSplitter(const VertexList &inVertices, const IndexedTriangleList &inTriangles);
|
||||
|
||||
/// Virtual destructor
|
||||
virtual ~TriangleSplitter() = default;
|
||||
|
||||
struct Stats
|
||||
{
|
||||
const char * mSplitterName = nullptr;
|
||||
int mLeafSize = 0;
|
||||
};
|
||||
|
||||
/// Get stats of splitter
|
||||
virtual void GetStats(Stats &outStats) const = 0;
|
||||
|
||||
/// Helper struct to indicate triangle range before and after the split
|
||||
struct Range
|
||||
{
|
||||
/// Constructor
|
||||
Range() = default;
|
||||
Range(uint inBegin, uint inEnd) : mBegin(inBegin), mEnd(inEnd) { }
|
||||
|
||||
/// Get number of triangles in range
|
||||
uint Count() const
|
||||
{
|
||||
return mEnd - mBegin;
|
||||
}
|
||||
|
||||
/// Start and end index (end = 1 beyond end)
|
||||
uint mBegin;
|
||||
uint mEnd;
|
||||
};
|
||||
|
||||
/// Range of triangles to start with
|
||||
Range GetInitialRange() const
|
||||
{
|
||||
return Range(0, (uint)mSortedTriangleIdx.size());
|
||||
}
|
||||
|
||||
/// Split triangles into two groups left and right, returns false if no split could be made
|
||||
/// @param inTriangles The range of triangles (in mSortedTriangleIdx) to process
|
||||
/// @param outLeft On return this will contain the ranges for the left subpart. mSortedTriangleIdx may have been shuffled.
|
||||
/// @param outRight On return this will contain the ranges for the right subpart. mSortedTriangleIdx may have been shuffled.
|
||||
/// @return Returns true when a split was found
|
||||
virtual bool Split(const Range &inTriangles, Range &outLeft, Range &outRight) = 0;
|
||||
|
||||
/// Get the list of vertices
|
||||
const VertexList & GetVertices() const
|
||||
{
|
||||
return mVertices;
|
||||
}
|
||||
|
||||
/// Get triangle by index
|
||||
const IndexedTriangle & GetTriangle(uint inIdx) const
|
||||
{
|
||||
return mTriangles[mSortedTriangleIdx[inIdx]];
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Helper function to split triangles based on dimension and split value
|
||||
bool SplitInternal(const Range &inTriangles, uint inDimension, float inSplit, Range &outLeft, Range &outRight);
|
||||
|
||||
const VertexList & mVertices; ///< Vertices of the indexed triangles
|
||||
const IndexedTriangleList & mTriangles; ///< Unsorted triangles
|
||||
Array<Float3> mCentroids; ///< Unsorted centroids of triangles
|
||||
Array<uint> mSortedTriangleIdx; ///< Indices to sort triangles
|
||||
};
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
136
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterBinning.cpp
vendored
Normal file
136
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterBinning.cpp
vendored
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
|
||||
#include <Jolt/TriangleSplitter/TriangleSplitterBinning.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
TriangleSplitterBinning::TriangleSplitterBinning(const VertexList &inVertices, const IndexedTriangleList &inTriangles, uint inMinNumBins, uint inMaxNumBins, uint inNumTrianglesPerBin) :
|
||||
TriangleSplitter(inVertices, inTriangles),
|
||||
mMinNumBins(inMinNumBins),
|
||||
mMaxNumBins(inMaxNumBins),
|
||||
mNumTrianglesPerBin(inNumTrianglesPerBin)
|
||||
{
|
||||
mBins.resize(mMaxNumBins * 3); // mMaxNumBins per dimension
|
||||
}
|
||||
|
||||
bool TriangleSplitterBinning::Split(const Range &inTriangles, Range &outLeft, Range &outRight)
|
||||
{
|
||||
// Calculate bounds for this range
|
||||
AABox centroid_bounds;
|
||||
for (uint t = inTriangles.mBegin; t < inTriangles.mEnd; ++t)
|
||||
centroid_bounds.Encapsulate(Vec3(mCentroids[mSortedTriangleIdx[t]]));
|
||||
|
||||
// Convert bounds to min coordinate and size
|
||||
// Prevent division by zero if one of the dimensions is zero
|
||||
constexpr float cMinSize = 1.0e-5f;
|
||||
Vec3 bounds_min = centroid_bounds.mMin;
|
||||
Vec3 bounds_size = Vec3::sMax(centroid_bounds.mMax - bounds_min, Vec3::sReplicate(cMinSize));
|
||||
|
||||
float best_cp = FLT_MAX;
|
||||
uint best_dim = 0xffffffff;
|
||||
float best_split = 0;
|
||||
|
||||
// Bin in all dimensions
|
||||
uint num_bins = Clamp(inTriangles.Count() / mNumTrianglesPerBin, mMinNumBins, mMaxNumBins);
|
||||
|
||||
// Initialize bins
|
||||
for (uint dim = 0; dim < 3; ++dim)
|
||||
{
|
||||
// Get bounding box size for this dimension
|
||||
float bounds_min_dim = bounds_min[dim];
|
||||
float bounds_size_dim = bounds_size[dim];
|
||||
|
||||
// Get the bins for this dimension
|
||||
Bin *bins_dim = &mBins[num_bins * dim];
|
||||
|
||||
for (uint b = 0; b < num_bins; ++b)
|
||||
{
|
||||
Bin &bin = bins_dim[b];
|
||||
bin.mBounds.SetEmpty();
|
||||
bin.mMinCentroid = bounds_min_dim + bounds_size_dim * (b + 1) / num_bins;
|
||||
bin.mNumTriangles = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Bin all triangles in all dimensions at once
|
||||
for (uint t = inTriangles.mBegin; t < inTriangles.mEnd; ++t)
|
||||
{
|
||||
Vec3 centroid_pos(mCentroids[mSortedTriangleIdx[t]]);
|
||||
|
||||
AABox triangle_bounds = AABox::sFromTriangle(mVertices, GetTriangle(t));
|
||||
|
||||
Vec3 bin_no_f = (centroid_pos - bounds_min) / bounds_size * float(num_bins);
|
||||
UVec4 bin_no = UVec4::sMin(bin_no_f.ToInt(), UVec4::sReplicate(num_bins - 1));
|
||||
|
||||
for (uint dim = 0; dim < 3; ++dim)
|
||||
{
|
||||
// Select bin
|
||||
Bin &bin = mBins[num_bins * dim + bin_no[dim]];
|
||||
|
||||
// Accumulate triangle in bin
|
||||
bin.mBounds.Encapsulate(triangle_bounds);
|
||||
bin.mMinCentroid = min(bin.mMinCentroid, centroid_pos[dim]);
|
||||
bin.mNumTriangles++;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint dim = 0; dim < 3; ++dim)
|
||||
{
|
||||
// Skip axis if too small
|
||||
if (bounds_size[dim] <= cMinSize)
|
||||
continue;
|
||||
|
||||
// Get the bins for this dimension
|
||||
Bin *bins_dim = &mBins[num_bins * dim];
|
||||
|
||||
// Calculate totals left to right
|
||||
AABox prev_bounds;
|
||||
int prev_triangles = 0;
|
||||
for (uint b = 0; b < num_bins; ++b)
|
||||
{
|
||||
Bin &bin = bins_dim[b];
|
||||
bin.mBoundsAccumulatedLeft = prev_bounds; // Don't include this node as we'll take a split on the left side of the bin
|
||||
bin.mNumTrianglesAccumulatedLeft = prev_triangles;
|
||||
prev_bounds.Encapsulate(bin.mBounds);
|
||||
prev_triangles += bin.mNumTriangles;
|
||||
}
|
||||
|
||||
// Calculate totals right to left
|
||||
prev_bounds.SetEmpty();
|
||||
prev_triangles = 0;
|
||||
for (int b = num_bins - 1; b >= 0; --b)
|
||||
{
|
||||
Bin &bin = bins_dim[b];
|
||||
prev_bounds.Encapsulate(bin.mBounds);
|
||||
prev_triangles += bin.mNumTriangles;
|
||||
bin.mBoundsAccumulatedRight = prev_bounds;
|
||||
bin.mNumTrianglesAccumulatedRight = prev_triangles;
|
||||
}
|
||||
|
||||
// Get best splitting plane
|
||||
for (uint b = 1; b < num_bins; ++b) // Start at 1 since selecting bin 0 would result in everything ending up on the right side
|
||||
{
|
||||
// Calculate surface area heuristic and see if it is better than the current best
|
||||
const Bin &bin = bins_dim[b];
|
||||
float cp = bin.mBoundsAccumulatedLeft.GetSurfaceArea() * bin.mNumTrianglesAccumulatedLeft + bin.mBoundsAccumulatedRight.GetSurfaceArea() * bin.mNumTrianglesAccumulatedRight;
|
||||
if (cp < best_cp)
|
||||
{
|
||||
best_cp = cp;
|
||||
best_dim = dim;
|
||||
best_split = bin.mMinCentroid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No split found?
|
||||
if (best_dim == 0xffffffff)
|
||||
return false;
|
||||
|
||||
return SplitInternal(inTriangles, best_dim, best_split, outLeft, outRight);
|
||||
}
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
52
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterBinning.h
vendored
Normal file
52
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterBinning.h
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Jolt/TriangleSplitter/TriangleSplitter.h>
|
||||
#include <Jolt/Geometry/AABox.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
/// Binning splitter approach taken from: Realtime Ray Tracing on GPU with BVH-based Packet Traversal by Johannes Gunther et al.
|
||||
class JPH_EXPORT TriangleSplitterBinning : public TriangleSplitter
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
TriangleSplitterBinning(const VertexList &inVertices, const IndexedTriangleList &inTriangles, uint inMinNumBins = 8, uint inMaxNumBins = 128, uint inNumTrianglesPerBin = 6);
|
||||
|
||||
// See TriangleSplitter::GetStats
|
||||
virtual void GetStats(Stats &outStats) const override
|
||||
{
|
||||
outStats.mSplitterName = "TriangleSplitterBinning";
|
||||
}
|
||||
|
||||
// See TriangleSplitter::Split
|
||||
virtual bool Split(const Range &inTriangles, Range &outLeft, Range &outRight) override;
|
||||
|
||||
private:
|
||||
// Configuration
|
||||
const uint mMinNumBins;
|
||||
const uint mMaxNumBins;
|
||||
const uint mNumTrianglesPerBin;
|
||||
|
||||
struct Bin
|
||||
{
|
||||
// Properties of this bin
|
||||
AABox mBounds;
|
||||
float mMinCentroid;
|
||||
uint mNumTriangles;
|
||||
|
||||
// Accumulated data from left most / right most bin to current (including this bin)
|
||||
AABox mBoundsAccumulatedLeft;
|
||||
AABox mBoundsAccumulatedRight;
|
||||
uint mNumTrianglesAccumulatedLeft;
|
||||
uint mNumTrianglesAccumulatedRight;
|
||||
};
|
||||
|
||||
// Scratch area to store the bins
|
||||
Array<Bin> mBins;
|
||||
};
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
170
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterFixedLeafSize.cpp
vendored
Normal file
170
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterFixedLeafSize.cpp
vendored
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
|
||||
#include <Jolt/TriangleSplitter/TriangleSplitterFixedLeafSize.h>
|
||||
#include <Jolt/TriangleGrouper/TriangleGrouperClosestCentroid.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
TriangleSplitterFixedLeafSize::TriangleSplitterFixedLeafSize(const VertexList &inVertices, const IndexedTriangleList &inTriangles, uint inLeafSize, uint inMinNumBins, uint inMaxNumBins, uint inNumTrianglesPerBin) :
|
||||
TriangleSplitter(inVertices, inTriangles),
|
||||
mLeafSize(inLeafSize),
|
||||
mMinNumBins(inMinNumBins),
|
||||
mMaxNumBins(inMaxNumBins),
|
||||
mNumTrianglesPerBin(inNumTrianglesPerBin)
|
||||
{
|
||||
// Group the triangles
|
||||
TriangleGrouperClosestCentroid grouper;
|
||||
grouper.Group(inVertices, inTriangles, mLeafSize, mSortedTriangleIdx);
|
||||
|
||||
// Pad triangles so that we have a multiple of mLeafSize
|
||||
const uint num_triangles = (uint)inTriangles.size();
|
||||
const uint num_groups = (num_triangles + mLeafSize - 1) / mLeafSize;
|
||||
const uint last_triangle_idx = mSortedTriangleIdx.back();
|
||||
for (uint t = num_triangles, t_end = num_groups * mLeafSize; t < t_end; ++t)
|
||||
mSortedTriangleIdx.push_back(last_triangle_idx);
|
||||
}
|
||||
|
||||
Vec3 TriangleSplitterFixedLeafSize::GetCentroidForGroup(uint inFirstTriangleInGroup)
|
||||
{
|
||||
JPH_ASSERT(inFirstTriangleInGroup % mLeafSize == 0);
|
||||
AABox box;
|
||||
for (uint g = 0; g < mLeafSize; ++g)
|
||||
box.Encapsulate(mVertices, GetTriangle(inFirstTriangleInGroup + g));
|
||||
return box.GetCenter();
|
||||
}
|
||||
|
||||
bool TriangleSplitterFixedLeafSize::Split(const Range &inTriangles, Range &outLeft, Range &outRight)
|
||||
{
|
||||
// Cannot split anything smaller than leaf size
|
||||
JPH_ASSERT(inTriangles.Count() > mLeafSize);
|
||||
JPH_ASSERT(inTriangles.Count() % mLeafSize == 0);
|
||||
|
||||
// Calculate bounds for this range
|
||||
AABox centroid_bounds;
|
||||
for (uint t = inTriangles.mBegin; t < inTriangles.mEnd; t += mLeafSize)
|
||||
centroid_bounds.Encapsulate(GetCentroidForGroup(t));
|
||||
|
||||
float best_cp = FLT_MAX;
|
||||
uint best_dim = 0xffffffff;
|
||||
float best_split = 0;
|
||||
|
||||
// Bin in all dimensions
|
||||
uint num_bins = Clamp(inTriangles.Count() / mNumTrianglesPerBin, mMinNumBins, mMaxNumBins);
|
||||
Array<Bin> bins(num_bins);
|
||||
for (uint dim = 0; dim < 3; ++dim)
|
||||
{
|
||||
float bounds_min = centroid_bounds.mMin[dim];
|
||||
float bounds_size = centroid_bounds.mMax[dim] - bounds_min;
|
||||
|
||||
// Skip axis if too small
|
||||
if (bounds_size < 1.0e-5f)
|
||||
continue;
|
||||
|
||||
// Initialize bins
|
||||
for (uint b = 0; b < num_bins; ++b)
|
||||
{
|
||||
Bin &bin = bins[b];
|
||||
bin.mBounds.SetEmpty();
|
||||
bin.mMinCentroid = bounds_min + bounds_size * (b + 1) / num_bins;
|
||||
bin.mNumTriangles = 0;
|
||||
}
|
||||
|
||||
// Bin all triangles
|
||||
for (uint t = inTriangles.mBegin; t < inTriangles.mEnd; t += mLeafSize)
|
||||
{
|
||||
// Calculate average centroid for group
|
||||
float centroid_pos = GetCentroidForGroup(t)[dim];
|
||||
|
||||
// Select bin
|
||||
uint bin_no = min(uint((centroid_pos - bounds_min) / bounds_size * num_bins), num_bins - 1);
|
||||
Bin &bin = bins[bin_no];
|
||||
|
||||
// Put all triangles of group in same bin
|
||||
for (uint g = 0; g < mLeafSize; ++g)
|
||||
bin.mBounds.Encapsulate(mVertices, GetTriangle(t + g));
|
||||
bin.mMinCentroid = min(bin.mMinCentroid, centroid_pos);
|
||||
bin.mNumTriangles += mLeafSize;
|
||||
}
|
||||
|
||||
// Calculate totals left to right
|
||||
AABox prev_bounds;
|
||||
int prev_triangles = 0;
|
||||
for (uint b = 0; b < num_bins; ++b)
|
||||
{
|
||||
Bin &bin = bins[b];
|
||||
bin.mBoundsAccumulatedLeft = prev_bounds; // Don't include this node as we'll take a split on the left side of the bin
|
||||
bin.mNumTrianglesAccumulatedLeft = prev_triangles;
|
||||
prev_bounds.Encapsulate(bin.mBounds);
|
||||
prev_triangles += bin.mNumTriangles;
|
||||
}
|
||||
|
||||
// Calculate totals right to left
|
||||
prev_bounds.SetEmpty();
|
||||
prev_triangles = 0;
|
||||
for (int b = num_bins - 1; b >= 0; --b)
|
||||
{
|
||||
Bin &bin = bins[b];
|
||||
prev_bounds.Encapsulate(bin.mBounds);
|
||||
prev_triangles += bin.mNumTriangles;
|
||||
bin.mBoundsAccumulatedRight = prev_bounds;
|
||||
bin.mNumTrianglesAccumulatedRight = prev_triangles;
|
||||
}
|
||||
|
||||
// Get best splitting plane
|
||||
for (uint b = 1; b < num_bins; ++b) // Start at 1 since selecting bin 0 would result in everything ending up on the right side
|
||||
{
|
||||
// Calculate surface area heuristic and see if it is better than the current best
|
||||
const Bin &bin = bins[b];
|
||||
float cp = bin.mBoundsAccumulatedLeft.GetSurfaceArea() * bin.mNumTrianglesAccumulatedLeft + bin.mBoundsAccumulatedRight.GetSurfaceArea() * bin.mNumTrianglesAccumulatedRight;
|
||||
if (cp < best_cp)
|
||||
{
|
||||
best_cp = cp;
|
||||
best_dim = dim;
|
||||
best_split = bin.mMinCentroid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No split found?
|
||||
if (best_dim == 0xffffffff)
|
||||
return false;
|
||||
|
||||
// Divide triangles
|
||||
uint start = inTriangles.mBegin, end = inTriangles.mEnd;
|
||||
while (start < end)
|
||||
{
|
||||
// Search for first element that is on the right hand side of the split plane
|
||||
while (start < end && GetCentroidForGroup(start)[best_dim] < best_split)
|
||||
start += mLeafSize;
|
||||
|
||||
// Search for the first element that is on the left hand side of the split plane
|
||||
while (start < end && GetCentroidForGroup(end - mLeafSize)[best_dim] >= best_split)
|
||||
end -= mLeafSize;
|
||||
|
||||
if (start < end)
|
||||
{
|
||||
// Swap the two elements
|
||||
for (uint g = 0; g < mLeafSize; ++g)
|
||||
std::swap(mSortedTriangleIdx[start + g], mSortedTriangleIdx[end - mLeafSize + g]);
|
||||
start += mLeafSize;
|
||||
end -= mLeafSize;
|
||||
}
|
||||
}
|
||||
JPH_ASSERT(start == end);
|
||||
|
||||
// No suitable split found, doing random split in half
|
||||
if (start == inTriangles.mBegin || start == inTriangles.mEnd)
|
||||
start = inTriangles.mBegin + (inTriangles.Count() / mLeafSize + 1) / 2 * mLeafSize;
|
||||
|
||||
outLeft = Range(inTriangles.mBegin, start);
|
||||
outRight = Range(start, inTriangles.mEnd);
|
||||
JPH_ASSERT(outLeft.mEnd > outLeft.mBegin && outRight.mEnd > outRight.mBegin);
|
||||
JPH_ASSERT(outLeft.Count() % mLeafSize == 0 && outRight.Count() % mLeafSize == 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
55
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterFixedLeafSize.h
vendored
Normal file
55
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterFixedLeafSize.h
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Jolt/TriangleSplitter/TriangleSplitter.h>
|
||||
#include <Jolt/Geometry/AABox.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
/// Same as TriangleSplitterBinning, but ensuring that leaves have a fixed amount of triangles
|
||||
/// The resulting tree should be suitable for processing on GPU where we want all threads to process an equal amount of triangles
|
||||
class JPH_EXPORT TriangleSplitterFixedLeafSize : public TriangleSplitter
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
TriangleSplitterFixedLeafSize(const VertexList &inVertices, const IndexedTriangleList &inTriangles, uint inLeafSize, uint inMinNumBins = 8, uint inMaxNumBins = 128, uint inNumTrianglesPerBin = 6);
|
||||
|
||||
// See TriangleSplitter::GetStats
|
||||
virtual void GetStats(Stats &outStats) const override
|
||||
{
|
||||
outStats.mSplitterName = "TriangleSplitterFixedLeafSize";
|
||||
outStats.mLeafSize = mLeafSize;
|
||||
}
|
||||
|
||||
// See TriangleSplitter::Split
|
||||
virtual bool Split(const Range &inTriangles, Range &outLeft, Range &outRight) override;
|
||||
|
||||
private:
|
||||
/// Get centroid for group
|
||||
Vec3 GetCentroidForGroup(uint inFirstTriangleInGroup);
|
||||
|
||||
// Configuration
|
||||
const uint mLeafSize;
|
||||
const uint mMinNumBins;
|
||||
const uint mMaxNumBins;
|
||||
const uint mNumTrianglesPerBin;
|
||||
|
||||
struct Bin
|
||||
{
|
||||
// Properties of this bin
|
||||
AABox mBounds;
|
||||
float mMinCentroid;
|
||||
uint mNumTriangles;
|
||||
|
||||
// Accumulated data from left most / right most bin to current (including this bin)
|
||||
AABox mBoundsAccumulatedLeft;
|
||||
AABox mBoundsAccumulatedRight;
|
||||
uint mNumTrianglesAccumulatedLeft;
|
||||
uint mNumTrianglesAccumulatedRight;
|
||||
};
|
||||
};
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
31
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterLongestAxis.cpp
vendored
Normal file
31
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterLongestAxis.cpp
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
|
||||
#include <Jolt/TriangleSplitter/TriangleSplitterLongestAxis.h>
|
||||
#include <Jolt/Geometry/AABox.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
TriangleSplitterLongestAxis::TriangleSplitterLongestAxis(const VertexList &inVertices, const IndexedTriangleList &inTriangles) :
|
||||
TriangleSplitter(inVertices, inTriangles)
|
||||
{
|
||||
}
|
||||
|
||||
bool TriangleSplitterLongestAxis::Split(const Range &inTriangles, Range &outLeft, Range &outRight)
|
||||
{
|
||||
// Calculate bounding box for triangles
|
||||
AABox bounds;
|
||||
for (uint t = inTriangles.mBegin; t < inTriangles.mEnd; ++t)
|
||||
bounds.Encapsulate(mVertices, GetTriangle(t));
|
||||
|
||||
// Calculate split plane
|
||||
uint dimension = bounds.GetExtent().GetHighestComponentIndex();
|
||||
float split = bounds.GetCenter()[dimension];
|
||||
|
||||
return SplitInternal(inTriangles, dimension, split, outLeft, outRight);
|
||||
}
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
28
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterLongestAxis.h
vendored
Normal file
28
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterLongestAxis.h
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Jolt/TriangleSplitter/TriangleSplitter.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
/// Splitter using center of bounding box with longest axis
|
||||
class JPH_EXPORT TriangleSplitterLongestAxis : public TriangleSplitter
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
TriangleSplitterLongestAxis(const VertexList &inVertices, const IndexedTriangleList &inTriangles);
|
||||
|
||||
// See TriangleSplitter::GetStats
|
||||
virtual void GetStats(Stats &outStats) const override
|
||||
{
|
||||
outStats.mSplitterName = "TriangleSplitterLongestAxis";
|
||||
}
|
||||
|
||||
// See TriangleSplitter::Split
|
||||
virtual bool Split(const Range &inTriangles, Range &outLeft, Range &outRight) override;
|
||||
};
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
40
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterMean.cpp
vendored
Normal file
40
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterMean.cpp
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
|
||||
#include <Jolt/TriangleSplitter/TriangleSplitterMean.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
TriangleSplitterMean::TriangleSplitterMean(const VertexList &inVertices, const IndexedTriangleList &inTriangles) :
|
||||
TriangleSplitter(inVertices, inTriangles)
|
||||
{
|
||||
}
|
||||
|
||||
bool TriangleSplitterMean::Split(const Range &inTriangles, Range &outLeft, Range &outRight)
|
||||
{
|
||||
// Calculate mean value for these triangles
|
||||
Vec3 mean = Vec3::sZero();
|
||||
for (uint t = inTriangles.mBegin; t < inTriangles.mEnd; ++t)
|
||||
mean += Vec3(mCentroids[mSortedTriangleIdx[t]]);
|
||||
mean *= 1.0f / inTriangles.Count();
|
||||
|
||||
// Calculate deviation
|
||||
Vec3 deviation = Vec3::sZero();
|
||||
for (uint t = inTriangles.mBegin; t < inTriangles.mEnd; ++t)
|
||||
{
|
||||
Vec3 delta = Vec3(mCentroids[mSortedTriangleIdx[t]]) - mean;
|
||||
deviation += delta * delta;
|
||||
}
|
||||
deviation *= 1.0f / inTriangles.Count();
|
||||
|
||||
// Calculate split plane
|
||||
uint dimension = deviation.GetHighestComponentIndex();
|
||||
float split = mean[dimension];
|
||||
|
||||
return SplitInternal(inTriangles, dimension, split, outLeft, outRight);
|
||||
}
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
28
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterMean.h
vendored
Normal file
28
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterMean.h
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Jolt/TriangleSplitter/TriangleSplitter.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
/// Splitter using mean of axis with biggest centroid deviation
|
||||
class JPH_EXPORT TriangleSplitterMean : public TriangleSplitter
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
TriangleSplitterMean(const VertexList &inVertices, const IndexedTriangleList &inTriangles);
|
||||
|
||||
// See TriangleSplitter::GetStats
|
||||
virtual void GetStats(Stats &outStats) const override
|
||||
{
|
||||
outStats.mSplitterName = "TriangleSplitterMean";
|
||||
}
|
||||
|
||||
// See TriangleSplitter::Split
|
||||
virtual bool Split(const Range &inTriangles, Range &outLeft, Range &outRight) override;
|
||||
};
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
63
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterMorton.cpp
vendored
Normal file
63
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterMorton.cpp
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
|
||||
#include <Jolt/TriangleSplitter/TriangleSplitterMorton.h>
|
||||
#include <Jolt/Geometry/MortonCode.h>
|
||||
#include <Jolt/Core/QuickSort.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
TriangleSplitterMorton::TriangleSplitterMorton(const VertexList &inVertices, const IndexedTriangleList &inTriangles) :
|
||||
TriangleSplitter(inVertices, inTriangles)
|
||||
{
|
||||
// Calculate bounds of centroids
|
||||
AABox bounds;
|
||||
for (uint t = 0; t < inTriangles.size(); ++t)
|
||||
bounds.Encapsulate(Vec3(mCentroids[t]));
|
||||
|
||||
// Make sure box is not degenerate
|
||||
bounds.EnsureMinimalEdgeLength(1.0e-5f);
|
||||
|
||||
// Calculate morton codes
|
||||
mMortonCodes.resize(inTriangles.size());
|
||||
for (uint t = 0; t < inTriangles.size(); ++t)
|
||||
mMortonCodes[t] = MortonCode::sGetMortonCode(Vec3(mCentroids[t]), bounds);
|
||||
|
||||
// Sort triangles on morton code
|
||||
const Array<uint32> &morton_codes = mMortonCodes;
|
||||
QuickSort(mSortedTriangleIdx.begin(), mSortedTriangleIdx.end(), [&morton_codes](uint inLHS, uint inRHS) { return morton_codes[inLHS] < morton_codes[inRHS]; });
|
||||
}
|
||||
|
||||
bool TriangleSplitterMorton::Split(const Range &inTriangles, Range &outLeft, Range &outRight)
|
||||
{
|
||||
uint32 first_code = mMortonCodes[mSortedTriangleIdx[inTriangles.mBegin]];
|
||||
uint32 last_code = mMortonCodes[mSortedTriangleIdx[inTriangles.mEnd - 1]];
|
||||
|
||||
uint common_prefix = CountLeadingZeros(first_code ^ last_code);
|
||||
|
||||
// Use binary search to find where the next bit differs
|
||||
uint split = inTriangles.mBegin; // Initial guess
|
||||
uint step = inTriangles.Count();
|
||||
do
|
||||
{
|
||||
step = (step + 1) >> 1; // Exponential decrease
|
||||
uint new_split = split + step; // Proposed new position
|
||||
if (new_split < inTriangles.mEnd)
|
||||
{
|
||||
uint32 split_code = mMortonCodes[mSortedTriangleIdx[new_split]];
|
||||
uint split_prefix = CountLeadingZeros(first_code ^ split_code);
|
||||
if (split_prefix > common_prefix)
|
||||
split = new_split; // Accept proposal
|
||||
}
|
||||
}
|
||||
while (step > 1);
|
||||
|
||||
outLeft = Range(inTriangles.mBegin, split + 1);
|
||||
outRight = Range(split + 1, inTriangles.mEnd);
|
||||
return outLeft.Count() > 0 && outRight.Count() > 0;
|
||||
}
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
32
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterMorton.h
vendored
Normal file
32
engine/thirdparty/jolt_physics/Jolt/TriangleSplitter/TriangleSplitterMorton.h
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Jolt/TriangleSplitter/TriangleSplitter.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
/// Splitter using Morton codes, see: http://devblogs.nvidia.com/parallelforall/thinking-parallel-part-iii-tree-construction-gpu/
|
||||
class JPH_EXPORT TriangleSplitterMorton : public TriangleSplitter
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
TriangleSplitterMorton(const VertexList &inVertices, const IndexedTriangleList &inTriangles);
|
||||
|
||||
// See TriangleSplitter::GetStats
|
||||
virtual void GetStats(Stats &outStats) const override
|
||||
{
|
||||
outStats.mSplitterName = "TriangleSplitterMorton";
|
||||
}
|
||||
|
||||
// See TriangleSplitter::Split
|
||||
virtual bool Split(const Range &inTriangles, Range &outLeft, Range &outRight) override;
|
||||
|
||||
private:
|
||||
// Precalculated Morton codes
|
||||
Array<uint32> mMortonCodes;
|
||||
};
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
Loading…
Add table
Add a link
Reference in a new issue