| 89 | } |
| 90 | |
| 91 | void ParticlePreview::SetPreviewDeclName(const std::string& declName) |
| 92 | { |
| 93 | std::string nameClean = declName; |
| 94 | |
| 95 | if (string::ends_with(nameClean, ".prt")) |
| 96 | { |
| 97 | nameClean = nameClean.substr(0, nameClean.length() - 4); |
| 98 | } |
| 99 | |
| 100 | // If the model name is empty, release the model |
| 101 | if (nameClean.empty()) |
| 102 | { |
| 103 | if (_particleNode) |
| 104 | { |
| 105 | _entity->removeChildNode(_particleNode); |
| 106 | } |
| 107 | |
| 108 | _particleNode.reset(); |
| 109 | _lastParticle = ""; |
| 110 | stopPlayback(); |
| 111 | return; |
| 112 | } |
| 113 | |
| 114 | // Set up the scene |
| 115 | if (!_entity) |
| 116 | { |
| 117 | setupSceneGraph(); |
| 118 | } |
| 119 | |
| 120 | if (!_entity) return; // FUNC_EMITTER_CLASS not found |
| 121 | |
| 122 | if (_particleNode) |
| 123 | { |
| 124 | _entity->removeChildNode(_particleNode); |
| 125 | } |
| 126 | |
| 127 | // Construct the particle emitter node |
| 128 | _particleNode = GlobalParticlesManager().createParticleNode(nameClean); |
| 129 | |
| 130 | if (_particleNode && _lastParticle != nameClean) |
| 131 | { |
| 132 | _entity->addChildNode(_particleNode); |
| 133 | |
| 134 | // Reset preview time |
| 135 | stopPlayback(); |
| 136 | |
| 137 | // Call update(0) once to enable the bounds calculation |
| 138 | _particleNode->getParticle()->update(_modelView, _particleNode->localToWorld(), _entity->getRenderEntity()); |
| 139 | |
| 140 | // Reset the model rotation |
| 141 | resetModelRotation(); |
| 142 | |
| 143 | // Use particle AABB to adjust camera distance |
| 144 | const AABB& particleBounds = _particleNode->getParticle()->getBounds(); |
| 145 | |
| 146 | if (particleBounds.isValid()) |
| 147 | { |
| 148 | // Reset the default view, facing down to the model from diagonally above the bounding box |
no test coverage detected