Fix one frame pose duration issue in motion editor

This commit also remove height above ground settings.
master
Jeremy Hu 2019-06-06 23:48:48 +09:30
parent 0cb574b6ea
commit 54b5a9ef5e
5 changed files with 32 additions and 21 deletions

View File

@ -54,7 +54,7 @@ void AnimalPoser::resolveTransform()
mostBottomYBeforeTransform = bone.tailPosition.y(); mostBottomYBeforeTransform = bone.tailPosition.y();
} }
float legHeightBeforeTransform = std::abs(mostBottomYBeforeTransform - firstSpineBone.headPosition.y()); //float legHeightBeforeTransform = std::abs(mostBottomYBeforeTransform - firstSpineBone.headPosition.y());
auto transformedJointNodeTree = m_jointNodeTree; auto transformedJointNodeTree = m_jointNodeTree;
transformedJointNodeTree.recalculateTransformMatrices(); transformedJointNodeTree.recalculateTransformMatrices();
float mostBottomYAfterTransform = std::numeric_limits<float>::max(); float mostBottomYAfterTransform = std::numeric_limits<float>::max();
@ -70,11 +70,13 @@ void AnimalPoser::resolveTransform()
if (newPosition.y() < mostBottomYAfterTransform) if (newPosition.y() < mostBottomYAfterTransform)
mostBottomYAfterTransform = newPosition.y(); mostBottomYAfterTransform = newPosition.y();
} }
float legHeightAfterTransform = std::abs(mostBottomYAfterTransform - firstSpineBonePositionAfterTransform.y()); //float legHeightAfterTransform = std::abs(mostBottomYAfterTransform - firstSpineBonePositionAfterTransform.y());
float translateY = legHeightAfterTransform - legHeightBeforeTransform; //float translateY = legHeightAfterTransform - legHeightBeforeTransform;
float translateY = mostBottomYBeforeTransform - mostBottomYAfterTransform;
//qDebug() << "Leg height changed, translateY:" << translateY << "legHeightBeforeTransform:" << legHeightBeforeTransform << "legHeightAfterTransform:" << legHeightAfterTransform << "firstSpineBonePositionAfterTransform:" << firstSpineBonePositionAfterTransform << "firstSpineBone.headPosition:" << firstSpineBone.headPosition; //qDebug() << "Leg height changed, translateY:" << translateY << "legHeightBeforeTransform:" << legHeightBeforeTransform << "legHeightAfterTransform:" << legHeightAfterTransform << "firstSpineBonePositionAfterTransform:" << firstSpineBonePositionAfterTransform << "firstSpineBone.headPosition:" << firstSpineBone.headPosition;
/*
const auto &findRootParameters = parameters().find(Rigger::rootBoneName); const auto &findRootParameters = parameters().find(Rigger::rootBoneName);
if (findRootParameters != parameters().end()) { if (findRootParameters != parameters().end()) {
auto findHeightAboveGroundLevel = findRootParameters->second.find("heightAboveGroundLevel"); auto findHeightAboveGroundLevel = findRootParameters->second.find("heightAboveGroundLevel");
@ -85,6 +87,7 @@ void AnimalPoser::resolveTransform()
//qDebug() << "heightAboveGroundLevel:" << heightAboveGroundLevel << "myHeightAboveGroundLevel:" << myHeightAboveGroundLevel << "legHeightBeforeTransform:" << legHeightBeforeTransform << "applied translateY:" << translateY; //qDebug() << "heightAboveGroundLevel:" << heightAboveGroundLevel << "myHeightAboveGroundLevel:" << myHeightAboveGroundLevel << "legHeightBeforeTransform:" << legHeightBeforeTransform << "applied translateY:" << translateY;
} }
} }
*/
if (!qFuzzyIsNull(translateY)) { if (!qFuzzyIsNull(translateY)) {
int rootBoneIndex = findBoneIndex(Rigger::rootBoneName); int rootBoneIndex = findBoneIndex(Rigger::rootBoneName);

View File

@ -85,8 +85,11 @@ float MotionsGenerator::calculatePoseDuration(const QUuid &poseId)
if (nullptr == pose) if (nullptr == pose)
return 0; return 0;
float totalDuration = 0; float totalDuration = 0;
for (const auto &frame: *pose) { if (pose->size() > 1) {
totalDuration += valueOfKeyInMapOrEmpty(frame.first, "duration").toFloat(); // Pose with only one frame has zero duration
for (const auto &frame: *pose) {
totalDuration += valueOfKeyInMapOrEmpty(frame.first, "duration").toFloat();
}
} }
return totalDuration; return totalDuration;
} }
@ -149,6 +152,8 @@ void MotionsGenerator::generateMotion(const QUuid &motionId, std::set<QUuid> &vi
float interval = 1.0 / m_fps; float interval = 1.0 / m_fps;
float lastProgress = 0; float lastProgress = 0;
if (totalDuration < interval)
totalDuration = interval;
for (float progress = 0; progress < totalDuration; ) { for (float progress = 0; progress < totalDuration; ) {
int clipIndex = findClipIndexByProgress(progress); int clipIndex = findClipIndexByProgress(progress);
if (-1 == clipIndex) { if (-1 == clipIndex) {

View File

@ -158,8 +158,8 @@ void PoseDocument::reset()
m_otherIds.clear(); m_otherIds.clear();
m_boneNameToIdsMap.clear(); m_boneNameToIdsMap.clear();
m_bonesPartId = QUuid(); m_bonesPartId = QUuid();
m_groundPartId = QUuid(); //m_groundPartId = QUuid();
m_groundEdgeId = QUuid(); //m_groundEdgeId = QUuid();
emit cleanup(); emit cleanup();
emit parametersChanged(); emit parametersChanged();
} }
@ -253,24 +253,24 @@ void PoseDocument::fromParameters(const std::vector<RiggerBone> *rigBones,
otherParameters); otherParameters);
std::map<QString, std::pair<QUuid, QUuid>> boneNameToIdsMap; std::map<QString, std::pair<QUuid, QUuid>> boneNameToIdsMap;
QUuid groundPartId; //QUuid groundPartId;
QUuid bonesPartId; QUuid bonesPartId;
QUuid groundEdgeId; //QUuid groundEdgeId;
parametersToNodes(&otherBones, parametersToNodes(&otherBones,
otherHeightAboveGroundLevel, otherHeightAboveGroundLevel,
&boneNameToIdsMap, &boneNameToIdsMap,
&groundPartId, //&groundPartId,
&bonesPartId, &bonesPartId,
&groundEdgeId, //&groundEdgeId,
true); true);
} }
parametersToNodes(&bones, parametersToNodes(&bones,
heightAboveGroundLevel, heightAboveGroundLevel,
&m_boneNameToIdsMap, &m_boneNameToIdsMap,
&m_groundPartId, //&m_groundPartId,
&m_bonesPartId, &m_bonesPartId,
&m_groundEdgeId, //&m_groundEdgeId,
false); false);
emit parametersChanged(); emit parametersChanged();
@ -279,9 +279,9 @@ void PoseDocument::fromParameters(const std::vector<RiggerBone> *rigBones,
void PoseDocument::parametersToNodes(const std::vector<RiggerBone> *rigBones, void PoseDocument::parametersToNodes(const std::vector<RiggerBone> *rigBones,
const float heightAboveGroundLevel, const float heightAboveGroundLevel,
std::map<QString, std::pair<QUuid, QUuid>> *boneNameToIdsMap, std::map<QString, std::pair<QUuid, QUuid>> *boneNameToIdsMap,
QUuid *groundPartId, //QUuid *groundPartId,
QUuid *bonesPartId, QUuid *bonesPartId,
QUuid *groundEdgeId, //QUuid *groundEdgeId,
bool isOther) bool isOther)
{ {
if (nullptr == rigBones || rigBones->empty()) { if (nullptr == rigBones || rigBones->empty()) {
@ -402,6 +402,7 @@ void PoseDocument::parametersToNodes(const std::vector<RiggerBone> *rigBones,
nodeMap[findRootNodeId->second].setRadius(m_nodeRadius * 2); nodeMap[findRootNodeId->second].setRadius(m_nodeRadius * 2);
} }
/*
if (!isOther) { if (!isOther) {
*groundPartId = QUuid::createUuid(); *groundPartId = QUuid::createUuid();
auto &groundPart = partMap[*groundPartId]; auto &groundPart = partMap[*groundPartId];
@ -452,6 +453,7 @@ void PoseDocument::parametersToNodes(const std::vector<RiggerBone> *rigBones,
nodeMap[groundNodesPair.second].edgeIds.push_back(edge.id); nodeMap[groundNodesPair.second].edgeIds.push_back(edge.id);
} }
} }
*/
if (isOther) { if (isOther) {
for (const auto &nodeIt: newAddedNodeIds) for (const auto &nodeIt: newAddedNodeIds)
@ -536,6 +538,7 @@ float PoseDocument::findFirstSpineY() const
void PoseDocument::toParameters(std::map<QString, std::map<QString, QString>> &parameters, const std::set<QUuid> &limitNodeIds) const void PoseDocument::toParameters(std::map<QString, std::map<QString, QString>> &parameters, const std::set<QUuid> &limitNodeIds) const
{ {
/*
float heightAboveGroundLevel = 0; float heightAboveGroundLevel = 0;
auto findGroundEdge = edgeMap.find(m_groundEdgeId); auto findGroundEdge = edgeMap.find(m_groundEdgeId);
if (findGroundEdge != edgeMap.end()) { if (findGroundEdge != edgeMap.end()) {
@ -559,6 +562,7 @@ void PoseDocument::toParameters(std::map<QString, std::map<QString, QString>> &p
auto &boneParameter = parameters[Rigger::rootBoneName]; auto &boneParameter = parameters[Rigger::rootBoneName];
boneParameter["heightAboveGroundLevel"] = QString::number(heightAboveGroundLevel); boneParameter["heightAboveGroundLevel"] = QString::number(heightAboveGroundLevel);
} }
*/
for (const auto &item: m_boneNameToIdsMap) { for (const auto &item: m_boneNameToIdsMap) {
const auto &boneNodeIdPair = item.second; const auto &boneNodeIdPair = item.second;
auto findFirstNode = nodeMap.find(boneNodeIdPair.first); auto findFirstNode = nodeMap.find(boneNodeIdPair.first);

View File

@ -66,18 +66,18 @@ private:
void parametersToNodes(const std::vector<RiggerBone> *rigBones, void parametersToNodes(const std::vector<RiggerBone> *rigBones,
const float heightAboveGroundLevel, const float heightAboveGroundLevel,
std::map<QString, std::pair<QUuid, QUuid>> *boneNameToIdsMap, std::map<QString, std::pair<QUuid, QUuid>> *boneNameToIdsMap,
QUuid *groundPartId, //QUuid *groundPartId,
QUuid *bonesPartId, QUuid *bonesPartId,
QUuid *groundEdgeId, //QUuid *groundEdgeId,
bool isOther=false); bool isOther=false);
void updateBonesAndHeightAboveGroundLevelFromParameters(std::vector<RiggerBone> *bones, void updateBonesAndHeightAboveGroundLevelFromParameters(std::vector<RiggerBone> *bones,
float *heightAboveGroundLevel, float *heightAboveGroundLevel,
const std::map<QString, std::map<QString, QString>> &parameters); const std::map<QString, std::map<QString, QString>> &parameters);
std::map<QString, std::pair<QUuid, QUuid>> m_boneNameToIdsMap; std::map<QString, std::pair<QUuid, QUuid>> m_boneNameToIdsMap;
QUuid m_groundPartId; //QUuid m_groundPartId;
QUuid m_bonesPartId; QUuid m_bonesPartId;
QUuid m_groundEdgeId; //QUuid m_groundEdgeId;
std::deque<PoseHistoryItem> m_undoItems; std::deque<PoseHistoryItem> m_undoItems;
std::deque<PoseHistoryItem> m_redoItems; std::deque<PoseHistoryItem> m_redoItems;
std::vector<RiggerBone> m_riggerBones; std::vector<RiggerBone> m_riggerBones;

View File

@ -12,9 +12,8 @@ PoseManageWidget::PoseManageWidget(const Document *document, QWidget *parent) :
{ {
QPushButton *addPoseButton = new QPushButton(Theme::awesome()->icon(fa::plus), tr("Add Pose...")); QPushButton *addPoseButton = new QPushButton(Theme::awesome()->icon(fa::plus), tr("Add Pose..."));
addPoseButton->hide(); addPoseButton->hide();
connect(addPoseButton, &QPushButton::clicked, this, &PoseManageWidget::showAddPoseDialog); connect(addPoseButton, &QPushButton::clicked, this, &PoseManageWidget::showAddPoseDialog);
QHBoxLayout *toolsLayout = new QHBoxLayout; QHBoxLayout *toolsLayout = new QHBoxLayout;
toolsLayout->addWidget(addPoseButton); toolsLayout->addWidget(addPoseButton);