bool AnimationPreview::onPreRender()
{
	if (!_model) return false;

	// Set the animation to play
	model::ModelNodePtr model = Node_getModel(_model);
	dynamic_cast<md5::IMD5Model&>(model->getIModel()).updateAnim(_renderSystem->getTime());

	return true;
}
void AnimationPreview::setAnim(const md5::IMD5AnimPtr& anim)
{
	_anim = anim;

	if (!_model)
	{
		return;
	}

	// Set the animation to play
	model::ModelNodePtr model = Node_getModel(_model);
	dynamic_cast<md5::IMD5Model&>(model->getIModel()).setAnim(_anim);
}
Example #3
0
void ModelSelector::showInfoForSelectedModel()
{
    // Prepare to populate the info table
    _infoTable->Clear();

    // Get the model name, if this is blank we are looking at a directory,
    // so leave the table empty
    std::string mName = getSelectedValue(_columns.vfspath);
    if (mName.empty())
        return;

    // Get the skin if set
    std::string skinName = getSelectedValue(_columns.skin);

    // Pass the model and skin to the preview widget
    _modelPreview->setModel(mName);
    _modelPreview->setSkin(skinName);

    // Check that the model is actually valid by querying the IModelPtr
    // returned from the preview widget.
    scene::INodePtr mdl = _modelPreview->getModelNode();
    if (!mdl) {
        return; // no valid model
    }

    model::ModelNodePtr modelNode = Node_getModel(mdl);

    if (!modelNode)
    {
        return;
    }

    // Update the text in the info table
    const model::IModel& model = modelNode->getIModel();
    _infoTable->Append(_("Model name"), mName);
    _infoTable->Append(_("Skin name"), skinName);
    _infoTable->Append(_("Total vertices"), string::to_string(model.getVertexCount()));
    _infoTable->Append(_("Total polys"), string::to_string(model.getPolyCount()));
    _infoTable->Append(_("Material surfaces"), string::to_string(model.getSurfaceCount()));

    // Add the list of active materials
    _materialsList->clear();

    const model::StringList& matList(model.getActiveMaterials());

    std::for_each(
        matList.begin(), matList.end(),
        boost::bind(&MaterialsList::addMaterial, _materialsList, _1)
    );
}
Example #4
0
void ModelExporter::processNodes()
{
	AABB bounds = calculateModelBounds();

	if (_centerObjects)
	{
		// Depending on the center point, we need to use the object bounds
		// or just the translation towards the user-defined origin, ignoring bounds
		_centerTransform = _useOriginAsCenter ?
			Matrix4::getTranslation(-_origin) :
			Matrix4::getTranslation(-bounds.origin);
	}

	for (const scene::INodePtr& node : _nodes)
	{
		if (Node_isModel(node))
		{
			model::ModelNodePtr modelNode = Node_getModel(node);

			// Push the geometry into the exporter
			model::IModel& model = modelNode->getIModel();

			Matrix4 exportTransform = node->localToWorld().getPremultipliedBy(_centerTransform);

			for (int s = 0; s < model.getSurfaceCount(); ++s)
			{
				const model::IModelSurface& surface = model.getSurface(s);

				if (isExportableMaterial(surface.getActiveMaterial()))
				{
					_exporter->addSurface(surface, exportTransform);
				}
			}
		}
		else if (Node_isBrush(node))
		{
			processBrush(node);
		}
		else if (Node_isPatch(node))
		{
			processPatch(node);
		}
		else if (_exportLightsAsObjects && Node_getLightNode(node))
		{
			processLight(node);
		}
	}
}
Example #5
0
void ModelPreview::setSkin(const std::string& skin) {

	// Load and apply the skin, checking first to make sure the model is valid
	// and not null
	if (_modelNode != NULL)
	{
		model::ModelNodePtr model = Node_getModel(_modelNode);

		if (model)
		{
			ModelSkin& mSkin = GlobalModelSkinCache().capture(skin);
			model->getIModel().applySkin(mSkin);
		}
	}

	// Redraw
	queueDraw();
}
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);
}
// Set the model, this also resets the camera
void AnimationPreview::setModelNode(const scene::INodePtr& node)
{
	// Ensure that this is an MD5 model node
	model::ModelNodePtr model = Node_getModel(node);
	
	if (!model)
	{
		rError() << "AnimationPreview::setModelNode: node is not a model." << std::endl;
		_model.reset();
		return;
	}

	// Set up the scene
	if (!_entity)
	{
		setupSceneGraph();
	}

	try
	{
		dynamic_cast<const md5::IMD5Model&>(model->getIModel());
	}
	catch (std::bad_cast&)
	{
		rError() << "AnimationPreview::setModelNode: modelnode doesn't contain an MD5 model." << std::endl;
		_model.reset();
		return;
	}

	if (_model)
	{
		_entity->removeChildNode(_model);
	}

	_model = node;

	// Set the animation to play
	dynamic_cast<md5::IMD5Model&>(model->getIModel()).setAnim(_anim);

	// AddChildNode also tells the model which renderentity it is attached to
	_entity->addChildNode(_model);

	if (_model != NULL)
	{
		// 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)));
		
		// Use AABB to adjust camera distance
		const AABB& bounds = _model->localAABB();

		if (bounds.isValid())
		{
			_camDist = -5.0f * static_cast<float>(bounds.getRadius());
		}
		else
		{
			// Bounds not valid, fall back to default
			_camDist = -40.0f;
		}

		// Start playback when switching particles
		startPlayback();
	}
	else
	{
		stopPlayback();
	}

	// Redraw
	queueDraw();
}