// Populate the particles list void ParticlesChooser::populateParticleList() { _iterMap.clear(); _particlesList->clear(); // Create and use a ParticlesVisitor to populate the list ParticlesVisitor visitor(_particlesList, _iterMap); GlobalParticlesManager().forEachParticleDef(visitor); }
// The worker function that will execute in the thread void run() { ScopedDebugTimer timer("ThreadedParticlesLoader::run()"); // Create and use a ParticlesVisitor to populate the list GlobalParticlesManager().forEachParticleDef(*this); wxutil::TreeModel::PopulationFinishedEvent finishedEvent; finishedEvent.SetTreeModel(_store); _finishedHandler->AddPendingEvent(finishedEvent); }
// Static instance owner ParticlesChooser& ParticlesChooser::getInstance() { ParticlesChooserPtr& instancePtr = getInstancePtr(); if (!instancePtr) { instancePtr.reset(new ParticlesChooser); GlobalRadiant().signal_radiantShutdown().connect( sigc::mem_fun(*instancePtr, &ParticlesChooser::onRadiantShutdown) ); GlobalParticlesManager().signal_particlesReloaded().connect( sigc::mem_fun(*instancePtr, &ParticlesChooser::reloadParticles) ); } return *instancePtr; }
scene::INodePtr ModelCache::getModelNode(const std::string& modelPath) { // Check if we have a reference to a modeldef IModelDefPtr modelDef = GlobalEntityClassManager().findModel(modelPath); // The actual model path (is usually the same as the incoming modelPath) std::string actualModelPath(modelPath); if (modelDef != NULL) { // We have a valid modelDef, override the model path actualModelPath = modelDef->mesh; } // Get the extension of this model std::string type = actualModelPath.substr(actualModelPath.rfind(".") + 1); if (type == "prt") { // This is a particle, pass the call to the Particles Manager return GlobalParticlesManager().createParticleNode(actualModelPath); } // Get a suitable model loader ModelLoaderPtr modelLoader = getModelLoaderForType(type); // Try to construct a model node using the suitable loader scene::INodePtr node = modelLoader->loadModel(actualModelPath); if (node) { // For MD5 models, apply the idle animation by default if (modelDef) { model::ModelNodePtr modelNode = Node_getModel(node); if (!modelNode) { return node; } // Set the animation to play try { md5::IMD5Model& md5model = dynamic_cast<md5::IMD5Model&>(modelNode->getIModel()); // Look up the "idle" anim if there is one IModelDef::Anims::const_iterator found = modelDef->anims.find("idle"); if (found != modelDef->anims.end()) { // Load the anim md5::IMD5AnimPtr anim = GlobalAnimationCache().getAnim(found->second); if (anim) { md5model.setAnim(anim); md5model.updateAnim(0); } } } catch (std::bad_cast&) { // not an MD5 model, do nothing } } // Model load was successful return node; } // The model load failed, let's return the NullModel // This call should never fail, i.e. the returned model is non-NULL return NullModelLoader::InstancePtr()->loadModel(actualModelPath); }
void ParticlePreview::setParticle(const std::string& name) { std::string nameClean = name; if (boost::algorithm::ends_with(nameClean, ".prt")) { nameClean = nameClean.substr(0, nameClean.length() - 4); } // If the model name is empty, release the model if (nameClean.empty()) { if (_particleNode) { _entity->removeChildNode(_particleNode); } _particleNode.reset(); stopPlayback(); return; } // Set up the scene if (!_entity) { setupSceneGraph(); } if (_particleNode) { _entity->removeChildNode(_particleNode); } // Construct the particle emitter node _particleNode = GlobalParticlesManager().createParticleNode(nameClean); if (_particleNode && _lastParticle != nameClean) { _entity->addChildNode(_particleNode); // Reset preview time stopPlayback(); // Reset the rotation to the default one _rotation = Matrix4::getRotation(Vector3(0,-1,0), Vector3(0,-0.3f,1)); _rotation.multiplyBy(Matrix4::getRotation(Vector3(0,1,0), Vector3(1,-1,0))); // Call update(0) once to enable the bounds calculation _particleNode->getParticle()->update(_rotation); // Use particle AABB to adjust camera distance const AABB& particleBounds = _particleNode->getParticle()->getBounds(); if (particleBounds.isValid()) { _camDist = -2.0f * static_cast<float>(particleBounds.getRadius()); } else { // Bounds not valid, fall back to default _camDist = -40.0f; } _lastParticle = nameClean; // Start playback when switching particles startPlayback(); } // Redraw queueDraw(); }