Change the spine bone naming convention
When there is tail bone, the spine bone start with "Spine01" and "Spine02", this is to make the spine bone name match with none-tail bones. Why "Spine01"? Because the bone chain is ordered by name, "Spine01" and "Spine02" come before "Spine1".master
parent
0b18da76ea
commit
033ea5f53e
|
@ -20,13 +20,13 @@ void AnimalPoser::resolveTransform()
|
||||||
resolveChainRotation(chain.second);
|
resolveChainRotation(chain.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
int firstSpineBoneIndex = findBoneIndex(Rigger::firstSpineBoneName);
|
//int firstSpineBoneIndex = findBoneIndex(Rigger::firstSpineBoneName);
|
||||||
if (-1 == firstSpineBoneIndex) {
|
//if (-1 == firstSpineBoneIndex) {
|
||||||
qDebug() << "Find first spine bone failed:" << Rigger::firstSpineBoneName;
|
// qDebug() << "Find first spine bone failed:" << Rigger::firstSpineBoneName;
|
||||||
return;
|
// return;
|
||||||
}
|
//}
|
||||||
|
|
||||||
const auto &firstSpineBone = bones()[firstSpineBoneIndex];
|
//const auto &firstSpineBone = bones()[firstSpineBoneIndex];
|
||||||
|
|
||||||
float mostBottomYBeforeTransform = std::numeric_limits<float>::max();
|
float mostBottomYBeforeTransform = std::numeric_limits<float>::max();
|
||||||
for (const auto &bone: bones()) {
|
for (const auto &bone: bones()) {
|
||||||
|
@ -38,15 +38,15 @@ void AnimalPoser::resolveTransform()
|
||||||
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();
|
||||||
QVector3D firstSpineBonePositionAfterTransform = firstSpineBone.headPosition;
|
//QVector3D firstSpineBonePositionAfterTransform = firstSpineBone.headPosition;
|
||||||
for (int i = 0; i < (int)transformedJointNodeTree.nodes().size(); ++i) {
|
for (int i = 0; i < (int)transformedJointNodeTree.nodes().size(); ++i) {
|
||||||
const auto &bone = bones()[i];
|
const auto &bone = bones()[i];
|
||||||
const auto &jointNode = transformedJointNodeTree.nodes()[i];
|
const auto &jointNode = transformedJointNodeTree.nodes()[i];
|
||||||
QVector3D newPosition = jointNode.transformMatrix * bone.tailPosition;
|
QVector3D newPosition = jointNode.transformMatrix * bone.tailPosition;
|
||||||
if (0 == i) {
|
//if (0 == i) {
|
||||||
// Root bone's tail position is the first spine bone's head position
|
// Root bone's tail position is the first spine bone's head position
|
||||||
firstSpineBonePositionAfterTransform = newPosition;
|
// firstSpineBonePositionAfterTransform = newPosition;
|
||||||
}
|
//}
|
||||||
if (newPosition.y() < mostBottomYAfterTransform)
|
if (newPosition.y() < mostBottomYAfterTransform)
|
||||||
mostBottomYAfterTransform = newPosition.y();
|
mostBottomYAfterTransform = newPosition.y();
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,6 +219,7 @@ bool AnimalRigger::rig()
|
||||||
auto tailIndices = m_marksMap.find(std::make_pair(BoneMark::Tail, SkeletonSide::None));
|
auto tailIndices = m_marksMap.find(std::make_pair(BoneMark::Tail, SkeletonSide::None));
|
||||||
auto leftLimbIndices = m_marksMap.find(std::make_pair(BoneMark::Limb, SkeletonSide::Left));
|
auto leftLimbIndices = m_marksMap.find(std::make_pair(BoneMark::Limb, SkeletonSide::Left));
|
||||||
auto rightLimbIndices = m_marksMap.find(std::make_pair(BoneMark::Limb, SkeletonSide::Right));
|
auto rightLimbIndices = m_marksMap.find(std::make_pair(BoneMark::Limb, SkeletonSide::Right));
|
||||||
|
bool hasTail = false;
|
||||||
std::vector<int> nosideMarkIndices;
|
std::vector<int> nosideMarkIndices;
|
||||||
std::vector<int> leftMarkIndices;
|
std::vector<int> leftMarkIndices;
|
||||||
std::vector<int> righMarkIndices;
|
std::vector<int> righMarkIndices;
|
||||||
|
@ -229,6 +230,7 @@ bool AnimalRigger::rig()
|
||||||
if (tailIndices != m_marksMap.end()) {
|
if (tailIndices != m_marksMap.end()) {
|
||||||
for (const auto &index: tailIndices->second)
|
for (const auto &index: tailIndices->second)
|
||||||
nosideMarkIndices.push_back(index);
|
nosideMarkIndices.push_back(index);
|
||||||
|
hasTail = true;
|
||||||
}
|
}
|
||||||
if (leftLimbIndices != m_marksMap.end()) {
|
if (leftLimbIndices != m_marksMap.end()) {
|
||||||
for (const auto &index: leftLimbIndices->second)
|
for (const auto &index: leftLimbIndices->second)
|
||||||
|
@ -421,7 +423,7 @@ bool AnimalRigger::rig()
|
||||||
spineBoneHeadPosition.setY(averagePoint.y());
|
spineBoneHeadPosition.setY(averagePoint.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString spineName = namingSpine(spineGenerateOrder);
|
QString spineName = namingSpine(spineGenerateOrder, hasTail);
|
||||||
|
|
||||||
m_resultBones.push_back(RiggerBone());
|
m_resultBones.push_back(RiggerBone());
|
||||||
RiggerBone &spineBone = m_resultBones.back();
|
RiggerBone &spineBone = m_resultBones.back();
|
||||||
|
@ -439,8 +441,8 @@ bool AnimalRigger::rig()
|
||||||
m_resultBones[boneIndexMap[Rigger::rootBoneName]].tailPosition = spineBone.headPosition;
|
m_resultBones[boneIndexMap[Rigger::rootBoneName]].tailPosition = spineBone.headPosition;
|
||||||
m_resultBones[boneIndexMap[Rigger::rootBoneName]].children.push_back(spineBone.index);
|
m_resultBones[boneIndexMap[Rigger::rootBoneName]].children.push_back(spineBone.index);
|
||||||
} else {
|
} else {
|
||||||
m_resultBones[boneIndexMap[namingSpine(spineGenerateOrder - 1)]].tailPosition = spineBone.headPosition;
|
m_resultBones[boneIndexMap[namingSpine(spineGenerateOrder - 1, hasTail)]].tailPosition = spineBone.headPosition;
|
||||||
m_resultBones[boneIndexMap[namingSpine(spineGenerateOrder - 1)]].children.push_back(spineBone.index);
|
m_resultBones[boneIndexMap[namingSpine(spineGenerateOrder - 1, hasTail)]].children.push_back(spineBone.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &chainMarkIndex: spineNode.chainMarkIndices) {
|
for (const auto &chainMarkIndex: spineNode.chainMarkIndices) {
|
||||||
|
@ -460,7 +462,7 @@ bool AnimalRigger::rig()
|
||||||
if (1 == spineGenerateOrder) {
|
if (1 == spineGenerateOrder) {
|
||||||
m_resultBones[boneIndexMap[Rigger::rootBoneName]].children.push_back(ribBone.index);
|
m_resultBones[boneIndexMap[Rigger::rootBoneName]].children.push_back(ribBone.index);
|
||||||
} else {
|
} else {
|
||||||
m_resultBones[boneIndexMap[namingSpine(spineGenerateOrder)]].children.push_back(ribBone.index);
|
m_resultBones[boneIndexMap[namingSpine(spineGenerateOrder, hasTail)]].children.push_back(ribBone.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> jointMarkIndices;
|
std::vector<int> jointMarkIndices;
|
||||||
|
@ -619,10 +621,14 @@ QString AnimalRigger::namingChain(const QString &baseName, SkeletonSide side, in
|
||||||
return namingChainPrefix(baseName, side, orderInSide, totalInSide) + "_Joint" + QString::number(jointOrder);
|
return namingChainPrefix(baseName, side, orderInSide, totalInSide) + "_Joint" + QString::number(jointOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AnimalRigger::namingSpine(int spineOrder)
|
QString AnimalRigger::namingSpine(int spineOrder, bool hasTail)
|
||||||
{
|
{
|
||||||
if (1 == spineOrder)
|
if (hasTail) {
|
||||||
return Rigger::firstSpineBoneName;
|
if (spineOrder <= 2) {
|
||||||
|
return "Spine0" + QString::number(spineOrder);
|
||||||
|
}
|
||||||
|
spineOrder -= 2;
|
||||||
|
}
|
||||||
return "Spine" + QString::number(spineOrder);
|
return "Spine" + QString::number(spineOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ protected:
|
||||||
BoneMark translateBoneMark(BoneMark boneMark) override;
|
BoneMark translateBoneMark(BoneMark boneMark) override;
|
||||||
private:
|
private:
|
||||||
bool collectJontsForChain(int markIndex, std::vector<int> &jointMarkIndices);
|
bool collectJontsForChain(int markIndex, std::vector<int> &jointMarkIndices);
|
||||||
static QString namingSpine(int spineOrder);
|
static QString namingSpine(int spineOrder, bool hasTail);
|
||||||
static QString namingConnector(const QString &spineName, const QString &chainName);
|
static QString namingConnector(const QString &spineName, const QString &chainName);
|
||||||
static QString namingChain(const QString &baseName, SkeletonSide side, int orderInSide, int totalInSide, int jointOrder);
|
static QString namingChain(const QString &baseName, SkeletonSide side, int orderInSide, int totalInSide, int jointOrder);
|
||||||
static QString namingChainPrefix(const QString &baseName, SkeletonSide side, int orderInSide, int totalInSide);
|
static QString namingChainPrefix(const QString &baseName, SkeletonSide side, int orderInSide, int totalInSide);
|
||||||
|
|
|
@ -514,13 +514,14 @@ float PoseDocument::findFootBottomY() const
|
||||||
return maxY;
|
return maxY;
|
||||||
}
|
}
|
||||||
|
|
||||||
float PoseDocument::findLegHeight() const
|
//float PoseDocument::findLegHeight() const
|
||||||
{
|
//{
|
||||||
float firstSpineY = findFirstSpineY();
|
// float firstSpineY = findFirstSpineY();
|
||||||
float footBottomY = findFootBottomY();
|
// float footBottomY = findFootBottomY();
|
||||||
return std::abs(footBottomY - firstSpineY);
|
// return std::abs(footBottomY - firstSpineY);
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
/*
|
||||||
float PoseDocument::findFirstSpineY() const
|
float PoseDocument::findFirstSpineY() const
|
||||||
{
|
{
|
||||||
const auto &findFirstSpine = m_boneNameToIdsMap.find(Rigger::firstSpineBoneName);
|
const auto &findFirstSpine = m_boneNameToIdsMap.find(Rigger::firstSpineBoneName);
|
||||||
|
@ -535,6 +536,7 @@ float PoseDocument::findFirstSpineY() const
|
||||||
}
|
}
|
||||||
return firstSpineNode->y;
|
return firstSpineNode->y;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void PoseDocument::toParameters(std::map<QString, std::map<QString, QString>> ¶meters, const std::set<QUuid> &limitNodeIds) const
|
void PoseDocument::toParameters(std::map<QString, std::map<QString, QString>> ¶meters, const std::set<QUuid> &limitNodeIds) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,8 +61,8 @@ public:
|
||||||
private:
|
private:
|
||||||
QString findBoneNameByNodeId(const QUuid &nodeId);
|
QString findBoneNameByNodeId(const QUuid &nodeId);
|
||||||
float findFootBottomY() const;
|
float findFootBottomY() const;
|
||||||
float findFirstSpineY() const;
|
//float findFirstSpineY() const;
|
||||||
float findLegHeight() const;
|
//float findLegHeight() const;
|
||||||
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,
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
size_t Rigger::m_maxCutOffSplitterExpandRound = 3;
|
size_t Rigger::m_maxCutOffSplitterExpandRound = 3;
|
||||||
QString Rigger::rootBoneName = "Body";
|
QString Rigger::rootBoneName = "Body";
|
||||||
QString Rigger::firstSpineBoneName = "Spine1";
|
//QString Rigger::firstSpineBoneName = "Spine1";
|
||||||
|
|
||||||
Rigger::Rigger(const std::vector<QVector3D> &verticesPositions,
|
Rigger::Rigger(const std::vector<QVector3D> &verticesPositions,
|
||||||
const std::set<MeshSplitterTriangle> &inputTriangles) :
|
const std::set<MeshSplitterTriangle> &inputTriangles) :
|
||||||
|
|
|
@ -130,7 +130,7 @@ public:
|
||||||
const std::map<int, RiggerVertexWeights> &resultWeights();
|
const std::map<int, RiggerVertexWeights> &resultWeights();
|
||||||
virtual bool rig() = 0;
|
virtual bool rig() = 0;
|
||||||
static QString rootBoneName;
|
static QString rootBoneName;
|
||||||
static QString firstSpineBoneName;
|
//static QString firstSpineBoneName;
|
||||||
protected:
|
protected:
|
||||||
virtual bool validate() = 0;
|
virtual bool validate() = 0;
|
||||||
virtual bool isCutOffSplitter(BoneMark boneMark) = 0;
|
virtual bool isCutOffSplitter(BoneMark boneMark) = 0;
|
||||||
|
|
Loading…
Reference in New Issue