feat: multithread building vbo

This commit is contained in:
parker
2025-08-03 03:47:51 +01:00
parent 488ff9ff72
commit 40c37438ce
4 changed files with 59 additions and 54 deletions

View File

@@ -75,7 +75,7 @@ public:
{ {
// TODO:protect against invalid positions // TODO:protect against invalid positions
// TODO: cast types // TODO: cast types
return data_[pos]; return (*data_)[pos];
} }
void setValue(size_t pos, const T& value) void setValue(size_t pos, const T& value)

View File

@@ -170,24 +170,25 @@ enzo::geo::HeMesh geo::Geometry::computeHalfEdgeMesh()
return heMesh; return heMesh;
} }
unsigned int geo::Geometry::getPrimStartVertex(ga::Offset primOffset) ga::Offset geo::Geometry::getPrimStartVertex(ga::Offset primOffset) const
{ {
const ga::Offset handleSize = vertexCountHandlePrim_.getSize();
// TODO: add smarter system to recompute primStarts_, also move to separate function
// if size changed, recompute
if(handleSize!=primStarts_.size())
{
bt::intT primStart = 0;
for(size_t i=0; i<handleSize; ++i)
{
primStarts_.push_back(primStart);
primStart += vertexCountHandlePrim_.getValue(i);
}
}
return primStarts_[primOffset]; return primStarts_[primOffset];
} }
// TODO: handle this automatically
void geo::Geometry::computePrimStartVertices()
{
const ga::Offset handleSize = vertexCountHandlePrim_.getSize();
bt::intT primStart = 0;
for(size_t i=0; i<handleSize; ++i)
{
primStarts_.push_back(primStart);
primStart += vertexCountHandlePrim_.getValue(i);
}
}
ga::AttributeHandle<int> geo::Geometry::addIntAttribute(ga::AttributeOwner owner, std::string name) ga::AttributeHandle<int> geo::Geometry::addIntAttribute(ga::AttributeOwner owner, std::string name)

View File

@@ -31,14 +31,15 @@ public:
std::vector<bt::Vector3> derivePointNormals(); std::vector<bt::Vector3> derivePointNormals();
HeMesh computeHalfEdgeMesh(); HeMesh computeHalfEdgeMesh();
// returns the first vertex of the primitive // returns the first vertex of the primitive
unsigned int getPrimStartVertex(ga::Offset primOffset);
void addFace(std::initializer_list<ga::Offset> pointOffsets); void addFace(std::initializer_list<ga::Offset> pointOffsets);
ga::Offset getPrimStartVertex(ga::Offset primOffset) const;
bt::Vector3 getPosFromVert(ga::Offset vertexOffset) const; bt::Vector3 getPosFromVert(ga::Offset vertexOffset) const;
bt::Vector3 getPointPos(ga::Offset pointOffset) const; bt::Vector3 getPointPos(ga::Offset pointOffset) const;
unsigned int getPrimVertCount(ga::Offset primOffset) const; unsigned int getPrimVertCount(ga::Offset primOffset) const;
ga::Offset getNumPrims() const; ga::Offset getNumPrims() const;
ga::Offset getNumVerts() const; ga::Offset getNumVerts() const;
void computePrimStartVertices();
private: private:
using attribVector = std::vector<std::shared_ptr<ga::Attribute>>; using attribVector = std::vector<std::shared_ptr<ga::Attribute>>;
attribVector& getAttributeStore(ga::AttributeOwner& owner); attribVector& getAttributeStore(ga::AttributeOwner& owner);

View File

@@ -5,6 +5,8 @@
#include "Engine/Operator/Geometry.h" #include "Engine/Operator/Geometry.h"
#include "Engine/Types.h" #include "Engine/Types.h"
#include <CGAL/Polygon_mesh_processing/compute_normal.h> #include <CGAL/Polygon_mesh_processing/compute_normal.h>
#include <oneapi/tbb/blocked_range.h>
#include <oneapi/tbb/parallel_for.h>
#include "icecream.hpp" #include "icecream.hpp"
@@ -61,53 +63,54 @@ void GLMesh::setPosBuffer(enzo::geo::Geometry& geometry)
const size_t numPrims = geometry.getNumPrims(); const size_t numPrims = geometry.getNumPrims();
vertices.resize(geometry.getNumVerts()); vertices.resize(geometry.getNumVerts());
geometry.computePrimStartVertices();
tbb::parallel_for(tbb::blocked_range<size_t>(0, numPrims), [&](tbb::blocked_range<size_t> range)
for (int primOffset=0; primOffset<numPrims; ++primOffset)
{ {
const unsigned int primStartVert = geometry.getPrimStartVertex(primOffset); for (int primOffset=range.begin(); primOffset<range.end(); ++primOffset)
auto faceIndex = primOffset;
int faceVertCnt = geometry.getPrimVertCount(primOffset);
enzo::bt::Vector3 n;
// compute normal
if(faceVertCnt>=3)
{ {
const unsigned v1 = primStartVert; const enzo::ga::Offset primStartVert = geometry.getPrimStartVertex(primOffset);
const unsigned v2 = primStartVert + 1; const unsigned int faceVertCnt = geometry.getPrimVertCount(primOffset);
const unsigned v3 = primStartVert + 2;
const enzo::bt::Vector3 pos1 = geometry.getPosFromVert(v1); enzo::bt::Vector3 Normal;
const enzo::bt::Vector3 pos2 = geometry.getPosFromVert(v2);
const enzo::bt::Vector3 pos3 = geometry.getPosFromVert(v3);
enzo::bt::Vector3 tang1 = (pos2-pos1); // compute normal
enzo::bt::Vector3 tang2 = (pos3-pos1); if(faceVertCnt>=3)
{
const unsigned v1 = primStartVert;
const unsigned v2 = primStartVert + 1;
const unsigned v3 = primStartVert + 2;
tang1.normalize(); const enzo::bt::Vector3 pos1 = geometry.getPosFromVert(v1);
tang2.normalize(); const enzo::bt::Vector3 pos2 = geometry.getPosFromVert(v2);
const enzo::bt::Vector3 pos3 = geometry.getPosFromVert(v3);
enzo::bt::Vector3 tang1 = (pos2-pos1);
enzo::bt::Vector3 tang2 = (pos3-pos1);
tang1.normalize();
tang2.normalize();
Normal = tang1.cross(tang2);
}
for(int i=0; i< faceVertCnt; ++i)
{
const unsigned int vertexCount = primStartVert+i;
enzo::bt::Vector3 p = geometry.getPosFromVert(vertexCount);
vertices[vertexCount] ={
{ p.x(),
p.y(),
p.z()},
{ Normal.x(),
Normal.y(),
Normal.z()}
};
}
n = tang1.cross(tang2);
} }
});
for(int i=0; i< faceVertCnt; ++i)
{
const unsigned int vertexCount = primStartVert+i;
enzo::bt::Vector3 p = geometry.getPosFromVert(vertexCount);
vertices[vertexCount] ={
{ p.x(),
p.y(),
p.z()},
{ n.x(),
n.y(),
n.z()}
};
}
}
glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(Vertex), vertices.data(), GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(Vertex), vertices.data(), GL_STATIC_DRAW);
unbind(); unbind();