mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-29 21:45:32 +00:00
Created cell renderer w/NIF loading. Runs but is WIP.
This commit is contained in:
parent
e8c6caa0b5
commit
86b78b18f4
9 changed files with 218 additions and 31 deletions
|
@ -11,11 +11,14 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
|
|||
set(BSA bsa/bsa_archive.cpp bsa/bsa_file.cpp)
|
||||
set(BSA_HEADER bsa/bsa_archive.hpp bsa/bsa_file.hpp)
|
||||
|
||||
set(NIF nif/nif_file.cpp nifogre/ogre_nif_loader.cpp)
|
||||
set(NIF nif/nif_file.cpp)
|
||||
set(NIF_HEADER nif/controlled.hpp nif/effect.hpp nif/nif_types.hpp nif/record.hpp
|
||||
nif/controller.hpp nif/extra.hpp nif/node.hpp nif/record_ptr.hpp
|
||||
nif/data.hpp nif/nif_file.hpp nif/property.hpp)
|
||||
|
||||
|
||||
set(NIFOGRE nifogre/ogre_nif_loader.cpp)
|
||||
set(NIFOGRE_HEADER nifogre/ogre_nif_loader.hpp)
|
||||
|
||||
set(TOOLS tools/stringops.cpp tools/fileops.cpp)
|
||||
set(TOOLS_HEADER tools/fileops.hpp tools/slice_array.hpp tools/stringops.hpp)
|
||||
|
||||
|
@ -30,7 +33,7 @@ set(INPUT_HEADER input/oismanager.hpp input/listener.hpp)
|
|||
set(GAME game/main.cpp game/esm_store/store.cpp game/cell_store.cpp)
|
||||
set(GAME_HEADER game/cell_store.hpp game/esm_store/reclists.hpp game/esm_store/store.hpp)
|
||||
|
||||
set(GAMEREND game/render/mwscene.cpp)
|
||||
set(GAMEREND game/render/mwscene.cpp game/render/cell.cpp)
|
||||
set(GAMEREND_HEADER game/render/cell.hpp game/render/mwscene.hpp)
|
||||
|
||||
# Platform specific
|
||||
|
@ -70,6 +73,9 @@ add_executable(openmw
|
|||
${TOOLS} ${TOOLS_HEADER}
|
||||
${OGRE} ${OGRE_HEADER}
|
||||
${INPUT} ${INPUT_HEADER}
|
||||
${NIF} ${NIF_HEADER}
|
||||
${NIFOGRE} ${NIFOGRE_HEADER}
|
||||
${MANGLE_VFS}
|
||||
${GAME} ${GAME_HEADER}
|
||||
${GAMEREND} ${GAMEREND_HEADER})
|
||||
|
||||
|
|
|
@ -42,7 +42,8 @@ namespace ESMS
|
|||
struct CellRefList
|
||||
{
|
||||
typedef LiveCellRef<X> LiveRef;
|
||||
std::list<LiveRef> list;
|
||||
typedef std::list<LiveRef> List;
|
||||
List list;
|
||||
|
||||
// Search for the given reference in the given reclist from
|
||||
// ESMStore. Insert the reference into the list if a match is
|
||||
|
|
|
@ -21,15 +21,24 @@ namespace ESMS
|
|||
template <typename X>
|
||||
struct RecListT : RecList
|
||||
{
|
||||
typedef std::map<std::string,X> MapType;
|
||||
typedef std::map<std::string,X*> MapType;
|
||||
|
||||
MapType list;
|
||||
|
||||
// Load one object of this type
|
||||
void load(ESMReader &esm, const std::string &id)
|
||||
{
|
||||
X &ref = list[id];
|
||||
ref.load(esm);
|
||||
X *ref;
|
||||
|
||||
if(list.find(id) == list.end())
|
||||
{
|
||||
ref = new X;
|
||||
list[id] = ref;
|
||||
}
|
||||
else
|
||||
ref = list[id];
|
||||
|
||||
ref->load(esm);
|
||||
}
|
||||
|
||||
// Find the given object ID, or return NULL if not found.
|
||||
|
@ -37,7 +46,7 @@ namespace ESMS
|
|||
{
|
||||
if(list.find(id) == list.end())
|
||||
return NULL;
|
||||
return &list.find(id)->second;
|
||||
return list.find(id)->second;
|
||||
}
|
||||
|
||||
int getSize() { return list.size(); }
|
||||
|
@ -49,15 +58,24 @@ namespace ESMS
|
|||
template <typename X>
|
||||
struct RecIDListT : RecList
|
||||
{
|
||||
typedef std::map<std::string,X> MapType;
|
||||
typedef std::map<std::string,X*> MapType;
|
||||
|
||||
MapType list;
|
||||
|
||||
void load(ESMReader &esm, const std::string &id)
|
||||
{
|
||||
X &ref = list[id];
|
||||
ref.id = id;
|
||||
ref.load(esm);
|
||||
X *ref;
|
||||
|
||||
if(list.find(id) == list.end())
|
||||
{
|
||||
ref = new X;
|
||||
list[id] = ref;
|
||||
}
|
||||
else
|
||||
ref = list[id];
|
||||
|
||||
ref->id = id;
|
||||
ref->load(esm);
|
||||
}
|
||||
|
||||
int getSize() { return list.size(); }
|
||||
|
@ -73,11 +91,11 @@ namespace ESMS
|
|||
int getSize() { return count; }
|
||||
|
||||
// List of interior cells. Indexed by cell name.
|
||||
typedef std::map<std::string,Cell> IntCells;
|
||||
typedef std::map<std::string,Cell*> IntCells;
|
||||
IntCells intCells;
|
||||
|
||||
// List of exterior cells. Indexed as extCells[gridX][gridY].
|
||||
typedef std::map<int, std::map<int, Cell> > ExtCells;
|
||||
typedef std::map<int, std::map<int, Cell*> > ExtCells;
|
||||
ExtCells extCells;
|
||||
|
||||
const Cell* findInt(const std::string &id) const
|
||||
|
@ -87,7 +105,7 @@ namespace ESMS
|
|||
if(it == intCells.end())
|
||||
return NULL;
|
||||
|
||||
return &it->second;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void load(ESMReader &esm, const std::string &id)
|
||||
|
@ -97,13 +115,13 @@ namespace ESMS
|
|||
count++;
|
||||
|
||||
// All cells have a name record, even nameless exterior cells.
|
||||
Cell cell;
|
||||
cell.name = id;
|
||||
Cell *cell = new Cell;
|
||||
cell->name = id;
|
||||
|
||||
// The cell itself takes care of all the hairy details
|
||||
cell.load(esm);
|
||||
cell->load(esm);
|
||||
|
||||
if(cell.data.flags & Cell::Interior)
|
||||
if(cell->data.flags & Cell::Interior)
|
||||
{
|
||||
// Store interior cell by name
|
||||
intCells[id] = cell;
|
||||
|
@ -111,7 +129,7 @@ namespace ESMS
|
|||
else
|
||||
{
|
||||
// Store exterior cells by grid position
|
||||
extCells[cell.data.gridX][cell.data.gridY] = cell;
|
||||
extCells[cell->data.gridX][cell->data.gridY] = cell;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -35,18 +35,22 @@ void maintest()
|
|||
// This parses the ESM file and loads a sample cell
|
||||
esm.open(esmFile);
|
||||
store.load(esm);
|
||||
|
||||
cell.loadInt("Beshara", store, esm);
|
||||
|
||||
// Create the window
|
||||
ogre.createWindow("OpenMW");
|
||||
|
||||
cout << "\nSetting up cell rendering (not done)\n";
|
||||
cout << "\nSetting up cell rendering\n";
|
||||
|
||||
// Sets up camera, scene manager etc
|
||||
Render::MWScene scene(ogre);
|
||||
|
||||
// This doesn't do anything yet.
|
||||
Render::CellRender rend(cell);
|
||||
// This connects the cell data with the rendering scene.
|
||||
Render::CellRender rend(cell, scene);
|
||||
|
||||
// Load the cell and insert it into the renderer
|
||||
rend.show();
|
||||
|
||||
cout << "Setting up input system\n";
|
||||
|
||||
|
|
129
game/render/cell.cpp
Normal file
129
game/render/cell.cpp
Normal file
|
@ -0,0 +1,129 @@
|
|||
#include "cell.hpp"
|
||||
|
||||
#include <OgreEntity.h>
|
||||
|
||||
#include "nifogre/ogre_nif_loader.hpp"
|
||||
|
||||
using namespace Render;
|
||||
using namespace Ogre;
|
||||
using namespace ESMS;
|
||||
|
||||
// Inserts one mesh into the scene
|
||||
static void insertObj(SceneNode *base, // Parent scene node
|
||||
SceneManager *mgr, // Scene manager
|
||||
const std::string mesh, // NIF file
|
||||
const CellRef &ref) // Reference information
|
||||
{
|
||||
// Create and place scene node for this object
|
||||
SceneNode *node = base->createChildSceneNode();
|
||||
|
||||
const float *f = ref.pos.pos;
|
||||
node->setPosition(f[0], f[1], f[2]);
|
||||
node->setScale(ref.scale, ref.scale, ref.scale);
|
||||
|
||||
// Convert MW rotation to a quaternion:
|
||||
f = ref.pos.rot;
|
||||
|
||||
// Rotate around X axis
|
||||
Quaternion xr(Radian(-f[0]), Vector3::UNIT_X);
|
||||
|
||||
// Rotate around Y axis
|
||||
Quaternion yr(Radian(-f[1]), Vector3::UNIT_Y);
|
||||
|
||||
// Rotate around Z axis
|
||||
Quaternion zr(Radian(-f[2]), Vector3::UNIT_Z);
|
||||
|
||||
// Rotates first around z, then y, then x
|
||||
node->setOrientation(xr*yr*zr);
|
||||
|
||||
// Finally, load the NIF mesh and attach it to the node
|
||||
NIFLoader::load(mesh);
|
||||
MovableObject *ent = mgr->createEntity(mesh);
|
||||
node->attachObject(ent);
|
||||
}
|
||||
|
||||
void CellRender::show()
|
||||
{
|
||||
// If already loaded, just make the cell visible.
|
||||
if(base)
|
||||
{
|
||||
base->setVisible(true);
|
||||
return;
|
||||
}
|
||||
|
||||
base = scene.getRoot()->createChildSceneNode();
|
||||
|
||||
// Loop through all statics in the cell
|
||||
CellRefList<Static>::List::const_iterator it;
|
||||
for(it = cell.statics.list.begin();
|
||||
it != cell.statics.list.end();
|
||||
it++)
|
||||
{
|
||||
assert(it->base != NULL);
|
||||
insertObj(base, scene.getMgr(),
|
||||
"meshes\\" + it->base->model,
|
||||
it->ref);
|
||||
}
|
||||
|
||||
/*
|
||||
// Containers
|
||||
CellRefList<Container>::List::const_iterator it;
|
||||
|
||||
for(it = cell.containers.list.begin();
|
||||
it != cell.containers.list.end();
|
||||
it++)
|
||||
{
|
||||
assert(it->base != NULL);
|
||||
|
||||
cout << "refID = " << it->ref.refID << " x" << it->ref.scale << endl;
|
||||
cout << "flags = " << it->base->flags << endl;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void CellRender::hide()
|
||||
{
|
||||
if(base)
|
||||
base->setVisible(false);
|
||||
}
|
||||
|
||||
void CellRender::destroy()
|
||||
{
|
||||
if(base)
|
||||
{
|
||||
base->removeAndDestroyAllChildren();
|
||||
scene.getMgr()->destroySceneNode(base);
|
||||
}
|
||||
|
||||
base = NULL;
|
||||
}
|
||||
|
||||
// Magic function from the internets. Might need this later.
|
||||
/*
|
||||
void Scene::DestroyAllAttachedMovableObjects( SceneNode* i_pSceneNode )
|
||||
{
|
||||
if ( !i_pSceneNode )
|
||||
{
|
||||
ASSERT( false );
|
||||
return;
|
||||
}
|
||||
|
||||
// Destroy all the attached objects
|
||||
SceneNode::ObjectIterator itObject = i_pSceneNode->getAttachedObjectIterator();
|
||||
|
||||
while ( itObject.hasMoreElements() )
|
||||
{
|
||||
MovableObject* pObject = static_cast<MovableObject*>(itObject.getNext());
|
||||
i_pSceneNode->getCreator()->destroyMovableObject( pObject );
|
||||
}
|
||||
|
||||
// Recurse to child SceneNodes
|
||||
SceneNode::ChildNodeIterator itChild = i_pSceneNode->getChildIterator();
|
||||
|
||||
while ( itChild.hasMoreElements() )
|
||||
{
|
||||
SceneNode* pChildNode = static_cast<SceneNode*>(itChild.getNext());
|
||||
DestroyAllAttachedMovableObjects( pChildNode );
|
||||
}
|
||||
}
|
||||
*/
|
|
@ -2,16 +2,40 @@
|
|||
#define _GAME_RENDER_CELL_H
|
||||
|
||||
#include "../cell_store.hpp"
|
||||
#include "mwscene.hpp"
|
||||
|
||||
namespace Render
|
||||
{
|
||||
/**
|
||||
This class is responsible for inserting meshes and other
|
||||
rendering objects from the given cell into the given rendering
|
||||
scene.
|
||||
|
||||
*/
|
||||
class CellRender
|
||||
{
|
||||
const ESMS::CellStore *cell;
|
||||
const ESMS::CellStore &cell;
|
||||
MWScene &scene;
|
||||
|
||||
/// The scene node that contains all objects belonging to this
|
||||
/// cell.
|
||||
Ogre::SceneNode *base;
|
||||
|
||||
public:
|
||||
CellRender(const ESMS::CellStore &_cell)
|
||||
: cell(&_cell) {}
|
||||
CellRender(const ESMS::CellStore &_cell,
|
||||
MWScene &_scene)
|
||||
: cell(_cell), scene(_scene), base(NULL) {}
|
||||
~CellRender() { destroy(); }
|
||||
|
||||
/// Make the cell visible. Load the cell if necessary.
|
||||
void show();
|
||||
|
||||
/// Remove the cell from rendering, but don't remove it from
|
||||
/// memory.
|
||||
void hide();
|
||||
|
||||
/// Destroy all rendering objects connected with this cell.
|
||||
void destroy();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,9 @@ namespace Render
|
|||
|
||||
public:
|
||||
MWScene(OgreRenderer &_rend);
|
||||
|
||||
Ogre::SceneNode *getRoot() { return mwRoot; }
|
||||
Ogre::SceneManager *getMgr() { return sceneMgr; }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -46,13 +46,13 @@ using namespace Mangle::VFS;
|
|||
// tell Ogre to look (eg. in zip or rar files.) It's also used to
|
||||
// check for the existence of texture files, so we can exchange the
|
||||
// extension from .tga to .dds if the texture is missing.
|
||||
OgreVFS *vfs;
|
||||
static OgreVFS *vfs;
|
||||
|
||||
// Singleton instance used by load()
|
||||
static NIFLoader g_sing;
|
||||
|
||||
// Makeshift error reporting system
|
||||
static string errName;
|
||||
|
||||
static void warn(const string &msg)
|
||||
{
|
||||
cout << "WARNING (NIF:" << errName << "): " << msg << endl;
|
||||
|
@ -615,12 +615,13 @@ void NIFLoader::loadResource(Resource *resource)
|
|||
mesh->_setBoundingSphereRadius(10);
|
||||
}
|
||||
|
||||
MeshPtr NIFLoader::load(const char* name, const char* group)
|
||||
MeshPtr NIFLoader::load(const std::string &name,
|
||||
const std::string &group)
|
||||
{
|
||||
MeshManager *m = MeshManager::getSingletonPtr();
|
||||
|
||||
// Check if the resource already exists
|
||||
ResourcePtr ptr = m->getByName(name/*, group*/);
|
||||
ResourcePtr ptr = m->getByName(name, group);
|
||||
if(!ptr.isNull())
|
||||
return MeshPtr(ptr);
|
||||
|
||||
|
|
|
@ -47,7 +47,8 @@ struct NIFLoader : Ogre::ManualResourceLoader
|
|||
{
|
||||
void loadResource(Ogre::Resource *resource);
|
||||
|
||||
static Ogre::MeshPtr load(const char* name, const char* group="General");
|
||||
static Ogre::MeshPtr load(const std::string &name,
|
||||
const std::string &group="General");
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue