1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-03-29 16:06:44 +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; std::string mesh = "meshes\\" + ref->base->model;
NifOgre::NIFLoader::load(mesh); // FIXME: There can be more than one!
base = mRend.getScene()->createEntity(mesh); NifOgre::MeshPairList meshes = NifOgre::NIFLoader::load(mesh);
base = mRend.getScene()->createEntity(meshes[0].first->getName());
base->setVisibilityFlags(RV_Actors); base->setVisibilityFlags(RV_Actors);
bool transparent = false; bool transparent = false;

View file

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

View file

@ -453,16 +453,6 @@ void SkyManager::create()
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton(); HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
// Stars // 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 // Stars vertex shader
HighLevelGpuProgramPtr stars_vp = mgr.createProgram("Stars_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, HighLevelGpuProgramPtr stars_vp = mgr.createProgram("Stars_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
"cg", GPT_VERTEX_PROGRAM); "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("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
stars_fp->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_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) for (unsigned int i=0; i<night1_ent->getNumSubEntities(); ++i)
{ {
MaterialPtr mp = night1_ent->getSubEntity(i)->getMaterial(); 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)->setVertexProgram(stars_vp->getName());
mp->getTechnique(0)->getPass(0)->setFragmentProgram(stars_fp->getName()); mp->getTechnique(0)->getPass(0)->setFragmentProgram(stars_fp->getName());
mp->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false); mp->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
mStarsMaterials[i] = mp; mStarsMaterials.push_back(mp);
}
} }
// Atmosphere (day) // 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 // Atmosphere shader
HighLevelGpuProgramPtr vshader = mgr.createProgram("Atmosphere_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, HighLevelGpuProgramPtr vshader = mgr.createProgram("Atmosphere_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
"cg", GPT_VERTEX_PROGRAM); "cg", GPT_VERTEX_PROGRAM);
@ -570,7 +560,6 @@ void SkyManager::create()
vshader->load(); vshader->load();
vshader->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); 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, HighLevelGpuProgramPtr fshader = mgr.createProgram("Atmosphere_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
"cg", GPT_FRAGMENT_PROGRAM); "cg", GPT_FRAGMENT_PROGRAM);
@ -598,19 +587,36 @@ void SkyManager::create()
fshader->load(); fshader->load();
fshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR); 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()); mAtmosphereMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(fshader->getName());
// Clouds mAtmosphereMaterial->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
NifOgre::NIFLoader::load("meshes\\sky_clouds_01.nif"); mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(1.0, 1.0, 1.0);
Entity* clouds_ent = mSceneMgr->createEntity("meshes\\sky_clouds_01.nif"); mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, 0.0);
clouds_ent->setVisibilityFlags(RV_Sky); mAtmosphereMaterial->getTechnique(0)->getPass(0)->setAmbient(0.0, 0.0, 0.0);
clouds_ent->setRenderQueueGroup(RQG_SkiesEarly+5); mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
SceneNode* clouds_node = mRootNode->createChildSceneNode(); mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
clouds_node->attachObject(clouds_ent); }
mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial();
mCloudMaterial->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
clouds_ent->setCastShadows(false);
// Clouds
// Clouds vertex shader // Clouds vertex shader
HighLevelGpuProgramPtr vshader2 = mgr.createProgram("Clouds_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, HighLevelGpuProgramPtr vshader2 = mgr.createProgram("Clouds_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
"cg", GPT_VERTEX_PROGRAM); "cg", GPT_VERTEX_PROGRAM);
@ -635,7 +641,6 @@ void SkyManager::create()
vshader2->setSource(outStream3.str()); vshader2->setSource(outStream3.str());
vshader2->load(); vshader2->load();
vshader2->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX); vshader2->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
mCloudMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader2->getName());
// Clouds fragment shader // Clouds fragment shader
mCloudFragmentShader = mgr.createProgram("Clouds_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mCloudFragmentShader = mgr.createProgram("Clouds_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
@ -670,30 +675,35 @@ void SkyManager::create()
mCloudFragmentShader->setSource(outStream2.str()); mCloudFragmentShader->setSource(outStream2.str());
mCloudFragmentShader->load(); mCloudFragmentShader->load();
mCloudFragmentShader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR); 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 mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial();
// Make a unique "modifiable" copy of the materials to be sure
mCloudMaterial = mCloudMaterial->clone("Clouds"); mCloudMaterial = mCloudMaterial->clone("Clouds");
clouds_ent->getSubEntity(0)->setMaterial(mCloudMaterial); 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); mCloudMaterial->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, 0.0); clouds_ent->setCastShadows(false);
mAtmosphereMaterial->getTechnique(0)->getPass(0)->setAmbient(0.0, 0.0, 0.0);
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)->setSelfIllumination(1.0, 1.0, 1.0);
mCloudMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); 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)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
mCloudMaterial->getTechnique(0)->getPass(0)->removeAllTextureUnitStates(); mCloudMaterial->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
mCloudMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("textures\\tx_sky_cloudy.dds"); mCloudMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("textures\\tx_sky_cloudy.dds");
mCloudMaterial->getTechnique(0)->getPass(0)->createTextureUnitState(""); mCloudMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("");
}
setCloudsOpacity(0.75);
mCreated = true; mCreated = true;
} }
@ -851,7 +861,7 @@ void SkyManager::setWeather(const MWWorld::WeatherResult& weather)
else else
{ {
mAtmosphereNight->setVisible(true); 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); mStarsMaterials[i]->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, weather.mNightFade);
mStarsOpacity = weather.mNightFade; mStarsOpacity = weather.mNightFade;
} }

View file

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

View file

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