mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 22:16:58 +02:00
update how nodes are initially parsed
This commit is contained in:
parent
c970a58715
commit
3c84a46cba
2 changed files with 69 additions and 75 deletions
|
@ -751,43 +751,25 @@ void GLTFSerializer::getSkinInverseBindMatrices(std::vector<std::vector<float>>&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLTFSerializer::getNodeQueueByDepthFirstChildren(std::vector<int>& children, int stride, bool addChildrenInReverseOrder, std::vector<int>& result) {
|
|
||||||
int startingIndex = 0;
|
|
||||||
int finalIndex = (int)children.size();
|
|
||||||
if (stride == -1 || addChildrenInReverseOrder) {
|
|
||||||
startingIndex = (int)children.size() - 1;
|
|
||||||
finalIndex = -1;
|
|
||||||
stride = -1;
|
|
||||||
}
|
|
||||||
for (int index = startingIndex; index != finalIndex; index += stride) {
|
|
||||||
int c = children[index];
|
|
||||||
result.push_back(c);
|
|
||||||
std::vector<int> nested = _file.nodes[c].children.toStdVector();
|
|
||||||
if (nested.size() != 0) {
|
|
||||||
std::sort(nested.begin(), nested.end());
|
|
||||||
for (int r : nested) {
|
|
||||||
if (result.end() == std::find(result.begin(), result.end(), r)) {
|
|
||||||
getNodeQueueByDepthFirstChildren(nested, stride, addChildrenInReverseOrder, result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::URL& url) {
|
bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::URL& url) {
|
||||||
int numNodes = _file.nodes.size();
|
int numNodes = _file.nodes.size();
|
||||||
bool skinnedModel = !_file.skins.isEmpty();
|
bool skinnedModel = !_file.skins.isEmpty();
|
||||||
|
|
||||||
|
|
||||||
//Build dependencies
|
//Build dependencies
|
||||||
QVector<QVector<int>> nodeDependencies(numNodes);
|
QVector<QVector<int>> nodeDependencies(numNodes);
|
||||||
|
QVector<int> parents;
|
||||||
|
QVector<int> nodesToSort = _file.scenes[_file.scene].nodes;
|
||||||
|
parents.fill(-1, numNodes);
|
||||||
|
nodesToSort.reserve(numNodes);
|
||||||
int nodecount = 0;
|
int nodecount = 0;
|
||||||
bool parentGreaterThanChild = false;
|
|
||||||
foreach(auto &node, _file.nodes) {
|
foreach(auto &node, _file.nodes) {
|
||||||
//nodes_transforms.push_back(getModelTransform(node));
|
|
||||||
foreach(int child, node.children) {
|
foreach(int child, node.children) {
|
||||||
nodeDependencies[child].push_back(nodecount);
|
nodeDependencies[child].push_back(nodecount);
|
||||||
parentGreaterThanChild |= nodecount > child;
|
parents[child] = nodecount;
|
||||||
|
}
|
||||||
|
if (!nodesToSort.contains(nodecount)) {
|
||||||
|
nodesToSort.push_back(nodecount);
|
||||||
}
|
}
|
||||||
nodecount++;
|
nodecount++;
|
||||||
}
|
}
|
||||||
|
@ -806,47 +788,62 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::URL& url) {
|
||||||
} else break;
|
} else break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nodecount++;
|
nodecount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// initialize order in which nodes will be parsed
|
// initialize order in which nodes will be parsed
|
||||||
std::vector<int> nodeQueue;
|
std::vector<int> nodeQueue;
|
||||||
nodeQueue.reserve(numNodes);
|
QVector<int> originalToNewNodeIndexMap;
|
||||||
int rootNode = 0;
|
QVector<bool> hasBeenSorted;
|
||||||
int finalNode = numNodes;
|
originalToNewNodeIndexMap.fill(-1, numNodes);
|
||||||
for (int sceneNode : _file.scenes[_file.scene].nodes) {
|
hasBeenSorted.fill(false, numNodes);
|
||||||
// reverse the order in which the nodes are initialized
|
nodeQueue = _file.scenes[_file.scene].nodes.toStdVector();
|
||||||
if (!_file.nodes[sceneNode].defined["camera"] && sceneNode != 0) {
|
|
||||||
rootNode = numNodes - 1;
|
for (int sceneNodeCount = 0; sceneNodeCount < _file.scenes[_file.scene].nodes.size(); sceneNodeCount++) {
|
||||||
finalNode = -1;
|
int sceneNode = nodeQueue[sceneNodeCount];
|
||||||
break;
|
originalToNewNodeIndexMap[sceneNode] = sceneNodeCount;
|
||||||
|
nodesToSort[nodesToSort.indexOf(sceneNode)] = nodesToSort.back();
|
||||||
|
nodesToSort.pop_back();
|
||||||
|
hasBeenSorted[sceneNode] = true;
|
||||||
|
for (int child : _file.nodes[sceneNode].children.toStdVector()) {
|
||||||
|
nodesToSort[nodesToSort.indexOf(child)] = nodesToSort.back();
|
||||||
|
nodesToSort.pop_back();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
bool rootAtStartOfList = rootNode < finalNode;
|
|
||||||
int nodeListStride = 1;
|
|
||||||
if (!rootAtStartOfList) { nodeListStride = -1; }
|
|
||||||
|
|
||||||
QVector<int> initialSceneNodes = _file.scenes[_file.scene].nodes;
|
for (int child : _file.nodes[sceneNode].children) {
|
||||||
std::sort(initialSceneNodes.begin(), initialSceneNodes.end());
|
originalToNewNodeIndexMap[child] = nodeQueue.size();
|
||||||
|
nodeQueue.push_back(child);
|
||||||
|
hasBeenSorted[child] = true;
|
||||||
|
|
||||||
int sceneRootNode = 0;
|
if (!_file.nodes[child].children.isEmpty() && nodeQueue.size() < numNodes) {
|
||||||
int sceneFinalNode = initialSceneNodes.size();
|
int newSize = nodesToSort.size();
|
||||||
if (!rootAtStartOfList) {
|
while (!nodesToSort.isEmpty()) {
|
||||||
sceneRootNode = initialSceneNodes.size() - 1;
|
int i = 0;
|
||||||
sceneFinalNode = -1;
|
|
||||||
}
|
while (i < nodesToSort.size()) {
|
||||||
// this is an edge case where, for a skinned model, there is a parent who's index is greater than it's child's index
|
int nodeIndex = nodesToSort[i];
|
||||||
// when the opposite is expected
|
int parentIndex = parents[nodeIndex];
|
||||||
// in this case, we want the order of the children to be reversed, even if the root node is 0
|
newSize = nodesToSort.size();
|
||||||
bool addChildrenInReverseOrder = rootAtStartOfList && parentGreaterThanChild && skinnedModel;
|
|
||||||
for (int index = sceneRootNode; index != sceneFinalNode; index += nodeListStride) {
|
if ((parentIndex == -1 || hasBeenSorted[parentIndex])) {
|
||||||
int i = initialSceneNodes[index];
|
originalToNewNodeIndexMap[nodeIndex] = nodeQueue.size();
|
||||||
nodeQueue.push_back(i);
|
nodeQueue.push_back(nodeIndex);
|
||||||
std::vector<int> children = _file.nodes[i].children.toStdVector();
|
hasBeenSorted[nodeIndex] = true;
|
||||||
std::sort(children.begin(), children.end());
|
// copy back and pop
|
||||||
getNodeQueueByDepthFirstChildren(children, nodeListStride, addChildrenInReverseOrder, nodeQueue);
|
nodesToSort[i] = nodesToSort.back();
|
||||||
|
nodesToSort.pop_back();
|
||||||
|
} else { // skip
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if the end of nodesToSort is reached without removing any nodes, break to move onto the next child
|
||||||
|
if (newSize == nodesToSort.size() && i == nodesToSort.size()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -861,13 +858,13 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::URL& url) {
|
||||||
|
|
||||||
joint.parentIndex = -1;
|
joint.parentIndex = -1;
|
||||||
if (!_file.scenes[_file.scene].nodes.contains(nodeIndex)) {
|
if (!_file.scenes[_file.scene].nodes.contains(nodeIndex)) {
|
||||||
joint.parentIndex = std::distance(nodeQueue.begin(), std::find(nodeQueue.begin(), nodeQueue.end(), nodeDependencies[nodeIndex][0]));
|
joint.parentIndex = originalToNewNodeIndexMap[parents[nodeIndex]];
|
||||||
}
|
}
|
||||||
joint.transform = node.transforms.first();
|
joint.transform = node.transforms.first();
|
||||||
joint.translation = extractTranslation(joint.transform);
|
joint.translation = extractTranslation(joint.transform);
|
||||||
joint.rotation = glmExtractRotation(joint.transform);
|
joint.rotation = glmExtractRotation(joint.transform);
|
||||||
glm::vec3 scale = extractScale(joint.transform);
|
glm::vec3 scale = extractScale(joint.transform);
|
||||||
joint.postTransform = glm::scale(glm::mat4(), scale);
|
joint.postTransform = glm::scale(glm::mat4(), scale);
|
||||||
|
|
||||||
joint.name = node.name;
|
joint.name = node.name;
|
||||||
joint.isSkeletonJoint = false;
|
joint.isSkeletonJoint = false;
|
||||||
|
@ -882,20 +879,19 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::URL& url) {
|
||||||
std::vector<std::vector<float>> inverseBindValues;
|
std::vector<std::vector<float>> inverseBindValues;
|
||||||
getSkinInverseBindMatrices(inverseBindValues);
|
getSkinInverseBindMatrices(inverseBindValues);
|
||||||
|
|
||||||
int jointIndex = finalNode;
|
for (int jointIndex = 0; jointIndex < numNodes; jointIndex++) {
|
||||||
while (jointIndex != rootNode) {
|
int nodeIndex = nodeQueue[jointIndex];
|
||||||
rootAtStartOfList ? jointIndex-- : jointIndex++;
|
|
||||||
int jOffset = nodeQueue[jointIndex];
|
|
||||||
auto joint = hfmModel.joints[jointIndex];
|
auto joint = hfmModel.joints[jointIndex];
|
||||||
|
|
||||||
hfmModel.hasSkeletonJoints = true;
|
hfmModel.hasSkeletonJoints = true;
|
||||||
for (int s = 0; s < _file.skins.size(); s++) {
|
for (int s = 0; s < _file.skins.size(); s++) {
|
||||||
auto skin = _file.skins[s];
|
const auto& skin = _file.skins[s];
|
||||||
joint.isSkeletonJoint = skin.joints.contains(jOffset);
|
int matrixIndex = skin.joints.indexOf(nodeIndex);
|
||||||
|
joint.isSkeletonJoint = skin.joints.contains(nodeIndex);
|
||||||
|
|
||||||
if (joint.isSkeletonJoint) {
|
if (joint.isSkeletonJoint) {
|
||||||
std::vector<float> value = inverseBindValues[s];
|
std::vector<float>& value = inverseBindValues[s];
|
||||||
int matrixCount = 16 * skin.joints.indexOf(jOffset);
|
int matrixCount = 16 * matrixIndex;
|
||||||
jointInverseBindTransforms[jointIndex] =
|
jointInverseBindTransforms[jointIndex] =
|
||||||
glm::mat4(value[matrixCount], value[matrixCount + 1], value[matrixCount + 2], value[matrixCount + 3],
|
glm::mat4(value[matrixCount], value[matrixCount + 1], value[matrixCount + 2], value[matrixCount + 3],
|
||||||
value[matrixCount + 4], value[matrixCount + 5], value[matrixCount + 6], value[matrixCount + 7],
|
value[matrixCount + 4], value[matrixCount + 5], value[matrixCount + 6], value[matrixCount + 7],
|
||||||
|
@ -932,7 +928,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::URL& url) {
|
||||||
|
|
||||||
// Build meshes
|
// Build meshes
|
||||||
nodecount = 0;
|
nodecount = 0;
|
||||||
for (int nodeIndex = rootNode; nodeIndex != finalNode; nodeIndex += nodeListStride) {
|
for (int nodeIndex : nodeQueue) {
|
||||||
auto& node = _file.nodes[nodeIndex];
|
auto& node = _file.nodes[nodeIndex];
|
||||||
|
|
||||||
if (node.defined["mesh"]) {
|
if (node.defined["mesh"]) {
|
||||||
|
@ -947,7 +943,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::URL& url) {
|
||||||
cluster.inverseBindTransform = Transform(cluster.inverseBindMatrix);
|
cluster.inverseBindTransform = Transform(cluster.inverseBindMatrix);
|
||||||
mesh.clusters.append(cluster);
|
mesh.clusters.append(cluster);
|
||||||
} else {
|
} else {
|
||||||
for (int j = rootNode; j != finalNode; j += nodeListStride) {
|
for (int j : nodeQueue) {
|
||||||
HFMCluster cluster;
|
HFMCluster cluster;
|
||||||
cluster.jointIndex = j;
|
cluster.jointIndex = j;
|
||||||
cluster.inverseBindMatrix = jointInverseBindTransforms[j];
|
cluster.inverseBindMatrix = jointInverseBindTransforms[j];
|
||||||
|
@ -956,7 +952,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::URL& url) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HFMCluster root;
|
HFMCluster root;
|
||||||
root.jointIndex = rootNode;
|
root.jointIndex = nodeQueue[0];
|
||||||
if (root.jointIndex == -1) {
|
if (root.jointIndex == -1) {
|
||||||
root.jointIndex = 0;
|
root.jointIndex = 0;
|
||||||
}
|
}
|
||||||
|
@ -1181,7 +1177,6 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::URL& url) {
|
||||||
nodecount++;
|
nodecount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -713,7 +713,6 @@ private:
|
||||||
|
|
||||||
glm::mat4 getModelTransform(const GLTFNode& node);
|
glm::mat4 getModelTransform(const GLTFNode& node);
|
||||||
void getSkinInverseBindMatrices(std::vector<std::vector<float>>& inverseBindMatrixValues);
|
void getSkinInverseBindMatrices(std::vector<std::vector<float>>& inverseBindMatrixValues);
|
||||||
void getNodeQueueByDepthFirstChildren(std::vector<int>& children, int stride, bool addChildrenInReverseOrder, std::vector<int>& result);
|
|
||||||
|
|
||||||
bool buildGeometry(HFMModel& hfmModel, const hifi::URL& url);
|
bool buildGeometry(HFMModel& hfmModel, const hifi::URL& url);
|
||||||
bool parseGLTF(const hifi::ByteArray& data);
|
bool parseGLTF(const hifi::ByteArray& data);
|
||||||
|
|
Loading…
Reference in a new issue