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 | 308 | state.clusterDualQuaternions.resize(mesh.clusters.size()); |
| 309 | 309 | state.clusterMatrices.resize(mesh.clusters.size()); |
| 310 | 310 | _meshStates.push_back(state); |
| 311 | − if (!mesh.blendshapes.empty() && _blendedVertexBuffers.find(i) == _blendedVertexBuffers.end()) { | |
| 311 | + if (_blendshapeBuffers.find(i) == _blendshapeBuffers.end()) { | |
| 312 | 312 | initializeBlendshapes(mesh, i); |
| 313 | 313 | } |
| 314 | 314 | i++; |
| 315 | 315 | } |
| 316 | − _blendedVertexBuffersInitialized = true; | |
| 316 | + _blendshapeBuffersInitialized = true; | |
| 317 | 317 | needFullUpdate = true; |
| 318 | 318 | emit rigReady(); |
| 319 | 319 | } |
| @@ -1034,9 +1034,9 @@ void Model::removeFromScene(const render::ScenePointer& scene, render::Transacti · 714 unmodified lines | ||
| 1034 | 1034 | _modelMeshMaterialNames.clear(); |
| 1035 | 1035 | _modelMeshRenderItemShapes.clear(); |
| 1036 | 1036 | |
| 1037 | − _blendedVertexBuffers.clear(); | |
| 1038 | − _normalsAndTangents.clear(); | |
| 1039 | − _blendedVertexBuffersInitialized = false; | |
| 1037 | + _blendshapeBuffers.clear(); | |
| 1038 | + _blendshapeOffsets.clear(); | |
| 1039 | + _blendshapeBuffersInitialized = false; | |
| 1040 | 1040 | |
| 1041 | 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 | 1306 | void Blender::run() { |
| 1307 | − QVector<glm::vec3> vertices; | |
| 1308 | − QVector<NormalType> normalsAndTangents; | |
| 1307 | + QVector<BlendshapeOffset> blendshapeOffsets; | |
| 1309 | 1308 | if (_model && _model->isLoaded()) { |
| 1310 | 1309 | DETAILED_PROFILE_RANGE_EX(simulation_animation, __FUNCTION__, 0xFFFF0000, 0, { { "url", _model->getURL().toString() } }); |
| 1311 | 1310 | int offset = 0; |
| 1312 | − int normalsAndTangentsOffset = 0; | |
| 1313 | 1311 | auto meshes = _model->getFBXGeometry().meshes; |
| 1314 | 1312 | int meshIndex = 0; |
| 1315 | 1313 | foreach (const FBXMesh& mesh, meshes) { |
| 1316 | − auto modelMeshNormalsAndTangents = _model->_normalsAndTangents.find(meshIndex++); | |
| 1317 | − if (mesh.blendshapes.isEmpty() || modelMeshNormalsAndTangents == _model->_normalsAndTangents.end()) { | |
| 1314 | + auto modelMeshBlendshapeOffsets = _model->_blendshapeOffsets.find(meshIndex++); | |
| 1315 | + if (mesh.blendshapes.isEmpty() || modelMeshBlendshapeOffsets == _model->_blendshapeOffsets.end()) { | |
| 1318 | 1316 | continue; |
| 1319 | 1317 | } |
| 1320 | 1318 | |
| 1321 | − vertices += mesh.vertices; | |
| 1322 | − normalsAndTangents += modelMeshNormalsAndTangents->second; | |
| 1323 | − glm::vec3* meshVertices = vertices.data() + offset; | |
| 1324 | − NormalType* meshNormalsAndTangents = normalsAndTangents.data() + normalsAndTangentsOffset; | |
| 1325 | − offset += mesh.vertices.size(); | |
| 1326 | − normalsAndTangentsOffset += modelMeshNormalsAndTangents->second.size(); | |
| 1319 | + blendshapeOffsets += modelMeshBlendshapeOffsets->second; | |
| 1320 | + BlendshapeOffset* meshBlendshapeOffsets = blendshapeOffsets.data() + offset; | |
| 1321 | + offset += modelMeshBlendshapeOffsets->second.size(); | |
| 1327 | 1322 | const float NORMAL_COEFFICIENT_SCALE = 0.01f; |
| 1328 | 1323 | for (int i = 0, n = qMin(_blendshapeCoefficients.size(), mesh.blendshapes.size()); i < n; i++) { |
| 1329 | 1324 | float vertexCoefficient = _blendshapeCoefficients.at(i); |
| @@ -1336,26 +1331,15 @@ void Blender::run() { · 6 unmodified lines | ||
| 1336 | 1331 | tbb::parallel_for(tbb::blocked_range<int>(0, blendshape.indices.size()), [&](const tbb::blocked_range<int>& range) { |
| 1337 | 1332 | for (auto j = range.begin(); j < range.end(); j++) { |
| 1338 | 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; | |
| 1342 | − glm::vec3 tangent; | |
| 1337 | + currentBlendshapeOffset.normalOffsetAndSpare += glm::vec4(blendshape.normals.at(j) * normalCoefficient, 0.0f); | |
| 1343 | 1338 | if (index < mesh.tangents.size()) { |
| 1344 | − tangent = mesh.tangents.at(index); | |
| 1345 | 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 | 1348 | // post the result to the ModelBlender, which will dispatch to the model if still alive |
| 1365 | 1349 | QMetaObject::invokeMethod(DependencyManager::get<ModelBlender>().data(), "setBlendedVertices", |
| 1366 | − Q_ARG(ModelPointer, _model), Q_ARG(int, _blendNumber), Q_ARG(QVector<glm::vec3>, vertices), | |
| 1367 | − Q_ARG(QVector<NormalType>, normalsAndTangents)); | |
| 1350 | + Q_ARG(ModelPointer, _model), Q_ARG(int, _blendNumber), Q_ARG(QVector<BlendshapeOffset>, blendshapeOffsets)); | |
| 1368 | 1351 | } |
| 1369 | 1352 | |
| 1370 | 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 | 1509 | // post the blender if we're not currently waiting for one to finish |
| 1527 | 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 | 1512 | _blendedBlendshapeCoefficients = _blendshapeCoefficients; |
| 1530 | 1513 | modelBlender->noteRequiresBlend(getThisPointer()); |
| 1531 | 1514 | } |
| @@ -1542,39 +1525,34 @@ bool Model::maybeStartBlender() { · 10 unmodified lines | ||
| 1542 | 1525 | return false; |
| 1543 | 1526 | } |
| 1544 | 1527 | |
| 1545 | −void Model::setBlendedVertices(int blendNumber, const QVector<glm::vec3>& vertices, const QVector<NormalType>& normalsAndTangents) { | |
| 1546 | − if (!isLoaded() || blendNumber < _appliedBlendNumber || !_blendedVertexBuffersInitialized) { | |
| 1528 | +void Model::setBlendedVertices(int blendNumber, const QVector<BlendshapeOffset>& blendshapeOffsets) { | |
| 1529 | + if (!isLoaded() || blendNumber < _appliedBlendNumber || !_blendshapeBuffersInitialized) { | |
| 1547 | 1530 | return; |
| 1548 | 1531 | } |
| 1549 | 1532 | _appliedBlendNumber = blendNumber; |
| 1550 | 1533 | const FBXGeometry& fbxGeometry = getFBXGeometry(); |
| 1551 | 1534 | int index = 0; |
| 1552 | − int normalAndTangentIndex = 0; | |
| 1553 | 1535 | for (int i = 0; i < fbxGeometry.meshes.size(); i++) { |
| 1554 | 1536 | const FBXMesh& mesh = fbxGeometry.meshes.at(i); |
| 1555 | − auto meshNormalsAndTangents = _normalsAndTangents.find(i); | |
| 1556 | − if (mesh.blendshapes.isEmpty() || meshNormalsAndTangents == _normalsAndTangents.end()) { | |
| 1537 | + auto meshBlendshapeOffsets = _blendshapeOffsets.find(i); | |
| 1538 | + if (mesh.blendshapes.isEmpty() || meshBlendshapeOffsets == _blendshapeOffsets.end()) { | |
| 1557 | 1539 | continue; |
| 1558 | 1540 | } |
| 1559 | 1541 | |
| 1560 | − const auto vertexCount = mesh.vertices.size(); | |
| 1561 | − const auto verticesSize = vertexCount * sizeof(glm::vec3); | |
| 1562 | − const auto& buffer = _blendedVertexBuffers.find(i); | |
| 1563 | − assert(buffer != _blendedVertexBuffers.end()); | |
| 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)); | |
| 1542 | + const auto& buffer = _blendshapeBuffers.find(i); | |
| 1543 | + assert(buffer != _blendshapeBuffers.end()); | |
| 1544 | + const auto blendshapeOffsetSize = meshBlendshapeOffsets->second.size() * sizeof(BlendshapeOffset); | |
| 1545 | + buffer->second->setData(blendshapeOffsetSize, (gpu::Byte*) blendshapeOffsets.constData() + index * sizeof(BlendshapeOffset)); | |
| 1567 | 1546 | |
| 1568 | − index += vertexCount; | |
| 1569 | − normalAndTangentIndex += meshNormalsAndTangents->second.size(); | |
| 1547 | + index += meshBlendshapeOffsets->second.size(); | |
| 1570 | 1548 | } |
| 1571 | 1549 | } |
| 1572 | 1550 | |
| 1573 | 1551 | void Model::deleteGeometry() { |
| 1574 | 1552 | _deleteGeometryCounter++; |
| 1575 | − _blendedVertexBuffers.clear(); | |
| 1576 | − _normalsAndTangents.clear(); | |
| 1577 | − _blendedVertexBuffersInitialized = false; | |
| 1553 | + _blendshapeBuffers.clear(); | |
| 1554 | + _blendshapeOffsets.clear(); | |
| 1555 | + _blendshapeBuffersInitialized = false; | |
| 1578 | 1556 | _meshStates.clear(); |
| 1579 | 1557 | _rig.destroyAnimGraph(); |
| 1580 | 1558 | _blendedBlendshapeCoefficients.clear(); |
| @@ -1607,39 +1585,12 @@ const render::ItemIDs& Model::fetchRenderItemIDs() const { · 26 unmodified lines | ||
| 1607 | 1585 | } |
| 1608 | 1586 | |
| 1609 | 1587 | void Model::initializeBlendshapes(const FBXMesh& mesh, int index) { |
| 1610 | − _blendedVertexBuffers[index] = std::make_shared<gpu::Buffer>(); | |
| 1611 | − QVector<NormalType> normalsAndTangents; | |
| 1612 | − normalsAndTangents.resize(2 * mesh.normals.size()); | |
| 1613 | − | |
| 1614 | − // Interleave normals and tangents | |
| 1615 | − // Parallel version for performance | |
| 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; | |
| 1588 | + _blendshapeBuffers[index] = std::make_shared<gpu::Buffer>(); | |
| 1589 | + QVector<BlendshapeOffset> blendshapeOffset; | |
| 1590 | + blendshapeOffset.fill(BlendshapeOffset(), 3 * mesh.vertices.size()); | |
| 1591 | + const auto blendshapeOffsetsSize = blendshapeOffset.size() * sizeof(BlendshapeOffset); | |
| 1592 | + _blendshapeBuffers[index]->setData(blendshapeOffsetsSize, (const gpu::Byte*) blendshapeOffset.constData()); | |
| 1593 | + _blendshapeOffsets[index] = blendshapeOffset; | |
| 1643 | 1594 | } |
| 1644 | 1595 | |
| 1645 | 1596 | void Model::createRenderItemSet() { |
| @@ -1680,7 +1631,7 @@ void Model::createRenderItemSet() { · 34 unmodified lines | ||
| 1680 | 1631 | // Create the render payloads |
| 1681 | 1632 | int numParts = (int)mesh->getNumParts(); |
| 1682 | 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 | 1635 | initializeBlendshapes(fbxGeometry.meshes[i], i); |
| 1685 | 1636 | } |
| 1686 | 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 | 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 | 1749 | if (model) { |
| 1799 | − model->setBlendedVertices(blendNumber, vertices, normalsAndTangents); | |
| 1750 | + model->setBlendedVertices(blendNumber, blendshapeOffsets); | |
| 1800 | 1751 | } |
| 1801 | 1752 | { |
| 1802 | 1753 | Lock lock(_mutex); |