mirror of
https://github.com/overte-org/overte.git
synced 2025-04-07 20:14:22 +02:00
Merge pull request #15555 from raveenajain/gltf_walkingBounding
Case 22352: gltf walking, bounding, collision
This commit is contained in:
commit
8d8c7c1a10
1 changed files with 76 additions and 53 deletions
|
@ -841,7 +841,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
parents[child] = nodecount;
|
||||
}
|
||||
sortedNodes.push_back(nodecount);
|
||||
nodecount++;
|
||||
++nodecount;
|
||||
}
|
||||
|
||||
|
||||
|
@ -857,7 +857,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
_file.nodes[nodecount].transforms.push_back(getModelTransform(parentNode));
|
||||
parentIndex = parents[parentIndex];
|
||||
}
|
||||
nodecount++;
|
||||
++nodecount;
|
||||
}
|
||||
|
||||
|
||||
|
@ -871,7 +871,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
int parentIndex = parents[currentNode];
|
||||
if (parentIndex == -1 || hasBeenSorted[parentIndex]) {
|
||||
hasBeenSorted[currentNode] = true;
|
||||
i++;
|
||||
++i;
|
||||
} else {
|
||||
int j = i + 1; // index of node to be sorted
|
||||
while (j < numNodes) {
|
||||
|
@ -882,10 +882,10 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
hasBeenSorted[nextNode] = true;
|
||||
sortedNodes[i] = nextNode;
|
||||
sortedNodes[j] = currentNode;
|
||||
i++;
|
||||
++i;
|
||||
currentNode = sortedNodes[i];
|
||||
}
|
||||
j++;
|
||||
++j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -894,7 +894,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
// Build map from original to new indices
|
||||
QVector<int> originalToNewNodeIndexMap;
|
||||
originalToNewNodeIndexMap.fill(-1, numNodes);
|
||||
for (int i = 0; i < numNodes; i++) {
|
||||
for (int i = 0; i < numNodes; ++i) {
|
||||
originalToNewNodeIndexMap[sortedNodes[i]] = i;
|
||||
}
|
||||
|
||||
|
@ -903,6 +903,8 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
HFMJoint joint;
|
||||
joint.distanceToParent = 0;
|
||||
hfmModel.jointIndices["x"] = numNodes;
|
||||
QVector<glm::mat4> globalTransforms;
|
||||
globalTransforms.resize(numNodes);
|
||||
|
||||
for (int nodeIndex : sortedNodes) {
|
||||
auto& node = _file.nodes[nodeIndex];
|
||||
|
@ -917,6 +919,13 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
glm::vec3 scale = extractScale(joint.transform);
|
||||
joint.postTransform = glm::scale(glm::mat4(), scale);
|
||||
|
||||
joint.parentIndex = parents[nodeIndex];
|
||||
globalTransforms[nodeIndex] = joint.transform;
|
||||
if (joint.parentIndex != -1) {
|
||||
globalTransforms[nodeIndex] = globalTransforms[joint.parentIndex] * globalTransforms[nodeIndex];
|
||||
joint.parentIndex = originalToNewNodeIndexMap[joint.parentIndex];
|
||||
}
|
||||
|
||||
joint.name = node.name;
|
||||
joint.isSkeletonJoint = false;
|
||||
hfmModel.joints.push_back(joint);
|
||||
|
@ -924,20 +933,30 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
hfmModel.shapeVertices.resize(hfmModel.joints.size());
|
||||
|
||||
|
||||
// get offset transform from mapping
|
||||
float unitScaleFactor = 1.0f;
|
||||
float offsetScale = mapping.value("scale", 1.0f).toFloat() * unitScaleFactor;
|
||||
glm::quat offsetRotation = glm::quat(glm::radians(glm::vec3(mapping.value("rx").toFloat(), mapping.value("ry").toFloat(), mapping.value("rz").toFloat())));
|
||||
hfmModel.offset = glm::translate(glm::mat4(), glm::vec3(mapping.value("tx").toFloat(), mapping.value("ty").toFloat(), mapping.value("tz").toFloat())) *
|
||||
glm::mat4_cast(offsetRotation) * glm::scale(glm::mat4(), glm::vec3(offsetScale, offsetScale, offsetScale));
|
||||
|
||||
|
||||
// Build skeleton
|
||||
std::vector<glm::mat4> jointInverseBindTransforms;
|
||||
std::vector<glm::mat4> globalBindTransforms;
|
||||
jointInverseBindTransforms.resize(numNodes);
|
||||
globalBindTransforms.resize(numNodes);
|
||||
|
||||
hfmModel.hasSkeletonJoints = !_file.skins.isEmpty();
|
||||
if (hfmModel.hasSkeletonJoints) {
|
||||
hfmModel.hasSkeletonJoints = true;
|
||||
std::vector<std::vector<float>> inverseBindValues;
|
||||
getSkinInverseBindMatrices(inverseBindValues);
|
||||
|
||||
for (int jointIndex = 0; jointIndex < numNodes; jointIndex++) {
|
||||
for (int jointIndex = 0; jointIndex < numNodes; ++jointIndex) {
|
||||
int nodeIndex = sortedNodes[jointIndex];
|
||||
auto joint = hfmModel.joints[jointIndex];
|
||||
|
||||
for (int s = 0; s < _file.skins.size(); s++) {
|
||||
for (int s = 0; s < _file.skins.size(); ++s) {
|
||||
const auto& skin = _file.skins[s];
|
||||
int matrixIndex = skin.joints.indexOf(nodeIndex);
|
||||
joint.isSkeletonJoint = skin.joints.contains(nodeIndex);
|
||||
|
@ -954,6 +973,10 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
} else {
|
||||
jointInverseBindTransforms[jointIndex] = glm::mat4();
|
||||
}
|
||||
globalBindTransforms[jointIndex] = jointInverseBindTransforms[jointIndex];
|
||||
if (joint.parentIndex != -1) {
|
||||
globalBindTransforms[jointIndex] = globalBindTransforms[joint.parentIndex] * globalBindTransforms[jointIndex];
|
||||
}
|
||||
glm::vec3 bindTranslation = extractTranslation(hfmModel.offset * glm::inverse(jointInverseBindTransforms[jointIndex]));
|
||||
hfmModel.bindExtents.addPoint(bindTranslation);
|
||||
}
|
||||
|
@ -962,13 +985,13 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
}
|
||||
|
||||
|
||||
//Build materials
|
||||
// Build materials
|
||||
QVector<QString> materialIDs;
|
||||
QString unknown = "Default";
|
||||
int ukcount = 0;
|
||||
foreach(auto material, _file.materials) {
|
||||
if (!material.defined["name"]) {
|
||||
QString name = unknown + QString::number(ukcount++);
|
||||
QString name = unknown + QString::number(++ukcount);
|
||||
material.name = name;
|
||||
material.defined.insert("name", true);
|
||||
}
|
||||
|
@ -977,7 +1000,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
materialIDs.push_back(mid);
|
||||
}
|
||||
|
||||
for (int i = 0; i < materialIDs.size(); i++) {
|
||||
for (int i = 0; i < materialIDs.size(); ++i) {
|
||||
QString& matid = materialIDs[i];
|
||||
hfmModel.materials[matid] = HFMMaterial();
|
||||
HFMMaterial& hfmMaterial = hfmModel.materials[matid];
|
||||
|
@ -989,6 +1012,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
|
||||
// Build meshes
|
||||
nodecount = 0;
|
||||
hfmModel.meshExtents.reset();
|
||||
for (int nodeIndex : sortedNodes) {
|
||||
auto& node = _file.nodes[nodeIndex];
|
||||
|
||||
|
@ -1003,7 +1027,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
cluster.inverseBindTransform = Transform(cluster.inverseBindMatrix);
|
||||
mesh.clusters.append(cluster);
|
||||
} else { // skinned model
|
||||
for (int j = 0; j < numNodes; j++) {
|
||||
for (int j = 0; j < numNodes; ++j) {
|
||||
HFMCluster cluster;
|
||||
cluster.jointIndex = j;
|
||||
cluster.inverseBindMatrix = jointInverseBindTransforms[j];
|
||||
|
@ -1300,7 +1324,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
}
|
||||
|
||||
QVector<int> validatedIndices;
|
||||
for (int n = 0; n < indices.count(); n++) {
|
||||
for (int n = 0; n < indices.count(); ++n) {
|
||||
if (indices[n] < partVerticesCount) {
|
||||
validatedIndices.push_back(indices[n] + prevMeshVerticesCount);
|
||||
} else {
|
||||
|
@ -1332,7 +1356,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
}
|
||||
} else {
|
||||
if (meshAttributes.contains("TANGENT")) {
|
||||
for (int i = 0; i < partVerticesCount; i++) {
|
||||
for (int i = 0; i < partVerticesCount; ++i) {
|
||||
mesh.tangents.push_back(glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
}
|
||||
|
@ -1344,7 +1368,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
}
|
||||
} else {
|
||||
if (meshAttributes.contains("TEXCOORD_0")) {
|
||||
for (int i = 0; i < partVerticesCount; i++) {
|
||||
for (int i = 0; i < partVerticesCount; ++i) {
|
||||
mesh.texCoords.push_back(glm::vec2(0.0f, 0.0f));
|
||||
}
|
||||
}
|
||||
|
@ -1356,7 +1380,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
}
|
||||
} else {
|
||||
if (meshAttributes.contains("TEXCOORD_1")) {
|
||||
for (int i = 0; i < partVerticesCount; i++) {
|
||||
for (int i = 0; i < partVerticesCount; ++i) {
|
||||
mesh.texCoords1.push_back(glm::vec2(0.0f, 0.0f));
|
||||
}
|
||||
}
|
||||
|
@ -1368,7 +1392,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
}
|
||||
} else {
|
||||
if (meshAttributes.contains("COLOR_0")) {
|
||||
for (int i = 0; i < partVerticesCount; i++) {
|
||||
for (int i = 0; i < partVerticesCount; ++i) {
|
||||
mesh.colors.push_back(glm::vec3(1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
}
|
||||
|
@ -1398,8 +1422,8 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
}
|
||||
} else {
|
||||
if (meshAttributes.contains("JOINTS_0")) {
|
||||
for (int i = 0; i < partVerticesCount; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
for (int i = 0; i < partVerticesCount; ++i) {
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
clusterJoints.push_back(0);
|
||||
}
|
||||
}
|
||||
|
@ -1430,9 +1454,9 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
}
|
||||
} else {
|
||||
if (meshAttributes.contains("WEIGHTS_0")) {
|
||||
for (int i = 0; i < partVerticesCount; i++) {
|
||||
for (int i = 0; i < partVerticesCount; ++i) {
|
||||
clusterWeights.push_back(1.0f);
|
||||
for (int j = 1; j < 4; j++) {
|
||||
for (int j = 1; j < 4; ++j) {
|
||||
clusterWeights.push_back(0.0f);
|
||||
}
|
||||
}
|
||||
|
@ -1448,12 +1472,12 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
int numVertices = mesh.vertices.size() - prevMeshVerticesCount;
|
||||
|
||||
// Append new cluster indices and weights for this mesh part
|
||||
for (int i = 0; i < numVertices * WEIGHTS_PER_VERTEX; i++) {
|
||||
for (int i = 0; i < numVertices * WEIGHTS_PER_VERTEX; ++i) {
|
||||
mesh.clusterIndices.push_back(mesh.clusters.size() - 1);
|
||||
mesh.clusterWeights.push_back(0);
|
||||
}
|
||||
|
||||
for (int c = 0; c < clusterJoints.size(); c++) {
|
||||
for (int c = 0; c < clusterJoints.size(); ++c) {
|
||||
mesh.clusterIndices[prevMeshClusterIndexCount + c] =
|
||||
originalToNewNodeIndexMap[_file.skins[node.skin].joints[clusterJoints[c]]];
|
||||
}
|
||||
|
@ -1474,6 +1498,20 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
} else {
|
||||
mesh.clusterWeights[prevMeshClusterWeightCount + j] = (uint16_t)((float)(UINT16_MAX) + ALMOST_HALF);
|
||||
}
|
||||
for (int clusterIndex = 0; clusterIndex < mesh.clusters.size() - 1; ++clusterIndex) {
|
||||
ShapeVertices& points = hfmModel.shapeVertices.at(clusterIndex);
|
||||
glm::vec3 globalMeshScale = extractScale(globalTransforms[nodeIndex]);
|
||||
const glm::mat4 meshToJoint = glm::scale(glm::mat4(), globalMeshScale) * jointInverseBindTransforms[clusterIndex];
|
||||
|
||||
const float EXPANSION_WEIGHT_THRESHOLD = 0.25f;
|
||||
if (mesh.clusterWeights[j] >= EXPANSION_WEIGHT_THRESHOLD) {
|
||||
// TODO: fix transformed vertices being pushed back
|
||||
auto& vertex = mesh.vertices[i];
|
||||
const glm::mat4 vertexTransform = meshToJoint * (glm::translate(glm::mat4(), vertex));
|
||||
glm::vec3 transformedVertex = hfmModel.joints[clusterIndex].translation * (extractTranslation(vertexTransform));
|
||||
points.push_back(transformedVertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1484,7 +1522,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
|
||||
// populate the texture coordinates if they don't exist
|
||||
if (mesh.texCoords.size() == 0 && !hfmModel.hasSkeletonJoints) {
|
||||
for (int i = 0; i < part.triangleIndices.size(); i++) { mesh.texCoords.push_back(glm::vec2(0.0, 1.0)); }
|
||||
for (int i = 0; i < part.triangleIndices.size(); ++i) { mesh.texCoords.push_back(glm::vec2(0.0, 1.0)); }
|
||||
}
|
||||
|
||||
// Build morph targets (blend shapes)
|
||||
|
@ -1495,7 +1533,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
hifi::VariantHash blendshapeMappings = mapping.value("bs").toHash();
|
||||
QMultiHash<QString, WeightedIndex> blendshapeIndices;
|
||||
|
||||
for (int i = 0;; i++) {
|
||||
for (int i = 0;; ++i) {
|
||||
hifi::ByteArray blendshapeName = FACESHIFT_BLENDSHAPES[i];
|
||||
if (blendshapeName.isEmpty()) {
|
||||
break;
|
||||
|
@ -1515,7 +1553,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
auto names = _file.meshes[node.mesh].extras.targetNames;
|
||||
QVector<double> weights = _file.meshes[node.mesh].weights;
|
||||
|
||||
for (int weightedIndex = 0; weightedIndex < values.size(); weightedIndex++) {
|
||||
for (int weightedIndex = 0; weightedIndex < values.size(); ++weightedIndex) {
|
||||
float weight = 0.1f;
|
||||
int indexFromMapping = weightedIndex;
|
||||
int targetIndex = weightedIndex;
|
||||
|
@ -1556,32 +1594,17 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
} else {
|
||||
blendshape.vertices[count] = blendshape.vertices[count] + vertices[i];
|
||||
blendshape.normals[count] = blendshape.normals[count] + normals[i];
|
||||
count++;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int clusterIndex = 0; clusterIndex < mesh.clusters.size() - 1; clusterIndex++) {
|
||||
ShapeVertices& points = hfmModel.shapeVertices.at(clusterIndex);
|
||||
for (glm::vec3 vertex : mesh.vertices) {
|
||||
points.push_back(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
mesh.meshExtents.reset();
|
||||
foreach(const glm::vec3& vertex, mesh.vertices) {
|
||||
mesh.meshExtents.addPoint(vertex);
|
||||
hfmModel.meshExtents.addPoint(vertex);
|
||||
}
|
||||
|
||||
mesh.meshIndex = hfmModel.meshes.size();
|
||||
}
|
||||
|
||||
mesh.meshExtents.reset();
|
||||
foreach(const glm::vec3& vertex, mesh.vertices) {
|
||||
mesh.meshExtents.addPoint(vertex);
|
||||
hfmModel.meshExtents.addPoint(vertex);
|
||||
glm::vec3 transformedVertex = glm::vec3(globalTransforms[nodeIndex] * glm::vec4(vertex, 1.0f));
|
||||
mesh.meshExtents.addPoint(transformedVertex);
|
||||
hfmModel.meshExtents.addPoint(transformedVertex);
|
||||
}
|
||||
}
|
||||
|
||||
// Add epsilon to mesh extents to compensate for planar meshes
|
||||
|
@ -1592,7 +1615,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
|||
|
||||
mesh.meshIndex = hfmModel.meshes.size();
|
||||
}
|
||||
nodecount++;
|
||||
++nodecount;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1839,8 +1862,8 @@ bool GLTFSerializer::readArray(const hifi::ByteArray& bin, int byteOffset, int c
|
|||
blobstream.unsetDevice();
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < count; i++) {
|
||||
for (int j = 0; j < bufferCount; j++) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
for (int j = 0; j < bufferCount; ++j) {
|
||||
if (!blobstream.atEnd()) {
|
||||
T value;
|
||||
blobstream >> value;
|
||||
|
@ -1893,7 +1916,7 @@ bool GLTFSerializer::addArrayFromAccessor(GLTFAccessor& accessor, QVector<T>& ou
|
|||
success = addArrayOfType(buffer.blob, bufferview.byteOffset + accBoffset, accessor.count, outarray, accessor.type,
|
||||
accessor.componentType);
|
||||
} else {
|
||||
for (int i = 0; i < accessor.count; i++) {
|
||||
for (int i = 0; i < accessor.count; ++i) {
|
||||
T value;
|
||||
memset(&value, 0, sizeof(T)); // Make sure the dummy array is initalised to zero.
|
||||
outarray.push_back(value);
|
||||
|
@ -1924,10 +1947,10 @@ bool GLTFSerializer::addArrayFromAccessor(GLTFAccessor& accessor, QVector<T>& ou
|
|||
accessor.sparse.count, out_sparse_values_array, accessor.type, accessor.componentType);
|
||||
|
||||
if (success) {
|
||||
for (int i = 0; i < accessor.sparse.count; i++) {
|
||||
for (int i = 0; i < accessor.sparse.count; ++i) {
|
||||
if ((i * 3) + 2 < out_sparse_values_array.size()) {
|
||||
if ((out_sparse_indices_array[i] * 3) + 2 < outarray.length()) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
outarray[(out_sparse_indices_array[i] * 3) + j] = out_sparse_values_array[(i * 3) + j];
|
||||
}
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue