Merge pull request #3009 from ZappoMan/bugFix

fix some bugs in models
This commit is contained in:
Andrzej Kapolka 2014-06-10 16:56:56 -07:00
commit f677858891
2 changed files with 124 additions and 74 deletions

View file

@ -57,21 +57,29 @@ void ModelTreeRenderer::render(RenderMode renderMode) {
const FBXGeometry* ModelTreeRenderer::getGeometryForModel(const ModelItem& modelItem) {
const FBXGeometry* result = NULL;
Model* model = getModel(modelItem);
if (model) {
result = &model->getGeometry()->getFBXGeometry();
}
return result;
}
Model* ModelTreeRenderer::getModel(const ModelItem& modelItem) {
Model* model = NULL;
if (modelItem.isKnownID()) {
if (_knownModelsItemModels.find(modelItem.getID()) != _knownModelsItemModels.end()) {
model = _knownModelsItemModels[modelItem.getID()];
} 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->init();
model->setURL(QUrl(modelItem.getModelURL()));
@ -81,6 +89,13 @@ Model* ModelTreeRenderer::getModel(const ModelItem& modelItem) {
if (_unknownModelsItemModels.find(modelItem.getCreatorTokenID()) != _unknownModelsItemModels.end()) {
model = _unknownModelsItemModels[modelItem.getCreatorTokenID()];
} 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->init();
model->setURL(QUrl(modelItem.getModelURL()));
@ -187,92 +202,122 @@ void ModelTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
if (drawAsModel) {
glPushMatrix();
{
const float alpha = 1.0f;
Model* model = getModel(modelItem);
model->setScaleToFit(true, radius * 2.0f);
model->setSnapModelToCenter(true);
// set the rotation
glm::quat rotation = modelItem.getModelRotation();
model->setRotation(rotation);
// set the position
model->setTranslation(position);
// handle animations..
if (modelItem.hasAnimation()) {
if (!modelItem.jointsMapped()) {
QStringList modelJointNames = model->getJointNames();
modelItem.mapJoints(modelJointNames);
if (model) {
model->setScaleToFit(true, radius * 2.0f);
model->setSnapModelToCenter(true);
// set the rotation
glm::quat rotation = modelItem.getModelRotation();
model->setRotation(rotation);
// set the position
model->setTranslation(position);
// handle animations..
if (modelItem.hasAnimation()) {
if (!modelItem.jointsMapped()) {
QStringList modelJointNames = model->getJointNames();
modelItem.mapJoints(modelJointNames);
}
QVector<glm::quat> frameData = modelItem.getAnimationFrame();
for (int i = 0; i < frameData.size(); i++) {
model->setJointState(i, true, frameData[i]);
}
}
// make sure to simulate so everything gets set up correctly for rendering
model->simulate(0.0f);
// 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();
}
}
QVector<glm::quat> frameData = modelItem.getAnimationFrame();
for (int i = 0; i < frameData.size(); i++) {
model->setJointState(i, true, frameData[i]);
}
}
// make sure to simulate so everything gets set up correctly for rendering
model->simulate(0.0f);
if (!isShadowMode && displayModelBounds) {
// 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());
model->render(alpha, modelRenderMode);
glm::vec3 unRotatedMinimum = model->getUnscaledMeshExtents().minimum;
glm::vec3 unRotatedMaximum = model->getUnscaledMeshExtents().maximum;
glm::vec3 unRotatedExtents = unRotatedMaximum - unRotatedMinimum;
float width = unRotatedExtents.x;
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();
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);
glPopMatrix();
}
} else {
model->render(alpha, modelRenderMode);
}
if (!isShadowMode && displayModelBounds) {
glm::vec3 unRotatedMinimum = model->getUnscaledMeshExtents().minimum;
glm::vec3 unRotatedMaximum = model->getUnscaledMeshExtents().maximum;
glm::vec3 unRotatedExtents = unRotatedMaximum - unRotatedMinimum;
float width = unRotatedExtents.x;
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();
// 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);
// 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);
glutSolidSphere(radius, 15, 15);
glPopMatrix();
}
}
glPopMatrix();
} 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();
glTranslatef(position.x, position.y, position.z);
glutSolidSphere(radius, 15, 15);

View file

@ -186,6 +186,11 @@ bool ModelTreeElement::findDetailedRayIntersection(const glm::vec3& origin, cons
if (fbxGeometry && fbxGeometry->meshExtents.isValid()) {
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
// 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...