Read flow data from the fst file

This commit is contained in:
luiscuenca 2019-03-05 18:50:53 -07:00
parent b2d08e9d42
commit 76609197e2
6 changed files with 99 additions and 2 deletions

View file

@ -2337,6 +2337,7 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
_skeletonModel->setCauterizeBoneSet(_headBoneSet);
_fstAnimGraphOverrideUrl = _skeletonModel->getGeometry()->getAnimGraphOverrideUrl();
initAnimGraph();
initFlow();
_skeletonModelLoaded = true;
}
QObject::disconnect(*skeletonConnection);
@ -5383,6 +5384,37 @@ void MyAvatar::useFlow(bool isActive, bool isCollidable, const QVariantMap& phys
}
}
void MyAvatar::initFlow() {
auto &flowData = _skeletonModel->getHFMModel().flowData;
if (flowData._physicsData.size() > 0) {
QVariantMap physicsConfig;
QVariantMap collisionsConfig;
for (auto &data : flowData._physicsData) {
QJsonObject map = QJsonDocument::fromJson(data).object();
if (!map.isEmpty() && map.keys().size() == 1) {
QString group = map.keys()[0];
if (map[group].isObject()) {
physicsConfig.insert(group, map[group].toObject().toVariantMap());
}
}
}
for (auto &data : flowData._collisionsData) {
QJsonObject map = QJsonDocument::fromJson(data).object();
if (!map.isEmpty() && map.keys().size() == 1) {
QString jointName = map.keys()[0];
if (map[jointName].isObject()) {
collisionsConfig.insert(jointName, map[jointName].toObject().toVariantMap());
}
}
}
if (collisionsConfig.size() > 0) {
useFlow(true, true, physicsConfig, collisionsConfig);
} else {
useFlow(true, false, physicsConfig);
}
}
}
void MyAvatar::sendPacket(const QUuid& entityID, const EntityItemProperties& properties) const {
auto treeRenderer = DependencyManager::get<EntityTreeRenderer>();
EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr;

View file

@ -1751,6 +1751,7 @@ private:
void updateCollisionSound(const glm::vec3& penetration, float deltaTime, float frequency);
void initHeadBones();
void initAnimGraph();
void initFlow();
// Avatar Preferences
QUrl _fullAvatarURLFromPreferences;

View file

@ -273,6 +273,13 @@ public:
{}
};
class FlowData {
public:
FlowData() {};
std::vector<QByteArray> _physicsData;
std::vector<QByteArray> _collisionsData;
};
/// The runtime model format.
class Model {
public:
@ -319,6 +326,7 @@ public:
QList<QString> blendshapeChannelNames;
QMap<int, glm::quat> jointRotationOffsets;
FlowData flowData;
};
};
@ -343,6 +351,7 @@ typedef hfm::Mesh HFMMesh;
typedef hfm::AnimationFrame HFMAnimationFrame;
typedef hfm::Light HFMLight;
typedef hfm::Model HFMModel;
typedef hfm::FlowData FlowData;
Q_DECLARE_METATYPE(HFMAnimationFrame)
Q_DECLARE_METATYPE(QVector<HFMAnimationFrame>)

View file

@ -20,6 +20,7 @@
#include "CalculateBlendshapeNormalsTask.h"
#include "CalculateBlendshapeTangentsTask.h"
#include "PrepareJointsTask.h"
#include "ParseFlowDataTask.h"
namespace baker {
@ -101,7 +102,7 @@ namespace baker {
class BuildModelTask {
public:
using Input = VaryingSet5<hfm::Model::Pointer, std::vector<hfm::Mesh>, std::vector<hfm::Joint>, QMap<int, glm::quat>, QHash<QString, int>>;
using Input = VaryingSet6<hfm::Model::Pointer, std::vector<hfm::Mesh>, std::vector<hfm::Joint>, QMap<int, glm::quat>, QHash<QString, int>, FlowData>;
using Output = hfm::Model::Pointer;
using JobModel = Job::ModelIO<BuildModelTask, Input, Output>;
@ -111,6 +112,7 @@ namespace baker {
hfmModelOut->joints = QVector<hfm::Joint>::fromStdVector(input.get2());
hfmModelOut->jointRotationOffsets = input.get3();
hfmModelOut->jointIndices = input.get4();
hfmModelOut->flowData = input.get5();
output = hfmModelOut;
}
};
@ -157,12 +159,15 @@ namespace baker {
// Parse material mapping
const auto materialMapping = model.addJob<ParseMaterialMappingTask>("ParseMaterialMapping", mapping);
// Parse flow data
const auto flowData = model.addJob<ParseFlowDataTask>("ParseFlowData", mapping);
// Combine the outputs into a new hfm::Model
const auto buildBlendshapesInputs = BuildBlendshapesTask::Input(blendshapesPerMeshIn, normalsPerBlendshapePerMesh, tangentsPerBlendshapePerMesh).asVarying();
const auto blendshapesPerMeshOut = model.addJob<BuildBlendshapesTask>("BuildBlendshapes", buildBlendshapesInputs);
const auto buildMeshesInputs = BuildMeshesTask::Input(meshesIn, graphicsMeshes, normalsPerMesh, tangentsPerMesh, blendshapesPerMeshOut).asVarying();
const auto meshesOut = model.addJob<BuildMeshesTask>("BuildMeshes", buildMeshesInputs);
const auto buildModelInputs = BuildModelTask::Input(hfmModelIn, meshesOut, jointsOut, jointRotationOffsets, jointIndices).asVarying();
const auto buildModelInputs = BuildModelTask::Input(hfmModelIn, meshesOut, jointsOut, jointRotationOffsets, jointIndices, flowData).asVarying();
const auto hfmModelOut = model.addJob<BuildModelTask>("BuildModel", buildModelInputs);
output = Output(hfmModelOut, materialMapping);

View file

@ -0,0 +1,26 @@
//
// Created by Luis Cuenca on 5/3/2019
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "ParseFlowDataTask.h"
void ParseFlowDataTask::run(const baker::BakeContextPointer& context, const Input& mapping, Output& output) {
FlowData flowData;
static const QString FLOW_PHYSICS_FIELD = "flowPhysicsData";
static const QString FLOW_COLLISIONS_FIELD = "flowCollisionsData";
for (auto &mappingIter = mapping.begin(); mappingIter != mapping.end(); mappingIter++) {
if (mappingIter.key() == FLOW_PHYSICS_FIELD || mappingIter.key() == FLOW_COLLISIONS_FIELD) {
QByteArray flowDataValue = mappingIter.value().toByteArray();
if (mappingIter.key() == FLOW_PHYSICS_FIELD) {
flowData._physicsData.push_back(flowDataValue);
} else {
flowData._collisionsData.push_back(flowDataValue);
}
}
}
output = flowData;
}

View file

@ -0,0 +1,24 @@
//
// Created by Luis Cuenca on 3/7/2019
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_ParseFlowDataTask_h
#define hifi_ParseFlowDataTask_h
#include <hfm/HFM.h>
#include "Engine.h"
class ParseFlowDataTask {
public:
using Input = QVariantHash;
using Output = FlowData;
using JobModel = baker::Job::ModelIO<ParseFlowDataTask, Input, Output>;
void run(const baker::BakeContextPointer& context, const Input& input, Output& output);
};
#endif // hifi_ParseFlowDataTask_h