// Returns a new ModelNode for the given model name scene::INodePtr PicoModelLoader::loadModel(const std::string& modelName) { // Initialise the paths, this is all needed for realisation std::string path = rootPath(modelName); std::string name = os::getRelativePath(modelName, path); // greebo: Path is empty for models in PK4 files, don't check this // Try to load the model from the given VFS path IModelPtr model = GlobalModelCache().getModel(name); if (model == NULL) { rError() << "PicoModelLoader: Could not load model << " << modelName << std::endl; return scene::INodePtr(); } // The cached model should be an PicoModel, otherwise we're in the wrong movie RenderablePicoModelPtr picoModel = std::dynamic_pointer_cast<RenderablePicoModel>(model); if (picoModel != NULL) { // Load was successful, construct a modelnode using this resource return PicoModelNodePtr(new PicoModelNode(picoModel)); } else { rError() << "PicoModelLoader: Cached model is not a PicoModel?" << std::endl; } return scene::INodePtr(); }
// Set the model, this also resets the camera void ModelPreview::setModel(const std::string& model) { // If the model name is empty, release the model if (model.empty()) { if (_modelNode) { _entity->removeChildNode(_modelNode); } _modelNode.reset(); stopPlayback(); return; } // Set up the scene if (!_entity) { getScene(); // trigger a setupscenegraph call } if (_modelNode) { _entity->removeChildNode(_modelNode); } _modelNode = GlobalModelCache().getModelNode(model); if (_modelNode) { _entity->addChildNode(_modelNode); // Trigger an initial update of the subgraph GlobalFilterSystem().updateSubgraph(getScene()->root()); // Reset camera if the model has changed if (model != _lastModel) { // Reset preview time stopPlayback(); // Reset the rotation to the default one _rotation = Matrix4::getRotationAboutZDegrees(45); _rotation = _rotation.getMultipliedBy(Matrix4::getRotation(Vector3(1,-1,0), 45)); // Calculate camera distance so model is appropriately zoomed _camDist = -(_modelNode->localAABB().getRadius() * 5.0f); } _lastModel = model; } // Redraw queueDraw(); }
void MD5AnimationViewer::_onModelSelChanged() { IModelDefPtr modelDef = getSelectedModel(); if (!modelDef) { _animTreeView->set_sensitive(false); return; } _animTreeView->set_sensitive(true); scene::INodePtr modelNode = GlobalModelCache().getModelNode(modelDef->mesh); _preview->setAnim(md5::IMD5AnimPtr()); _preview->setModelNode(modelNode); populateAnimationList(); }
void ModelKey::attachModelNode() { // Remove the old model node first if (_modelNode != NULL) { _parentNode.removeChildNode(_modelNode); } if (_modelPath.empty()) { // Empty "model" spawnarg, clear the pointer and exit _modelNode = scene::INodePtr(); return; } // We have a non-empty model key, send the request to // the model cache to acquire a new child node _modelNode = GlobalModelCache().getModelNode(_modelPath); // The model loader should not return NULL, but a sanity check is always ok if (_modelNode) { // Add the model node as child of the entity node _parentNode.addChildNode(_modelNode); // Assign the model node to the same layers as the parent entity _modelNode->assignToLayers(_parentNode.getLayers()); // Inherit the parent node's visibility. This should do the trick to resolve #2709 // but is not as heavy on performance as letting the Filtersystem check the whole subgraph // The sophisticated check would be like this // GlobalFilterSystem().updateSubgraph(_parentNode.getSelf()); _modelNode->setFiltered(_parentNode.isFiltered()); if (_parentNode.excluded()) { _modelNode->enable(scene::Node::eExcluded); } } }