feat: modules moved and engine moved to submodule
This commit is contained in:
parent
dfb5e645cd
commit
c33d2130cc
5136 changed files with 225275 additions and 64485 deletions
|
|
@ -13,7 +13,7 @@ TriangleSplitter::TriangleSplitter(const VertexList &inVertices, const IndexedTr
|
|||
mTriangles(inTriangles)
|
||||
{
|
||||
mSortedTriangleIdx.resize(inTriangles.size());
|
||||
mCentroids.resize(inTriangles.size());
|
||||
mCentroids.resize(inTriangles.size() + 1); // Add 1 so we can load with Vec3::sLoadFloat3Unsafe
|
||||
|
||||
for (uint t = 0; t < inTriangles.size(); ++t)
|
||||
{
|
||||
|
|
@ -23,44 +23,50 @@ TriangleSplitter::TriangleSplitter(const VertexList &inVertices, const IndexedTr
|
|||
// Calculate centroid
|
||||
inTriangles[t].GetCentroid(inVertices).StoreFloat3(&mCentroids[t]);
|
||||
}
|
||||
|
||||
// Make sure Vec3::sLoatFloat3Unsafe doesn't read uninitialized data
|
||||
mCentroids.back() = Float3(0, 0, 0);
|
||||
}
|
||||
|
||||
bool TriangleSplitter::SplitInternal(const Range &inTriangles, uint inDimension, float inSplit, Range &outLeft, Range &outRight)
|
||||
{
|
||||
// Divide triangles
|
||||
uint start = inTriangles.mBegin, end = inTriangles.mEnd;
|
||||
uint *start = mSortedTriangleIdx.data() + inTriangles.mBegin;
|
||||
uint *end = mSortedTriangleIdx.data() + 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)
|
||||
while (start < end && mCentroids[*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)
|
||||
while (start < end && mCentroids[*(end - 1)][inDimension] >= inSplit)
|
||||
--end;
|
||||
|
||||
if (start < end)
|
||||
{
|
||||
// Swap the two elements
|
||||
std::swap(mSortedTriangleIdx[start], mSortedTriangleIdx[end - 1]);
|
||||
++start;
|
||||
--end;
|
||||
std::swap(*start, *end);
|
||||
++start;
|
||||
}
|
||||
}
|
||||
JPH_ASSERT(start == end);
|
||||
|
||||
uint start_idx = uint(start - mSortedTriangleIdx.data());
|
||||
|
||||
#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(inTriangles.mBegin <= start_idx);
|
||||
JPH_ASSERT(start_idx <= inTriangles.mEnd);
|
||||
for (uint i = inTriangles.mBegin; i < start_idx; ++i)
|
||||
JPH_ASSERT(mCentroids[mSortedTriangleIdx[i]][inDimension] < inSplit);
|
||||
for (uint i = start; i < inTriangles.mEnd; ++i)
|
||||
for (uint i = start_idx; i < inTriangles.mEnd; ++i)
|
||||
JPH_ASSERT(mCentroids[mSortedTriangleIdx[i]][inDimension] >= inSplit);
|
||||
#endif
|
||||
|
||||
outLeft = Range(inTriangles.mBegin, start);
|
||||
outRight = Range(start, inTriangles.mEnd);
|
||||
outLeft = Range(inTriangles.mBegin, start_idx);
|
||||
outRight = Range(start_idx, inTriangles.mEnd);
|
||||
return outLeft.Count() > 0 && outRight.Count() > 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,13 @@ TriangleSplitterBinning::TriangleSplitterBinning(const VertexList &inVertices, c
|
|||
|
||||
bool TriangleSplitterBinning::Split(const Range &inTriangles, Range &outLeft, Range &outRight)
|
||||
{
|
||||
const uint *begin = mSortedTriangleIdx.data() + inTriangles.mBegin;
|
||||
const uint *end = mSortedTriangleIdx.data() + inTriangles.mEnd;
|
||||
|
||||
// Calculate bounds for this range
|
||||
AABox centroid_bounds;
|
||||
for (uint t = inTriangles.mBegin; t < inTriangles.mEnd; ++t)
|
||||
centroid_bounds.Encapsulate(Vec3(mCentroids[mSortedTriangleIdx[t]]));
|
||||
for (const uint *t = begin; t < end; ++t)
|
||||
centroid_bounds.Encapsulate(Vec3::sLoadFloat3Unsafe(mCentroids[*t]));
|
||||
|
||||
// Convert bounds to min coordinate and size
|
||||
// Prevent division by zero if one of the dimensions is zero
|
||||
|
|
@ -57,11 +60,11 @@ bool TriangleSplitterBinning::Split(const Range &inTriangles, Range &outLeft, Ra
|
|||
}
|
||||
|
||||
// Bin all triangles in all dimensions at once
|
||||
for (uint t = inTriangles.mBegin; t < inTriangles.mEnd; ++t)
|
||||
for (const uint *t = begin; t < end; ++t)
|
||||
{
|
||||
Vec3 centroid_pos(mCentroids[mSortedTriangleIdx[t]]);
|
||||
Vec3 centroid_pos = Vec3::sLoadFloat3Unsafe(mCentroids[*t]);
|
||||
|
||||
AABox triangle_bounds = AABox::sFromTriangle(mVertices, GetTriangle(t));
|
||||
AABox triangle_bounds = AABox::sFromTriangle(mVertices, mTriangles[*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));
|
||||
|
|
|
|||
|
|
@ -1,170 +0,0 @@
|
|||
// 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
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
// 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
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
// 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
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
// 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
|
||||
|
|
@ -15,17 +15,20 @@ TriangleSplitterMean::TriangleSplitterMean(const VertexList &inVertices, const I
|
|||
|
||||
bool TriangleSplitterMean::Split(const Range &inTriangles, Range &outLeft, Range &outRight)
|
||||
{
|
||||
const uint *begin = mSortedTriangleIdx.data() + inTriangles.mBegin;
|
||||
const uint *end = mSortedTriangleIdx.data() + inTriangles.mEnd;
|
||||
|
||||
// Calculate mean value for these triangles
|
||||
Vec3 mean = Vec3::sZero();
|
||||
for (uint t = inTriangles.mBegin; t < inTriangles.mEnd; ++t)
|
||||
mean += Vec3(mCentroids[mSortedTriangleIdx[t]]);
|
||||
for (const uint *t = begin; t < end; ++t)
|
||||
mean += Vec3::sLoadFloat3Unsafe(mCentroids[*t]);
|
||||
mean *= 1.0f / inTriangles.Count();
|
||||
|
||||
// Calculate deviation
|
||||
Vec3 deviation = Vec3::sZero();
|
||||
for (uint t = inTriangles.mBegin; t < inTriangles.mEnd; ++t)
|
||||
for (const uint *t = begin; t < end; ++t)
|
||||
{
|
||||
Vec3 delta = Vec3(mCentroids[mSortedTriangleIdx[t]]) - mean;
|
||||
Vec3 delta = Vec3::sLoadFloat3Unsafe(mCentroids[*t]) - mean;
|
||||
deviation += delta * delta;
|
||||
}
|
||||
deviation *= 1.0f / inTriangles.Count();
|
||||
|
|
|
|||
|
|
@ -1,63 +0,0 @@
|
|||
// 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
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
// 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