mirror of
https://github.com/JulianGro/overte.git
synced 2025-07-14 07:26:34 +02:00
fix some bugs in models
This commit is contained in:
parent
f3fb39574f
commit
0ae7411bf0
2 changed files with 124 additions and 74 deletions
|
@ -57,10 +57,10 @@ void ModelTreeRenderer::render(RenderMode renderMode) {
|
||||||
|
|
||||||
const FBXGeometry* ModelTreeRenderer::getGeometryForModel(const ModelItem& modelItem) {
|
const FBXGeometry* ModelTreeRenderer::getGeometryForModel(const ModelItem& modelItem) {
|
||||||
const FBXGeometry* result = NULL;
|
const FBXGeometry* result = NULL;
|
||||||
|
|
||||||
Model* model = getModel(modelItem);
|
Model* model = getModel(modelItem);
|
||||||
if (model) {
|
if (model) {
|
||||||
result = &model->getGeometry()->getFBXGeometry();
|
result = &model->getGeometry()->getFBXGeometry();
|
||||||
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,14 @@ Model* ModelTreeRenderer::getModel(const ModelItem& modelItem) {
|
||||||
if (_knownModelsItemModels.find(modelItem.getID()) != _knownModelsItemModels.end()) {
|
if (_knownModelsItemModels.find(modelItem.getID()) != _knownModelsItemModels.end()) {
|
||||||
model = _knownModelsItemModels[modelItem.getID()];
|
model = _knownModelsItemModels[modelItem.getID()];
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
// Make sure we only create new models on the thread that owns the ModelTreeRenderer
|
||||||
|
if (QThread::currentThread() != thread()) {
|
||||||
|
QMetaObject::invokeMethod(this, "getModel", Qt::BlockingQueuedConnection,
|
||||||
|
Q_RETURN_ARG(Model*, model), Q_ARG(const ModelItem&, modelItem));
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
model = new Model();
|
model = new Model();
|
||||||
model->init();
|
model->init();
|
||||||
model->setURL(QUrl(modelItem.getModelURL()));
|
model->setURL(QUrl(modelItem.getModelURL()));
|
||||||
|
@ -81,6 +89,13 @@ Model* ModelTreeRenderer::getModel(const ModelItem& modelItem) {
|
||||||
if (_unknownModelsItemModels.find(modelItem.getCreatorTokenID()) != _unknownModelsItemModels.end()) {
|
if (_unknownModelsItemModels.find(modelItem.getCreatorTokenID()) != _unknownModelsItemModels.end()) {
|
||||||
model = _unknownModelsItemModels[modelItem.getCreatorTokenID()];
|
model = _unknownModelsItemModels[modelItem.getCreatorTokenID()];
|
||||||
} else {
|
} else {
|
||||||
|
// Make sure we only create new models on the thread that owns the ModelTreeRenderer
|
||||||
|
if (QThread::currentThread() != thread()) {
|
||||||
|
QMetaObject::invokeMethod(this, "getModel", Qt::BlockingQueuedConnection,
|
||||||
|
Q_RETURN_ARG(Model*, model), Q_ARG(const ModelItem&, modelItem));
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
model = new Model();
|
model = new Model();
|
||||||
model->init();
|
model->init();
|
||||||
model->setURL(QUrl(modelItem.getModelURL()));
|
model->setURL(QUrl(modelItem.getModelURL()));
|
||||||
|
@ -187,92 +202,122 @@ void ModelTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
|
||||||
|
|
||||||
if (drawAsModel) {
|
if (drawAsModel) {
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
{
|
||||||
const float alpha = 1.0f;
|
const float alpha = 1.0f;
|
||||||
|
|
||||||
Model* model = getModel(modelItem);
|
Model* model = getModel(modelItem);
|
||||||
|
|
||||||
model->setScaleToFit(true, radius * 2.0f);
|
if (model) {
|
||||||
model->setSnapModelToCenter(true);
|
model->setScaleToFit(true, radius * 2.0f);
|
||||||
|
model->setSnapModelToCenter(true);
|
||||||
|
|
||||||
// set the rotation
|
// set the rotation
|
||||||
glm::quat rotation = modelItem.getModelRotation();
|
glm::quat rotation = modelItem.getModelRotation();
|
||||||
model->setRotation(rotation);
|
model->setRotation(rotation);
|
||||||
|
|
||||||
// set the position
|
// set the position
|
||||||
model->setTranslation(position);
|
model->setTranslation(position);
|
||||||
|
|
||||||
// handle animations..
|
// handle animations..
|
||||||
if (modelItem.hasAnimation()) {
|
if (modelItem.hasAnimation()) {
|
||||||
if (!modelItem.jointsMapped()) {
|
if (!modelItem.jointsMapped()) {
|
||||||
QStringList modelJointNames = model->getJointNames();
|
QStringList modelJointNames = model->getJointNames();
|
||||||
modelItem.mapJoints(modelJointNames);
|
modelItem.mapJoints(modelJointNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<glm::quat> frameData = modelItem.getAnimationFrame();
|
||||||
|
for (int i = 0; i < frameData.size(); i++) {
|
||||||
|
model->setJointState(i, true, frameData[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<glm::quat> frameData = modelItem.getAnimationFrame();
|
// make sure to simulate so everything gets set up correctly for rendering
|
||||||
for (int i = 0; i < frameData.size(); i++) {
|
model->simulate(0.0f);
|
||||||
model->setJointState(i, true, frameData[i]);
|
|
||||||
|
// TODO: should we allow modelItems to have alpha on their models?
|
||||||
|
Model::RenderMode modelRenderMode = args->_renderMode == OctreeRenderer::SHADOW_RENDER_MODE
|
||||||
|
? Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE;
|
||||||
|
|
||||||
|
if (modelItem.getGlowLevel() > 0.0f) {
|
||||||
|
Glower glower(modelItem.getGlowLevel());
|
||||||
|
|
||||||
|
if (model->isActive()) {
|
||||||
|
model->render(alpha, modelRenderMode);
|
||||||
|
} else {
|
||||||
|
// if we couldn't get a model, then just draw a sphere
|
||||||
|
glColor3ub(modelItem.getColor()[RED_INDEX],modelItem.getColor()[GREEN_INDEX],modelItem.getColor()[BLUE_INDEX]);
|
||||||
|
glPushMatrix();
|
||||||
|
glTranslatef(position.x, position.y, position.z);
|
||||||
|
glutSolidSphere(radius, 15, 15);
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (model->isActive()) {
|
||||||
|
model->render(alpha, modelRenderMode);
|
||||||
|
} else {
|
||||||
|
// if we couldn't get a model, then just draw a sphere
|
||||||
|
glColor3ub(modelItem.getColor()[RED_INDEX],modelItem.getColor()[GREEN_INDEX],modelItem.getColor()[BLUE_INDEX]);
|
||||||
|
glPushMatrix();
|
||||||
|
glTranslatef(position.x, position.y, position.z);
|
||||||
|
glutSolidSphere(radius, 15, 15);
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// make sure to simulate so everything gets set up correctly for rendering
|
if (!isShadowMode && displayModelBounds) {
|
||||||
model->simulate(0.0f);
|
|
||||||
|
|
||||||
// TODO: should we allow modelItems to have alpha on their models?
|
glm::vec3 unRotatedMinimum = model->getUnscaledMeshExtents().minimum;
|
||||||
Model::RenderMode modelRenderMode = args->_renderMode == OctreeRenderer::SHADOW_RENDER_MODE
|
glm::vec3 unRotatedMaximum = model->getUnscaledMeshExtents().maximum;
|
||||||
? Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE;
|
glm::vec3 unRotatedExtents = unRotatedMaximum - unRotatedMinimum;
|
||||||
|
|
||||||
if (modelItem.getGlowLevel() > 0.0f) {
|
float width = unRotatedExtents.x;
|
||||||
Glower glower(modelItem.getGlowLevel());
|
float height = unRotatedExtents.y;
|
||||||
model->render(alpha, modelRenderMode);
|
float depth = unRotatedExtents.z;
|
||||||
} else {
|
|
||||||
model->render(alpha, modelRenderMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isShadowMode && displayModelBounds) {
|
Extents rotatedExtents = model->getUnscaledMeshExtents();
|
||||||
|
calculateRotatedExtents(rotatedExtents, rotation);
|
||||||
|
|
||||||
glm::vec3 unRotatedMinimum = model->getUnscaledMeshExtents().minimum;
|
glm::vec3 rotatedSize = rotatedExtents.maximum - rotatedExtents.minimum;
|
||||||
glm::vec3 unRotatedMaximum = model->getUnscaledMeshExtents().maximum;
|
|
||||||
glm::vec3 unRotatedExtents = unRotatedMaximum - unRotatedMinimum;
|
|
||||||
|
|
||||||
float width = unRotatedExtents.x;
|
const glm::vec3& modelScale = model->getScale();
|
||||||
float height = unRotatedExtents.y;
|
|
||||||
float depth = unRotatedExtents.z;
|
|
||||||
|
|
||||||
Extents rotatedExtents = model->getUnscaledMeshExtents();
|
|
||||||
calculateRotatedExtents(rotatedExtents, rotation);
|
|
||||||
|
|
||||||
glm::vec3 rotatedSize = rotatedExtents.maximum - rotatedExtents.minimum;
|
|
||||||
|
|
||||||
const glm::vec3& modelScale = model->getScale();
|
|
||||||
|
|
||||||
glPushMatrix();
|
|
||||||
glTranslatef(position.x, position.y, position.z);
|
|
||||||
|
|
||||||
// draw the orignal bounding cube
|
|
||||||
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
|
|
||||||
glutWireCube(size);
|
|
||||||
|
|
||||||
// draw the rotated bounding cube
|
|
||||||
glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glScalef(rotatedSize.x * modelScale.x, rotatedSize.y * modelScale.y, rotatedSize.z * modelScale.z);
|
glTranslatef(position.x, position.y, position.z);
|
||||||
|
|
||||||
|
// draw the orignal bounding cube
|
||||||
|
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
|
||||||
|
glutWireCube(size);
|
||||||
|
|
||||||
|
// draw the rotated bounding cube
|
||||||
|
glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
|
||||||
|
glPushMatrix();
|
||||||
|
glScalef(rotatedSize.x * modelScale.x, rotatedSize.y * modelScale.y, rotatedSize.z * modelScale.z);
|
||||||
|
glutWireCube(1.0);
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
// draw the model relative bounding box
|
||||||
|
glm::vec3 axis = glm::axis(rotation);
|
||||||
|
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||||
|
glScalef(width * modelScale.x, height * modelScale.y, depth * modelScale.z);
|
||||||
|
glColor3f(0.0f, 1.0f, 0.0f);
|
||||||
glutWireCube(1.0);
|
glutWireCube(1.0);
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
// draw the model relative bounding box
|
}
|
||||||
glm::vec3 axis = glm::axis(rotation);
|
} else {
|
||||||
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
// if we couldn't get a model, then just draw a sphere
|
||||||
glScalef(width * modelScale.x, height * modelScale.y, depth * modelScale.z);
|
glColor3ub(modelItem.getColor()[RED_INDEX],modelItem.getColor()[GREEN_INDEX],modelItem.getColor()[BLUE_INDEX]);
|
||||||
glColor3f(0.0f, 1.0f, 0.0f);
|
glPushMatrix();
|
||||||
glutWireCube(1.0);
|
glTranslatef(position.x, position.y, position.z);
|
||||||
|
glutSolidSphere(radius, 15, 15);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
} else {
|
} else {
|
||||||
glColor3ub(modelItem.getColor()[RED_INDEX],modelItem.getColor()[GREEN_INDEX],modelItem.getColor()[BLUE_INDEX]);
|
//glColor3ub(modelItem.getColor()[RED_INDEX],modelItem.getColor()[GREEN_INDEX],modelItem.getColor()[BLUE_INDEX]);
|
||||||
|
glColor3f(1.0f, 0.0f, 0.0f);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(position.x, position.y, position.z);
|
glTranslatef(position.x, position.y, position.z);
|
||||||
glutSolidSphere(radius, 15, 15);
|
glutSolidSphere(radius, 15, 15);
|
||||||
|
|
|
@ -186,6 +186,11 @@ bool ModelTreeElement::findDetailedRayIntersection(const glm::vec3& origin, cons
|
||||||
if (fbxGeometry && fbxGeometry->meshExtents.isValid()) {
|
if (fbxGeometry && fbxGeometry->meshExtents.isValid()) {
|
||||||
Extents extents = fbxGeometry->meshExtents;
|
Extents extents = fbxGeometry->meshExtents;
|
||||||
|
|
||||||
|
// NOTE: If the model has a bad mesh, then extents will be 0,0,0 & 0,0,0
|
||||||
|
if (extents.minimum == extents.maximum && extents.minimum == glm::vec3(0,0,0)) {
|
||||||
|
extents.maximum = glm::vec3(1.0f,1.0f,1.0f); // in this case we will simulate the unit cube
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: these extents are model space, so we need to scale and center them accordingly
|
// NOTE: these extents are model space, so we need to scale and center them accordingly
|
||||||
// size is our "target size in world space"
|
// size is our "target size in world space"
|
||||||
// we need to set our model scale so that the extents of the mesh, fit in a cube that size...
|
// we need to set our model scale so that the extents of the mesh, fit in a cube that size...
|
||||||
|
|
Loading…
Reference in a new issue