mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 11:17:34 +02:00
fix collision mesh for non-trivial registration
This commit is contained in:
parent
502146b171
commit
b95cb566cd
3 changed files with 27 additions and 18 deletions
|
@ -631,7 +631,7 @@ bool RenderableModelEntityItem::isReadyToComputeShape() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
||||||
const uint32_t TRIANGLE_STRIDE = 3;
|
const uint32_t TRIANGLE_STRIDE = 3;
|
||||||
const uint32_t QUAD_STRIDE = 4;
|
const uint32_t QUAD_STRIDE = 4;
|
||||||
|
|
||||||
|
@ -645,7 +645,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
assert(_model && _model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded());
|
assert(_model && _model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded());
|
||||||
const FBXGeometry& collisionGeometry = _compoundShapeResource->getFBXGeometry();
|
const FBXGeometry& collisionGeometry = _compoundShapeResource->getFBXGeometry();
|
||||||
|
|
||||||
ShapeInfo::PointCollection& pointCollection = info.getPointCollection();
|
ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection();
|
||||||
pointCollection.clear();
|
pointCollection.clear();
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
|
|
||||||
|
@ -721,15 +721,14 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
glm::vec3 scaleToFit = dimensions / _model->getFBXGeometry().getUnscaledMeshExtents().size();
|
glm::vec3 scaleToFit = dimensions / _model->getFBXGeometry().getUnscaledMeshExtents().size();
|
||||||
// multiply each point by scale before handing the point-set off to the physics engine.
|
// multiply each point by scale before handing the point-set off to the physics engine.
|
||||||
// also determine the extents of the collision model.
|
// also determine the extents of the collision model.
|
||||||
|
glm::vec3 registrationOffset = dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint());
|
||||||
for (int32_t i = 0; i < pointCollection.size(); i++) {
|
for (int32_t i = 0; i < pointCollection.size(); i++) {
|
||||||
for (int32_t j = 0; j < pointCollection[i].size(); j++) {
|
for (int32_t j = 0; j < pointCollection[i].size(); j++) {
|
||||||
// compensate for registration
|
// back compensate for registration so we can apply that offset to the shapeInfo later
|
||||||
pointCollection[i][j] += _model->getOffset();
|
pointCollection[i][j] = scaleToFit * (pointCollection[i][j] + _model->getOffset()) - registrationOffset;
|
||||||
// scale so the collision points match the model points
|
|
||||||
pointCollection[i][j] *= scaleToFit;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
info.setParams(type, dimensions, _compoundShapeURL);
|
shapeInfo.setParams(type, dimensions, _compoundShapeURL);
|
||||||
} else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) {
|
} else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) {
|
||||||
// should never fall in here when model not fully loaded
|
// should never fall in here when model not fully loaded
|
||||||
assert(_model && _model->isLoaded());
|
assert(_model && _model->isLoaded());
|
||||||
|
@ -742,29 +741,31 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
const FBXGeometry& fbxGeometry = _model->getFBXGeometry();
|
const FBXGeometry& fbxGeometry = _model->getFBXGeometry();
|
||||||
int numFbxMeshes = fbxGeometry.meshes.size();
|
int numFbxMeshes = fbxGeometry.meshes.size();
|
||||||
int totalNumVertices = 0;
|
int totalNumVertices = 0;
|
||||||
|
glm::mat4 invRegistraionOffset = glm::translate(dimensions * (getRegistrationPoint() - ENTITY_ITEM_DEFAULT_REGISTRATION_POINT));
|
||||||
for (int i = 0; i < numFbxMeshes; i++) {
|
for (int i = 0; i < numFbxMeshes; i++) {
|
||||||
const FBXMesh& mesh = fbxGeometry.meshes.at(i);
|
const FBXMesh& mesh = fbxGeometry.meshes.at(i);
|
||||||
if (mesh.clusters.size() > 0) {
|
if (mesh.clusters.size() > 0) {
|
||||||
const FBXCluster& cluster = mesh.clusters.at(0);
|
const FBXCluster& cluster = mesh.clusters.at(0);
|
||||||
auto jointMatrix = _model->getRig()->getJointTransform(cluster.jointIndex);
|
auto jointMatrix = _model->getRig()->getJointTransform(cluster.jointIndex);
|
||||||
localTransforms.push_back(jointMatrix * cluster.inverseBindMatrix);
|
// we backtranslate by the registration offset so we can apply that offset to the shapeInfo later
|
||||||
|
localTransforms.push_back(invRegistraionOffset * jointMatrix * cluster.inverseBindMatrix);
|
||||||
} else {
|
} else {
|
||||||
glm::mat4 identity;
|
glm::mat4 identity;
|
||||||
localTransforms.push_back(identity);
|
localTransforms.push_back(invRegistraionOffset);
|
||||||
}
|
}
|
||||||
totalNumVertices += mesh.vertices.size();
|
totalNumVertices += mesh.vertices.size();
|
||||||
}
|
}
|
||||||
const int32_t MAX_VERTICES_PER_STATIC_MESH = 1e6;
|
const int32_t MAX_VERTICES_PER_STATIC_MESH = 1e6;
|
||||||
if (totalNumVertices > MAX_VERTICES_PER_STATIC_MESH) {
|
if (totalNumVertices > MAX_VERTICES_PER_STATIC_MESH) {
|
||||||
qWarning() << "model" << getModelURL() << "has too many vertices" << totalNumVertices << "and will collide as a box.";
|
qWarning() << "model" << getModelURL() << "has too many vertices" << totalNumVertices << "and will collide as a box.";
|
||||||
info.setParams(SHAPE_TYPE_BOX, 0.5f * dimensions);
|
shapeInfo.setParams(SHAPE_TYPE_BOX, 0.5f * dimensions);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& meshes = _model->getGeometry()->getMeshes();
|
auto& meshes = _model->getGeometry()->getMeshes();
|
||||||
int32_t numMeshes = (int32_t)(meshes.size());
|
int32_t numMeshes = (int32_t)(meshes.size());
|
||||||
|
|
||||||
ShapeInfo::PointCollection& pointCollection = info.getPointCollection();
|
ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection();
|
||||||
pointCollection.clear();
|
pointCollection.clear();
|
||||||
if (type == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
if (type == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
||||||
pointCollection.resize(numMeshes);
|
pointCollection.resize(numMeshes);
|
||||||
|
@ -772,7 +773,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
pointCollection.resize(1);
|
pointCollection.resize(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeInfo::TriangleIndices& triangleIndices = info.getTriangleIndices();
|
ShapeInfo::TriangleIndices& triangleIndices = shapeInfo.getTriangleIndices();
|
||||||
triangleIndices.clear();
|
triangleIndices.clear();
|
||||||
|
|
||||||
Extents extents;
|
Extents extents;
|
||||||
|
@ -946,12 +947,13 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info.setParams(type, 0.5f * dimensions, _modelURL);
|
shapeInfo.setParams(type, 0.5f * dimensions, _modelURL);
|
||||||
} else {
|
} else {
|
||||||
ModelEntityItem::computeShapeInfo(info);
|
ModelEntityItem::computeShapeInfo(shapeInfo);
|
||||||
info.setParams(type, 0.5f * dimensions);
|
shapeInfo.setParams(type, 0.5f * dimensions);
|
||||||
adjustShapeInfoByRegistration(info);
|
|
||||||
}
|
}
|
||||||
|
// finally apply the registration offset to the shapeInfo
|
||||||
|
adjustShapeInfoByRegistration(shapeInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableModelEntityItem::setCollisionShape(const btCollisionShape* shape) {
|
void RenderableModelEntityItem::setCollisionShape(const btCollisionShape* shape) {
|
||||||
|
|
|
@ -60,7 +60,7 @@ public:
|
||||||
virtual void setCompoundShapeURL(const QString& url) override;
|
virtual void setCompoundShapeURL(const QString& url) override;
|
||||||
|
|
||||||
virtual bool isReadyToComputeShape() override;
|
virtual bool isReadyToComputeShape() override;
|
||||||
virtual void computeShapeInfo(ShapeInfo& info) override;
|
virtual void computeShapeInfo(ShapeInfo& shapeInfo) override;
|
||||||
|
|
||||||
void setCollisionShape(const btCollisionShape* shape) override;
|
void setCollisionShape(const btCollisionShape* shape) override;
|
||||||
|
|
||||||
|
|
|
@ -1284,6 +1284,11 @@ void Model::createCollisionRenderItemSet() {
|
||||||
// We should not have any existing renderItems if we enter this section of code
|
// We should not have any existing renderItems if we enter this section of code
|
||||||
Q_ASSERT(_collisionRenderItemsSet.isEmpty());
|
Q_ASSERT(_collisionRenderItemsSet.isEmpty());
|
||||||
|
|
||||||
|
Transform identity;
|
||||||
|
identity.setIdentity();
|
||||||
|
Transform offset;
|
||||||
|
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();
|
||||||
for (uint32_t i = 0; i < numMeshes; i++) {
|
for (uint32_t i = 0; i < numMeshes; i++) {
|
||||||
|
@ -1296,7 +1301,9 @@ void Model::createCollisionRenderItemSet() {
|
||||||
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 = _collisionMaterials[partIndex % NUM_COLLISION_HULL_COLORS];
|
model::MaterialPointer& material = _collisionMaterials[partIndex % NUM_COLLISION_HULL_COLORS];
|
||||||
_collisionRenderItemsSet << std::make_shared<MeshPartPayload>(mesh, partIndex, material);
|
auto payload = std::make_shared<MeshPartPayload>(mesh, partIndex, material);
|
||||||
|
payload->updateTransform(identity, offset);
|
||||||
|
_collisionRenderItemsSet << payload;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue