mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 15:29:32 +02:00
fix render geometry for collision shapes
This commit is contained in:
parent
daff897fc4
commit
26f5d3cfaa
2 changed files with 67 additions and 40 deletions
|
@ -18,53 +18,69 @@
|
||||||
|
|
||||||
#include <ShapeInfo.h> // for MAX_HULL_POINTS
|
#include <ShapeInfo.h> // for MAX_HULL_POINTS
|
||||||
|
|
||||||
float verts[3 * MAX_HULL_POINTS];
|
const int32_t MAX_HULL_INDICES = 6 * MAX_HULL_POINTS;
|
||||||
|
float tempVertexBuffer[3 * MAX_HULL_POINTS];
|
||||||
|
model::Index tempIndexBuffer[MAX_HULL_INDICES];
|
||||||
|
|
||||||
void copyShapeToMesh(const btTransform& transform, const btConvexShape* shape, model::MeshPointer mesh) {
|
//void copyShapeToMesh(const btTransform& transform, const btConvexShape* shape, model::MeshPointer mesh) {
|
||||||
assert((bool)mesh);
|
void copyShapeToMesh(const btTransform& transform, const btConvexShape* shape,
|
||||||
|
gpu::BufferView& vertices, gpu::BufferView& indices, gpu::BufferView& parts) {
|
||||||
assert(shape);
|
assert(shape);
|
||||||
|
|
||||||
btShapeHull hull(shape);
|
btShapeHull hull(shape);
|
||||||
const btScalar MARGIN = 0.0f;
|
const btScalar MARGIN = 0.0f;
|
||||||
hull.buildHull(MARGIN);
|
hull.buildHull(MARGIN);
|
||||||
|
|
||||||
const uint32_t* hullIndices = hull.getIndexPointer();
|
int32_t numHullIndices = hull.numIndices();
|
||||||
int32_t numIndices = hull.numIndices();
|
assert(numHullIndices <= MAX_HULL_INDICES);
|
||||||
assert(numIndices <= 6 * MAX_HULL_POINTS);
|
|
||||||
|
int32_t numHullVertices = hull.numVertices();
|
||||||
|
assert(numHullVertices <= MAX_HULL_POINTS);
|
||||||
|
|
||||||
{ // new part
|
{ // new part
|
||||||
model::Mesh::Part part;
|
model::Mesh::Part part;
|
||||||
part._startIndex = mesh->getIndexBuffer().getNumElements();
|
part._startIndex = indices.getNumElements();
|
||||||
part._numIndices = (model::Index)numIndices;
|
part._numIndices = (model::Index)numHullIndices;
|
||||||
part._baseVertex = mesh->getVertexBuffer().getNumElements();
|
// FIXME: the render code cannot handle the case where part._baseVertex != 0
|
||||||
|
//part._baseVertex = vertices.getNumElements(); // DOES NOT WORK
|
||||||
|
part._baseVertex = 0;
|
||||||
|
|
||||||
gpu::BufferView::Size numBytes = sizeof(model::Mesh::Part);
|
gpu::BufferView::Size numBytes = sizeof(model::Mesh::Part);
|
||||||
const gpu::Byte* data = reinterpret_cast<const gpu::Byte*>(&part);
|
const gpu::Byte* data = reinterpret_cast<const gpu::Byte*>(&part);
|
||||||
mesh->getPartBuffer()._buffer->append(numBytes, data);
|
parts._buffer->append(numBytes, data);
|
||||||
|
parts._size = parts._buffer->getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model::Index indexOffset = vertices.getNumElements();
|
||||||
{ // new vertices
|
{ // new vertices
|
||||||
const btVector3* hullVertices = hull.getVertexPointer();
|
const btVector3* hullVertices = hull.getVertexPointer();
|
||||||
int32_t numVertices = hull.numVertices();
|
assert(numHullVertices <= MAX_HULL_POINTS);
|
||||||
assert(numVertices <= MAX_HULL_POINTS);
|
for (int32_t i = 0; i < numHullVertices; ++i) {
|
||||||
for (int32_t i = 0; i < numVertices; ++i) {
|
|
||||||
btVector3 transformedPoint = transform * hullVertices[i];
|
btVector3 transformedPoint = transform * hullVertices[i];
|
||||||
memcpy(transformedPoint.m_floats, verts + 3 * i, 3 * sizeof(float));
|
memcpy(tempVertexBuffer + 3 * i, transformedPoint.m_floats, 3 * sizeof(float));
|
||||||
//data[0] = transformedPoint.getX();
|
|
||||||
//data[1] = transformedPoint.getY();
|
|
||||||
//data[2] = transformedPoint.getZ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu::BufferView::Size numBytes = sizeof(float) * (3 * numVertices);
|
gpu::BufferView::Size numBytes = sizeof(float) * (3 * numHullVertices);
|
||||||
const gpu::Byte* data = reinterpret_cast<const gpu::Byte*>(verts);
|
const gpu::Byte* data = reinterpret_cast<const gpu::Byte*>(tempVertexBuffer);
|
||||||
mesh->getVertexBuffer()._buffer->append(numBytes, data);
|
vertices._buffer->append(numBytes, data);
|
||||||
|
vertices._size = vertices._buffer->getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // new indices
|
{ // new indices
|
||||||
gpu::BufferView::Size numBytes = (gpu::BufferView::Size)(sizeof(uint32_t) * hull.numIndices());
|
const uint32_t* hullIndices = hull.getIndexPointer();
|
||||||
const gpu::Byte* data = reinterpret_cast<const gpu::Byte*>(hullIndices);
|
// FIXME: the render code cannot handle the case where part._baseVertex != 0
|
||||||
mesh->getIndexBuffer()._buffer->append(numBytes, data);
|
// so we must add an offset to each index
|
||||||
|
for (int32_t i = 0; i < numHullIndices; ++i) {
|
||||||
|
tempIndexBuffer[i] = hullIndices[i] + indexOffset;
|
||||||
|
}
|
||||||
|
const gpu::Byte* data = reinterpret_cast<const gpu::Byte*>(tempIndexBuffer);
|
||||||
|
gpu::BufferView::Size numBytes = (gpu::BufferView::Size)(sizeof(model::Index) * numHullIndices);
|
||||||
|
indices._buffer->append(numBytes, data);
|
||||||
|
indices._size = indices._buffer->getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gpu::BufferView::Iterator<const model::Mesh::Part> partItr = parts.cbegin<const model::Mesh::Part>();
|
||||||
|
gpu::Size numParts = parts.getNumElements();
|
||||||
}
|
}
|
||||||
|
|
||||||
model::MeshPointer createMeshFromShape(const void* pointer) {
|
model::MeshPointer createMeshFromShape(const void* pointer) {
|
||||||
|
@ -73,17 +89,18 @@ model::MeshPointer createMeshFromShape(const void* pointer) {
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pointer must actually be a const btCollisionShape*, but it only
|
// pointer must be a const btCollisionShape* (cast to void*), but it only
|
||||||
// needs to be valid here when its render mesh is created.
|
// needs to be valid here when its render mesh is created, after this call
|
||||||
|
// the cache doesn't care what happens to the shape behind the pointer
|
||||||
const btCollisionShape* shape = static_cast<const btCollisionShape*>(pointer);
|
const btCollisionShape* shape = static_cast<const btCollisionShape*>(pointer);
|
||||||
|
|
||||||
int32_t shapeType = shape->getShapeType();
|
int32_t shapeType = shape->getShapeType();
|
||||||
if (shapeType == (int32_t)COMPOUND_SHAPE_PROXYTYPE || shape->isConvex()) {
|
if (shapeType == (int32_t)COMPOUND_SHAPE_PROXYTYPE || shape->isConvex()) {
|
||||||
// create the mesh and allocate buffers for it
|
// create the mesh and allocate buffers for it
|
||||||
mesh = std::make_shared<model::Mesh>();
|
mesh = std::make_shared<model::Mesh>();
|
||||||
mesh->setVertexBuffer(gpu::BufferView(new gpu::Buffer(), mesh->getVertexBuffer()._element));
|
gpu::BufferView vertices(new gpu::Buffer(), mesh->getVertexBuffer()._element);
|
||||||
mesh->setIndexBuffer(gpu::BufferView(new gpu::Buffer(), mesh->getIndexBuffer()._element));
|
gpu::BufferView indices(new gpu::Buffer(), mesh->getIndexBuffer()._element);
|
||||||
mesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(), mesh->getPartBuffer()._element));
|
gpu::BufferView parts(new gpu::Buffer(), mesh->getPartBuffer()._element);
|
||||||
|
|
||||||
if (shapeType == (int32_t)COMPOUND_SHAPE_PROXYTYPE) {
|
if (shapeType == (int32_t)COMPOUND_SHAPE_PROXYTYPE) {
|
||||||
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
|
const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(shape);
|
||||||
|
@ -92,14 +109,19 @@ model::MeshPointer createMeshFromShape(const void* pointer) {
|
||||||
const btCollisionShape* childShape = compoundShape->getChildShape(i);
|
const btCollisionShape* childShape = compoundShape->getChildShape(i);
|
||||||
if (childShape->isConvex()) {
|
if (childShape->isConvex()) {
|
||||||
const btConvexShape* convexShape = static_cast<const btConvexShape*>(childShape);
|
const btConvexShape* convexShape = static_cast<const btConvexShape*>(childShape);
|
||||||
copyShapeToMesh(compoundShape->getChildTransform(i), convexShape, mesh);
|
copyShapeToMesh(compoundShape->getChildTransform(i), convexShape, vertices, indices, parts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// shape is convex
|
// shape is convex
|
||||||
const btConvexShape* convexShape = static_cast<const btConvexShape*>(shape);
|
const btConvexShape* convexShape = static_cast<const btConvexShape*>(shape);
|
||||||
copyShapeToMesh(btTransform(), convexShape, mesh);
|
btTransform transform;
|
||||||
|
transform.setIdentity();
|
||||||
|
copyShapeToMesh(transform, convexShape, vertices, indices, parts);
|
||||||
}
|
}
|
||||||
|
mesh->setVertexBuffer(vertices);
|
||||||
|
mesh->setIndexBuffer(indices);
|
||||||
|
mesh->setPartBuffer(parts);
|
||||||
}
|
}
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
@ -151,7 +173,7 @@ bool CollisionRenderMeshCache::releaseMesh(CollisionRenderMeshCache::Key key) {
|
||||||
|
|
||||||
void CollisionRenderMeshCache::collectGarbage() {
|
void CollisionRenderMeshCache::collectGarbage() {
|
||||||
uint32_t numShapes = _pendingGarbage.size();
|
uint32_t numShapes = _pendingGarbage.size();
|
||||||
for (int32_t i = 0; i < numShapes; ++i) {
|
for (uint32_t i = 0; i < numShapes; ++i) {
|
||||||
CollisionRenderMeshCache::Key key = _pendingGarbage[i];
|
CollisionRenderMeshCache::Key key = _pendingGarbage[i];
|
||||||
CollisionMeshMap::const_iterator itr = _meshMap.find(key);
|
CollisionMeshMap::const_iterator itr = _meshMap.find(key);
|
||||||
if (itr != _meshMap.end()) {
|
if (itr != _meshMap.end()) {
|
||||||
|
|
|
@ -219,10 +219,6 @@ void Model::updateRenderItems() {
|
||||||
modelMeshOffset.postTranslate(self->_offset);
|
modelMeshOffset.postTranslate(self->_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// only apply offset only, collision mesh does not share the same unit scale as the FBX file's mesh.
|
|
||||||
Transform collisionMeshOffset;
|
|
||||||
collisionMeshOffset.postTranslate(self->_offset);
|
|
||||||
|
|
||||||
uint32_t deleteGeometryCounter = self->_deleteGeometryCounter;
|
uint32_t deleteGeometryCounter = self->_deleteGeometryCounter;
|
||||||
|
|
||||||
render::PendingChanges pendingChanges;
|
render::PendingChanges pendingChanges;
|
||||||
|
@ -243,6 +239,11 @@ void Model::updateRenderItems() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// collision mesh does not share the same unit scale as the FBX file's mesh: only apply offset
|
||||||
|
Transform collisionMeshOffset;
|
||||||
|
// adebug FIXME: recover correct behavior for collisionURL shapes
|
||||||
|
//collisionMeshOffset.postTranslate(self->_offset);
|
||||||
|
collisionMeshOffset.setIdentity();
|
||||||
foreach (auto itemID, self->_collisionRenderItems.keys()) {
|
foreach (auto itemID, self->_collisionRenderItems.keys()) {
|
||||||
pendingChanges.updateItem<MeshPartPayload>(itemID, [modelTransform, collisionMeshOffset](MeshPartPayload& data) {
|
pendingChanges.updateItem<MeshPartPayload>(itemID, [modelTransform, collisionMeshOffset](MeshPartPayload& data) {
|
||||||
// update the model transform for this render item.
|
// update the model transform for this render item.
|
||||||
|
@ -1321,12 +1322,16 @@ void Model::createCollisionRenderItemSet() {
|
||||||
Q_ASSERT(_collisionRenderItemsSet.isEmpty());
|
Q_ASSERT(_collisionRenderItemsSet.isEmpty());
|
||||||
|
|
||||||
Transform transform;
|
Transform transform;
|
||||||
transform.setTranslation(_translation);
|
transform.setIdentity();
|
||||||
transform.setRotation(_rotation);
|
// adebug FIXME: recover correct behavior for collisionURL
|
||||||
|
//transform.setTranslation(_translation);
|
||||||
|
//transform.setRotation(_rotation);
|
||||||
|
|
||||||
Transform offset;
|
Transform offset;
|
||||||
offset.setScale(_scale);
|
// adebug FIXME: recover correct behavior for collisionURL
|
||||||
offset.postTranslate(_offset);
|
offset.setIdentity();
|
||||||
|
//offset.setScale(_scale);
|
||||||
|
//offset.postTranslate(_offset);
|
||||||
|
|
||||||
// Run through all of the meshes, and place them into their segregated, but unsorted buckets
|
// Run through all of the meshes, and place them into their segregated, but unsorted buckets
|
||||||
uint32_t numMeshes = (uint32_t)meshes.size();
|
uint32_t numMeshes = (uint32_t)meshes.size();
|
||||||
|
@ -1339,7 +1344,7 @@ void Model::createCollisionRenderItemSet() {
|
||||||
// Create the render payloads
|
// Create the render payloads
|
||||||
int numParts = (int)mesh->getNumParts();
|
int numParts = (int)mesh->getNumParts();
|
||||||
for (int partIndex = 0; partIndex < numParts; partIndex++) {
|
for (int partIndex = 0; partIndex < numParts; partIndex++) {
|
||||||
model::MaterialPointer& material = _collisionHullMaterials[partIndex % NUM_COLLISION_HULL_COLORS];
|
model::MaterialPointer& material = _collisionHullMaterials[partIndex % NUM_COLLISION_HULL_COLORS];
|
||||||
_collisionRenderItemsSet << std::make_shared<MeshPartPayload>(mesh, partIndex, material, transform, offset);
|
_collisionRenderItemsSet << std::make_shared<MeshPartPayload>(mesh, partIndex, material, transform, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue