Add new base normal option: Average

When this option enabled, the mesh generator will average all the base normals of nodes with radius as a weight.
master
Jeremy Hu 2019-06-25 08:14:04 +09:30
parent c76bc4f77c
commit 83cb6383c1
5 changed files with 34 additions and 2 deletions

View File

@ -155,7 +155,7 @@ void AnimalPoser::resolveChainRotation(const std::vector<QString> &limbBoneNames
QVector3D targetMiddleBoneStartPosition; QVector3D targetMiddleBoneStartPosition;
{ {
qDebug() << beginBoneName << "Angle:" << angleBetweenDistanceAndMiddleBones << "Distance:" << targetDistanceBetweenBeginAndEndBones; //qDebug() << beginBoneName << "Angle:" << angleBetweenDistanceAndMiddleBones << "Distance:" << targetDistanceBetweenBeginAndEndBones;
auto rotation = QQuaternion::fromAxisAndAngle(matchRotatePlaneNormal, angleBetweenDistanceAndMiddleBones); auto rotation = QQuaternion::fromAxisAndAngle(matchRotatePlaneNormal, angleBetweenDistanceAndMiddleBones);
targetMiddleBoneStartPosition = targetEndBoneStartPosition + rotation.rotatedVector(-matchDirectionBetweenBeginAndEndPones).normalized() * targetMiddleBoneLength; targetMiddleBoneStartPosition = targetEndBoneStartPosition + rotation.rotatedVector(-matchDirectionBetweenBeginAndEndPones).normalized() * targetMiddleBoneLength;
} }

View File

@ -457,6 +457,8 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt
builder->setCutRotation(cutRotation); builder->setCutRotation(cutRotation);
if (PartBase::YZ == base) { if (PartBase::YZ == base) {
builder->enableBaseNormalOnX(false); builder->enableBaseNormalOnX(false);
} else if (PartBase::Average == base) {
builder->enableBaseNormalAverage(true);
} else if (PartBase::XY == base) { } else if (PartBase::XY == base) {
builder->enableBaseNormalOnZ(false); builder->enableBaseNormalOnZ(false);
} else if (PartBase::ZX == base) { } else if (PartBase::ZX == base) {
@ -793,7 +795,7 @@ nodemesh::Combiner::Mesh *MeshGenerator::combineMultipleMeshes(const std::vector
for (const auto &it: multipleMeshes) { for (const auto &it: multipleMeshes) {
const auto &childCombineMode = it.second; const auto &childCombineMode = it.second;
nodemesh::Combiner::Mesh *subMesh = it.first; nodemesh::Combiner::Mesh *subMesh = it.first;
qDebug() << "Combine mode:" << CombineModeToString(childCombineMode); //qDebug() << "Combine mode:" << CombineModeToString(childCombineMode);
if (nullptr == subMesh) { if (nullptr == subMesh) {
qDebug() << "Child mesh is null"; qDebug() << "Child mesh is null";
continue; continue;

View File

@ -6,6 +6,7 @@
enum class PartBase enum class PartBase
{ {
XYZ = 0, XYZ = 0,
Average,
YZ, YZ,
XY, XY,
ZX, ZX,
@ -18,6 +19,8 @@ PartBase PartBaseFromString(const char *baseString)
QString base = baseString; \ QString base = baseString; \
if (base == "XYZ") \ if (base == "XYZ") \
return PartBase::XYZ; \ return PartBase::XYZ; \
if (base == "Average") \
return PartBase::Average; \
if (base == "YZ") \ if (base == "YZ") \
return PartBase::YZ; \ return PartBase::YZ; \
if (base == "XY") \ if (base == "XY") \
@ -33,6 +36,8 @@ const char *PartBaseToString(PartBase base)
switch (base) { \ switch (base) { \
case PartBase::XYZ: \ case PartBase::XYZ: \
return "XYZ"; \ return "XYZ"; \
case PartBase::Average: \
return "Average"; \
case PartBase::YZ: \ case PartBase::YZ: \
return "YZ"; \ return "YZ"; \
case PartBase::XY: \ case PartBase::XY: \
@ -50,6 +55,8 @@ QString PartBaseToDispName(PartBase base)
switch (base) { \ switch (base) { \
case PartBase::XYZ: \ case PartBase::XYZ: \
return QObject::tr("Dynamic"); \ return QObject::tr("Dynamic"); \
case PartBase::Average: \
return QObject::tr("Average"); \
case PartBase::YZ: \ case PartBase::YZ: \
return QObject::tr("Side Plane"); \ return QObject::tr("Side Plane"); \
case PartBase::XY: \ case PartBase::XY: \

View File

@ -259,6 +259,22 @@ bool Builder::build()
for (const auto &nodeIndex: m_sortedNodeIndices) { for (const auto &nodeIndex: m_sortedNodeIndices) {
prepareNode(nodeIndex); prepareNode(nodeIndex);
} }
if (m_baseNormalAverageEnabled) {
QVector3D sumNormal;
for (const auto &node: m_nodes) {
if (node.hasInitialBaseNormal) {
sumNormal += node.initialBaseNormal * node.radius;
}
}
QVector3D averageNormal = sumNormal.normalized();
if (!averageNormal.isNull()) {
for (auto &node: m_nodes) {
if (node.hasInitialBaseNormal) {
node.initialBaseNormal = revisedBaseNormalAcordingToCutNormal(averageNormal, node.traverseDirection);
}
}
}
}
for (const auto &nodeIndex: m_sortedNodeIndices) { for (const auto &nodeIndex: m_sortedNodeIndices) {
resolveBaseNormalRecursively(nodeIndex); resolveBaseNormalRecursively(nodeIndex);
} }
@ -304,6 +320,11 @@ void Builder::enableBaseNormalOnZ(bool enabled)
m_baseNormalOnZ = enabled; m_baseNormalOnZ = enabled;
} }
void Builder::enableBaseNormalAverage(bool enabled)
{
m_baseNormalAverageEnabled = enabled;
}
std::pair<QVector3D, bool> Builder::calculateBaseNormal(const std::vector<QVector3D> &inputDirects, std::pair<QVector3D, bool> Builder::calculateBaseNormal(const std::vector<QVector3D> &inputDirects,
const std::vector<QVector3D> &inputPositions, const std::vector<QVector3D> &inputPositions,
const std::vector<float> &weights) const std::vector<float> &weights)

View File

@ -20,6 +20,7 @@ public:
void enableBaseNormalOnX(bool enabled); void enableBaseNormalOnX(bool enabled);
void enableBaseNormalOnY(bool enabled); void enableBaseNormalOnY(bool enabled);
void enableBaseNormalOnZ(bool enabled); void enableBaseNormalOnZ(bool enabled);
void enableBaseNormalAverage(bool enabled);
const std::vector<QVector3D> &generatedVertices(); const std::vector<QVector3D> &generatedVertices();
const std::vector<std::vector<size_t>> &generatedFaces(); const std::vector<std::vector<size_t>> &generatedFaces();
const std::vector<size_t> &generatedVerticesSourceNodeIndices(); const std::vector<size_t> &generatedVerticesSourceNodeIndices();
@ -98,6 +99,7 @@ private:
bool m_baseNormalOnX = true; bool m_baseNormalOnX = true;
bool m_baseNormalOnY = true; bool m_baseNormalOnY = true;
bool m_baseNormalOnZ = true; bool m_baseNormalOnZ = true;
bool m_baseNormalAverageEnabled = false;
void sortNodeIndices(); void sortNodeIndices();
void prepareNode(size_t nodeIndex); void prepareNode(size_t nodeIndex);