mirror of
https://github.com/overte-org/overte.git
synced 2025-06-05 18:51:13 +02:00
Repesenting the collision meshes of a Model correctly
This commit is contained in:
parent
4b03001c61
commit
1adf2cc8ba
4 changed files with 45 additions and 37 deletions
|
@ -106,6 +106,7 @@ public:
|
||||||
bool setAttribute(Slot slot, Frequency frequency = PER_VERTEX);
|
bool setAttribute(Slot slot, Frequency frequency = PER_VERTEX);
|
||||||
bool setAttribute(Slot slot, Slot channel, Frequency frequency = PER_VERTEX);
|
bool setAttribute(Slot slot, Slot channel, Frequency frequency = PER_VERTEX);
|
||||||
|
|
||||||
|
bool hasAttribute(Slot slot) const { return (_attributes.find(slot) != _attributes.end()); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AttributeMap _attributes;
|
AttributeMap _attributes;
|
||||||
|
|
|
@ -39,30 +39,31 @@ namespace render {
|
||||||
|
|
||||||
using namespace render;
|
using namespace render;
|
||||||
|
|
||||||
MeshPartPayload::MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex,
|
MeshPartPayload::MeshPartPayload(Model* model, model::MeshPointer drawMesh, int meshIndex, int partIndex, int shapeIndex,
|
||||||
glm::vec3 position, glm::quat orientation) :
|
glm::vec3 position, glm::quat orientation, bool applyMeshJoints) :
|
||||||
model(model),
|
model(model),
|
||||||
|
_drawMesh(drawMesh),
|
||||||
meshIndex(meshIndex),
|
meshIndex(meshIndex),
|
||||||
partIndex(partIndex),
|
partIndex(partIndex),
|
||||||
_shapeID(shapeIndex),
|
_shapeID(shapeIndex),
|
||||||
_modelPosition(position),
|
_modelPosition(position),
|
||||||
_modelOrientation(orientation) {
|
_modelOrientation(orientation),
|
||||||
|
_applyMeshJoints(applyMeshJoints) {
|
||||||
initCache();
|
initCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshPartPayload::initCache() {
|
void MeshPartPayload::initCache() {
|
||||||
const std::vector<std::unique_ptr<NetworkMesh>>& networkMeshes = model->_geometry->getMeshes();
|
if (_drawMesh) {
|
||||||
const NetworkMesh& networkMesh = *(networkMeshes.at(meshIndex).get());
|
auto vertexFormat = _drawMesh->getVertexFormat();
|
||||||
_drawMesh = networkMesh._mesh;
|
_hasColorAttrib = vertexFormat->hasAttribute(gpu::Stream::COLOR);
|
||||||
|
_isSkinned = vertexFormat->hasAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT) && vertexFormat->hasAttribute(gpu::Stream::SKIN_CLUSTER_INDEX);
|
||||||
|
|
||||||
const FBXGeometry& geometry = model->_geometry->getFBXGeometry();
|
const FBXGeometry& geometry = model->_geometry->getFBXGeometry();
|
||||||
const FBXMesh& mesh = geometry.meshes.at(meshIndex);
|
const FBXMesh& mesh = geometry.meshes.at(meshIndex);
|
||||||
_hasColorAttrib = !mesh.colors.isEmpty();
|
_isBlendShaped = !mesh.blendshapes.isEmpty();
|
||||||
_isBlendShaped = !mesh.blendshapes.isEmpty();
|
|
||||||
_isSkinned = !mesh.clusterIndices.isEmpty();
|
|
||||||
|
|
||||||
|
_drawPart = _drawMesh->getPartBuffer().get<model::Mesh::Part>(partIndex);
|
||||||
_drawPart = _drawMesh->getPartBuffer().get<model::Mesh::Part>(partIndex);
|
}
|
||||||
|
|
||||||
auto networkMaterial = model->_geometry->getShapeMaterial(_shapeID);
|
auto networkMaterial = model->_geometry->getShapeMaterial(_shapeID);
|
||||||
if (networkMaterial) {
|
if (networkMaterial) {
|
||||||
|
@ -219,25 +220,34 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ModelRender::Locatio
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshPartPayload::bindTransform(gpu::Batch& batch, const ModelRender::Locations* locations) const {
|
void MeshPartPayload::bindTransform(gpu::Batch& batch, const ModelRender::Locations* locations) const {
|
||||||
// Still relying on the raw data from the model
|
if (_applyMeshJoints) {
|
||||||
const Model::MeshState& state = model->_meshStates.at(meshIndex);
|
// Still relying on the raw data from the model
|
||||||
|
const Model::MeshState& state = model->_meshStates.at(meshIndex);
|
||||||
|
|
||||||
Transform transform;
|
Transform transform;
|
||||||
if (state.clusterBuffer) {
|
if (state.clusterBuffer) {
|
||||||
if (model->_cauterizeBones) {
|
if (model->_cauterizeBones) {
|
||||||
batch.setUniformBuffer(ModelRender::SKINNING_GPU_SLOT, state.cauterizedClusterBuffer);
|
batch.setUniformBuffer(ModelRender::SKINNING_GPU_SLOT, state.cauterizedClusterBuffer);
|
||||||
|
} else {
|
||||||
|
batch.setUniformBuffer(ModelRender::SKINNING_GPU_SLOT, state.clusterBuffer);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
batch.setUniformBuffer(ModelRender::SKINNING_GPU_SLOT, state.clusterBuffer);
|
if (model->_cauterizeBones) {
|
||||||
|
transform = Transform(state.cauterizedClusterMatrices[0]);
|
||||||
|
} else {
|
||||||
|
transform = Transform(state.clusterMatrices[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
transform.preTranslate(_modelPosition);
|
||||||
|
batch.setModelTransform(transform);
|
||||||
} else {
|
} else {
|
||||||
if (model->_cauterizeBones) {
|
Transform transform;
|
||||||
transform = Transform(state.cauterizedClusterMatrices[0]);
|
transform.setTranslation(_modelPosition);
|
||||||
} else {
|
transform.setRotation(_modelOrientation);
|
||||||
transform = Transform(state.clusterMatrices[0]);
|
transform.postScale(model->getScale());
|
||||||
}
|
transform.postTranslate(model->getOffset());
|
||||||
|
batch.setModelTransform(transform);
|
||||||
}
|
}
|
||||||
transform.preTranslate(_modelPosition);
|
|
||||||
batch.setModelTransform(transform);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -280,13 +290,7 @@ void MeshPartPayload::render(RenderArgs* args) const {
|
||||||
// sanity check
|
// sanity check
|
||||||
return; // FIXME!
|
return; // FIXME!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// guard against partially loaded meshes
|
|
||||||
if (partIndex >= mesh.parts.size()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
model::MaterialKey drawMaterialKey;
|
model::MaterialKey drawMaterialKey;
|
||||||
if (_drawMaterial) {
|
if (_drawMaterial) {
|
||||||
drawMaterialKey = _drawMaterial->getKey();
|
drawMaterialKey = _drawMaterial->getKey();
|
||||||
|
|
|
@ -24,7 +24,7 @@ class Model;
|
||||||
|
|
||||||
class MeshPartPayload {
|
class MeshPartPayload {
|
||||||
public:
|
public:
|
||||||
MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex, glm::vec3 position, glm::quat orientation);
|
MeshPartPayload(Model* model, model::MeshPointer drawMesh, int meshIndex, int partIndex, int shapeIndex, glm::vec3 position, glm::quat orientation, bool applyMeshJoints = true);
|
||||||
|
|
||||||
typedef render::Payload<MeshPartPayload> Payload;
|
typedef render::Payload<MeshPartPayload> Payload;
|
||||||
typedef Payload::DataPointer Pointer;
|
typedef Payload::DataPointer Pointer;
|
||||||
|
@ -36,6 +36,7 @@ public:
|
||||||
glm::vec3 _modelPosition;
|
glm::vec3 _modelPosition;
|
||||||
glm::quat _modelOrientation;
|
glm::quat _modelOrientation;
|
||||||
|
|
||||||
|
|
||||||
// can replace the material used to draw that item
|
// can replace the material used to draw that item
|
||||||
void updateDrawMaterial(model::MaterialPointer material);
|
void updateDrawMaterial(model::MaterialPointer material);
|
||||||
|
|
||||||
|
@ -62,6 +63,7 @@ public:
|
||||||
bool _hasColorAttrib = false;
|
bool _hasColorAttrib = false;
|
||||||
bool _isSkinned = false;
|
bool _isSkinned = false;
|
||||||
bool _isBlendShaped = false;
|
bool _isBlendShaped = false;
|
||||||
|
bool _applyMeshJoints = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace render {
|
namespace render {
|
||||||
|
|
|
@ -90,7 +90,7 @@ void Model::setScale(const glm::vec3& scale) {
|
||||||
_scaledToFit = false;
|
_scaledToFit = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float METERS_PER_MILLIMETER = 0.01f;
|
const float METERS_PER_MILLIMETER = 0.01f;
|
||||||
|
|
||||||
void Model::setScaleInternal(const glm::vec3& scale) {
|
void Model::setScaleInternal(const glm::vec3& scale) {
|
||||||
if (glm::distance(_scale, scale) > METERS_PER_MILLIMETER) {
|
if (glm::distance(_scale, scale) > METERS_PER_MILLIMETER) {
|
||||||
|
@ -1147,11 +1147,12 @@ void Model::segregateMeshGroups() {
|
||||||
int shapeID = 0;
|
int shapeID = 0;
|
||||||
for (int i = 0; i < (int)networkMeshes.size(); i++) {
|
for (int i = 0; i < (int)networkMeshes.size(); i++) {
|
||||||
const FBXMesh& mesh = geometry.meshes.at(i);
|
const FBXMesh& mesh = geometry.meshes.at(i);
|
||||||
|
const NetworkMesh& networkMesh = *(networkMeshes.at(i).get());
|
||||||
|
|
||||||
// Create the render payloads
|
// Create the render payloads
|
||||||
int totalParts = mesh.parts.size();
|
int totalParts = mesh.parts.size();
|
||||||
for (int partIndex = 0; partIndex < totalParts; partIndex++) {
|
for (int partIndex = 0; partIndex < totalParts; partIndex++) {
|
||||||
auto renderItem = std::make_shared<MeshPartPayload>(this, i, partIndex, shapeID, _translation, _rotation);
|
auto renderItem = std::make_shared<MeshPartPayload>(this, networkMesh._mesh, i, partIndex, shapeID, _translation, _rotation, !showingCollisionHull);
|
||||||
if (showingCollisionHull) {
|
if (showingCollisionHull) {
|
||||||
renderItem->updateDrawMaterial(ModelRender::getCollisionHullMaterial());
|
renderItem->updateDrawMaterial(ModelRender::getCollisionHullMaterial());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue