1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-26 09:35:28 +00:00

Return a list of meshes and the skeleton from NIFLoader::load

This commit is contained in:
Chris Robinson 2012-07-13 18:25:35 -07:00
parent fdfe40a55a
commit 939d0d2fc5
7 changed files with 146 additions and 119 deletions

View File

@ -26,8 +26,9 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, OEngine::Render::O
{
std::string mesh = "meshes\\" + ref->base->model;
NifOgre::NIFLoader::load(mesh);
base = mRend.getScene()->createEntity(mesh);
// FIXME: There can be more than one!
NifOgre::MeshPairList meshes = NifOgre::NIFLoader::load(mesh);
base = mRend.getScene()->createEntity(meshes[0].first->getName());
base->setVisibilityFlags(RV_Actors);
bool transparent = false;

View File

@ -82,8 +82,10 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRendere
assert(insert);
std::string smodel = (!isBeast ? "meshes\\base_anim.nif" : "meshes\\base_animkna.nif");
NifOgre::NIFLoader::load(smodel);
base = mRend.getScene()->createEntity(smodel);
// FIXME: There can be more than one!
NifOgre::MeshPairList meshes = NifOgre::NIFLoader::load(smodel);
base = mRend.getScene()->createEntity(meshes[0].first->getName());
base->setVisibilityFlags(RV_Actors);
bool transparent = false;
@ -382,9 +384,9 @@ void NpcAnimation::updateParts()
Ogre::Entity* NpcAnimation::insertBoundedPart(const std::string &mesh, const std::string &bonename)
{
NIFLoader::load(mesh);
Ogre::Entity* part = mRend.getScene()->createEntity(mesh);
// FIXME: There can be more than one!
NifOgre::MeshPairList meshes = NIFLoader::load(mesh);
Ogre::Entity* part = mRend.getScene()->createEntity(meshes[0].first->getName());
part->setVisibilityFlags(RV_Actors);
base->attachObjectToBone(bonename, part);

View File

@ -92,8 +92,9 @@ void Objects::insertMesh (const MWWorld::Ptr& ptr, const std::string& mesh)
Ogre::SceneNode* insert = ptr.getRefData().getBaseNode();
assert(insert);
NifOgre::NIFLoader::load(mesh);
Ogre::Entity *ent = mRenderer.getScene()->createEntity(mesh);
// FIXME: There can be more than one!
NifOgre::MeshPairList meshes = NifOgre::NIFLoader::load(mesh);
Ogre::Entity *ent = mRenderer.getScene()->createEntity(meshes[0].first->getName());
Ogre::Vector3 extents = ent->getBoundingBox().getSize();

View File

@ -453,16 +453,6 @@ void SkyManager::create()
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
// Stars
/// \todo sky_night_02.nif (available in Bloodmoon)
MeshPtr mesh = NifOgre::NIFLoader::load("meshes\\sky_night_01.nif");
Entity* night1_ent = mSceneMgr->createEntity("meshes\\sky_night_01.nif");
night1_ent->setRenderQueueGroup(RQG_SkiesEarly+1);
night1_ent->setVisibilityFlags(RV_Sky);
night1_ent->setCastShadows(false);
mAtmosphereNight = mRootNode->createChildSceneNode();
mAtmosphereNight->attachObject(night1_ent);
// Stars vertex shader
HighLevelGpuProgramPtr stars_vp = mgr.createProgram("Stars_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
"cg", GPT_VERTEX_PROGRAM);
@ -517,6 +507,18 @@ void SkyManager::create()
stars_fp->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
stars_fp->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR);
/// \todo sky_night_02.nif (available in Bloodmoon)
mAtmosphereNight = mRootNode->createChildSceneNode();
NifOgre::MeshPairList meshes = NifOgre::NIFLoader::load("meshes\\sky_night_01.nif");
for(size_t i = 0;i < meshes.size();i++)
{
Entity* night1_ent = mSceneMgr->createEntity(meshes[i].first->getName());
night1_ent->setRenderQueueGroup(RQG_SkiesEarly+1);
night1_ent->setVisibilityFlags(RV_Sky);
night1_ent->setCastShadows(false);
mAtmosphereNight->attachObject(night1_ent);
for (unsigned int i=0; i<night1_ent->getNumSubEntities(); ++i)
{
MaterialPtr mp = night1_ent->getSubEntity(i)->getMaterial();
@ -529,23 +531,11 @@ void SkyManager::create()
mp->getTechnique(0)->getPass(0)->setVertexProgram(stars_vp->getName());
mp->getTechnique(0)->getPass(0)->setFragmentProgram(stars_fp->getName());
mp->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
mStarsMaterials[i] = mp;
mStarsMaterials.push_back(mp);
}
}
// Atmosphere (day)
mesh = NifOgre::NIFLoader::load("meshes\\sky_atmosphere.nif");
Entity* atmosphere_ent = mSceneMgr->createEntity("meshes\\sky_atmosphere.nif");
atmosphere_ent->setCastShadows(false);
ModVertexAlpha(atmosphere_ent, 0);
atmosphere_ent->setRenderQueueGroup(RQG_SkiesEarly);
atmosphere_ent->setVisibilityFlags(RV_Sky);
mAtmosphereDay = mRootNode->createChildSceneNode();
mAtmosphereDay->attachObject(atmosphere_ent);
mAtmosphereMaterial = atmosphere_ent->getSubEntity(0)->getMaterial();
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
// Atmosphere shader
HighLevelGpuProgramPtr vshader = mgr.createProgram("Atmosphere_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
"cg", GPT_VERTEX_PROGRAM);
@ -570,7 +560,6 @@ void SkyManager::create()
vshader->load();
vshader->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader->getName());
HighLevelGpuProgramPtr fshader = mgr.createProgram("Atmosphere_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
"cg", GPT_FRAGMENT_PROGRAM);
@ -598,19 +587,36 @@ void SkyManager::create()
fshader->load();
fshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
mAtmosphereDay = mRootNode->createChildSceneNode();
meshes = NifOgre::NIFLoader::load("meshes\\sky_atmosphere.nif");
for(size_t i = 0;i < meshes.size();i++)
{
Entity* atmosphere_ent = mSceneMgr->createEntity(meshes[i].first->getName());
atmosphere_ent->setCastShadows(false);
ModVertexAlpha(atmosphere_ent, 0);
atmosphere_ent->setRenderQueueGroup(RQG_SkiesEarly);
atmosphere_ent->setVisibilityFlags(RV_Sky);
mAtmosphereDay->attachObject(atmosphere_ent);
mAtmosphereMaterial = atmosphere_ent->getSubEntity(0)->getMaterial();
mAtmosphereMaterial = mAtmosphereMaterial->clone("Atmosphere");
atmosphere_ent->getSubEntity(0)->setMaterial(mAtmosphereMaterial);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader->getName());
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(fshader->getName());
// Clouds
NifOgre::NIFLoader::load("meshes\\sky_clouds_01.nif");
Entity* clouds_ent = mSceneMgr->createEntity("meshes\\sky_clouds_01.nif");
clouds_ent->setVisibilityFlags(RV_Sky);
clouds_ent->setRenderQueueGroup(RQG_SkiesEarly+5);
SceneNode* clouds_node = mRootNode->createChildSceneNode();
clouds_node->attachObject(clouds_ent);
mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial();
mCloudMaterial->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
clouds_ent->setCastShadows(false);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(1.0, 1.0, 1.0);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, 0.0);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setAmbient(0.0, 0.0, 0.0);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
}
// Clouds
// Clouds vertex shader
HighLevelGpuProgramPtr vshader2 = mgr.createProgram("Clouds_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
"cg", GPT_VERTEX_PROGRAM);
@ -635,7 +641,6 @@ void SkyManager::create()
vshader2->setSource(outStream3.str());
vshader2->load();
vshader2->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
mCloudMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader2->getName());
// Clouds fragment shader
mCloudFragmentShader = mgr.createProgram("Clouds_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
@ -670,30 +675,35 @@ void SkyManager::create()
mCloudFragmentShader->setSource(outStream2.str());
mCloudFragmentShader->load();
mCloudFragmentShader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
mCloudMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(mCloudFragmentShader->getName());
setCloudsOpacity(0.75);
ModVertexAlpha(clouds_ent, 1);
SceneNode* clouds_node = mRootNode->createChildSceneNode();
meshes = NifOgre::NIFLoader::load("meshes\\sky_clouds_01.nif");
for(size_t i = 0;i < meshes.size();i++)
{
Entity* clouds_ent = mSceneMgr->createEntity(meshes[i].first->getName());
clouds_ent->setVisibilityFlags(RV_Sky);
clouds_ent->setRenderQueueGroup(RQG_SkiesEarly+5);
clouds_node->attachObject(clouds_ent);
// I'm not sure if the materials are being used by any other objects
// Make a unique "modifiable" copy of the materials to be sure
mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial();
mCloudMaterial = mCloudMaterial->clone("Clouds");
clouds_ent->getSubEntity(0)->setMaterial(mCloudMaterial);
mAtmosphereMaterial = mAtmosphereMaterial->clone("Atmosphere");
atmosphere_ent->getSubEntity(0)->setMaterial(mAtmosphereMaterial);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(1.0, 1.0, 1.0);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, 0.0);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setAmbient(0.0, 0.0, 0.0);
mCloudMaterial->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
clouds_ent->setCastShadows(false);
mCloudMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader2->getName());
mCloudMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(mCloudFragmentShader->getName());
ModVertexAlpha(clouds_ent, 1);
mCloudMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(1.0, 1.0, 1.0);
mCloudMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
mCloudMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
mCloudMaterial->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
mCloudMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("textures\\tx_sky_cloudy.dds");
mCloudMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("");
}
setCloudsOpacity(0.75);
mCreated = true;
}
@ -851,7 +861,7 @@ void SkyManager::setWeather(const MWWorld::WeatherResult& weather)
else
{
mAtmosphereNight->setVisible(true);
for (int i=0; i<7; ++i)
for (size_t i=0; i<mStarsMaterials.size(); ++i)
mStarsMaterials[i]->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, weather.mNightFade);
mStarsOpacity = weather.mNightFade;
}

View File

@ -1,13 +1,14 @@
#ifndef _GAME_RENDER_SKY_H
#define _GAME_RENDER_SKY_H
#include <vector>
#include <OgreVector3.h>
#include <OgreString.h>
#include <OgreMaterial.h>
#include <OgreColourValue.h>
#include <OgreHighLevelGpuProgram.h>
#include "sky.hpp"
#include "../mwworld/weather.hpp"
namespace Ogre
@ -195,7 +196,7 @@ namespace MWRender
Ogre::MaterialPtr mCloudMaterial;
Ogre::MaterialPtr mAtmosphereMaterial;
Ogre::MaterialPtr mStarsMaterials[7];
std::vector<Ogre::MaterialPtr> mStarsMaterials;
Ogre::HighLevelGpuProgramPtr mCloudFragmentShader;

View File

@ -322,12 +322,16 @@ void NIFLoader::createMaterial(const Ogre::String &name,
void NIFLoader::loadResource(Ogre::Resource *resource)
{
warn("Found no records in NIF.");
warn("Found no records in NIF for "+resource->getName());
}
Ogre::MeshPtr NIFLoader::load(const std::string &name, const std::string &group)
MeshPairList NIFLoader::load(const std::string &name, Ogre::SkeletonPtr *skel, const std::string &group)
{
Ogre::MeshManager &meshMgr = Ogre::MeshManager::getSingleton();
MeshPairList ret;
if(skel != NULL)
skel->setNull();
// Check if the resource already exists
Ogre::MeshPtr themesh = meshMgr.getByName(name, group);
@ -336,7 +340,9 @@ Ogre::MeshPtr NIFLoader::load(const std::string &name, const std::string &group)
NIFLoader *loader = &sLoaders[name];
themesh = meshMgr.createManual(name, group, loader);
}
return themesh;
ret.push_back(std::make_pair(themesh, std::string()));
return ret;
}

View File

@ -26,6 +26,7 @@
#include <OgreResource.h>
#include <OgreMesh.h>
#include <OgreSkeleton.h>
#include <cassert>
#include <string>
@ -67,6 +68,12 @@ namespace Nif
namespace NifOgre
{
/** This holds a list of meshes along with the names of their parent nodes
*/
typedef std::vector< std::pair<Ogre::MeshPtr,std::string> > MeshPairList;
/** Manual resource loader for NIF meshes. This is the main class
responsible for translating the internal NIF mesh structure into
something Ogre can use.
@ -75,18 +82,17 @@ namespace NifOgre
NIFLoader::load("somemesh.nif");
Afterwards, you can use the mesh name "somemesh.nif" normally to
create entities and so on. The mesh isn't loaded from disk until
OGRE needs it for rendering. Thus the above load() command is not
very resource intensive, and can safely be done for a large number
of meshes at load time.
This returns a list of meshes used by the model, as well as the names of
their parent nodes (as they pertain to the skeleton, which is optionally
returned in the second argument if it exists).
*/
class NIFLoader : Ogre::ManualResourceLoader
{
public:
virtual void loadResource(Ogre::Resource *resource);
static Ogre::MeshPtr load(const std::string &name,
static MeshPairList load(const std::string &name,
Ogre::SkeletonPtr *skel=NULL,
const std::string &group="General");
private: