proper pre-computing of mesh views (with equally horrid code)
This commit is contained in:
parent
16062f8135
commit
58dee945f8
@ -6,7 +6,7 @@
|
||||
"metadata": {
|
||||
"holdable": true,
|
||||
"physics": {
|
||||
"mass": 5,
|
||||
"mass": 10000,
|
||||
"type": "bounding box"
|
||||
// "type": "mesh"
|
||||
}
|
||||
|
@ -11,12 +11,9 @@
|
||||
#include <uf/utils/memory/unordered_set.h>
|
||||
|
||||
#include <uf/engine/object/object.h>
|
||||
#include <uf/utils/mesh/mesh.h>
|
||||
#include <cfloat>
|
||||
|
||||
namespace uf {
|
||||
class Mesh;
|
||||
}
|
||||
|
||||
namespace pod {
|
||||
enum class ShapeType {
|
||||
AABB,
|
||||
@ -107,6 +104,7 @@ namespace pod {
|
||||
struct MeshBVH {
|
||||
pod::BVH* bvh;
|
||||
const uf::Mesh* mesh;
|
||||
const uf::Mesh::views_t* views;
|
||||
};
|
||||
|
||||
typedef uint32_t CollisionMask;
|
||||
|
@ -191,6 +191,7 @@ namespace uf {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
typedef uf::stl::vector<uf::Mesh::View> views_t;
|
||||
|
||||
uf::stl::vector<buffer_t> buffers;
|
||||
|
||||
|
@ -212,7 +212,7 @@ namespace {
|
||||
bvh.dirty = false;
|
||||
}
|
||||
|
||||
void buildMeshBVH( pod::BVH& bvh, const uf::Mesh& mesh, pod::BVH::index_t capacity = 4 ) {
|
||||
void buildMeshBVH( pod::BVH& bvh, const uf::Mesh& mesh, const uf::Mesh::views_t& views, pod::BVH::index_t capacity = 4 ) {
|
||||
uint32_t triangles = mesh.index.count / 3;
|
||||
|
||||
bvh.indices.clear();
|
||||
@ -223,7 +223,6 @@ namespace {
|
||||
uf::stl::vector<pod::AABB> bounds;
|
||||
bounds.reserve( triangles );
|
||||
|
||||
auto views = mesh.makeViews({"position"});
|
||||
UF_ASSERT( !views.empty() );
|
||||
|
||||
// populate initial indices and bounds
|
||||
@ -376,13 +375,12 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
void refitBVH( pod::BVH& bvh, const uf::Mesh& mesh ) {
|
||||
void refitBVH( pod::BVH& bvh, const uf::Mesh& mesh, const uf::Mesh::views_t& views ) {
|
||||
uint32_t triangles = mesh.index.count / 3;
|
||||
|
||||
uf::stl::vector<pod::AABB> bounds;
|
||||
bounds.reserve( triangles );
|
||||
|
||||
auto views = mesh.makeViews({"position"});
|
||||
UF_ASSERT( !views.empty() );
|
||||
|
||||
// populate initial indices and bounds
|
||||
|
@ -9,8 +9,8 @@ namespace {
|
||||
bool blockContactSolver = true; // use BlockNxN solvers (where N = number of contacts for a manifold)
|
||||
bool psgContactSolver = true; // use PSG contact solver
|
||||
bool useGjk = false; // currently don't have a way to broadphase mesh => narrowphase tri via GJK
|
||||
bool fixedStep = true; // run physics simulation with a fixed delta time (with accumulation), rather than rely on actual engine deltatime
|
||||
uint32_t substeps = 0; // number of substeps per frame tick
|
||||
bool fixedStep = false; // run physics simulation with a fixed delta time (with accumulation), rather than rely on actual engine deltatime
|
||||
uint32_t substeps = 4; // number of substeps per frame tick
|
||||
uint32_t reserveCount = 32; // amount of elements to reserve for vectors used in this system, to-do: have it tie to a memory pool allocator
|
||||
|
||||
// increasing these make things lag for reasons I can imagine why
|
||||
@ -22,7 +22,7 @@ namespace {
|
||||
bool flattenBvhMeshes = true;
|
||||
|
||||
// use surface area heuristics for building the BVH, rather than naive splits
|
||||
bool useBvhSahBodies = true; // it actually seems slower to use these......
|
||||
bool useBvhSahBodies = false; // it actually seems slower to use these......
|
||||
bool useBvhSahMeshes = true;
|
||||
|
||||
bool useSplitBvhs = true; // creates separate BVHs for static / dynamic objects
|
||||
@ -396,10 +396,11 @@ pod::PhysicsBody& uf::physics::impl::create( pod::World& world, uf::Object& obje
|
||||
auto& body = uf::physics::impl::create( world, object, mass, offset );
|
||||
body.collider.type = pod::ShapeType::MESH;
|
||||
body.collider.mesh.mesh = &mesh;
|
||||
auto& views = *(body.collider.mesh.views = new uf::Mesh::views_t(mesh.makeViews({"position", "normal"})));
|
||||
|
||||
body.collider.mesh.bvh = new pod::BVH;
|
||||
auto& bvh = *body.collider.mesh.bvh;
|
||||
::buildMeshBVH( bvh, mesh, ::meshBvhCapacity );
|
||||
::buildMeshBVH( bvh, mesh, views, ::meshBvhCapacity );
|
||||
|
||||
body.bounds = ::computeAABB( body );
|
||||
uf::physics::impl::updateInertia( body );
|
||||
@ -458,6 +459,7 @@ void uf::physics::impl::destroy( pod::PhysicsBody& body ) {
|
||||
// remove any pointered collider data
|
||||
if ( body.collider.type == pod::ShapeType::MESH ) {
|
||||
if ( body.collider.mesh.bvh ) delete body.collider.mesh.bvh;
|
||||
if ( body.collider.mesh.views ) delete body.collider.mesh.views;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ namespace {
|
||||
|
||||
const auto& bvh = *mesh.collider.mesh.bvh;
|
||||
const auto& meshData = *mesh.collider.mesh.mesh;
|
||||
const auto& meshViews = *mesh.collider.mesh.views;
|
||||
|
||||
// transform to local space for BVH query
|
||||
auto bounds = ::transformAabbToLocal( aabb.bounds, ::getTransform( mesh ) );
|
||||
@ -31,7 +32,7 @@ namespace {
|
||||
bool hit = false;
|
||||
// do collision per triangle
|
||||
for ( auto triID : candidates ) {
|
||||
auto tri = ::fetchTriangle( meshData, triID, mesh ); // transform triangle to world space
|
||||
auto tri = ::fetchTriangle( meshData, meshViews, triID, mesh ); // transform triangle to world space
|
||||
if ( !::triangleAabb( tri, aabb, manifold, eps ) ) continue;
|
||||
hit = true;
|
||||
}
|
||||
@ -45,6 +46,7 @@ namespace {
|
||||
|
||||
const auto& bvh = *mesh.collider.mesh.bvh;
|
||||
const auto& meshData = *mesh.collider.mesh.mesh;
|
||||
const auto& meshViews = *mesh.collider.mesh.views;
|
||||
|
||||
// transform to local space for BVH query
|
||||
auto bounds = ::transformAabbToLocal( sphere.bounds, ::getTransform( mesh ) );
|
||||
@ -55,7 +57,7 @@ namespace {
|
||||
bool hit = false;
|
||||
// do collision per triangle
|
||||
for ( auto triID : candidates ) {
|
||||
auto tri = ::fetchTriangle( meshData, triID, mesh ); // transform triangle to world space
|
||||
auto tri = ::fetchTriangle( meshData, meshViews, triID, mesh ); // transform triangle to world space
|
||||
if ( !::triangleSphere( tri, sphere, manifold, eps ) ) continue;
|
||||
hit = true;
|
||||
}
|
||||
@ -71,6 +73,7 @@ namespace {
|
||||
|
||||
const auto& bvh = *mesh.collider.mesh.bvh;
|
||||
const auto& meshData = *mesh.collider.mesh.mesh;
|
||||
const auto& meshViews = *mesh.collider.mesh.views;
|
||||
|
||||
// transform to local space for BVH query
|
||||
auto bounds = ::transformAabbToLocal( plane.bounds, ::getTransform( mesh ) );
|
||||
@ -81,7 +84,7 @@ namespace {
|
||||
bool hit = false;
|
||||
// do collision per triangle
|
||||
for ( auto triID : candidates ) {
|
||||
auto tri = ::fetchTriangle( meshData, triID, mesh ); // transform triangle to world space
|
||||
auto tri = ::fetchTriangle( meshData, meshViews, triID, mesh ); // transform triangle to world space
|
||||
if ( !::trianglePlane( tri, plane, manifold, eps ) ) continue;
|
||||
hit = true;
|
||||
}
|
||||
@ -96,6 +99,7 @@ namespace {
|
||||
|
||||
const auto& bvh = *mesh.collider.mesh.bvh;
|
||||
const auto& meshData = *mesh.collider.mesh.mesh;
|
||||
const auto& meshViews = *mesh.collider.mesh.views;
|
||||
|
||||
// transform to local space for BVH query
|
||||
auto bounds = ::transformAabbToLocal( capsule.bounds, ::getTransform( mesh ) );
|
||||
@ -106,7 +110,7 @@ namespace {
|
||||
bool hit = false;
|
||||
// do collision per triangle
|
||||
for ( auto triID : candidates ) {
|
||||
auto tri = ::fetchTriangle( meshData, triID, mesh ); // transform triangle to world space
|
||||
auto tri = ::fetchTriangle( meshData, meshViews, triID, mesh ); // transform triangle to world space
|
||||
if ( !::triangleCapsule( tri, capsule, manifold, eps ) ) continue;
|
||||
hit = true;
|
||||
}
|
||||
@ -119,9 +123,11 @@ namespace {
|
||||
|
||||
const auto& bvhA = *a.collider.mesh.bvh;
|
||||
const auto& meshA = *a.collider.mesh.mesh;
|
||||
const auto& viewsA = *a.collider.mesh.views;
|
||||
|
||||
const auto& meshB = *b.collider.mesh.mesh;
|
||||
const auto& bvhB = *b.collider.mesh.bvh;
|
||||
const auto& meshB = *b.collider.mesh.mesh;
|
||||
const auto& viewsB = *b.collider.mesh.views;
|
||||
|
||||
// compute overlaps between one BVH and another BVH
|
||||
thread_local pod::BVH::pairs_t pairs;
|
||||
@ -131,8 +137,8 @@ namespace {
|
||||
bool hit = false;
|
||||
// do collision per triangle
|
||||
for (auto [ idA, idB] : pairs ) {
|
||||
auto tA = ::fetchTriangle( meshA, idA, a ); // transform triangles to world space
|
||||
auto tB = ::fetchTriangle( meshB, idB, b );
|
||||
auto tA = ::fetchTriangle( meshA, viewsA, idA, a ); // transform triangles to world space
|
||||
auto tB = ::fetchTriangle( meshB, viewsB, idB, b );
|
||||
|
||||
if ( !::triangleTriangle( tA, tB, manifold, eps ) ) continue;
|
||||
hit = true;
|
||||
|
@ -193,8 +193,9 @@ namespace {
|
||||
}
|
||||
|
||||
bool rayMesh( const pod::Ray& r, const pod::PhysicsBody& body, pod::RayQuery& rayHit ) {
|
||||
const auto& meshData = *body.collider.mesh.mesh;
|
||||
const auto& bvh = *body.collider.mesh.bvh;
|
||||
const auto& meshData = *body.collider.mesh.mesh;
|
||||
const auto& meshViews = *body.collider.mesh.views;
|
||||
|
||||
const auto transform = ::getTransform( body );
|
||||
|
||||
@ -207,7 +208,7 @@ namespace {
|
||||
::queryBVH( bvh, ray, candidates );
|
||||
|
||||
for ( auto triID : candidates ) {
|
||||
auto tri = ::fetchTriangle( meshData, triID );
|
||||
auto tri = ::fetchTriangle( meshData, meshViews, triID );
|
||||
|
||||
float t, u, v;
|
||||
if ( !::rayTriangleIntersect( ray, tri, t, u, v ) ) continue;
|
||||
|
@ -91,10 +91,7 @@ namespace {
|
||||
return tri;
|
||||
}
|
||||
|
||||
pod::TriangleWithNormal fetchTriangle( const uf::Mesh& mesh, size_t triID ) {
|
||||
static thread_local uf::stl::unordered_map<const uf::Mesh*, uf::stl::vector<uf::Mesh::View>> cachedViews;
|
||||
if ( cachedViews.count(&mesh) == 0 ) cachedViews[&mesh] = mesh.makeViews({"position"});
|
||||
auto& views = cachedViews[&mesh];
|
||||
pod::TriangleWithNormal fetchTriangle( const uf::Mesh& mesh, const uf::Mesh::views_t& views, size_t triID ) {
|
||||
UF_ASSERT(!views.empty());
|
||||
|
||||
// find which view contains this triangle index.
|
||||
@ -121,8 +118,8 @@ namespace {
|
||||
}
|
||||
|
||||
// if body is a mesh, apply its transform to the triangles, else reorient the normal with respect to the body
|
||||
pod::TriangleWithNormal fetchTriangle( const uf::Mesh& mesh, size_t triID, const pod::PhysicsBody& body, bool fast = false ) {
|
||||
auto tri = ::fetchTriangle( mesh, triID );
|
||||
pod::TriangleWithNormal fetchTriangle( const uf::Mesh& mesh, const uf::Mesh::views_t& views, size_t triID, const pod::PhysicsBody& body, bool fast = false ) {
|
||||
auto tri = ::fetchTriangle( mesh, views, triID );
|
||||
|
||||
auto transform = ::getTransform( body );
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user