mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 12:57:18 +02:00
First pass: add collision Shapes to Model
This commit is contained in:
parent
25bdfd7677
commit
9dc26ddfa7
2 changed files with 85 additions and 43 deletions
|
@ -13,6 +13,9 @@
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "Model.h"
|
#include "Model.h"
|
||||||
|
|
||||||
|
#include <SphereShape.h>
|
||||||
|
#include <CapsuleShape.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Model::Model(QObject* parent) :
|
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) {
|
void Model::simulate(float deltaTime) {
|
||||||
// update our LOD
|
// update our LOD
|
||||||
if (_geometry) {
|
if (_geometry) {
|
||||||
|
@ -105,39 +169,17 @@ void Model::simulate(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up world vertices on first simulate after load
|
// set up world vertices on first simulate after load
|
||||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
|
||||||
if (_jointStates.isEmpty()) {
|
if (_jointStates.isEmpty()) {
|
||||||
foreach (const FBXJoint& joint, geometry.joints) {
|
createJointStates();
|
||||||
JointState state;
|
} else {
|
||||||
state.translation = joint.translation;
|
// update the world space transforms for all joints
|
||||||
state.rotation = joint.rotation;
|
for (int i = 0; i < _jointStates.size(); i++) {
|
||||||
_jointStates.append(state);
|
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
|
// update the attachment transforms and simulate them
|
||||||
|
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||||
for (int i = 0; i < _attachments.size(); i++) {
|
for (int i = 0; i < _attachments.size(); i++) {
|
||||||
const FBXAttachment& attachment = geometry.attachments.at(i);
|
const FBXAttachment& attachment = geometry.attachments.at(i);
|
||||||
Model* model = _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) {
|
void Model::renderCollisionProxies(float alpha) {
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
Application::getInstance()->loadTranslatedViewMatrix(_translation);
|
Application::getInstance()->loadTranslatedViewMatrix(_translation);
|
||||||
|
updateShapePositions();
|
||||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
|
||||||
float uniformScale = extractUniformScale(_scale);
|
float uniformScale = extractUniformScale(_scale);
|
||||||
for (int i = 0; i < _jointStates.size(); i++) {
|
for (int i = 0; i < _shapes.size(); i++) {
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
||||||
|
Shape* shape = _shapes[i];
|
||||||
|
|
||||||
glm::vec3 position = extractTranslation(_jointStates[i].transform);
|
glm::vec3 position = shape->getPosition();
|
||||||
glTranslatef(position.x, position.y, position.z);
|
glTranslatef(position.x, position.y, position.z);
|
||||||
|
|
||||||
glm::quat rotation;
|
const glm::quat& rotation = shape->getRotation();
|
||||||
getJointRotation(i, rotation);
|
|
||||||
glm::vec3 axis = glm::axis(rotation);
|
glm::vec3 axis = glm::axis(rotation);
|
||||||
glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z);
|
glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z);
|
||||||
|
|
||||||
glColor4f(0.75f, 0.75f, 0.75f, alpha);
|
glColor4f(0.75f, 0.75f, 0.75f, alpha);
|
||||||
float scaledRadius = geometry.joints[i].boneRadius * uniformScale;
|
|
||||||
const int BALL_SUBDIVISIONS = 10;
|
const int BALL_SUBDIVISIONS = 10;
|
||||||
glutSolidSphere(scaledRadius, BALL_SUBDIVISIONS, BALL_SUBDIVISIONS);
|
glutSolidSphere(shape->getBoundingRadius(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS);
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
int parentIndex = geometry.joints[i].parentIndex;
|
|
||||||
if (parentIndex != -1) {
|
|
||||||
Avatar::renderJointConnectingCone(extractTranslation(_jointStates[parentIndex].transform), position,
|
|
||||||
geometry.joints[parentIndex].boneRadius * uniformScale, scaledRadius);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -796,6 +830,7 @@ void Model::deleteGeometry() {
|
||||||
_blendedVertexBufferIDs.clear();
|
_blendedVertexBufferIDs.clear();
|
||||||
_jointStates.clear();
|
_jointStates.clear();
|
||||||
_meshStates.clear();
|
_meshStates.clear();
|
||||||
|
clearShapes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::renderMeshes(float alpha, bool translucent) {
|
void Model::renderMeshes(float alpha, bool translucent) {
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include "ProgramObject.h"
|
#include "ProgramObject.h"
|
||||||
#include "TextureCache.h"
|
#include "TextureCache.h"
|
||||||
|
|
||||||
|
class Shape;
|
||||||
|
|
||||||
/// A generic 3D model displaying geometry loaded from a URL.
|
/// A generic 3D model displaying geometry loaded from a URL.
|
||||||
class Model : public QObject {
|
class Model : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -48,6 +50,10 @@ public:
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void reset();
|
void reset();
|
||||||
|
void createJointStates();
|
||||||
|
void clearShapes();
|
||||||
|
void createCollisionShapes();
|
||||||
|
void updateShapePositions();
|
||||||
void simulate(float deltaTime);
|
void simulate(float deltaTime);
|
||||||
bool render(float alpha);
|
bool render(float alpha);
|
||||||
|
|
||||||
|
@ -183,6 +189,7 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
QVector<JointState> _jointStates;
|
QVector<JointState> _jointStates;
|
||||||
|
QVector<Shape*> _shapes;
|
||||||
|
|
||||||
class MeshState {
|
class MeshState {
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in a new issue