actorid
Nicolay Korslund 15 years ago
commit 304692dc8e

@ -41,6 +41,14 @@ set(GAMEGUI
)
source_group(apps\\openmw\\mwgui FILES ${GAMEGUI_HEADER} ${GAMEGUI})
set(GAMEDIALOGUE_HEADER
mwdialogue/dialoguemanager.hpp
)
set(GAMEDIALOGUE
mwdialogue/dialoguemanager.cpp
)
source_group(apps\\openmw\\mwdialogue FILES ${GAMEDIALOGUE_HEADER} ${GAMEDIALOGUE})
set(GAMESCRIPT
mwscript/scriptmanager.cpp
mwscript/compilercontext.cpp
@ -97,6 +105,7 @@ set(GAMEWORLD_HEADER
mwworld/action.hpp
mwworld/nullaction.hpp
mwworld/actionteleport.hpp
mwworld/containerstore.hpp
mwworld/actiontalk.hpp
mwworld/actiontake.hpp
mwworld/containerstore.hpp
@ -164,11 +173,11 @@ set(GAMEMECHANICS_HEADER
source_group(apps\\openmw\\mwmechanics FILES ${GAMEMECHANICS} ${GAMEMECHANICS_HEADER})
set(OPENMW_CPP ${GAME} ${GAMEREND} ${GAMEINPUT} ${GAMESCRIPT} ${GAMESOUND} ${GAMEGUI} ${GAMEWORLD}
${GAMECLASS} ${GAMEMECHANICS}
${GAMECLASS} ${GAMEMECHANICS} ${GAMEDIALOGUE}
)
set(OPENMW_HEADER ${GAME_HEADER} ${GAMEREND_HEADER} ${GAMEINPUT_HEADER} ${GAMESCRIPT_HEADER}
${GAMESOUND_HEADER} ${GAMEGUI_HEADER} ${GAMEWORLD_HEADER} ${GAMECLASS_HEADER}
${GAMEMECHANICS_HEADER}
${GAMEMECHANICS_HEADER} ${GAMEDIALOG_HEADERUE}
)
# Main executable

@ -28,6 +28,8 @@
#include "mwclass/classes.hpp"
#include "mwdialogue/dialoguemanager.hpp"
#include "mwmechanics/mechanicsmanager.hpp"
#include <OgreRoot.h>
@ -117,6 +119,7 @@ OMW::Engine::~Engine()
delete mEnvironment.mSoundManager;
delete mEnvironment.mGlobalScripts;
delete mEnvironment.mMechanicsManager;
delete mEnvironment.mDialogueManager;
delete mScriptManager;
delete mScriptContext;
}
@ -253,6 +256,9 @@ void OMW::Engine::go()
mEnvironment.mMechanicsManager = new MWMechanics::MechanicsManager (
mEnvironment.mWorld->getStore(), *mEnvironment.mWindowManager);
// Create dialog system
mEnvironment.mDialogueManager = new MWDialogue::DialogueManager (mEnvironment);
// load cell
ESM::Position pos;
pos.pos[0] = pos.pos[1] = pos.pos[2] = 0;

@ -15,6 +15,14 @@
namespace MWClass
{
std::string Creature::getId (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref =
ptr.get<ESM::Creature>();
return ref->base->mId;
}
void Creature::insertObj (const MWWorld::Ptr& ptr, MWRender::CellRenderImp& cellRender,
MWWorld::Environment& environment) const
{
@ -96,7 +104,7 @@ namespace MWClass
}
return *ptr.getRefData().getContainerStore();
}
}
std::string Creature::getScript (const MWWorld::Ptr& ptr) const
{

@ -9,6 +9,9 @@ namespace MWClass
{
public:
virtual std::string getId (const MWWorld::Ptr& ptr) const;
///< Return ID of \a ptr
virtual void insertObj (const MWWorld::Ptr& ptr, MWRender::CellRenderImp& cellRender,
MWWorld::Environment& environment) const;
///< Add reference into a cell for rendering

@ -16,6 +16,14 @@
namespace MWClass
{
std::string Npc::getId (const MWWorld::Ptr& ptr) const
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref =
ptr.get<ESM::NPC>();
return ref->base->mId;
}
void Npc::insertObj (const MWWorld::Ptr& ptr, MWRender::CellRenderImp& cellRender,
MWWorld::Environment& environment) const
{

@ -9,6 +9,9 @@ namespace MWClass
{
public:
virtual std::string getId (const MWWorld::Ptr& ptr) const;
///< Return ID of \a ptr
virtual void insertObj (const MWWorld::Ptr& ptr, MWRender::CellRenderImp& cellRender,
MWWorld::Environment& environment) const;
///< Add reference into a cell for rendering
@ -26,14 +29,14 @@ namespace MWClass
virtual MWMechanics::CreatureStats& getCreatureStats (const MWWorld::Ptr& ptr) const;
///< Return creature stats
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
///< Generate action for activation
virtual MWWorld::ContainerStore<MWWorld::RefData>& getContainerStore (
const MWWorld::Ptr& ptr) const;
///< Return container store
virtual boost::shared_ptr<MWWorld::Action> activate (const MWWorld::Ptr& ptr,
const MWWorld::Ptr& actor, const MWWorld::Environment& environment) const;
///< Generate action for activation
virtual std::string getScript (const MWWorld::Ptr& ptr) const;
///< Return name of the script attached to ptr

@ -0,0 +1,280 @@
#include "dialoguemanager.hpp"
#include <cctype>
#include <algorithm>
#include <iterator>
#include <components/esm/loaddial.hpp>
#include <components/esm_store/store.hpp>
#include "../mwworld/class.hpp"
#include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
#include "../mwworld/refdata.hpp"
#include "../mwgui/window_manager.hpp"
#include <iostream>
namespace
{
std::string toLower (const std::string& name)
{
std::string lowerCase;
std::transform (name.begin(), name.end(), std::back_inserter (lowerCase),
(int(*)(int)) std::tolower);
return lowerCase;
}
template<typename T1, typename T2>
bool selectCompare (char comp, T1 value1, T2 value2)
{
switch (comp)
{
case '0': return value1==value2;
case '1': return value1!=value2;
case '2': return value1>value2;
case '3': return value1>=value2;
case '4': return value1<value2;
case '5': return value1<=value2;
}
throw std::runtime_error ("unknown compare type in dialogue info select");
}
template<typename T>
bool checkLocal (char comp, const std::string& name, T value, const MWWorld::Ptr& actor,
const ESMS::ESMStore& store)
{
std::string scriptName = MWWorld::Class::get (actor).getScript (actor);
if (scriptName.empty())
return false; // no script
const ESM::Script *script = store.scripts.find (scriptName);
int i = 0;
for (; i<static_cast<int> (script->varNames.size()); ++i)
if (script->varNames[i]==name)
break;
if (i>=static_cast<int> (script->varNames.size()))
return false; // script does not have a variable of this name
const MWScript::Locals& locals = actor.getRefData().getLocals();
if (i<script->data.numShorts)
return selectCompare (comp, locals.mShorts[i], value);
else
i -= script->data.numShorts;
if (i<script->data.numLongs)
return selectCompare (comp, locals.mLongs[i], value);
else
i -= script->data.numShorts;
return selectCompare (comp, locals.mFloats.at (i), value);
}
template<typename T>
bool checkGlobal (char comp, const std::string& name, T value, MWWorld::World& world)
{
switch (world.getGlobalVariableType (name))
{
case 's':
return selectCompare (comp, value, world.getGlobalVariable (name).mShort);
case 'l':
return selectCompare (comp, value, world.getGlobalVariable (name).mLong);
case 'f':
return selectCompare (comp, value, world.getGlobalVariable (name).mFloat);
case ' ':
world.getGlobalVariable (name); // trigger exception
break;
default:
throw std::runtime_error ("unsupported gobal variable type");
}
return false;
}
}
namespace MWDialogue
{
bool DialogueManager::isMatching (const MWWorld::Ptr& actor,
const ESM::DialInfo::SelectStruct& select) const
{
char type = select.selectRule[1];
if (type!='0')
{
char comp = select.selectRule[4];
std::string name = select.selectRule.substr (5);
// TODO types 4, 5, 6, 7, 8, 9, A, B, C
switch (type)
{
case '1': // function
return false; // TODO implement functions
case '2': // global
if (select.type==ESM::VT_Short || select.type==ESM::VT_Int ||
select.type==ESM::VT_Long)
{
if (!checkGlobal (comp, toLower (name), select.i, *mEnvironment.mWorld))
return false;
}
else if (select.type==ESM::VT_Float)
{
if (!checkGlobal (comp, toLower (name), select.f, *mEnvironment.mWorld))
return false;
}
else
throw std::runtime_error (
"unsupported variable type in dialogue info select");
return true;
case '3': // local
if (select.type==ESM::VT_Short || select.type==ESM::VT_Int ||
select.type==ESM::VT_Long)
{
if (!checkLocal (comp, toLower (name), select.i, actor,
mEnvironment.mWorld->getStore()))
return false;
}
else if (select.type==ESM::VT_Float)
{
if (!checkLocal (comp, toLower (name), select.f, actor,
mEnvironment.mWorld->getStore()))
return false;
}
else
throw std::runtime_error (
"unsupported variable type in dialogue info select");
return true;
default:
std::cout << "unchecked select: " << type << " " << comp << " " << name << std::endl;
}
}
return true;
}
bool DialogueManager::isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const
{
// actor id
if (!info.actor.empty())
if (toLower (info.actor)!=MWWorld::Class::get (actor).getId (actor))
return false;
if (!info.race.empty())
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
if (!cellRef)
return false;
if (toLower (info.race)!=toLower (cellRef->base->race))
return false;
}
if (!info.clas.empty())
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
if (!cellRef)
return false;
if (toLower (info.clas)!=toLower (cellRef->base->cls))
return false;
}
if (!info.npcFaction.empty())
{
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *cellRef = actor.get<ESM::NPC>();
if (!cellRef)
return false;
if (toLower (info.npcFaction)!=toLower (cellRef->base->faction))
return false;
}
// TODO check player faction
// check cell
if (!info.cell.empty())
if (mEnvironment.mWorld->getPlayerPos().getPlayer().getCell()->cell->name != info.cell)
return false;
// TODO check DATAstruct
for (std::vector<ESM::DialInfo::SelectStruct>::const_iterator iter (info.selects.begin());
iter != info.selects.end(); ++iter)
if (!isMatching (actor, *iter))
return false;
std::cout
<< "unchecked entries:" << std::endl
<< " player faction: " << info.pcFaction << std::endl
<< " DATAstruct" << std::endl;
return true;
}
DialogueManager::DialogueManager (MWWorld::Environment& environment) : mEnvironment (environment) {}
void DialogueManager::startDialogue (const MWWorld::Ptr& actor)
{
std::cout << "talking with " << MWWorld::Class::get (actor).getName (actor) << std::endl;
const ESM::Dialogue *dialogue = mEnvironment.mWorld->getStore().dialogs.find ("hello");
for (std::vector<ESM::DialInfo>::const_iterator iter (dialogue->mInfo.begin());
iter!=dialogue->mInfo.end(); ++iter)
{
if (isMatching (actor, *iter))
{
// start dialogue
std::cout << "found matching info record" << std::endl;
std::cout << "response: " << iter->response << std::endl;
if (!iter->sound.empty())
{
// TODO play sound
}
if (!iter->resultScript.empty())
{
std::cout << "script: " << iter->resultScript << std::endl;
// TODO execute script
}
mEnvironment.mWindowManager->setMode (MWGui::GM_Dialogue);
}
}
}
}

@ -0,0 +1,32 @@
#ifndef GAME_MMDIALOG_DIALOGUEMANAGER_H
#define GAME_MWDIALOG_DIALOGUEMANAGER_H
#include <components/esm/loadinfo.hpp>
#include "../mwworld/ptr.hpp"
namespace MWWorld
{
class Environment;
}
namespace MWDialogue
{
class DialogueManager
{
MWWorld::Environment& mEnvironment;
bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo::SelectStruct& select) const;
bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const;
public:
DialogueManager (MWWorld::Environment& environment);
void startDialogue (const MWWorld::Ptr& actor);
};
}
#endif

@ -3,7 +3,7 @@
#include "environment.hpp"
#include "../mwgui/window_manager.hpp"
#include "../mwdialogue/dialoguemanager.hpp"
namespace MWWorld
{
@ -11,6 +11,6 @@ namespace MWWorld
void ActionTalk::execute (Environment& environment)
{
environment.mWindowManager->setMode (MWGui::GM_Dialogue);
environment.mDialogueManager->startDialogue (mActor);
}
}

@ -13,6 +13,7 @@ namespace MWWorld
public:
ActionTalk (const Ptr& actor);
///< \param actor The actor the player is talking to
virtual void execute (Environment& environment);
};

@ -14,6 +14,11 @@ namespace MWWorld
Class::~Class() {}
std::string Class::getId (const Ptr& ptr) const
{
throw std::runtime_error ("class does not support ID retrieval");
}
void Class::insertObj (const Ptr& ptr, MWRender::CellRenderImp& cellRender,
MWWorld::Environment& environment) const
{

@ -42,6 +42,10 @@ namespace MWWorld
virtual ~Class();
virtual std::string getId (const Ptr& ptr) const;
///< Return ID of \a ptr or throw an exception, if class does not support ID retrieval
/// (default implementation: throw an exception)
virtual void insertObj (const Ptr& ptr, MWRender::CellRenderImp& cellRender,
MWWorld::Environment& environment) const;
///< Add reference into a cell for rendering (default implementation: don't render anything).

@ -21,17 +21,22 @@ namespace MWMechanics
class MechanicsManager;
}
namespace MWDialogue
{
class DialogueManager;
}
namespace MWWorld
{
class World;
///< Collection of script-accessable sub-systems
class Environment
{
{
public:
Environment()
: mWorld (0), mSoundManager (0), mGlobalScripts (0), mWindowManager (0),
mMechanicsManager (0), mFrameDuration (0)
mMechanicsManager (0), mDialogueManager (0), mFrameDuration (0)
{}
World *mWorld;
@ -39,9 +44,9 @@ namespace MWWorld
MWScript::GlobalScripts *mGlobalScripts;
MWGui::WindowManager *mWindowManager;
MWMechanics::MechanicsManager *mMechanicsManager;
MWDialogue::DialogueManager *mDialogueManager;
float mFrameDuration;
};
}
#endif

@ -14,6 +14,11 @@ IF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
SET(ICONV_FIND_QUIETLY TRUE)
ENDIF (ICONV_INCLUDE_DIR AND ICONV_LIBRARIES)
IF(WIN32)
SET(ICONV_INCLUDE_DIR $ENV{ICONV_INCLUDE_DIR})
SET(ICONV_LIBRARIES $ENV{ICONV_LIBRARIES})
ENDIF(WIN32)
FIND_PATH(ICONV_INCLUDE_DIR iconv.h)
FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv c)

@ -9,7 +9,10 @@
#include <sstream>
#include <iomanip>
#include <errno.h>
#include <iconv.h>
#ifndef __WIN32__
#include <iconv.h>
#endif
#include <libs/mangle/stream/stream.hpp>
#include <libs/mangle/stream/servers/file_stream.hpp>
@ -618,89 +621,93 @@ public:
return convertToUTF8(res);
}
// Convert a string from the encoding used by Morrowind to UTF-8
std::string convertToUTF8(std::string input)
{
std::string output = "";
//create convert description
iconv_t cd = iconv_open("UTF-8", "WINDOWS-1252");
if (cd == (iconv_t)-1) //error handling
{
std::string errMsg = "Creating description for UTF-8 converting failed: ";
switch (errno) //detailed error messages (maybe it contains too much detail :)
{
case EMFILE:
errMsg += "{OPEN_MAX} files descriptors are currently open in the calling process.";
case ENFILE:
errMsg += "Too many files are currently open in the system.";
case ENOMEM:
errMsg +="Insufficient storage space is available.";
case EINVAL:
errMsg += "The conversion specified by fromcode and tocode is not supported by the implementation.";
default:
errMsg += "Unknown Error\n";
}
fail(errMsg);
}
else
// Convert a string from the encoding used by Morrowind to UTF-8
std::string convertToUTF8 (std::string input)
{
const size_t inputSize = input.size();
#ifdef __WIN32__
return input;
#else
std::string output = "";
if (inputSize) //input is not empty
{
//convert function doesn't accept const char *, therefore copy content into an char *
std::vector<char> inputBuffer(input.begin(), input.end());
char *inputBufferBegin = &inputBuffer[0];
//create convert description
iconv_t cd = iconv_open ("UTF-8", "WINDOWS-1252");
size_t inputBytesLeft = inputSize; //bytes to convert
if (cd == (iconv_t)-1) //error handling
{
std::string errMsg = "Creating description for UTF-8 converting failed: ";
static const size_t outputSize = 1000;
size_t outputBytesLeft;
switch (errno) //detailed error messages (maybe it contains too much detail :)
{
case EMFILE:
errMsg += "{OPEN_MAX} files descriptors are currently open in the calling process.";
case ENFILE:
errMsg += "Too many files are currently open in the system.";
case ENOMEM:
errMsg +="Insufficient storage space is available.";
case EINVAL:
errMsg += "The conversion specified by fromcode and tocode is not supported by the implementation.";
default:
errMsg += "Unknown Error\n";
}
char outputBuffer[outputSize];
char *outputBufferBegin;
fail (errMsg);
while (inputBytesLeft > 0 )
}
else
{
outputBytesLeft = outputSize;
outputBufferBegin = outputBuffer;
const size_t inputSize = input.size();
if (iconv(cd, &inputBufferBegin, &inputBytesLeft, &outputBufferBegin, &outputBytesLeft) == (size_t)-1)
{
switch (errno)
if (inputSize) //input is not empty
{
case E2BIG: //outputBuffer is full
output += std::string(outputBuffer, outputSize);
break;
case EILSEQ:
fail("Iconv: Invalid multibyte sequence.\n");
break;
case EINVAL:
fail("Iconv: Incomplete multibyte sequence.\n");
break;
default:
fail("Iconv: Unknown Error\n");
}
//convert function doesn't accept const char *, therefore copy content into an char *
std::vector<char> inputBuffer (input.begin(), input.end());
char *inputBufferBegin = &inputBuffer[0];
size_t inputBytesLeft = inputSize; //bytes to convert
static const size_t outputSize = 1000;
size_t outputBytesLeft;
char outputBuffer[outputSize];
char *outputBufferBegin;
while (inputBytesLeft > 0)
{
outputBytesLeft = outputSize;
outputBufferBegin = outputBuffer;
if (iconv (cd, &inputBufferBegin, &inputBytesLeft, &outputBufferBegin, &outputBytesLeft) == (size_t)-1)
{
switch (errno)
{
case E2BIG: //outputBuffer is full
output += std::string (outputBuffer, outputSize);
break;
case EILSEQ:
fail ("Iconv: Invalid multibyte sequence.\n");
break;
case EINVAL:
fail ("Iconv: Incomplete multibyte sequence.\n");
break;
default:
fail ("Iconv: Unknown Error\n");
}
}
}
//read only relevant bytes from outputBuffer
output += std::string (outputBuffer, outputSize - outputBytesLeft);
}
}
}
//read only relevant bytes from outputBuffer
output += std::string(outputBuffer, outputSize - outputBytesLeft);
iconv_close (cd);
}
return output;
}
iconv_close (cd);
return output;
}
#endif
void skip(int bytes) { esm->seek(esm->tell()+bytes); }
uint64_t getOffset() { return esm->tell(); }

@ -1,7 +1,10 @@
#ifndef _ESM_DIAL_H
#define _ESM_DIAL_H
#include <vector>
#include "esm_reader.hpp"
#include "loadinfo.hpp"
namespace ESM {
@ -23,6 +26,7 @@ struct Dialogue
};
char type;
std::vector<DialInfo> mInfo;
void load(ESMReader &esm)
{

@ -14,13 +14,13 @@
#include "loadcont.hpp"
#include "loadcrea.hpp"
#include "loadcrec.hpp"
#include "loadinfo.hpp"
#include "loaddial.hpp"
#include "loaddoor.hpp"
#include "loadench.hpp"
#include "loadfact.hpp"
#include "loadglob.hpp"
#include "loadgmst.hpp"
#include "loadinfo.hpp"
#include "loadingr.hpp"
#include "loadland.hpp"
#include "loadlevlist.hpp"

@ -18,32 +18,70 @@ static string toStr(int i)
void ESMStore::load(ESMReader &esm)
{
set<string> missing;
set<string> missing;
// Loop through all records
while(esm.hasMoreRecs())
ESM::Dialogue *dialogue = 0;
// Loop through all records
while(esm.hasMoreRecs())
{
NAME n = esm.getRecName();
esm.getRecHeader();
NAME n = esm.getRecName();
esm.getRecHeader();
// Look up the record type.
RecListList::iterator it = recLists.find(n.val);
// Look up the record type.
RecListList::iterator it = recLists.find(n.val);
if(it == recLists.end())
if(it == recLists.end())
{
// Not found (this would be an error later)
esm.skipRecord();
missing.insert(n.toString());
continue;
if (n.val==ESM::REC_INFO)
{
if (dialogue)
{
ESM::DialInfo info;
info.load (esm);
dialogue->mInfo.push_back (info);
}
else
{
std::cerr << "error: info record without dialog" << std::endl;
esm.skipRecord();
continue;
}
}
else
{
// Not found (this would be an error later)
esm.skipRecord();
missing.insert(n.toString());
continue;
}
}
else
{
// Load it
std::string id = esm.getHNOString("NAME");
it->second->load(esm, id);
if (n.val==ESM::REC_DIAL)
{
RecListT<Dialogue>& recList = static_cast<RecListT<Dialogue>& > (*it->second);
// Load it
std::string id = esm.getHNOString("NAME");
it->second->load(esm, id);
id = recList.toLower (id);
// Insert the reference into the global lookup
if(!id.empty())
all[id] = n.val;
RecListT<Dialogue>::MapType::iterator iter = recList.list.find (id);
assert (iter!=recList.list.end());
dialogue = &iter->second;
}
else
dialogue = 0;
// Insert the reference into the global lookup
if(!id.empty())
all[id] = n.val;
}
}
/* This information isn't needed on screen. But keep the code around

@ -69,7 +69,6 @@ namespace ESMS
// Lists that need special rules
CellList cells;
RecIDListT<GameSetting> gameSettings;
//RecListT<DialInfo> dialInfos;
//RecListT<Land> lands;
//RecListT<LandTexture> landTexts;
//RecListT<MagicEffect> magicEffects;
@ -92,7 +91,6 @@ namespace ESMS
ESMStore()
{
recLists[REC_ACTI] = &activators;
recLists[REC_ACTI] = &activators;
recLists[REC_ALCH] = &potions;
recLists[REC_APPA] = &appas;
@ -113,7 +111,6 @@ namespace ESMS
recLists[REC_FACT] = &factions;
recLists[REC_GLOB] = &globals;
recLists[REC_GMST] = &gameSettings;
//recLists[REC_INFO] = &dialInfos;
recLists[REC_INGR] = &ingreds;
//recLists[REC_LAND] = &lands;
recLists[REC_LEVC] = &creatureLists;

File diff suppressed because it is too large Load Diff

@ -27,6 +27,27 @@
#include <OgreResource.h>
#include <OgreMesh.h>
#include <assert.h>
#include <string>
class BoundsFinder;
namespace Nif
{
class Node;
class Transformation;
class NiTriShape;
class Vector;
class Matrix;
}
namespace Mangle
{
namespace VFS
{
class OgreVFS;
}
}
/** Manual resource loader for NIF meshes. This is the main class
responsible for translating the internal NIF mesh structure into
@ -43,12 +64,66 @@
very resource intensive, and can safely be done for a large number
of meshes at load time.
*/
struct NIFLoader : Ogre::ManualResourceLoader
class NIFLoader : Ogre::ManualResourceLoader
{
void loadResource(Ogre::Resource *resource);
public:
static NIFLoader& getSingleton();
static NIFLoader* getSingletonPtr();
virtual void loadResource(Ogre::Resource *resource);
static Ogre::MeshPtr load(const std::string &name,
const std::string &group="General");
Ogre::Vector3 convertVector3(const Nif::Vector& vec);
Ogre::Quaternion convertRotation(const Nif::Matrix& rot);
private:
NIFLoader() : resourceGroup("General") {}
NIFLoader(NIFLoader& n) {}
void warn(std::string msg);
void fail(std::string msg);
void handleNode( Nif::Node *node, int flags,
const Nif::Transformation *trafo, BoundsFinder &bounds, Ogre::Bone *parentBone);
void handleNiTriShape(Nif::NiTriShape *shape, int flags, BoundsFinder &bounds);
void createOgreSubMesh(Nif::NiTriShape *shape, const Ogre::String &material);
void createMaterial(const Ogre::String &name,
const Nif::Vector &ambient,
const Nif::Vector &diffuse,
const Nif::Vector &specular,
const Nif::Vector &emissive,
float glossiness, float alpha,
float alphaFlags, float alphaTest,
const Ogre::String &texName);
void findRealTexture(Ogre::String &texName);
Ogre::String getUniqueName(const Ogre::String &input);
//returns the skeleton name of this mesh
std::string getSkeletonName()
{
return resourceName + ".skel";
}
// This is the interface to the Ogre resource system. It allows us to
// load NIFs from BSAs, in the file system and in any other place we
// 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.
Mangle::VFS::OgreVFS *vfs;
std::string resourceName;
std::string resourceGroup;
static Ogre::MeshPtr load(const std::string &name,
const std::string &group="General");
// pointer to the ogre mesh which is currently build
Ogre::Mesh *mesh;
Ogre::SkeletonPtr skel;
};
#endif

Loading…
Cancel
Save