Showing the changes to libraries/render-utils/src/Model.cpp (1 of 5 files). Show all
Unified · Split
| @@ -48,50 +48,10 @@ float Model::FAKE_DIMENSION_PLACEHOLDER = -1.0f; · 47 unmodified lines | |||
| 48 | #define HTTP_INVALID_COM "http://invalid.com" | 48 | #define HTTP_INVALID_COM "http://invalid.com" |
| 49 | 49 | ||
| 50 | const int NUM_COLLISION_HULL_COLORS = 24; | 50 | const int NUM_COLLISION_HULL_COLORS = 24; |
| 51 | std::vector<graphics::MaterialPointer> _collisionMaterials; | ||
| 52 | |||
| 53 | void initCollisionMaterials() { | ||
| 54 | // generates bright colors in red, green, blue, yellow, magenta, and cyan spectrums | ||
| 55 | // (no browns, greys, or dark shades) | ||
| 56 | float component[NUM_COLLISION_HULL_COLORS] = { | ||
| 57 | 0.0f, 0.0f, 0.0f, 0.0f, | ||
| 58 | 0.0f, 0.0f, 0.0f, 0.0f, | ||
| 59 | 0.2f, 0.4f, 0.6f, 0.8f, | ||
| 60 | 1.0f, 1.0f, 1.0f, 1.0f, | ||
| 61 | 1.0f, 1.0f, 1.0f, 1.0f, | ||
| 62 | 0.8f, 0.6f, 0.4f, 0.2f | ||
| 63 | }; | ||
| 64 | _collisionMaterials.reserve(NUM_COLLISION_HULL_COLORS); | ||
| 65 | |||
| 66 | // each component gets the same cuve | ||
| 67 | // but offset by a multiple of one third the full width | ||
| 68 | int numComponents = 3; | ||
| 69 | int sectionWidth = NUM_COLLISION_HULL_COLORS / numComponents; | ||
| 70 | int greenPhase = sectionWidth; | ||
| 71 | int bluePhase = 2 * sectionWidth; | ||
| 72 | |||
| 73 | // we stride through the colors to scatter adjacent shades | ||
| 74 | // so they don't tend to group together for large models | ||
| 75 | for (int i = 0; i < sectionWidth; ++i) { | ||
| 76 | for (int j = 0; j < numComponents; ++j) { | ||
| 77 | graphics::MaterialPointer material; | ||
| 78 | material = std::make_shared<graphics::Material>(); | ||
| 79 | int index = j * sectionWidth + i; | ||
| 80 | float red = component[index % NUM_COLLISION_HULL_COLORS]; | ||
| 81 | float green = component[(index + greenPhase) % NUM_COLLISION_HULL_COLORS]; | ||
| 82 | float blue = component[(index + bluePhase) % NUM_COLLISION_HULL_COLORS]; | ||
| 83 | material->setAlbedo(glm::vec3(red, green, blue)); | ||
| 84 | material->setMetallic(0.02f); | ||
| 85 | material->setRoughness(0.5f); | ||
| 86 | _collisionMaterials.push_back(material); | ||
| 87 | } | ||
| 88 | } | ||
| 89 | } | ||
| 90 | 51 | ||
| 91 | Model::Model(QObject* parent, SpatiallyNestable* spatiallyNestableOverride) : | 52 | Model::Model(QObject* parent, SpatiallyNestable* spatiallyNestableOverride) : |
| 92 | QObject(parent), | 53 | QObject(parent), |
| 93 | _renderGeometry(), | 54 | _renderGeometry(), |
| 94 | _collisionGeometry(), | ||
| 95 | _renderWatcher(_renderGeometry), | 55 | _renderWatcher(_renderGeometry), |
| 96 | _spatiallyNestableOverride(spatiallyNestableOverride), | 56 | _spatiallyNestableOverride(spatiallyNestableOverride), |
| 97 | _translation(0.0f), | 57 | _translation(0.0f), |
| @@ -310,16 +270,6 @@ void Model::updateRenderItems() { · 212 unmodified lines | |||
| 310 | }); | 270 | }); |
| 311 | } | 271 | } |
| 312 | 272 | ||
| 313 | Transform collisionMeshOffset; | ||
| 314 | collisionMeshOffset.setIdentity(); | ||
| 315 | foreach(auto itemID, self->_collisionRenderItemsMap.keys()) { | ||
| 316 | transaction.updateItem<MeshPartPayload>(itemID, [renderItemKeyGlobalFlags, modelTransform, collisionMeshOffset](MeshPartPayload& data) { | ||
| 317 | // update the model transform for this render item. | ||
| 318 | data.updateKey(renderItemKeyGlobalFlags); | ||
| 319 | data.updateTransform(modelTransform, collisionMeshOffset); | ||
| 320 | }); | ||
| 321 | } | ||
| 322 | |||
| 323 | AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); | 273 | AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); |
| 324 | }); | 274 | }); |
| 325 | } | 275 | } |
| @@ -777,11 +727,14 @@ void Model::updateRenderItemsKey(const render::ScenePointer& scene) { · 451 unmodified lines | |||
| 777 | data.updateKey(renderItemsKey); | 727 | data.updateKey(renderItemsKey); |
| 778 | }); | 728 | }); |
| 779 | } | 729 | } |
| 730 | //TODO: Remove | ||
| 731 | #ifdef RENDER_MODEL_BOUNDING_BOXES | ||
| 780 | foreach(auto item, _collisionRenderItemsMap.keys()) { | 732 | foreach(auto item, _collisionRenderItemsMap.keys()) { |
| 781 | transaction.updateItem<ModelMeshPartPayload>(item, [renderItemsKey](ModelMeshPartPayload& data) { | 733 | transaction.updateItem<ModelMeshPartPayload>(item, [renderItemsKey](ModelMeshPartPayload& data) { |
| 782 | data.updateKey(renderItemsKey); | 734 | data.updateKey(renderItemsKey); |
| 783 | }); | 735 | }); |
| 784 | } | 736 | } |
| 737 | #endif | ||
| 785 | scene->enqueueTransaction(transaction); | 738 | scene->enqueueTransaction(transaction); |
| 786 | } | 739 | } |
| 787 | 740 | ||
| @@ -862,49 +815,37 @@ const render::ItemKey Model::getRenderItemKeyGlobalFlags() const { · 74 unmodified lines | |||
| 862 | bool Model::addToScene(const render::ScenePointer& scene, | 815 | bool Model::addToScene(const render::ScenePointer& scene, |
| 863 | render::Transaction& transaction, | 816 | render::Transaction& transaction, |
| 864 | render::Item::Status::Getters& statusGetters) { | 817 | render::Item::Status::Getters& statusGetters) { |
| 865 | bool readyToRender = _collisionGeometry || isLoaded(); | 818 | if (!_addedToScene && isLoaded()) { |
| 866 | if (!_addedToScene && readyToRender) { | 819 | updateClusterMatrices(); |
| 867 | createRenderItemSet(); | 820 | if (_modelMeshRenderItems.empty()) { |
| 821 | createVisibleRenderItemSet(); | ||
| 822 | } | ||
| 868 | } | 823 | } |
| 869 | 824 | ||
| 870 | bool somethingAdded = false; | 825 | bool somethingAdded = false; |
| 871 | if (_collisionGeometry) { | ||
| 872 | if (_collisionRenderItemsMap.empty()) { | ||
| 873 | foreach (auto renderItem, _collisionRenderItems) { | ||
| 874 | auto item = scene->allocateID(); | ||
| 875 | auto renderPayload = std::make_shared<MeshPartPayload::Payload>(renderItem); | ||
| 876 | if (_collisionRenderItems.empty() && statusGetters.size()) { | ||
| 877 | renderPayload->addStatusGetters(statusGetters); | ||
| 878 | } | ||
| 879 | transaction.resetItem(item, renderPayload); | ||
| 880 | _collisionRenderItemsMap.insert(item, renderPayload); | ||
| 881 | } | ||
| 882 | somethingAdded = !_collisionRenderItemsMap.empty(); | ||
| 883 | } | ||
| 884 | } else { | ||
| 885 | if (_modelMeshRenderItemsMap.empty()) { | ||
| 886 | |||
| 887 | bool hasTransparent = false; | ||
| 888 | size_t verticesCount = 0; | ||
| 889 | foreach(auto renderItem, _modelMeshRenderItems) { | ||
| 890 | auto item = scene->allocateID(); | ||
| 891 | auto renderPayload = std::make_shared<ModelMeshPartPayload::Payload>(renderItem); | ||
| 892 | if (_modelMeshRenderItemsMap.empty() && statusGetters.size()) { | ||
| 893 | renderPayload->addStatusGetters(statusGetters); | ||
| 894 | } | ||
| 895 | transaction.resetItem(item, renderPayload); | ||
| 896 | 826 | ||
| 897 | hasTransparent = hasTransparent || renderItem.get()->getShapeKey().isTranslucent(); | 827 | if (_modelMeshRenderItemsMap.empty()) { |
| 898 | verticesCount += renderItem.get()->getVerticesCount(); | 828 | |
| 899 | _modelMeshRenderItemsMap.insert(item, renderPayload); | 829 | bool hasTransparent = false; |
| 900 | _modelMeshRenderItemIDs.emplace_back(item); | 830 | size_t verticesCount = 0; |
| 831 | foreach(auto renderItem, _modelMeshRenderItems) { | ||
| 832 | auto item = scene->allocateID(); | ||
| 833 | auto renderPayload = std::make_shared<ModelMeshPartPayload::Payload>(renderItem); | ||
| 834 | if (_modelMeshRenderItemsMap.empty() && statusGetters.size()) { | ||
| 835 | renderPayload->addStatusGetters(statusGetters); | ||
| 901 | } | 836 | } |
| 902 | somethingAdded = !_modelMeshRenderItemsMap.empty(); | 837 | transaction.resetItem(item, renderPayload); |
| 903 | 838 | ||
| 904 | _renderInfoVertexCount = verticesCount; | 839 | hasTransparent = hasTransparent || renderItem.get()->getShapeKey().isTranslucent(); |
| 905 | _renderInfoDrawCalls = _modelMeshRenderItemsMap.count(); | 840 | verticesCount += renderItem.get()->getVerticesCount(); |
| 906 | _renderInfoHasTransparent = hasTransparent; | 841 | _modelMeshRenderItemsMap.insert(item, renderPayload); |
| 842 | _modelMeshRenderItemIDs.emplace_back(item); | ||
| 907 | } | 843 | } |
| 844 | somethingAdded = !_modelMeshRenderItemsMap.empty(); | ||
| 845 | |||
| 846 | _renderInfoVertexCount = verticesCount; | ||
| 847 | _renderInfoDrawCalls = _modelMeshRenderItemsMap.count(); | ||
| 848 | _renderInfoHasTransparent = hasTransparent; | ||
| 908 | } | 849 | } |
| 909 | 850 | ||
| 910 | if (somethingAdded) { | 851 | if (somethingAdded) { |
| @@ -926,11 +867,6 @@ void Model::removeFromScene(const render::ScenePointer& scene, render::Transacti · 15 unmodified lines | |||
| 926 | _modelMeshMaterialNames.clear(); | 867 | _modelMeshMaterialNames.clear(); |
| 927 | _modelMeshRenderItemShapes.clear(); | 868 | _modelMeshRenderItemShapes.clear(); |
| 928 | 869 | ||
| 929 | foreach(auto item, _collisionRenderItemsMap.keys()) { | ||
| 930 | transaction.removeItem(item); | ||
| 931 | } | ||
| 932 | _collisionRenderItems.clear(); | ||
| 933 | _collisionRenderItemsMap.clear(); | ||
| 934 | _addedToScene = false; | 870 | _addedToScene = false; |
| 935 | 871 | ||
| 936 | _renderInfoVertexCount = 0; | 872 | _renderInfoVertexCount = 0; |
| @@ -1505,7 +1441,6 @@ void Model::deleteGeometry() { · 568 unmodified lines | |||
| 1505 | _rig.destroyAnimGraph(); | 1441 | _rig.destroyAnimGraph(); |
| 1506 | _blendedBlendshapeCoefficients.clear(); | 1442 | _blendedBlendshapeCoefficients.clear(); |
| 1507 | _renderGeometry.reset(); | 1443 | _renderGeometry.reset(); |
| 1508 | _collisionGeometry.reset(); | ||
| 1509 | } | 1444 | } |
| 1510 | 1445 | ||
| 1511 | void Model::overrideModelTransformAndOffset(const Transform& transform, const glm::vec3& offset) { | 1446 | void Model::overrideModelTransformAndOffset(const Transform& transform, const glm::vec3& offset) { |
| @@ -1533,19 +1468,6 @@ const render::ItemIDs& Model::fetchRenderItemIDs() const { · 21 unmodified lines | |||
| 1533 | return _modelMeshRenderItemIDs; | 1468 | return _modelMeshRenderItemIDs; |
| 1534 | } | 1469 | } |
| 1535 | 1470 | ||
| 1536 | void Model::createRenderItemSet() { | ||
| 1537 | updateClusterMatrices(); | ||
| 1538 | if (_collisionGeometry) { | ||
| 1539 | if (_collisionRenderItems.empty()) { | ||
| 1540 | createCollisionRenderItemSet(); | ||
| 1541 | } | ||
| 1542 | } else { | ||
| 1543 | if (_modelMeshRenderItems.empty()) { | ||
| 1544 | createVisibleRenderItemSet(); | ||
| 1545 | } | ||
| 1546 | } | ||
| 1547 | }; | ||
| 1548 | |||
| 1549 | void Model::createVisibleRenderItemSet() { | 1471 | void Model::createVisibleRenderItemSet() { |
| 1550 | assert(isLoaded()); | 1472 | assert(isLoaded()); |
| 1551 | const auto& meshes = _renderGeometry->getMeshes(); | 1473 | const auto& meshes = _renderGeometry->getMeshes(); |
| @@ -1592,41 +1514,6 @@ void Model::createVisibleRenderItemSet() { · 40 unmodified lines | |||
| 1592 | } | 1514 | } |
| 1593 | } | 1515 | } |
| 1594 | 1516 | ||
| 1595 | void Model::createCollisionRenderItemSet() { | ||
| 1596 | assert((bool)_collisionGeometry); | ||
| 1597 | if (_collisionMaterials.empty()) { | ||
| 1598 | initCollisionMaterials(); | ||
| 1599 | } | ||
| 1600 | |||
| 1601 | const auto& meshes = _collisionGeometry->getMeshes(); | ||
| 1602 | |||
| 1603 | // We should not have any existing renderItems if we enter this section of code | ||
| 1604 | Q_ASSERT(_collisionRenderItems.isEmpty()); | ||
| 1605 | |||
| 1606 | Transform identity; | ||
| 1607 | identity.setIdentity(); | ||
| 1608 | Transform offset; | ||
| 1609 | offset.postTranslate(_offset); | ||
| 1610 | |||
| 1611 | // Run through all of the meshes, and place them into their segregated, but unsorted buckets | ||
| 1612 | uint32_t numMeshes = (uint32_t)meshes.size(); | ||
| 1613 | for (uint32_t i = 0; i < numMeshes; i++) { | ||
| 1614 | const auto& mesh = meshes.at(i); | ||
| 1615 | if (!mesh) { | ||
| 1616 | continue; | ||
| 1617 | } | ||
| 1618 | |||
| 1619 | // Create the render payloads | ||
| 1620 | int numParts = (int)mesh->getNumParts(); | ||
| 1621 | for (int partIndex = 0; partIndex < numParts; partIndex++) { | ||
| 1622 | graphics::MaterialPointer& material = _collisionMaterials[partIndex % NUM_COLLISION_HULL_COLORS]; | ||
| 1623 | auto payload = std::make_shared<MeshPartPayload>(mesh, partIndex, material); | ||
| 1624 | payload->updateTransform(identity, offset); | ||
| 1625 | _collisionRenderItems << payload; | ||
| 1626 | } | ||
| 1627 | } | ||
| 1628 | } | ||
| 1629 | |||
| 1630 | bool Model::isRenderable() const { | 1517 | bool Model::isRenderable() const { |
| 1631 | return !_meshStates.empty() || (isLoaded() && _renderGeometry->getMeshes().empty()); | 1518 | return !_meshStates.empty() || (isLoaded() && _renderGeometry->getMeshes().empty()); |
| 1632 | } | 1519 | } |
| @@ -1710,15 +1597,6 @@ public: · 77 unmodified lines | |||
| 1710 | } | 1597 | } |
| 1711 | }; | 1598 | }; |
| 1712 | 1599 | ||
| 1713 | void Model::setCollisionMesh(graphics::MeshPointer mesh) { | ||
| 1714 | if (mesh) { | ||
| 1715 | _collisionGeometry = std::make_shared<CollisionRenderGeometry>(mesh); | ||
| 1716 | } else { | ||
| 1717 | _collisionGeometry.reset(); | ||
| 1718 | } | ||
| 1719 | _needsFixupInScene = true; | ||
| 1720 | } | ||
| 1721 | |||
| 1722 | ModelBlender::ModelBlender() : | 1600 | ModelBlender::ModelBlender() : |
| 1723 | _pendingBlenders(0) { | 1601 | _pendingBlenders(0) { |
| 1724 | } | 1602 | } |