From 9dc26ddfa755f392ab0c8808e6e6066d2577f993 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 27 Feb 2014 15:50:16 -0800 Subject: [PATCH] First pass: add collision Shapes to Model --- interface/src/renderer/Model.cpp | 121 ++++++++++++++++++++----------- interface/src/renderer/Model.h | 7 ++ 2 files changed, 85 insertions(+), 43 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index f1916db4d1..647332998e 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -13,6 +13,9 @@ #include "Application.h" #include "Model.h" +#include +#include + using namespace std; Model::Model(QObject* parent) : @@ -89,6 +92,67 @@ void Model::reset() { } } +void Model::createJointStates() { + const FBXGeometry& geometry = _geometry->getFBXGeometry(); + foreach (const FBXJoint& joint, geometry.joints) { + JointState state; + state.translation = joint.translation; + state.rotation = joint.rotation; + _jointStates.append(state); + } + foreach (const FBXMesh& mesh, geometry.meshes) { + MeshState state; + state.clusterMatrices.resize(mesh.clusters.size()); + if (mesh.springiness > 0.0f) { + state.worldSpaceVertices.resize(mesh.vertices.size()); + state.vertexVelocities.resize(mesh.vertices.size()); + state.worldSpaceNormals.resize(mesh.vertices.size()); + } + _meshStates.append(state); + } + foreach (const FBXAttachment& attachment, geometry.attachments) { + Model* model = new Model(this); + model->init(); + model->setURL(attachment.url); + _attachments.append(model); + } + _resetStates = true; + + for (int i = 0; i < _jointStates.size(); i++) { + updateJointState(i); + } + createCollisionShapes(); +} + +void Model::clearShapes() { + for (int i = 0; i < _shapes.size(); ++i) { + delete _shapes[i]; + } + _shapes.clear(); +} + +void Model::createCollisionShapes() { + const FBXGeometry& geometry = _geometry->getFBXGeometry(); + float uniformScale = extractUniformScale(_scale); + for (int i = 0; i < _jointStates.size(); i++) { + glm::vec3 position = extractTranslation(_jointStates[i].transform); + const FBXJoint& joint = geometry.joints[i]; + // for now make everything a sphere at joint end + float radius = uniformScale * joint.boneRadius; + SphereShape* shape = new SphereShape(radius, position); + _shapes.push_back(shape); + } +} + +void Model::updateShapePositions() { + if (_shapes.size() == _jointStates.size()) { + for (int i = 0; i < _jointStates.size(); i++) { + _shapes[i]->setPosition(extractTranslation(_jointStates[i].transform)); + _shapes[i]->setRotation(_jointStates[i].combinedRotation); + } + } +} + void Model::simulate(float deltaTime) { // update our LOD if (_geometry) { @@ -105,39 +169,17 @@ void Model::simulate(float deltaTime) { } // set up world vertices on first simulate after load - const FBXGeometry& geometry = _geometry->getFBXGeometry(); if (_jointStates.isEmpty()) { - foreach (const FBXJoint& joint, geometry.joints) { - JointState state; - state.translation = joint.translation; - state.rotation = joint.rotation; - _jointStates.append(state); + createJointStates(); + } else { + // update the world space transforms for all joints + for (int i = 0; i < _jointStates.size(); i++) { + updateJointState(i); } - foreach (const FBXMesh& mesh, geometry.meshes) { - MeshState state; - state.clusterMatrices.resize(mesh.clusters.size()); - if (mesh.springiness > 0.0f) { - state.worldSpaceVertices.resize(mesh.vertices.size()); - state.vertexVelocities.resize(mesh.vertices.size()); - state.worldSpaceNormals.resize(mesh.vertices.size()); - } - _meshStates.append(state); - } - foreach (const FBXAttachment& attachment, geometry.attachments) { - Model* model = new Model(this); - model->init(); - model->setURL(attachment.url); - _attachments.append(model); - } - _resetStates = true; - } - - // update the world space transforms for all joints - for (int i = 0; i < _jointStates.size(); i++) { - updateJointState(i); } // update the attachment transforms and simulate them + const FBXGeometry& geometry = _geometry->getFBXGeometry(); for (int i = 0; i < _attachments.size(); i++) { const FBXAttachment& attachment = geometry.attachments.at(i); Model* model = _attachments.at(i); @@ -706,34 +748,26 @@ void Model::applyRotationDelta(int jointIndex, const glm::quat& delta, bool cons void Model::renderCollisionProxies(float alpha) { glPushMatrix(); Application::getInstance()->loadTranslatedViewMatrix(_translation); - - const FBXGeometry& geometry = _geometry->getFBXGeometry(); + updateShapePositions(); float uniformScale = extractUniformScale(_scale); - for (int i = 0; i < _jointStates.size(); i++) { + for (int i = 0; i < _shapes.size(); i++) { glPushMatrix(); + + Shape* shape = _shapes[i]; - glm::vec3 position = extractTranslation(_jointStates[i].transform); + glm::vec3 position = shape->getPosition(); glTranslatef(position.x, position.y, position.z); - glm::quat rotation; - getJointRotation(i, rotation); + const glm::quat& rotation = shape->getRotation(); glm::vec3 axis = glm::axis(rotation); glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z); glColor4f(0.75f, 0.75f, 0.75f, alpha); - float scaledRadius = geometry.joints[i].boneRadius * uniformScale; const int BALL_SUBDIVISIONS = 10; - glutSolidSphere(scaledRadius, BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); + glutSolidSphere(shape->getBoundingRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS); glPopMatrix(); - - int parentIndex = geometry.joints[i].parentIndex; - if (parentIndex != -1) { - Avatar::renderJointConnectingCone(extractTranslation(_jointStates[parentIndex].transform), position, - geometry.joints[parentIndex].boneRadius * uniformScale, scaledRadius); - } } - glPopMatrix(); } @@ -796,6 +830,7 @@ void Model::deleteGeometry() { _blendedVertexBufferIDs.clear(); _jointStates.clear(); _meshStates.clear(); + clearShapes(); } void Model::renderMeshes(float alpha, bool translucent) { diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 28189d0379..07fd697479 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -17,6 +17,8 @@ #include "ProgramObject.h" #include "TextureCache.h" +class Shape; + /// A generic 3D model displaying geometry loaded from a URL. class Model : public QObject { Q_OBJECT @@ -48,6 +50,10 @@ public: void init(); void reset(); + void createJointStates(); + void clearShapes(); + void createCollisionShapes(); + void updateShapePositions(); void simulate(float deltaTime); bool render(float alpha); @@ -183,6 +189,7 @@ protected: }; QVector _jointStates; + QVector _shapes; class MeshState { public: