This commit is contained in:
Stephen Birarda 2014-05-05 13:57:19 -07:00
commit 9ffd93a167
16 changed files with 121 additions and 183 deletions

View file

@ -39,7 +39,7 @@ you to run the full stack of the virtual world.
In order to set up your own virtual world, you need to set up and run your own
local "domain".
The domain-server gives a number different types of assignments to the assignment-client for different features: audio, avatars, voxels, particles, and meta-voxels.
The domain-server gives a number different types of assignments to the assignment-client for different features: audio, avatars, voxels, particles, meta-voxels and models.
Follow the instructions in the [build guide](BUILD.md) to build the various components.
@ -57,7 +57,7 @@ Any target can be terminated with Ctrl-C (SIGINT) in the associated Terminal win
This assignment-client will grab one assignment from the domain-server. You can tell the assignment-client what type you want it to be with the `-t` option. You can also run an assignment-client that forks off *n* assignment-clients with the `-n` option.
./assignment-client -n 5
./assignment-client -n 6
To test things out you'll want to run the Interface client.

View file

@ -331,8 +331,9 @@ function ScaleSelector() {
});
this.setScale = function(scale) {
this.scale = scale;
this.power = Math.floor(Math.log(scale));
this.power = Math.floor(Math.log(scale) / Math.log(2));
rescaleImport();
this.update();
}
this.show = function(doShow) {
@ -835,7 +836,6 @@ function showPreviewLines() {
if (copyScale) {
scaleSelector.setScale(intersection.voxel.s);
scaleSelector.update();
}
moveTools();
} else {

View file

@ -561,42 +561,6 @@ void Application::paintGL() {
_myCamera.setTargetPosition(_myAvatar->getHead()->calculateAverageEyePosition());
_myCamera.setTargetRotation(_myAvatar->getHead()->getCameraOrientation());
if (Menu::getInstance()->isOptionChecked(MenuOption::CollideWithAvatars)) {
glm::vec3 planeNormal = _myCamera.getTargetRotation() * IDENTITY_FRONT;
const float BASE_PUSHBACK_RADIUS = 0.25f;
float pushbackRadius = _myCamera.getNearClip() + _myAvatar->getScale() * BASE_PUSHBACK_RADIUS;
glm::vec4 plane(planeNormal, -glm::dot(planeNormal, _myCamera.getTargetPosition()) - pushbackRadius);
// push camera out of any intersecting avatars
foreach (const AvatarSharedPointer& avatarData, _avatarManager.getAvatarHash()) {
Avatar* avatar = static_cast<Avatar*>(avatarData.data());
if (avatar->isMyAvatar()) {
continue;
}
if (glm::distance(avatar->getPosition(), _myCamera.getTargetPosition()) >
avatar->getBoundingRadius() + pushbackRadius) {
continue;
}
float angle = angleBetween(avatar->getPosition() - _myCamera.getTargetPosition(), planeNormal);
if (angle > PI_OVER_TWO) {
continue;
}
float scale = 1.0f - angle / PI_OVER_TWO;
scale = qMin(1.0f, scale * 2.5f);
static CollisionList collisions(64);
collisions.clear();
if (!avatar->findPlaneCollisions(plane, collisions)) {
continue;
}
for (int i = 0; i < collisions.size(); i++) {
pushback = qMax(pushback, glm::length(collisions.getCollision(i)->_penetration) * scale);
}
}
const float MAX_PUSHBACK = 0.35f;
pushback = qMin(pushback, MAX_PUSHBACK * _myAvatar->getScale());
const float BASE_PUSHBACK_FOCAL_LENGTH = 0.5f;
pushbackFocalLength = BASE_PUSHBACK_FOCAL_LENGTH * _myAvatar->getScale();
}
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
_myCamera.setTightness(0.0f); // Camera is directly connected to head without smoothing
_myCamera.setTargetPosition(_myAvatar->getUprightHeadPosition());
@ -3132,8 +3096,8 @@ void Application::updateWindowTitle(){
NodeList* nodeList = NodeList::getInstance();
QString username = AccountManager::getInstance().getAccountInfo().getUsername();
QString title = QString() + (!username.isEmpty() ? username + " " : QString()) + nodeList->getSessionUUID().toString()
+ " @ " + nodeList->getDomainHandler().getHostname() + buildVersion;
QString title = QString() + (!username.isEmpty() ? username + " @ " : QString())
+ nodeList->getDomainHandler().getHostname() + buildVersion;
qDebug("Application title set to: %s", title.toStdString().c_str());
_window->setWindowTitle(title);
}

View file

@ -10,6 +10,7 @@
//
#include "MainWindow.h"
#include "Menu.h"
#include <QEvent>
#include <QMoveEvent>
@ -56,6 +57,10 @@ void MainWindow::changeEvent(QEvent* event) {
} else {
emit windowShown(true);
}
if (isFullScreen() != Menu::getInstance()->isOptionChecked(MenuOption::Fullscreen)) {
Menu::getInstance()->setIsOptionChecked(MenuOption::Fullscreen, isFullScreen());
}
} else if (event->type() == QEvent::ActivationChange) {
if (isActiveWindow()) {
emit windowShown(true);

View file

@ -336,7 +336,6 @@ Menu::Menu() :
SLOT(setFilter(bool)));
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHands, 0, true);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::PlaySlaps, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::HandsCollideWithSelf, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::ShowIKConstraints, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, true);

View file

@ -340,7 +340,6 @@ namespace MenuOption {
const QString Particles = "Particles";
const QString PasteToVoxel = "Paste to Voxel...";
const QString PipelineWarnings = "Show Render Pipeline Warnings";
const QString PlaySlaps = "Play Slaps";
const QString Preferences = "Preferences...";
const QString Quit = "Quit";
const QString ReloadAllScripts = "Reload All Scripts";

View file

@ -153,14 +153,14 @@ bool ModelUploader::zip() {
// mixamo/autodesk defaults
if (!mapping.contains(SCALE_FIELD)) {
mapping.insert(SCALE_FIELD, 15.0);
mapping.insert(SCALE_FIELD, geometry.author == "www.makehuman.org" ? 150.0 : 15.0);
}
QVariantHash joints = mapping.value(JOINT_FIELD).toHash();
if (!joints.contains("jointEyeLeft")) {
joints.insert("jointEyeLeft", "LeftEye");
joints.insert("jointEyeLeft", geometry.jointIndices.contains("EyeLeft") ? "EyeLeft" : "LeftEye");
}
if (!joints.contains("jointEyeRight")) {
joints.insert("jointEyeRight", "RightEye");
joints.insert("jointEyeRight", geometry.jointIndices.contains("EyeRight") ? "EyeRight" : "RightEye");
}
if (!joints.contains("jointNeck")) {
joints.insert("jointNeck", "Neck");
@ -172,7 +172,8 @@ bool ModelUploader::zip() {
joints.insert("jointLean", "Spine");
}
if (!joints.contains("jointHead")) {
joints.insert("jointHead", geometry.applicationName == "mixamo.com" ? "HeadTop_End" : "HeadEnd");
const char* topName = (geometry.applicationName == "mixamo.com") ? "HeadTop_End" : "HeadEnd";
joints.insert("jointHead", geometry.jointIndices.contains(topName) ? topName : "Head");
}
if (!joints.contains("jointLeftHand")) {
joints.insert("jointLeftHand", "LeftHand");

View file

@ -29,11 +29,11 @@ void FaceModel::simulate(float deltaTime, bool fullUpdate) {
neckPosition = owningAvatar->getPosition();
}
setTranslation(neckPosition);
glm::quat neckRotation;
if (!owningAvatar->getSkeletonModel().getNeckRotation(neckRotation)) {
neckRotation = owningAvatar->getOrientation();
glm::quat neckParentRotation;
if (!owningAvatar->getSkeletonModel().getNeckParentRotation(neckParentRotation)) {
neckParentRotation = owningAvatar->getOrientation();
}
setRotation(neckRotation);
setRotation(neckParentRotation);
const float MODEL_SCALE = 0.0006f;
setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningHead->getScale() * MODEL_SCALE);

View file

@ -55,76 +55,10 @@ void Hand::simulate(float deltaTime, bool isMine) {
}
}
void Hand::playSlaps(PalmData& palm, Avatar* avatar) {
// Check for palm collisions
glm::vec3 myPalmPosition = palm.getPosition();
float palmCollisionDistance = 0.1f;
bool wasColliding = palm.getIsCollidingWithPalm();
palm.setIsCollidingWithPalm(false);
// If 'Play Slaps' is enabled, look for palm-to-palm collisions and make sound
for (size_t j = 0; j < avatar->getHand()->getNumPalms(); j++) {
PalmData& otherPalm = avatar->getHand()->getPalms()[j];
if (!otherPalm.isActive()) {
continue;
}
glm::vec3 otherPalmPosition = otherPalm.getPosition();
if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) {
palm.setIsCollidingWithPalm(true);
if (!wasColliding) {
const float PALM_COLLIDE_VOLUME = 1.f;
const float PALM_COLLIDE_FREQUENCY = 1000.f;
const float PALM_COLLIDE_DURATION_MAX = 0.75f;
const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.01f;
Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME,
PALM_COLLIDE_FREQUENCY,
PALM_COLLIDE_DURATION_MAX,
PALM_COLLIDE_DECAY_PER_SAMPLE);
// If the other person's palm is in motion, move mine downward to show I was hit
const float MIN_VELOCITY_FOR_SLAP = 0.05f;
if (glm::length(otherPalm.getVelocity()) > MIN_VELOCITY_FOR_SLAP) {
// add slapback here
}
}
}
}
}
// We create a static CollisionList that is recycled for each collision test.
const float MAX_COLLISIONS_PER_AVATAR = 32;
static CollisionList handCollisions(MAX_COLLISIONS_PER_AVATAR);
void Hand::collideAgainstAvatarOld(Avatar* avatar, bool isMyHand) {
if (!avatar || avatar == _owningAvatar) {
// don't collide with our own hands (that is done elsewhere)
return;
}
float scaledPalmRadius = PALM_COLLISION_RADIUS * _owningAvatar->getScale();
for (size_t i = 0; i < getNumPalms(); i++) {
PalmData& palm = getPalms()[i];
if (!palm.isActive()) {
continue;
}
if (isMyHand && Menu::getInstance()->isOptionChecked(MenuOption::PlaySlaps)) {
playSlaps(palm, avatar);
}
glm::vec3 totalPenetration;
handCollisions.clear();
if (avatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, handCollisions)) {
for (int j = 0; j < handCollisions.size(); ++j) {
CollisionInfo* collision = handCollisions.getCollision(j);
if (isMyHand) {
totalPenetration = addPenetrations(totalPenetration, collision->_penetration);
}
}
}
if (isMyHand) {
// resolve penetration
palm.addToPosition(-totalPenetration);
}
}
}
void Hand::collideAgainstAvatar(Avatar* avatar, bool isMyHand) {
if (!avatar || avatar == _owningAvatar) {
// don't collide hands against ourself (that is done elsewhere)

View file

@ -58,7 +58,6 @@ public:
const glm::vec3& getLeapFingerTipBallPosition (int ball) const { return _leapFingerTipBalls [ball].position;}
const glm::vec3& getLeapFingerRootBallPosition(int ball) const { return _leapFingerRootBalls[ball].position;}
void collideAgainstAvatarOld(Avatar* avatar, bool isMyHand);
void collideAgainstAvatar(Avatar* avatar, bool isMyHand);
void collideAgainstOurself();
@ -80,8 +79,6 @@ private:
void renderLeapFingerTrails();
void calculateGeometry();
void playSlaps(PalmData& palm, Avatar* avatar);
};
#endif // hifi_Hand_h

View file

@ -434,6 +434,17 @@ bool Model::getNeckRotation(glm::quat& neckRotation) const {
return isActive() && getJointRotation(_geometry->getFBXGeometry().neckJointIndex, neckRotation);
}
bool Model::getNeckParentRotation(glm::quat& neckParentRotation) const {
if (!isActive()) {
return false;
}
const FBXGeometry& geometry = _geometry->getFBXGeometry();
if (geometry.neckJointIndex == -1) {
return false;
}
return getJointRotation(geometry.joints.at(geometry.neckJointIndex).parentIndex, neckParentRotation);
}
bool Model::getEyePositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const {
if (!isActive()) {
return false;

View file

@ -132,6 +132,10 @@ public:
/// \return whether or not the neck was found
bool getNeckRotation(glm::quat& neckRotation) const;
/// Returns the rotation of the neck joint's parent.
/// \return whether or not the neck was found
bool getNeckParentRotation(glm::quat& neckRotation) const;
/// Retrieve the positions of up to two eye meshes.
/// \return whether or not both eye meshes were found
bool getEyePositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const;

View file

@ -19,7 +19,7 @@ ScriptLineNumberArea::ScriptLineNumberArea(ScriptEditBox* scriptEditBox) :
_scriptEditBox = scriptEditBox;
}
QSize ScriptLineNumberArea::sizeHint() {
QSize ScriptLineNumberArea::sizeHint() const {
return QSize(_scriptEditBox->lineNumberAreaWidth(), 0);
}

View file

@ -19,7 +19,7 @@ class ScriptLineNumberArea : public QWidget {
public:
ScriptLineNumberArea(ScriptEditBox* scriptEditBox);
QSize sizeHint();
QSize sizeHint() const;
protected:
void paintEvent(QPaintEvent* event);

View file

@ -406,7 +406,7 @@ QVariantHash parseMapping(QIODevice* device) {
QVector<glm::vec3> createVec3Vector(const QVector<double>& doubleVector) {
QVector<glm::vec3> values;
for (const double* it = doubleVector.constData(), *end = it + doubleVector.size(); it != end; ) {
for (const double* it = doubleVector.constData(), *end = it + (doubleVector.size() / 3 * 3); it != end; ) {
float x = *it++;
float y = *it++;
float z = *it++;
@ -417,7 +417,7 @@ QVector<glm::vec3> createVec3Vector(const QVector<double>& doubleVector) {
QVector<glm::vec2> createVec2Vector(const QVector<double>& doubleVector) {
QVector<glm::vec2> values;
for (const double* it = doubleVector.constData(), *end = it + doubleVector.size(); it != end; ) {
for (const double* it = doubleVector.constData(), *end = it + (doubleVector.size() / 2 * 2); it != end; ) {
float s = *it++;
float t = *it++;
values.append(glm::vec2(s, -t));
@ -432,58 +432,59 @@ glm::mat4 createMat4(const QVector<double>& doubleVector) {
doubleVector.at(12), doubleVector.at(13), doubleVector.at(14), doubleVector.at(15));
}
QVector<int> getIntVector(const QVariantList& properties, int index) {
if (index >= properties.size()) {
QVector<int> getIntVector(const FBXNode& node) {
foreach (const FBXNode& child, node.children) {
if (child.name == "a") {
return getIntVector(child);
}
}
if (node.properties.isEmpty()) {
return QVector<int>();
}
QVector<int> vector = properties.at(index).value<QVector<int> >();
QVector<int> vector = node.properties.at(0).value<QVector<int> >();
if (!vector.isEmpty()) {
return vector;
}
for (; index < properties.size(); index++) {
vector.append(properties.at(index).toInt());
for (int i = 0; i < node.properties.size(); i++) {
vector.append(node.properties.at(i).toInt());
}
return vector;
}
QVector<qlonglong> getLongVector(const QVariantList& properties, int index) {
if (index >= properties.size()) {
return QVector<qlonglong>();
QVector<float> getFloatVector(const FBXNode& node) {
foreach (const FBXNode& child, node.children) {
if (child.name == "a") {
return getFloatVector(child);
}
}
QVector<qlonglong> vector = properties.at(index).value<QVector<qlonglong> >();
if (!vector.isEmpty()) {
return vector;
}
for (; index < properties.size(); index++) {
vector.append(properties.at(index).toLongLong());
}
return vector;
}
QVector<float> getFloatVector(const QVariantList& properties, int index) {
if (index >= properties.size()) {
if (node.properties.isEmpty()) {
return QVector<float>();
}
QVector<float> vector = properties.at(index).value<QVector<float> >();
QVector<float> vector = node.properties.at(0).value<QVector<float> >();
if (!vector.isEmpty()) {
return vector;
}
for (; index < properties.size(); index++) {
vector.append(properties.at(index).toFloat());
for (int i = 0; i < node.properties.size(); i++) {
vector.append(node.properties.at(i).toFloat());
}
return vector;
}
QVector<double> getDoubleVector(const QVariantList& properties, int index) {
if (index >= properties.size()) {
QVector<double> getDoubleVector(const FBXNode& node) {
foreach (const FBXNode& child, node.children) {
if (child.name == "a") {
return getDoubleVector(child);
}
}
if (node.properties.isEmpty()) {
return QVector<double>();
}
QVector<double> vector = properties.at(index).value<QVector<double> >();
QVector<double> vector = node.properties.at(0).value<QVector<double> >();
if (!vector.isEmpty()) {
return vector;
}
for (; index < properties.size(); index++) {
vector.append(properties.at(index).toDouble());
for (int i = 0; i < node.properties.size(); i++) {
vector.append(node.properties.at(i).toDouble());
}
return vector;
}
@ -697,21 +698,30 @@ public:
};
void appendIndex(MeshData& data, QVector<int>& indices, int index) {
if (index >= data.polygonIndices.size()) {
return;
}
int vertexIndex = data.polygonIndices.at(index);
if (vertexIndex < 0) {
vertexIndex = -vertexIndex - 1;
}
Vertex vertex;
vertex.originalIndex = vertexIndex;
glm::vec3 position;
if (vertexIndex < data.vertices.size()) {
position = data.vertices.at(vertexIndex);
}
glm::vec3 normal;
if (data.normalIndices.isEmpty()) {
normal = data.normals.at(data.normalsByVertex ? vertexIndex : index);
} else {
int normalIndex = data.normalIndices.at(data.normalsByVertex ? vertexIndex : index);
if (normalIndex >= 0) {
int normalIndex = data.normalsByVertex ? vertexIndex : index;
if (data.normalIndices.isEmpty()) {
if (normalIndex < data.normals.size()) {
normal = data.normals.at(normalIndex);
}
} else if (normalIndex < data.normalIndices.size()) {
normalIndex = data.normalIndices.at(normalIndex);
if (normalIndex >= 0 && normalIndex < data.normals.size()) {
normal = data.normals.at(normalIndex);
}
}
@ -720,9 +730,9 @@ void appendIndex(MeshData& data, QVector<int>& indices, int index) {
if (index < data.texCoords.size()) {
vertex.texCoord = data.texCoords.at(index);
}
} else {
} else if (index < data.texCoordIndices.size()) {
int texCoordIndex = data.texCoordIndices.at(index);
if (texCoordIndex >= 0) {
if (texCoordIndex >= 0 && texCoordIndex < data.texCoords.size()) {
vertex.texCoord = data.texCoords.at(texCoordIndex);
}
}
@ -733,7 +743,7 @@ void appendIndex(MeshData& data, QVector<int>& indices, int index) {
indices.append(newIndex);
data.indices.insert(vertex, newIndex);
data.extracted.newIndices.insert(vertexIndex, newIndex);
data.extracted.mesh.vertices.append(data.vertices.at(vertexIndex));
data.extracted.mesh.vertices.append(position);
data.extracted.mesh.normals.append(normal);
data.extracted.mesh.texCoords.append(vertex.texCoord);
@ -749,44 +759,51 @@ ExtractedMesh extractMesh(const FBXNode& object) {
QVector<int> textures;
foreach (const FBXNode& child, object.children) {
if (child.name == "Vertices") {
data.vertices = createVec3Vector(getDoubleVector(child.properties, 0));
data.vertices = createVec3Vector(getDoubleVector(child));
} else if (child.name == "PolygonVertexIndex") {
data.polygonIndices = getIntVector(child.properties, 0);
data.polygonIndices = getIntVector(child);
} else if (child.name == "LayerElementNormal") {
data.normalsByVertex = false;
bool indexToDirect = false;
foreach (const FBXNode& subdata, child.children) {
if (subdata.name == "Normals") {
data.normals = createVec3Vector(getDoubleVector(subdata.properties, 0));
data.normals = createVec3Vector(getDoubleVector(subdata));
} else if (subdata.name == "NormalsIndex") {
data.normalIndices = getIntVector(subdata.properties, 0);
data.normalIndices = getIntVector(subdata);
} else if (subdata.name == "MappingInformationType" &&
subdata.properties.at(0) == "ByVertice") {
} else if (subdata.name == "MappingInformationType" && subdata.properties.at(0) == "ByVertice") {
data.normalsByVertex = true;
} else if (subdata.name == "ReferenceInformationType" && subdata.properties.at(0) == "IndexToDirect") {
indexToDirect = true;
}
}
if (indexToDirect && data.normalIndices.isEmpty()) {
// hack to work around wacky Makehuman exports
data.normalsByVertex = true;
}
} else if (child.name == "LayerElementUV" && child.properties.at(0).toInt() == 0) {
foreach (const FBXNode& subdata, child.children) {
if (subdata.name == "UV") {
data.texCoords = createVec2Vector(getDoubleVector(subdata.properties, 0));
data.texCoords = createVec2Vector(getDoubleVector(subdata));
} else if (subdata.name == "UVIndex") {
data.texCoordIndices = getIntVector(subdata.properties, 0);
data.texCoordIndices = getIntVector(subdata);
}
}
} else if (child.name == "LayerElementMaterial") {
foreach (const FBXNode& subdata, child.children) {
if (subdata.name == "Materials") {
materials = getIntVector(subdata.properties, 0);
materials = getIntVector(subdata);
}
}
} else if (child.name == "LayerElementTexture") {
foreach (const FBXNode& subdata, child.children) {
if (subdata.name == "TextureId") {
textures = getIntVector(subdata.properties, 0);
textures = getIntVector(subdata);
}
}
}
@ -797,7 +814,7 @@ ExtractedMesh extractMesh(const FBXNode& object) {
QHash<QPair<int, int>, int> materialTextureParts;
for (int beginIndex = 0; beginIndex < data.polygonIndices.size(); polygonIndex++) {
int endIndex = beginIndex;
while (data.polygonIndices.at(endIndex++) >= 0);
while (endIndex < data.polygonIndices.size() && data.polygonIndices.at(endIndex++) >= 0);
QPair<int, int> materialTexture((polygonIndex < materials.size()) ? materials.at(polygonIndex) : 0,
(polygonIndex < textures.size()) ? textures.at(polygonIndex) : 0);
@ -820,7 +837,7 @@ ExtractedMesh extractMesh(const FBXNode& object) {
appendIndex(data, part.triangleIndices, beginIndex);
appendIndex(data, part.triangleIndices, nextIndex++);
appendIndex(data, part.triangleIndices, nextIndex);
if (data.polygonIndices.at(nextIndex) < 0) {
if (nextIndex >= data.polygonIndices.size() || data.polygonIndices.at(nextIndex) < 0) {
break;
}
}
@ -835,13 +852,13 @@ FBXBlendshape extractBlendshape(const FBXNode& object) {
FBXBlendshape blendshape;
foreach (const FBXNode& data, object.children) {
if (data.name == "Indexes") {
blendshape.indices = getIntVector(data.properties, 0);
blendshape.indices = getIntVector(data);
} else if (data.name == "Vertices") {
blendshape.vertices = createVec3Vector(getDoubleVector(data.properties, 0));
blendshape.vertices = createVec3Vector(getDoubleVector(data));
} else if (data.name == "Normals") {
blendshape.normals = createVec3Vector(getDoubleVector(data.properties, 0));
blendshape.normals = createVec3Vector(getDoubleVector(data));
}
}
return blendshape;
@ -1016,7 +1033,13 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
foreach (const FBXNode& object, child.children) {
if (object.name == "SceneInfo") {
foreach (const FBXNode& subobject, object.children) {
if (subobject.name == "Properties70") {
if (subobject.name == "MetaData") {
foreach (const FBXNode& subsubobject, subobject.children) {
if (subsubobject.name == "Author") {
geometry.author = subsubobject.properties.at(0).toString();
}
}
} else if (subobject.name == "Properties70") {
foreach (const FBXNode& subsubobject, subobject.children) {
if (subsubobject.name == "P" && subsubobject.properties.size() >= 5 &&
subsubobject.properties.at(0) == "Original|ApplicationName") {
@ -1262,13 +1285,13 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
Cluster cluster;
foreach (const FBXNode& subobject, object.children) {
if (subobject.name == "Indexes") {
cluster.indices = getIntVector(subobject.properties, 0);
cluster.indices = getIntVector(subobject);
} else if (subobject.name == "Weights") {
cluster.weights = getDoubleVector(subobject.properties, 0);
cluster.weights = getDoubleVector(subobject);
} else if (subobject.name == "TransformLink") {
QVector<double> values = getDoubleVector(subobject.properties, 0);
QVector<double> values = getDoubleVector(subobject);
cluster.transformLink = createMat4(values);
}
}
@ -1290,7 +1313,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
AnimationCurve curve;
foreach (const FBXNode& subobject, object.children) {
if (subobject.name == "KeyValueFloat") {
curve.values = getFloatVector(subobject.properties, 0);
curve.values = getFloatVector(subobject);
}
}
animationCurves.insert(getID(object.properties), curve);

View file

@ -177,6 +177,7 @@ public:
class FBXGeometry {
public:
QString author;
QString applicationName; ///< the name of the application that generated the model
QVector<FBXJoint> joints;