Showing the changes to libraries/render-utils/src/Model.cpp (1 of 35 files). Show all
Unified · Split
| @@ -308,12 +308,12 @@ bool Model::updateGeometry() { · 307 unmodified lines | |||
| 308 | state.clusterDualQuaternions.resize(mesh.clusters.size()); | 308 | state.clusterDualQuaternions.resize(mesh.clusters.size()); |
| 309 | state.clusterMatrices.resize(mesh.clusters.size()); | 309 | state.clusterMatrices.resize(mesh.clusters.size()); |
| 310 | _meshStates.push_back(state); | 310 | _meshStates.push_back(state); |
| 311 | if (!mesh.blendshapes.empty() && _blendedVertexBuffers.find(i) == _blendedVertexBuffers.end()) { | 311 | if (_blendshapeBuffers.find(i) == _blendshapeBuffers.end()) { |
| 312 | initializeBlendshapes(mesh, i); | 312 | initializeBlendshapes(mesh, i); |
| 313 | } | 313 | } |
| 314 | i++; | 314 | i++; |
| 315 | } | 315 | } |
| 316 | _blendedVertexBuffersInitialized = true; | 316 | _blendshapeBuffersInitialized = true; |
| 317 | needFullUpdate = true; | 317 | needFullUpdate = true; |
| 318 | emit rigReady(); | 318 | emit rigReady(); |
| 319 | } | 319 | } |
| @@ -1034,9 +1034,9 @@ void Model::removeFromScene(const render::ScenePointer& scene, render::Transacti · 714 unmodified lines | |||
| 1034 | _modelMeshMaterialNames.clear(); | 1034 | _modelMeshMaterialNames.clear(); |
| 1035 | _modelMeshRenderItemShapes.clear(); | 1035 | _modelMeshRenderItemShapes.clear(); |
| 1036 | 1036 | ||
| 1037 | _blendedVertexBuffers.clear(); | 1037 | _blendshapeBuffers.clear(); |
| 1038 | _normalsAndTangents.clear(); | 1038 | _blendshapeOffsets.clear(); |
| 1039 | _blendedVertexBuffersInitialized = false; | 1039 | _blendshapeBuffersInitialized = false; |
| 1040 | 1040 | ||
| 1041 | _addedToScene = false; | 1041 | _addedToScene = false; |
| 1042 | 1042 | ||
| @@ -1304,26 +1304,21 @@ Blender::Blender(ModelPointer model, int blendNumber, const Geometry::WeakPointe · 261 unmodified lines | |||
| 1304 | } | 1304 | } |
| 1305 | 1305 | ||
| 1306 | void Blender::run() { | 1306 | void Blender::run() { |
| 1307 | QVector<glm::vec3> vertices; | 1307 | QVector<BlendshapeOffset> blendshapeOffsets; |
| 1308 | QVector<NormalType> normalsAndTangents; | ||
| 1309 | if (_model && _model->isLoaded()) { | 1308 | if (_model && _model->isLoaded()) { |
| 1310 | DETAILED_PROFILE_RANGE_EX(simulation_animation, __FUNCTION__, 0xFFFF0000, 0, { { "url", _model->getURL().toString() } }); | 1309 | DETAILED_PROFILE_RANGE_EX(simulation_animation, __FUNCTION__, 0xFFFF0000, 0, { { "url", _model->getURL().toString() } }); |
| 1311 | int offset = 0; | 1310 | int offset = 0; |
| 1312 | int normalsAndTangentsOffset = 0; | ||
| 1313 | auto meshes = _model->getFBXGeometry().meshes; | 1311 | auto meshes = _model->getFBXGeometry().meshes; |
| 1314 | int meshIndex = 0; | 1312 | int meshIndex = 0; |
| 1315 | foreach (const FBXMesh& mesh, meshes) { | 1313 | foreach (const FBXMesh& mesh, meshes) { |
| 1316 | auto modelMeshNormalsAndTangents = _model->_normalsAndTangents.find(meshIndex++); | 1314 | auto modelMeshBlendshapeOffsets = _model->_blendshapeOffsets.find(meshIndex++); |
| 1317 | if (mesh.blendshapes.isEmpty() || modelMeshNormalsAndTangents == _model->_normalsAndTangents.end()) { | 1315 | if (mesh.blendshapes.isEmpty() || modelMeshBlendshapeOffsets == _model->_blendshapeOffsets.end()) { |
| 1318 | continue; | 1316 | continue; |
| 1319 | } | 1317 | } |
| 1320 | 1318 | ||
| 1321 | vertices += mesh.vertices; | 1319 | blendshapeOffsets += modelMeshBlendshapeOffsets->second; |
| 1322 | normalsAndTangents += modelMeshNormalsAndTangents->second; | 1320 | BlendshapeOffset* meshBlendshapeOffsets = blendshapeOffsets.data() + offset; |
| 1323 | glm::vec3* meshVertices = vertices.data() + offset; | 1321 | offset += modelMeshBlendshapeOffsets->second.size(); |
| 1324 | NormalType* meshNormalsAndTangents = normalsAndTangents.data() + normalsAndTangentsOffset; | ||
| 1325 | offset += mesh.vertices.size(); | ||
| 1326 | normalsAndTangentsOffset += modelMeshNormalsAndTangents->second.size(); | ||
| 1327 | const float NORMAL_COEFFICIENT_SCALE = 0.01f; | 1322 | const float NORMAL_COEFFICIENT_SCALE = 0.01f; |
| 1328 | for (int i = 0, n = qMin(_blendshapeCoefficients.size(), mesh.blendshapes.size()); i < n; i++) { | 1323 | for (int i = 0, n = qMin(_blendshapeCoefficients.size(), mesh.blendshapes.size()); i < n; i++) { |
| 1329 | float vertexCoefficient = _blendshapeCoefficients.at(i); | 1324 | float vertexCoefficient = _blendshapeCoefficients.at(i); |
| @@ -1336,26 +1331,15 @@ void Blender::run() { · 6 unmodified lines | |||
| 1336 | tbb::parallel_for(tbb::blocked_range<int>(0, blendshape.indices.size()), [&](const tbb::blocked_range<int>& range) { | 1331 | tbb::parallel_for(tbb::blocked_range<int>(0, blendshape.indices.size()), [&](const tbb::blocked_range<int>& range) { |
| 1337 | for (auto j = range.begin(); j < range.end(); j++) { | 1332 | for (auto j = range.begin(); j < range.end(); j++) { |
| 1338 | int index = blendshape.indices.at(j); | 1333 | int index = blendshape.indices.at(j); |
| 1339 | meshVertices[index] += blendshape.vertices.at(j) * vertexCoefficient; | 1334 | auto& currentBlendshapeOffset = meshBlendshapeOffsets[index]; |
| 1335 | currentBlendshapeOffset.positionOffsetAndSpare += glm::vec4(blendshape.vertices.at(j) * vertexCoefficient, 0.0f); | ||
| 1340 | 1336 | ||
| 1341 | glm::vec3 normal = mesh.normals.at(index) + blendshape.normals.at(j) * normalCoefficient; | 1337 | currentBlendshapeOffset.normalOffsetAndSpare += glm::vec4(blendshape.normals.at(j) * normalCoefficient, 0.0f); |
| 1342 | glm::vec3 tangent; | ||
| 1343 | if (index < mesh.tangents.size()) { | 1338 | if (index < mesh.tangents.size()) { |
| 1344 | tangent = mesh.tangents.at(index); | ||
| 1345 | if ((int)j < blendshape.tangents.size()) { | 1339 | if ((int)j < blendshape.tangents.size()) { |
| 1346 | tangent += blendshape.tangents.at(j) * normalCoefficient; | 1340 | currentBlendshapeOffset.tangentOffsetAndSpare += glm::vec4(blendshape.tangents.at(j) * normalCoefficient, 0.0f); |
| 1347 | } | 1341 | } |
| 1348 | } | 1342 | } |
| 1349 | #if FBX_PACK_NORMALS | ||
| 1350 | glm::uint32 finalNormal; | ||
| 1351 | glm::uint32 finalTangent; | ||
| 1352 | buffer_helpers::packNormalAndTangent(normal, tangent, finalNormal, finalTangent); | ||
| 1353 | #else | ||
| 1354 | const auto& finalNormal = normal; | ||
| 1355 | const auto& finalTangent = tangent; | ||
| 1356 | #endif | ||
| 1357 | meshNormalsAndTangents[2 * index] = finalNormal; | ||
| 1358 | meshNormalsAndTangents[2 * index + 1] = finalTangent; | ||
| 1359 | } | 1343 | } |
| 1360 | }); | 1344 | }); |
| 1361 | } | 1345 | } |
| @@ -1363,8 +1347,7 @@ void Blender::run() { · 1 unmodified line | |||
| 1363 | } | 1347 | } |
| 1364 | // post the result to the ModelBlender, which will dispatch to the model if still alive | 1348 | // post the result to the ModelBlender, which will dispatch to the model if still alive |
| 1365 | QMetaObject::invokeMethod(DependencyManager::get<ModelBlender>().data(), "setBlendedVertices", | 1349 | QMetaObject::invokeMethod(DependencyManager::get<ModelBlender>().data(), "setBlendedVertices", |
| 1366 | Q_ARG(ModelPointer, _model), Q_ARG(int, _blendNumber), Q_ARG(QVector<glm::vec3>, vertices), | 1350 | Q_ARG(ModelPointer, _model), Q_ARG(int, _blendNumber), Q_ARG(QVector<BlendshapeOffset>, blendshapeOffsets)); |
| 1367 | Q_ARG(QVector<NormalType>, normalsAndTangents)); | ||
| 1368 | } | 1351 | } |
| 1369 | 1352 | ||
| 1370 | void Model::setScaleToFit(bool scaleToFit, const glm::vec3& dimensions, bool forceRescale) { | 1353 | void Model::setScaleToFit(bool scaleToFit, const glm::vec3& dimensions, bool forceRescale) { |
| @@ -1525,7 +1508,7 @@ void Model::updateClusterMatrices() { · 154 unmodified lines | |||
| 1525 | 1508 | ||
| 1526 | // post the blender if we're not currently waiting for one to finish | 1509 | // post the blender if we're not currently waiting for one to finish |
| 1527 | auto modelBlender = DependencyManager::get<ModelBlender>(); | 1510 | auto modelBlender = DependencyManager::get<ModelBlender>(); |
| 1528 | if (_blendedVertexBuffersInitialized && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { | 1511 | if (_blendshapeBuffersInitialized && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { |
| 1529 | _blendedBlendshapeCoefficients = _blendshapeCoefficients; | 1512 | _blendedBlendshapeCoefficients = _blendshapeCoefficients; |
| 1530 | modelBlender->noteRequiresBlend(getThisPointer()); | 1513 | modelBlender->noteRequiresBlend(getThisPointer()); |
| 1531 | } | 1514 | } |
| @@ -1542,39 +1525,34 @@ bool Model::maybeStartBlender() { · 10 unmodified lines | |||
| 1542 | return false; | 1525 | return false; |
| 1543 | } | 1526 | } |
| 1544 | 1527 | ||
| 1545 | void Model::setBlendedVertices(int blendNumber, const QVector<glm::vec3>& vertices, const QVector<NormalType>& normalsAndTangents) { | 1528 | void Model::setBlendedVertices(int blendNumber, const QVector<BlendshapeOffset>& blendshapeOffsets) { |
| 1546 | if (!isLoaded() || blendNumber < _appliedBlendNumber || !_blendedVertexBuffersInitialized) { | 1529 | if (!isLoaded() || blendNumber < _appliedBlendNumber || !_blendshapeBuffersInitialized) { |
| 1547 | return; | 1530 | return; |
| 1548 | } | 1531 | } |
| 1549 | _appliedBlendNumber = blendNumber; | 1532 | _appliedBlendNumber = blendNumber; |
| 1550 | const FBXGeometry& fbxGeometry = getFBXGeometry(); | 1533 | const FBXGeometry& fbxGeometry = getFBXGeometry(); |
| 1551 | int index = 0; | 1534 | int index = 0; |
| 1552 | int normalAndTangentIndex = 0; | ||
| 1553 | for (int i = 0; i < fbxGeometry.meshes.size(); i++) { | 1535 | for (int i = 0; i < fbxGeometry.meshes.size(); i++) { |
| 1554 | const FBXMesh& mesh = fbxGeometry.meshes.at(i); | 1536 | const FBXMesh& mesh = fbxGeometry.meshes.at(i); |
| 1555 | auto meshNormalsAndTangents = _normalsAndTangents.find(i); | 1537 | auto meshBlendshapeOffsets = _blendshapeOffsets.find(i); |
| 1556 | if (mesh.blendshapes.isEmpty() || meshNormalsAndTangents == _normalsAndTangents.end()) { | 1538 | if (mesh.blendshapes.isEmpty() || meshBlendshapeOffsets == _blendshapeOffsets.end()) { |
| 1557 | continue; | 1539 | continue; |
| 1558 | } | 1540 | } |
| 1559 | 1541 | ||
| 1560 | const auto vertexCount = mesh.vertices.size(); | 1542 | const auto& buffer = _blendshapeBuffers.find(i); |
| 1561 | const auto verticesSize = vertexCount * sizeof(glm::vec3); | 1543 | assert(buffer != _blendshapeBuffers.end()); |
| 1562 | const auto& buffer = _blendedVertexBuffers.find(i); | 1544 | const auto blendshapeOffsetSize = meshBlendshapeOffsets->second.size() * sizeof(BlendshapeOffset); |
| 1563 | assert(buffer != _blendedVertexBuffers.end()); | 1545 | buffer->second->setData(blendshapeOffsetSize, (gpu::Byte*) blendshapeOffsets.constData() + index * sizeof(BlendshapeOffset)); |
| 1564 | buffer->second->resize(mesh.vertices.size() * sizeof(glm::vec3) + meshNormalsAndTangents->second.size() * sizeof(NormalType)); | ||
| 1565 | buffer->second->setSubData(0, verticesSize, (gpu::Byte*) vertices.constData() + index * sizeof(glm::vec3)); | ||
| 1566 | buffer->second->setSubData(verticesSize, meshNormalsAndTangents->second.size() * sizeof(NormalType), (const gpu::Byte*) normalsAndTangents.data() + normalAndTangentIndex * sizeof(NormalType)); | ||
| 1567 | 1546 | ||
| 1568 | index += vertexCount; | 1547 | index += meshBlendshapeOffsets->second.size(); |
| 1569 | normalAndTangentIndex += meshNormalsAndTangents->second.size(); | ||
| 1570 | } | 1548 | } |
| 1571 | } | 1549 | } |
| 1572 | 1550 | ||
| 1573 | void Model::deleteGeometry() { | 1551 | void Model::deleteGeometry() { |
| 1574 | _deleteGeometryCounter++; | 1552 | _deleteGeometryCounter++; |
| 1575 | _blendedVertexBuffers.clear(); | 1553 | _blendshapeBuffers.clear(); |
| 1576 | _normalsAndTangents.clear(); | 1554 | _blendshapeOffsets.clear(); |
| 1577 | _blendedVertexBuffersInitialized = false; | 1555 | _blendshapeBuffersInitialized = false; |
| 1578 | _meshStates.clear(); | 1556 | _meshStates.clear(); |
| 1579 | _rig.destroyAnimGraph(); | 1557 | _rig.destroyAnimGraph(); |
| 1580 | _blendedBlendshapeCoefficients.clear(); | 1558 | _blendedBlendshapeCoefficients.clear(); |
| @@ -1607,39 +1585,12 @@ const render::ItemIDs& Model::fetchRenderItemIDs() const { · 26 unmodified lines | |||
| 1607 | } | 1585 | } |
| 1608 | 1586 | ||
| 1609 | void Model::initializeBlendshapes(const FBXMesh& mesh, int index) { | 1587 | void Model::initializeBlendshapes(const FBXMesh& mesh, int index) { |
| 1610 | _blendedVertexBuffers[index] = std::make_shared<gpu::Buffer>(); | 1588 | _blendshapeBuffers[index] = std::make_shared<gpu::Buffer>(); |
| 1611 | QVector<NormalType> normalsAndTangents; | 1589 | QVector<BlendshapeOffset> blendshapeOffset; |
| 1612 | normalsAndTangents.resize(2 * mesh.normals.size()); | 1590 | blendshapeOffset.fill(BlendshapeOffset(), 3 * mesh.vertices.size()); |
| 1613 | 1591 | const auto blendshapeOffsetsSize = blendshapeOffset.size() * sizeof(BlendshapeOffset); | |
| 1614 | // Interleave normals and tangents | 1592 | _blendshapeBuffers[index]->setData(blendshapeOffsetsSize, (const gpu::Byte*) blendshapeOffset.constData()); |
| 1615 | // Parallel version for performance | 1593 | _blendshapeOffsets[index] = blendshapeOffset; |
| 1616 | tbb::parallel_for(tbb::blocked_range<int>(0, mesh.normals.size()), [&](const tbb::blocked_range<int>& range) { | ||
| 1617 | auto normalsRange = std::make_pair(mesh.normals.begin() + range.begin(), mesh.normals.begin() + range.end()); | ||
| 1618 | auto tangentsRange = std::make_pair(mesh.tangents.begin() + range.begin(), mesh.tangents.begin() + range.end()); | ||
| 1619 | auto normalsAndTangentsIt = normalsAndTangents.begin() + 2 * range.begin(); | ||
| 1620 | |||
| 1621 | for (auto normalIt = normalsRange.first, tangentIt = tangentsRange.first; | ||
| 1622 | normalIt != normalsRange.second; | ||
| 1623 | ++normalIt, ++tangentIt) { | ||
| 1624 | #if FBX_PACK_NORMALS | ||
| 1625 | glm::uint32 finalNormal; | ||
| 1626 | glm::uint32 finalTangent; | ||
| 1627 | buffer_helpers::packNormalAndTangent(*normalIt, *tangentIt, finalNormal, finalTangent); | ||
| 1628 | #else | ||
| 1629 | const auto& finalNormal = *normalIt; | ||
| 1630 | const auto& finalTangent = *tangentIt; | ||
| 1631 | #endif | ||
| 1632 | *normalsAndTangentsIt = finalNormal; | ||
| 1633 | ++normalsAndTangentsIt; | ||
| 1634 | *normalsAndTangentsIt = finalTangent; | ||
| 1635 | ++normalsAndTangentsIt; | ||
| 1636 | } | ||
| 1637 | }); | ||
| 1638 | const auto verticesSize = mesh.vertices.size() * sizeof(glm::vec3); | ||
| 1639 | _blendedVertexBuffers[index]->resize(mesh.vertices.size() * sizeof(glm::vec3) + normalsAndTangents.size() * sizeof(NormalType)); | ||
| 1640 | _blendedVertexBuffers[index]->setSubData(0, verticesSize, (const gpu::Byte*) mesh.vertices.constData()); | ||
| 1641 | _blendedVertexBuffers[index]->setSubData(verticesSize, normalsAndTangents.size() * sizeof(NormalType), (const gpu::Byte*) normalsAndTangents.data()); | ||
| 1642 | _normalsAndTangents[index] = normalsAndTangents; | ||
| 1643 | } | 1594 | } |
| 1644 | 1595 | ||
| 1645 | void Model::createRenderItemSet() { | 1596 | void Model::createRenderItemSet() { |
| @@ -1680,7 +1631,7 @@ void Model::createRenderItemSet() { · 34 unmodified lines | |||
| 1680 | // Create the render payloads | 1631 | // Create the render payloads |
| 1681 | int numParts = (int)mesh->getNumParts(); | 1632 | int numParts = (int)mesh->getNumParts(); |
| 1682 | for (int partIndex = 0; partIndex < numParts; partIndex++) { | 1633 | for (int partIndex = 0; partIndex < numParts; partIndex++) { |
| 1683 | if (!fbxGeometry.meshes[i].blendshapes.empty() && _blendedVertexBuffers.find(i) == _blendedVertexBuffers.end()) { | 1634 | if (_blendshapeBuffers.find(i) == _blendshapeBuffers.end()) { |
| 1684 | initializeBlendshapes(fbxGeometry.meshes[i], i); | 1635 | initializeBlendshapes(fbxGeometry.meshes[i], i); |
| 1685 | } | 1636 | } |
| 1686 | _modelMeshRenderItems << std::make_shared<ModelMeshPartPayload>(shared_from_this(), i, partIndex, shapeID, transform, offset); | 1637 | _modelMeshRenderItems << std::make_shared<ModelMeshPartPayload>(shared_from_this(), i, partIndex, shapeID, transform, offset); |
| @@ -1794,9 +1745,9 @@ void ModelBlender::noteRequiresBlend(ModelPointer model) { · 107 unmodified lines | |||
| 1794 | _modelsRequiringBlends.insert(model); | 1745 | _modelsRequiringBlends.insert(model); |
| 1795 | } | 1746 | } |
| 1796 | 1747 | ||
| 1797 | void ModelBlender::setBlendedVertices(ModelPointer model, int blendNumber, QVector<glm::vec3> vertices, QVector<NormalType> normalsAndTangents) { | 1748 | void ModelBlender::setBlendedVertices(ModelPointer model, int blendNumber, QVector<BlendshapeOffset> blendshapeOffsets) { |
| 1798 | if (model) { | 1749 | if (model) { |
| 1799 | model->setBlendedVertices(blendNumber, vertices, normalsAndTangents); | 1750 | model->setBlendedVertices(blendNumber, blendshapeOffsets); |
| 1800 | } | 1751 | } |
| 1801 | { | 1752 | { |
| 1802 | Lock lock(_mutex); | 1753 | Lock lock(_mutex); |