From 6fd22856f22449bc4c973612cb7d86886050a035 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 28 May 2014 10:24:02 -0700 Subject: [PATCH 1/5] hacking on non-AABox models --- examples/editModelExample.js | 14 ++-- interface/src/models/ModelTreeRenderer.cpp | 87 ++++++++++++++++++++++ libraries/models/src/ModelTreeElement.cpp | 53 ++++++++++++- 3 files changed, 143 insertions(+), 11 deletions(-) diff --git a/examples/editModelExample.js b/examples/editModelExample.js index dbea1419ba..3b23b3ca5a 100644 --- a/examples/editModelExample.js +++ b/examples/editModelExample.js @@ -15,13 +15,13 @@ var count = 0; var moveUntil = 2000; var stopAfter = moveUntil + 100; -var pitch = 90.0; +var pitch = 0.0; var yaw = 0.0; -var roll = 180.0; +var roll = 0.0; var rotation = Quat.fromPitchYawRollDegrees(pitch, yaw, roll) var originalProperties = { - position: { x: 10, + position: { x: 0, y: 0, z: 0 }, @@ -31,12 +31,12 @@ var originalProperties = { green: 255, blue: 0 }, - //modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/Feisar_Ship.FBX", + modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/Feisar_Ship.FBX", //modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/birarda/birarda_head.fbx", //modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/pug.fbx", //modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/newInvader16x16-large-purple.svo", //modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/minotaur/mino_full.fbx", - modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/Combat_tank_V01.FBX", + //modelURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/Combat_tank_V01.FBX", modelRotation: rotation }; @@ -51,8 +51,8 @@ function moveModel(deltaTime) { // delete it... if (count == moveUntil) { - print("calling Models.deleteModel()"); - Models.deleteModel(modelID); + //print("calling Models.deleteModel()"); + //Models.deleteModel(modelID); } // stop it... diff --git a/interface/src/models/ModelTreeRenderer.cpp b/interface/src/models/ModelTreeRenderer.cpp index 68bebd7b99..777459d642 100644 --- a/interface/src/models/ModelTreeRenderer.cpp +++ b/interface/src/models/ModelTreeRenderer.cpp @@ -10,6 +10,7 @@ // #include +#include #include @@ -267,6 +268,92 @@ void ModelTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args) glutWireCube(1.0); glPopMatrix(); + + + glPushMatrix(); + { + Extents extents = model->getUnscaledMeshExtents(); + +qDebug() << "original..."; + +qDebug() << " extents.minimum=" << extents.minimum.x << "," << extents.minimum.y << "," << extents.minimum.z; +qDebug() << " extents.maximum=" << extents.maximum.x << "," << extents.maximum.y << "," << extents.maximum.z; + + float maxDimension = glm::distance(extents.maximum, extents.minimum); + float scale = modelItem.getSize() / maxDimension; + +qDebug() << " maxDimension=" << maxDimension; +qDebug() << " modelItem.getSize()=" << modelItem.getSize(); +qDebug() << " modelItem.getSize() [meters]=" << modelItem.getSize() * (float)TREE_SCALE; +qDebug() << " scale=" << scale; + + glm::vec3 halfDimensions = (extents.maximum - extents.minimum) * 0.5f; + glm::vec3 offset = -extents.minimum - halfDimensions; + + extents.minimum += offset; + extents.maximum += offset; + +qDebug() << "after offset..."; + +qDebug() << " extents.minimum=" << extents.minimum.x << "," << extents.minimum.y << "," << extents.minimum.z; +qDebug() << " extents.maximum=" << extents.maximum.x << "," << extents.maximum.y << "," << extents.maximum.z; + + extents.minimum *= (scale * (float)TREE_SCALE); + extents.maximum *= (scale * (float)TREE_SCALE); + +qDebug() << "after scale..."; + +qDebug() << " extents.minimum=" << extents.minimum.x << "," << extents.minimum.y << "," << extents.minimum.z; +qDebug() << " extents.maximum=" << extents.maximum.x << "," << extents.maximum.y << "," << extents.maximum.z; + + // using transform matrix draw spheres at corners + glm::mat4 rotation = glm::mat4_cast(modelItem.getModelRotation()); + glm::vec3 modelPosition = modelItem.getPosition() * (float)TREE_SCALE; + glm::mat4 translation = glm::translate(modelPosition); + glm::mat4 modelToWorldMatrix = translation * rotation; + glm::mat4 worldToModelMatrix = glm::inverse(modelToWorldMatrix); + + + glm::vec3 modelOrigin(0); + glm::vec3 modelOriginInWorld = glm::vec3(modelToWorldMatrix * glm::vec4(modelOrigin, 1.0f)); + + glm::vec3 bottomLeftNear = extents.minimum; + glm::vec3 topRightFar = extents.maximum; + + glm::vec3 blnInWorld = glm::vec3(modelToWorldMatrix * glm::vec4(bottomLeftNear, 1.0f)); + glm::vec3 trfInWorld = glm::vec3(modelToWorldMatrix * glm::vec4(topRightFar, 1.0f)); + +//qDebug() << "modelPosition =" << modelPosition.x << "," << modelPosition.y << "," << modelPosition.z; +//qDebug() << "modelOrigin =" << modelOrigin.x << "," << modelOrigin.y << "," << modelOrigin.z; +//qDebug() << "modelOriginInWorld =" << modelOriginInWorld.x << "," << modelOriginInWorld.y << "," << modelOriginInWorld.z; + +qDebug() << " modelPosition =" << modelPosition.x << "," << modelPosition.y << "," << modelPosition.z; +qDebug() << " bottomLeftNear =" << bottomLeftNear.x << "," << bottomLeftNear.y << "," << bottomLeftNear.z; +qDebug() << " blnInWorld =" << blnInWorld.x << "," << blnInWorld.y << "," << blnInWorld.z; + + glPushMatrix(); + glTranslatef(modelOriginInWorld.x, modelOriginInWorld.y, modelOriginInWorld.z); + // draw the orignal bounding cube + glColor3f(0.0f, 1.0f, 0.0f); + glutSolidCube(0.02f); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(blnInWorld.x, blnInWorld.y, blnInWorld.z); + // draw the orignal bounding cube + glColor3f(0.0f, 0.0f, 1.0f); + glutSolidCube(0.02f); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(trfInWorld.x, trfInWorld.y, trfInWorld.z); + // draw the orignal bounding cube + glColor3f(1.0f, 0.0f, 1.0f); + glutSolidCube(0.02f); + glPopMatrix(); + + } + glPopMatrix(); } diff --git a/libraries/models/src/ModelTreeElement.cpp b/libraries/models/src/ModelTreeElement.cpp index dad592f838..12d427aee5 100644 --- a/libraries/models/src/ModelTreeElement.cpp +++ b/libraries/models/src/ModelTreeElement.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include #include @@ -177,15 +179,58 @@ bool ModelTreeElement::findDetailedRayIntersection(const glm::vec3& origin, cons extents.minimum *= scale; extents.maximum *= scale; + + Extents rotatedExtents = extents; - calculateRotatedExtents(extents, model.getModelRotation()); + calculateRotatedExtents(rotatedExtents, model.getModelRotation()); - extents.minimum += model.getPosition(); - extents.maximum += model.getPosition(); + rotatedExtents.minimum += model.getPosition(); + rotatedExtents.maximum += model.getPosition(); - AABox rotatedExtentsBox(extents.minimum, (extents.maximum - extents.minimum)); + + AABox rotatedExtentsBox(rotatedExtents.minimum, (rotatedExtents.maximum - rotatedExtents.minimum)); if (rotatedExtentsBox.findRayIntersection(origin, direction, localDistance, localFace)) { + // if it's in our AABOX for our rotated extents, then check to see if it's in our non-AABox + + glm::mat4 rotation = glm::mat4_cast(model.getModelRotation()); + glm::mat4 translation = glm::translate(model.getPosition()); + glm::mat4 modelToWorldMatrix = rotation; // * translation; + glm::mat4 worldToModelMatrix = modelToWorldMatrix; // glm::inverse(modelToWorldMatrix); + + // Note: reference, to get the point after rotation, take the rotation * the original point + //glm::vec3 rotatedPoint = rotation * originalPoint; + + AABox nonAABox(extents.minimum, (extents.maximum - extents.minimum)); + + glm::vec3 endPoint = origin + direction; + + + glm::vec3 originInModelFrame = glm::vec3(worldToModelMatrix * glm::vec4(origin, 0.0f)); + glm::vec3 endPointInModelFrame = glm::vec3(worldToModelMatrix * glm::vec4(endPoint, 0.0f)); + glm::vec3 directionInModelFrame = endPointInModelFrame - originInModelFrame; + glm::vec3 altDirectionInModelFrame = glm::vec3(worldToModelMatrix * glm::vec4(direction, 0.0f)); + + +qDebug() << "origin =" << origin.x << "," << origin.y << "," << origin.z; +qDebug() << "originInModelFrame =" << originInModelFrame.x << "," << originInModelFrame.y << "," << originInModelFrame.z; + +qDebug() << "endPoint =" << endPoint.x << "," << endPoint.y << "," << endPoint.z; +qDebug() << "endPointInModelFrame =" << endPointInModelFrame.x << "," << endPointInModelFrame.y << "," << endPointInModelFrame.z; + +qDebug() << "direction =" << direction.x << "," << direction.y << "," << direction.z; +qDebug() << "directionInModelFrame =" << directionInModelFrame.x << "," << directionInModelFrame.y << "," << directionInModelFrame.z; +qDebug() << "altDirectionInModelFrame=" << altDirectionInModelFrame.x << "," << altDirectionInModelFrame.y << "," << altDirectionInModelFrame.z; + + float xDistance; + BoxFace xFace; + + if (nonAABox.findRayIntersection(originInModelFrame, directionInModelFrame, xDistance, xFace)) { + qDebug() << "woot! got it! (originInModelFrame, directionInModelFrame) intersects nonAABox!"; + } else { + qDebug() << "NOPE! doesn't (originInModelFrame, directionInModelFrame) intersect nonAABox!"; + } + if (localDistance < distance) { distance = localDistance; face = localFace; From bebfd7a301be868cd7961004f6dd43dad809c0bb Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 28 May 2014 12:02:22 -0700 Subject: [PATCH 2/5] non-aabox picking working --- interface/src/models/ModelTreeRenderer.cpp | 86 ---------------------- libraries/models/src/ModelTreeElement.cpp | 52 ++++--------- 2 files changed, 14 insertions(+), 124 deletions(-) diff --git a/interface/src/models/ModelTreeRenderer.cpp b/interface/src/models/ModelTreeRenderer.cpp index 777459d642..5f6ac5f21f 100644 --- a/interface/src/models/ModelTreeRenderer.cpp +++ b/interface/src/models/ModelTreeRenderer.cpp @@ -268,92 +268,6 @@ void ModelTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args) glutWireCube(1.0); glPopMatrix(); - - - glPushMatrix(); - { - Extents extents = model->getUnscaledMeshExtents(); - -qDebug() << "original..."; - -qDebug() << " extents.minimum=" << extents.minimum.x << "," << extents.minimum.y << "," << extents.minimum.z; -qDebug() << " extents.maximum=" << extents.maximum.x << "," << extents.maximum.y << "," << extents.maximum.z; - - float maxDimension = glm::distance(extents.maximum, extents.minimum); - float scale = modelItem.getSize() / maxDimension; - -qDebug() << " maxDimension=" << maxDimension; -qDebug() << " modelItem.getSize()=" << modelItem.getSize(); -qDebug() << " modelItem.getSize() [meters]=" << modelItem.getSize() * (float)TREE_SCALE; -qDebug() << " scale=" << scale; - - glm::vec3 halfDimensions = (extents.maximum - extents.minimum) * 0.5f; - glm::vec3 offset = -extents.minimum - halfDimensions; - - extents.minimum += offset; - extents.maximum += offset; - -qDebug() << "after offset..."; - -qDebug() << " extents.minimum=" << extents.minimum.x << "," << extents.minimum.y << "," << extents.minimum.z; -qDebug() << " extents.maximum=" << extents.maximum.x << "," << extents.maximum.y << "," << extents.maximum.z; - - extents.minimum *= (scale * (float)TREE_SCALE); - extents.maximum *= (scale * (float)TREE_SCALE); - -qDebug() << "after scale..."; - -qDebug() << " extents.minimum=" << extents.minimum.x << "," << extents.minimum.y << "," << extents.minimum.z; -qDebug() << " extents.maximum=" << extents.maximum.x << "," << extents.maximum.y << "," << extents.maximum.z; - - // using transform matrix draw spheres at corners - glm::mat4 rotation = glm::mat4_cast(modelItem.getModelRotation()); - glm::vec3 modelPosition = modelItem.getPosition() * (float)TREE_SCALE; - glm::mat4 translation = glm::translate(modelPosition); - glm::mat4 modelToWorldMatrix = translation * rotation; - glm::mat4 worldToModelMatrix = glm::inverse(modelToWorldMatrix); - - - glm::vec3 modelOrigin(0); - glm::vec3 modelOriginInWorld = glm::vec3(modelToWorldMatrix * glm::vec4(modelOrigin, 1.0f)); - - glm::vec3 bottomLeftNear = extents.minimum; - glm::vec3 topRightFar = extents.maximum; - - glm::vec3 blnInWorld = glm::vec3(modelToWorldMatrix * glm::vec4(bottomLeftNear, 1.0f)); - glm::vec3 trfInWorld = glm::vec3(modelToWorldMatrix * glm::vec4(topRightFar, 1.0f)); - -//qDebug() << "modelPosition =" << modelPosition.x << "," << modelPosition.y << "," << modelPosition.z; -//qDebug() << "modelOrigin =" << modelOrigin.x << "," << modelOrigin.y << "," << modelOrigin.z; -//qDebug() << "modelOriginInWorld =" << modelOriginInWorld.x << "," << modelOriginInWorld.y << "," << modelOriginInWorld.z; - -qDebug() << " modelPosition =" << modelPosition.x << "," << modelPosition.y << "," << modelPosition.z; -qDebug() << " bottomLeftNear =" << bottomLeftNear.x << "," << bottomLeftNear.y << "," << bottomLeftNear.z; -qDebug() << " blnInWorld =" << blnInWorld.x << "," << blnInWorld.y << "," << blnInWorld.z; - - glPushMatrix(); - glTranslatef(modelOriginInWorld.x, modelOriginInWorld.y, modelOriginInWorld.z); - // draw the orignal bounding cube - glColor3f(0.0f, 1.0f, 0.0f); - glutSolidCube(0.02f); - glPopMatrix(); - - glPushMatrix(); - glTranslatef(blnInWorld.x, blnInWorld.y, blnInWorld.z); - // draw the orignal bounding cube - glColor3f(0.0f, 0.0f, 1.0f); - glutSolidCube(0.02f); - glPopMatrix(); - - glPushMatrix(); - glTranslatef(trfInWorld.x, trfInWorld.y, trfInWorld.z); - // draw the orignal bounding cube - glColor3f(1.0f, 0.0f, 1.0f); - glutSolidCube(0.02f); - glPopMatrix(); - - } - glPopMatrix(); } diff --git a/libraries/models/src/ModelTreeElement.cpp b/libraries/models/src/ModelTreeElement.cpp index 12d427aee5..31f786c15c 100644 --- a/libraries/models/src/ModelTreeElement.cpp +++ b/libraries/models/src/ModelTreeElement.cpp @@ -192,51 +192,27 @@ bool ModelTreeElement::findDetailedRayIntersection(const glm::vec3& origin, cons if (rotatedExtentsBox.findRayIntersection(origin, direction, localDistance, localFace)) { // if it's in our AABOX for our rotated extents, then check to see if it's in our non-AABox - + + // extents is the model relative, scaled, centered extents of the model + glm::mat4 rotation = glm::mat4_cast(model.getModelRotation()); glm::mat4 translation = glm::translate(model.getPosition()); - glm::mat4 modelToWorldMatrix = rotation; // * translation; - glm::mat4 worldToModelMatrix = modelToWorldMatrix; // glm::inverse(modelToWorldMatrix); + glm::mat4 modelToWorldMatrix = translation * rotation; + glm::mat4 worldToModelMatrix = glm::inverse(modelToWorldMatrix); - // Note: reference, to get the point after rotation, take the rotation * the original point - //glm::vec3 rotatedPoint = rotation * originalPoint; - AABox nonAABox(extents.minimum, (extents.maximum - extents.minimum)); - glm::vec3 endPoint = origin + direction; - + glm::vec3 originInModelFrame = glm::vec3(worldToModelMatrix * glm::vec4(origin, 1.0f)); + glm::vec3 directionInModelFrame = glm::vec3(worldToModelMatrix * glm::vec4(direction, 1.0f)); - glm::vec3 originInModelFrame = glm::vec3(worldToModelMatrix * glm::vec4(origin, 0.0f)); - glm::vec3 endPointInModelFrame = glm::vec3(worldToModelMatrix * glm::vec4(endPoint, 0.0f)); - glm::vec3 directionInModelFrame = endPointInModelFrame - originInModelFrame; - glm::vec3 altDirectionInModelFrame = glm::vec3(worldToModelMatrix * glm::vec4(direction, 0.0f)); - - -qDebug() << "origin =" << origin.x << "," << origin.y << "," << origin.z; -qDebug() << "originInModelFrame =" << originInModelFrame.x << "," << originInModelFrame.y << "," << originInModelFrame.z; - -qDebug() << "endPoint =" << endPoint.x << "," << endPoint.y << "," << endPoint.z; -qDebug() << "endPointInModelFrame =" << endPointInModelFrame.x << "," << endPointInModelFrame.y << "," << endPointInModelFrame.z; - -qDebug() << "direction =" << direction.x << "," << direction.y << "," << direction.z; -qDebug() << "directionInModelFrame =" << directionInModelFrame.x << "," << directionInModelFrame.y << "," << directionInModelFrame.z; -qDebug() << "altDirectionInModelFrame=" << altDirectionInModelFrame.x << "," << altDirectionInModelFrame.y << "," << altDirectionInModelFrame.z; - - float xDistance; - BoxFace xFace; - - if (nonAABox.findRayIntersection(originInModelFrame, directionInModelFrame, xDistance, xFace)) { - qDebug() << "woot! got it! (originInModelFrame, directionInModelFrame) intersects nonAABox!"; - } else { - qDebug() << "NOPE! doesn't (originInModelFrame, directionInModelFrame) intersect nonAABox!"; + if (nonAABox.findRayIntersection(originInModelFrame, directionInModelFrame, localDistance, localFace)) { + if (localDistance < distance) { + distance = localDistance; + face = localFace; + *intersectedObject = (void*)(&model); + somethingIntersected = true; + } } - - if (localDistance < distance) { - distance = localDistance; - face = localFace; - *intersectedObject = (void*)(&model); - somethingIntersected = true; - } } } else if (localDistance < distance) { distance = localDistance; From e3d880248f2be9c1241453a96db8eac67a580c4a Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 28 May 2014 12:03:40 -0700 Subject: [PATCH 3/5] tweaks --- examples/editModelExample.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/editModelExample.js b/examples/editModelExample.js index 3b23b3ca5a..83491e2fb1 100644 --- a/examples/editModelExample.js +++ b/examples/editModelExample.js @@ -15,13 +15,13 @@ var count = 0; var moveUntil = 2000; var stopAfter = moveUntil + 100; -var pitch = 0.0; +var pitch = 90.0; var yaw = 0.0; -var roll = 0.0; +var roll = 180.0; var rotation = Quat.fromPitchYawRollDegrees(pitch, yaw, roll) var originalProperties = { - position: { x: 0, + position: { x: 10, y: 0, z: 0 }, @@ -51,8 +51,8 @@ function moveModel(deltaTime) { // delete it... if (count == moveUntil) { - //print("calling Models.deleteModel()"); - //Models.deleteModel(modelID); + print("calling Models.deleteModel()"); + Models.deleteModel(modelID); } // stop it... From d88dd90d79c1ed76165560f9cef7aea7770f0065 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 28 May 2014 12:04:24 -0700 Subject: [PATCH 4/5] revert dead code --- interface/src/models/ModelTreeRenderer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/models/ModelTreeRenderer.cpp b/interface/src/models/ModelTreeRenderer.cpp index 5f6ac5f21f..68bebd7b99 100644 --- a/interface/src/models/ModelTreeRenderer.cpp +++ b/interface/src/models/ModelTreeRenderer.cpp @@ -10,7 +10,6 @@ // #include -#include #include From 574bca38e60f912068bb4e27611e95bc73fdfa76 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 28 May 2014 12:10:51 -0700 Subject: [PATCH 5/5] clean up comments and variable names --- libraries/models/src/ModelTreeElement.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libraries/models/src/ModelTreeElement.cpp b/libraries/models/src/ModelTreeElement.cpp index 31f786c15c..c655a45b57 100644 --- a/libraries/models/src/ModelTreeElement.cpp +++ b/libraries/models/src/ModelTreeElement.cpp @@ -190,22 +190,23 @@ bool ModelTreeElement::findDetailedRayIntersection(const glm::vec3& origin, cons AABox rotatedExtentsBox(rotatedExtents.minimum, (rotatedExtents.maximum - rotatedExtents.minimum)); + // if it's in our AABOX for our rotated extents, then check to see if it's in our non-AABox if (rotatedExtentsBox.findRayIntersection(origin, direction, localDistance, localFace)) { - // if it's in our AABOX for our rotated extents, then check to see if it's in our non-AABox // extents is the model relative, scaled, centered extents of the model - glm::mat4 rotation = glm::mat4_cast(model.getModelRotation()); glm::mat4 translation = glm::translate(model.getPosition()); glm::mat4 modelToWorldMatrix = translation * rotation; glm::mat4 worldToModelMatrix = glm::inverse(modelToWorldMatrix); - AABox nonAABox(extents.minimum, (extents.maximum - extents.minimum)); + AABox modelFrameBox(extents.minimum, (extents.maximum - extents.minimum)); - glm::vec3 originInModelFrame = glm::vec3(worldToModelMatrix * glm::vec4(origin, 1.0f)); - glm::vec3 directionInModelFrame = glm::vec3(worldToModelMatrix * glm::vec4(direction, 1.0f)); + glm::vec3 modelFrameOrigin = glm::vec3(worldToModelMatrix * glm::vec4(origin, 1.0f)); + glm::vec3 modelFrameDirection = glm::vec3(worldToModelMatrix * glm::vec4(direction, 1.0f)); - if (nonAABox.findRayIntersection(originInModelFrame, directionInModelFrame, localDistance, localFace)) { + // we can use the AABox's ray intersection by mapping our origin and direction into the model frame + // and testing intersection there. + if (modelFrameBox.findRayIntersection(modelFrameOrigin, modelFrameDirection, localDistance, localFace)) { if (localDistance < distance) { distance = localDistance; face = localFace;