mirror of
https://github.com/overte-org/overte.git
synced 2025-04-23 18:13:29 +02:00
Support for attaching models to joints.
This commit is contained in:
parent
3f96343761
commit
41f73b5e9d
4 changed files with 96 additions and 2 deletions
|
@ -9,6 +9,7 @@
|
|||
#include <QBuffer>
|
||||
#include <QDataStream>
|
||||
#include <QIODevice>
|
||||
#include <QStringList>
|
||||
#include <QTextStream>
|
||||
#include <QtDebug>
|
||||
#include <QtEndian>
|
||||
|
@ -397,6 +398,19 @@ glm::vec3 getVec3(const QVariantList& properties, int index) {
|
|||
properties.at(index + 2).value<double>());
|
||||
}
|
||||
|
||||
glm::vec3 parseVec3(const QString& string) {
|
||||
QStringList elements = string.split(',');
|
||||
if (elements.isEmpty()) {
|
||||
return glm::vec3();
|
||||
}
|
||||
glm::vec3 value;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
// duplicate last value if there aren't three elements
|
||||
value[i] = elements.at(min(i, elements.size() - 1)).trimmed().toFloat();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
const char* FACESHIFT_BLENDSHAPES[] = {
|
||||
"EyeBlink_L",
|
||||
"EyeBlink_R",
|
||||
|
@ -1129,6 +1143,34 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
|
|||
geometry.meshes.append(mesh);
|
||||
}
|
||||
|
||||
// process attachments
|
||||
QVariantHash attachments = mapping.value("attach").toHash();
|
||||
for (QVariantHash::const_iterator it = attachments.constBegin(); it != attachments.constEnd(); it++) {
|
||||
FBXAttachment attachment;
|
||||
attachment.jointIndex = modelIDs.indexOf(it.key());
|
||||
attachment.scale = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
|
||||
QVariantList properties = it->toList();
|
||||
if (properties.isEmpty()) {
|
||||
attachment.url = it->toUrl();
|
||||
} else {
|
||||
attachment.url = properties.at(0).toString();
|
||||
|
||||
if (properties.size() >= 2) {
|
||||
attachment.translation = parseVec3(properties.at(1).toString());
|
||||
|
||||
if (properties.size() >= 3) {
|
||||
attachment.rotation = glm::quat(glm::radians(parseVec3(properties.at(2).toString())));
|
||||
|
||||
if (properties.size() >= 4) {
|
||||
attachment.scale = parseVec3(properties.at(3).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
geometry.attachments.append(attachment);
|
||||
}
|
||||
|
||||
return geometry;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#ifndef __interface__FBXReader__
|
||||
#define __interface__FBXReader__
|
||||
|
||||
#include <QUrl>
|
||||
#include <QVarLengthArray>
|
||||
#include <QVariant>
|
||||
#include <QVector>
|
||||
|
@ -98,6 +99,17 @@ public:
|
|||
QVector<QVarLengthArray<QPair<int, int>, 4> > vertexConnections;
|
||||
};
|
||||
|
||||
/// An attachment to an FBX document.
|
||||
class FBXAttachment {
|
||||
public:
|
||||
|
||||
int jointIndex;
|
||||
QUrl url;
|
||||
glm::vec3 translation;
|
||||
glm::quat rotation;
|
||||
glm::vec3 scale;
|
||||
};
|
||||
|
||||
/// A set of meshes extracted from an FBX document.
|
||||
class FBXGeometry {
|
||||
public:
|
||||
|
@ -117,6 +129,8 @@ public:
|
|||
int headJointIndex;
|
||||
|
||||
glm::vec3 neckPivot;
|
||||
|
||||
QVector<FBXAttachment> attachments;
|
||||
};
|
||||
|
||||
/// Reads FBX geometry from the supplied model and mapping data.
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
Model::Model() :
|
||||
Model::Model(QObject* parent) :
|
||||
QObject(parent),
|
||||
_pupilDilation(0.0f)
|
||||
{
|
||||
// we may have been created in the network thread, but we live in the main thread
|
||||
|
@ -56,6 +57,10 @@ void Model::init() {
|
|||
|
||||
void Model::reset() {
|
||||
_resetStates = true;
|
||||
|
||||
foreach (Model* attachment, _attachments) {
|
||||
attachment->reset();
|
||||
}
|
||||
}
|
||||
|
||||
void Model::simulate(float deltaTime) {
|
||||
|
@ -81,6 +86,13 @@ void Model::simulate(float deltaTime) {
|
|||
}
|
||||
_meshStates.append(state);
|
||||
}
|
||||
foreach (const FBXAttachment& attachment, geometry.attachments) {
|
||||
Model* model = new Model(this);
|
||||
model->init();
|
||||
model->setURL(attachment.url);
|
||||
model->setScale(attachment.scale);
|
||||
_attachments.append(model);
|
||||
}
|
||||
_resetStates = true;
|
||||
}
|
||||
|
||||
|
@ -89,6 +101,22 @@ void Model::simulate(float deltaTime) {
|
|||
updateJointState(i);
|
||||
}
|
||||
|
||||
// update the attachment transforms and simulate them
|
||||
for (int i = 0; i < _attachments.size(); i++) {
|
||||
const FBXAttachment& attachment = geometry.attachments.at(i);
|
||||
Model* model = _attachments.at(i);
|
||||
|
||||
glm::vec3 jointTranslation = _translation;
|
||||
glm::quat jointRotation = _rotation;
|
||||
getJointPosition(attachment.jointIndex, jointTranslation);
|
||||
getJointRotation(attachment.jointIndex, jointRotation);
|
||||
|
||||
model->setTranslation(jointTranslation + jointRotation * attachment.translation);
|
||||
model->setRotation(jointRotation * attachment.rotation);
|
||||
|
||||
model->simulate(deltaTime);
|
||||
}
|
||||
|
||||
for (int i = 0; i < _meshStates.size(); i++) {
|
||||
MeshState& state = _meshStates[i];
|
||||
const FBXMesh& mesh = geometry.meshes.at(i);
|
||||
|
@ -175,6 +203,10 @@ void Model::simulate(float deltaTime) {
|
|||
}
|
||||
|
||||
bool Model::render(float alpha) {
|
||||
// render the attachments
|
||||
foreach (Model* attachment, _attachments) {
|
||||
attachment->render(alpha);
|
||||
}
|
||||
if (_meshStates.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -443,6 +475,10 @@ bool Model::getJointRotation(int jointIndex, glm::quat& rotation) const {
|
|||
}
|
||||
|
||||
void Model::deleteGeometry() {
|
||||
foreach (Model* attachment, _attachments) {
|
||||
delete attachment;
|
||||
}
|
||||
_attachments.clear();
|
||||
foreach (GLuint id, _blendedVertexBufferIDs) {
|
||||
glDeleteBuffers(1, &id);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ class Model : public QObject {
|
|||
|
||||
public:
|
||||
|
||||
Model();
|
||||
Model(QObject* parent = NULL);
|
||||
virtual ~Model();
|
||||
|
||||
void setTranslation(const glm::vec3& translation) { _translation = translation; }
|
||||
|
@ -126,6 +126,8 @@ private:
|
|||
QVector<glm::vec3> _blendedVertices;
|
||||
QVector<glm::vec3> _blendedNormals;
|
||||
|
||||
QVector<Model*> _attachments;
|
||||
|
||||
static ProgramObject _program;
|
||||
static ProgramObject _skinProgram;
|
||||
static int _clusterMatricesLocation;
|
||||
|
|
Loading…
Reference in a new issue