From 13d8ea09b0f5da97a0dae719cb4cb39aa4ef97eb Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Wed, 27 Oct 2010 23:22:01 -0400 Subject: [PATCH 01/12] Cell case insensitivity, exterior and interior cells --- components/esm_store/reclists.hpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/components/esm_store/reclists.hpp b/components/esm_store/reclists.hpp index 75debb8fc..ee8de7578 100644 --- a/components/esm_store/reclists.hpp +++ b/components/esm_store/reclists.hpp @@ -9,7 +9,12 @@ #include #include #include +#include + + +using namespace boost::algorithm; + namespace ESMS { using namespace ESM; @@ -233,6 +238,15 @@ namespace ESMS } }; + struct ciLessBoost : std::binary_function +{ + bool operator() (const std::string & s1, const std::string & s2) const { + //case insensitive version of is_less + return lexicographical_compare(s1, s2, is_iless()); + } +}; + + // Cells aren't simply indexed by name. Exterior cells are treated // separately. // TODO: case handling (cell names are case-insensitive, but they are also showen to the @@ -245,7 +259,7 @@ namespace ESMS int getSize() { return count; } // List of interior cells. Indexed by cell name. - typedef std::map IntCells; + typedef std::map IntCells; IntCells intCells; // List of exterior cells. Indexed as extCells[gridX][gridY]. @@ -268,6 +282,7 @@ namespace ESMS } } + const Cell* findInt(const std::string &id) const { IntCells::const_iterator it = intCells.find(id); @@ -300,7 +315,7 @@ namespace ESMS const ExtCellsCol& column = iter->second; for (ExtCellsCol::const_iterator iter = column.begin(); iter!=column.end(); ++iter) { - if (iter->second->name==id) + if ( toLower(iter->second->name) == toLower(id)) return iter->second; } } From 74aba130534509a17973fbe06da9f7be48c1535c Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sun, 31 Oct 2010 12:23:03 -0400 Subject: [PATCH 02/12] Music Player --- apps/openmw/engine.cpp | 47 ++++++++++++++++++++++------ apps/openmw/mwsound/soundmanager.cpp | 26 ++++++++++++--- apps/openmw/mwsound/soundmanager.hpp | 8 +++++ 3 files changed, 67 insertions(+), 14 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 6cd3ded1e..da9e9bede 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -57,8 +57,42 @@ void OMW::Engine::executeLocalScripts() mIgnoreLocalPtr = MWWorld::Ptr(); } +void OMW::Engine::startRandomTitle() +{ + char number[100]; + /* initialize random seed: */ + srand ( time(NULL) ); + + /* generate secret number: */ + int r = rand() % 7 + 1; + + sprintf(number, "Music/Explore/mx_explore_%d.mp3", r); + //std::string music = (mDataDir / "Music/Explore/mx_explore_5.mp3").file_string(); + std::string music = (mDataDir / number).file_string(); + try + { + std::cout << "Playing " << music << "\n"; + mEnvironment.mSoundManager->streamMusic(music); + } + catch(std::exception &e) + { + std::cout << " Music Error: " << e.what() << "\n"; + } +} + bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt) { + // + MWWorld::Environment test = mEnvironment; + if(! (test.mSoundManager->isMusicPlaying())) + { + // Play some good 'ol tunes + startRandomTitle(); + } + + //tesprintf("HERE");t.mSoundManager. + + try { mEnvironment.mFrameDuration = evt.timeSinceLastFrame; @@ -216,6 +250,8 @@ void OMW::Engine::go() assert (!mCellName.empty()); assert (!mMaster.empty()); + + std::cout << "Data directory: " << mDataDir << "\n"; const char* plugCfg = "plugins.cfg"; @@ -293,16 +329,7 @@ void OMW::Engine::go() mOgre.getRoot()->addFrameListener (this); // Play some good 'ol tunes - std::string music = (mDataDir / "Music/Explore/mx_explore_5.mp3").file_string(); - try - { - std::cout << "Playing " << music << "\n"; - mEnvironment.mSoundManager->streamMusic(music); - } - catch(std::exception &e) - { - std::cout << " Music Error: " << e.what() << "\n"; - } + startRandomTitle(); // Start the main rendering loop mOgre.start(); diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index 88f62e112..3dedab9ef 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -62,6 +62,7 @@ namespace MWSound sounds based on the sound factory it is given. */ OEManagerPtr mgr; + SoundPtr music; /* This class calls update() on the sound manager each frame using and Ogre::FrameListener @@ -319,6 +320,20 @@ namespace MWSound delete mData; } + bool SoundManager::isMusicPlaying() + { + bool test = mData->music->isPlaying(); + return test; + } + + SoundManager::SoundImpl SoundManager::getMData() + { + // bool test = mData->music->isPlaying(); + return *mData; + } + + + void SoundManager::say (MWWorld::Ptr ptr, const std::string& filename) { // The range values are not tested @@ -342,10 +357,13 @@ namespace MWSound // Play the sound and tell it to stream, if possible. TODO: // Store the reference, the jukebox will need to check status, // control volume etc. - SoundPtr music = mData->mgr->load(filename); - music->setStreaming(true); - music->setVolume(0.4); - music->play(); + if (mData->music) + mData->music->stop(); + mData->music = mData->mgr->load(filename); + mData->music->setStreaming(true); + mData->music->setVolume(0.4); + mData->music->play(); + } void SoundManager::playSound (const std::string& soundId, float volume, float pitch) diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanager.hpp index 9f99b34b2..017069a63 100644 --- a/apps/openmw/mwsound/soundmanager.hpp +++ b/apps/openmw/mwsound/soundmanager.hpp @@ -5,6 +5,7 @@ #include #include "../mwworld/ptr.hpp" +#include namespace Ogre { @@ -19,17 +20,24 @@ namespace ESMS namespace MWSound { + //SoundPtr *music; class SoundManager { // Hide implementation details - engine.cpp is compiling // enough as it is. struct SoundImpl; + SoundImpl *mData; + public: SoundManager(Ogre::Root*, Ogre::Camera*, const ESMS::ESMStore &store, const std::string &soundDir, bool useSound); ~SoundManager(); + //struct SoundImpl; + bool isMusicPlaying(); + + SoundImpl getMData(); void say (MWWorld::Ptr reference, const std::string& filename); ///< Make an actor say some text. From a7c3a29ffd6ce979741e3cd272ef1773011f86a7 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Mon, 1 Nov 2010 17:06:13 -0400 Subject: [PATCH 03/12] Music Player with directory mp3 lookup --- apps/openmw/engine.cpp | 47 ++++++++++++++++++++++++++++++++---------- apps/openmw/engine.hpp | 4 ++++ 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index da9e9bede..913d1f679 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -56,19 +56,43 @@ void OMW::Engine::executeLocalScripts() mIgnoreLocalPtr = MWWorld::Ptr(); } +void OMW::Engine::MP3Lookup() +{ + boost::filesystem::directory_iterator dir_iter(mDataDir / "Music/Explore/"), dir_end; + //std::list files; + + nFiles = 0; + std::string mp3extension = ".mp3"; + for(;dir_iter != dir_end; dir_iter++) + { + if(boost::filesystem::extension(*dir_iter) == mp3extension) + { + files.push_front((*dir_iter)); + nFiles++; + } + }//*/ +} void OMW::Engine::startRandomTitle() { - char number[100]; - /* initialize random seed: */ - srand ( time(NULL) ); - /* generate secret number: */ - int r = rand() % 7 + 1; + std::list::iterator fileIter; + if(nFiles > 0) + { + fileIter = files.begin(); + srand ( time(NULL) ); + - sprintf(number, "Music/Explore/mx_explore_%d.mp3", r); - //std::string music = (mDataDir / "Music/Explore/mx_explore_5.mp3").file_string(); - std::string music = (mDataDir / number).file_string(); + int r = rand() % nFiles + 1; //old random code + + //int lowest=1, highest=nFiles; + //int range=(highest-lowest)+1; + //int r = lowest+int(range*rand()/(highest + 1.0)); + for(int i = 1; i < r; i++) + { + fileIter++; + } + std::string music = fileIter->file_string(); try { std::cout << "Playing " << music << "\n"; @@ -78,13 +102,12 @@ void OMW::Engine::startRandomTitle() { std::cout << " Music Error: " << e.what() << "\n"; } + } } bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt) { - // - MWWorld::Environment test = mEnvironment; - if(! (test.mSoundManager->isMusicPlaying())) + if(! (mEnvironment.mSoundManager->isMusicPlaying())) { // Play some good 'ol tunes startRandomTitle(); @@ -250,6 +273,8 @@ void OMW::Engine::go() assert (!mCellName.empty()); assert (!mMaster.empty()); + MP3Lookup(); + std::cout << "Data directory: " << mDataDir << "\n"; diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index d7420889f..f9b1caab4 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -52,6 +52,8 @@ namespace OMW class Engine : private Ogre::FrameListener { + std::list files; + int nFiles; boost::filesystem::path mDataDir; OEngine::Render::OgreRenderer mOgre; std::string mCellName; @@ -78,6 +80,8 @@ namespace OMW /// add resources directory /// \note This function works recursively. + void OMW::Engine::MP3Lookup(); + void startRandomTitle(); void addResourcesDirectory (const boost::filesystem::path& path); /// Load all BSA files in data directory. From cab23412592c3dfcd3b6a9a64db91efdf9d5701e Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sat, 6 Nov 2010 13:11:09 -0400 Subject: [PATCH 04/12] Preliminary region sound framework --- apps/openmw/engine.cpp | 79 +++++++++++++++++++++-------------- apps/openmw/engine.hpp | 5 ++- apps/openmw/mwworld/world.cpp | 53 +++++++++++++++++++++-- apps/openmw/mwworld/world.hpp | 11 ++++- 4 files changed, 111 insertions(+), 37 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 913d1f679..54fa6ab46 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -7,7 +7,8 @@ #include #include - +#include +#include #include #include "mwgui/window_manager.hpp" @@ -59,49 +60,41 @@ void OMW::Engine::executeLocalScripts() void OMW::Engine::MP3Lookup() { boost::filesystem::directory_iterator dir_iter(mDataDir / "Music/Explore/"), dir_end; - //std::list files; - - nFiles = 0; + std::string mp3extension = ".mp3"; for(;dir_iter != dir_end; dir_iter++) { if(boost::filesystem::extension(*dir_iter) == mp3extension) { - files.push_front((*dir_iter)); - nFiles++; + files.push_back(*dir_iter); } - }//*/ + } } void OMW::Engine::startRandomTitle() { + std::vector::iterator fileIter; - std::list::iterator fileIter; - if(nFiles > 0) + if(files.size() > 0) { fileIter = files.begin(); - srand ( time(NULL) ); - + srand ( time(NULL) ); + int r = rand() % files.size() + 1; //old random code - int r = rand() % nFiles + 1; //old random code - - //int lowest=1, highest=nFiles; - //int range=(highest-lowest)+1; - //int r = lowest+int(range*rand()/(highest + 1.0)); - for(int i = 1; i < r; i++) - { - fileIter++; - } - std::string music = fileIter->file_string(); - try - { - std::cout << "Playing " << music << "\n"; + for(int i = 1; i < r; i++) + { + fileIter++; + } + std::string music = fileIter->file_string(); + try + { + std::cout << "Playing " << music << "\n"; mEnvironment.mSoundManager->streamMusic(music); - } - catch(std::exception &e) - { - std::cout << " Music Error: " << e.what() << "\n"; - } + } + catch(std::exception &e) + { + std::cout << " Music Error: " << e.what() << "\n"; + } } } @@ -112,9 +105,31 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt) // Play some good 'ol tunes startRandomTitle(); } - - //tesprintf("HERE");t.mSoundManager. + + //If the region has changed + if(mEnvironment.mWorld->getIsExterior() && test.name != mEnvironment.mWorld->getCurrentRegion().name){ + test = mEnvironment.mWorld->getCurrentRegion(); + if(test.soundList.size() > 0) + { + std::vector::iterator soundIter = test.soundList.begin(); + while (!(soundIter == test.soundList.end())) + { + ESM::NAME32 go = soundIter->sound; + char chance = soundIter->chance; + std::cout << "Sound: " << go.name <<" Chance:" << (int) chance << "\n"; + soundIter++; + } + + } + + + //printf("REGION: %s\n", test.name); + } + else if(!mEnvironment.mWorld->getIsExterior()) + { + test.name = ""; + } try { @@ -165,6 +180,7 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt) { std::cerr << "Error in framelistener: " << e.what() << std::endl; } + //std::cout << "TESTING2"; return true; } @@ -274,6 +290,7 @@ void OMW::Engine::go() assert (!mMaster.empty()); MP3Lookup(); + test.name = ""; diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index f9b1caab4..500fe2808 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -52,8 +52,8 @@ namespace OMW class Engine : private Ogre::FrameListener { - std::list files; - int nFiles; + std::vector files; + //int nFiles; boost::filesystem::path mDataDir; OEngine::Render::OgreRenderer mOgre; std::string mCellName; @@ -68,6 +68,7 @@ namespace OMW Compiler::Extensions mExtensions; Compiler::Context *mScriptContext; OEngine::GUI::MyGUIManager *mGuiManager; + ESM::Region test; int focusFrameCounter; static const int focusUpdateFrame = 10; diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index ca29facfd..3e91b76b8 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -18,6 +18,10 @@ #include "environment.hpp" #include "class.hpp" + +#include "refdata.hpp" +#include "globals.hpp" + namespace { template @@ -62,6 +66,30 @@ namespace namespace MWWorld { + ESM::ESMReader World::getEsmReader(){ + return mEsm; + } + + Ptr::CellStore World::getMCurrentCell() + { + return *mCurrentCell; + } + + + ESM::Region World::getCurrentRegion() + { + return *currentRegion; + } + + + bool World::getIsExterior() + { + return isExterior; + } + void World::setIsExterior(bool set) + { + isExterior = set; + } void World::insertInteriorScripts (ESMS::CellStore& cell) { listCellScripts (mStore, cell.activators, mLocalScripts, &cell); @@ -315,6 +343,7 @@ namespace MWWorld : mSkyManager (0), mScene (renderer), mPlayerPos (0), mCurrentCell (0), mGlobalVariables (0), mSky (false), mCellChanged (false), mEnvironment (environment) { + isExterior = false; boost::filesystem::path masterPath (dataDir); masterPath /= master; @@ -605,6 +634,8 @@ namespace MWWorld adjustSky(); mCellChanged = true; + isExterior = false; + //currentRegion->name = ""; } void World::changeCell (int X, int Y, const ESM::Position& position) @@ -685,6 +716,7 @@ namespace MWWorld { int x = 0; int y = 0; + isExterior = true; positionToIndex (position.pos[0], position.pos[1], x, y); @@ -695,9 +727,21 @@ namespace MWWorld { // first try named cells if (const ESM::Cell *cell = mStore.cells.searchExtByName (cellName)) + { + //mCellChanged = true; + + getExteriorRegion(cell->region); return cell; - // didn't work -> now check for regions + } + + + return getExteriorRegion(cellName); + } + + const ESM::Cell *World::getExteriorRegion(const std::string& cellName) const + { + // didn't work -> now check for regions std::string cellName2 = ESMS::RecListT::toLower (cellName); for (ESMS::RecListT::MapType::const_iterator iter (mStore.regions.list.begin()); @@ -705,6 +749,7 @@ namespace MWWorld { if (ESMS::RecListT::toLower (iter->second.name)==cellName2) { + *currentRegion = iter->second; if (const ESM::Cell *cell = mStore.cells.searchExtByRegion (iter->first)) return cell; @@ -712,8 +757,8 @@ namespace MWWorld } } - return 0; - } + return 0; + } void World::markCellAsUnchanged() { @@ -794,6 +839,8 @@ namespace MWWorld } } + + void World::positionToIndex (float x, float y, int &cellX, int &cellY) const { const int cellSize = 8192; diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index 832c90bf0..56cba9e9a 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -39,10 +39,16 @@ namespace MWWorld class World { + public: - typedef std::list > ScriptList; + ESM::ESMReader getEsmReader(); + Ptr::CellStore getMCurrentCell(); + ESM::Region getCurrentRegion(); + bool getIsExterior(); + void setIsExterior(bool set); + private: typedef std::map CellRenderCollection; @@ -61,7 +67,9 @@ namespace MWWorld MWWorld::Globals *mGlobalVariables; bool mSky; bool mCellChanged; + bool isExterior; Environment& mEnvironment; + ESM::Region *currentRegion; // not implemented World (const World&); @@ -146,6 +154,7 @@ namespace MWWorld void changeToExteriorCell (const ESM::Position& position); const ESM::Cell *getExterior (const std::string& cellName) const; + const ESM::Cell *getExteriorRegion (const std::string& cellName) const; ///< Return a cell matching the given name or a 0-pointer, if there is no such cell. void markCellAsUnchanged(); From a038c67e5a3cf68d6bcee3c3c8ed136477d10388 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sun, 7 Nov 2010 12:51:59 -0500 Subject: [PATCH 05/12] Preliminary region sound framework2 --- apps/openmw/engine.cpp | 11 +++++--- apps/openmw/mwworld/world.cpp | 49 ++++------------------------------- apps/openmw/mwworld/world.hpp | 13 ++-------- 3 files changed, 15 insertions(+), 58 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 54fa6ab46..46c34f1b9 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -1,10 +1,12 @@ #include "engine.hpp" +#include "components/esm/loadcell.hpp" #include #include #include +#include #include #include #include @@ -107,11 +109,14 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt) } //If the region has changed - if(mEnvironment.mWorld->getIsExterior() && test.name != mEnvironment.mWorld->getCurrentRegion().name){ - test = mEnvironment.mWorld->getCurrentRegion(); + MWWorld::Ptr::CellStore *current = mEnvironment.mWorld->getPlayerPos().getPlayer().getCell(); + if(!(current->cell->data.flags & current->cell->Interior) && (test.name != current->cell->region)){ + test = *(mEnvironment.mWorld->getStore().regions.find(current->cell->region)); if(test.soundList.size() > 0) { std::vector::iterator soundIter = test.soundList.begin(); + mEnvironment.mWorld->getPlayerPos().getPlayer().getCell(); + //mEnvironment.mSoundManager while (!(soundIter == test.soundList.end())) { ESM::NAME32 go = soundIter->sound; @@ -126,7 +131,7 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt) //printf("REGION: %s\n", test.name); } - else if(!mEnvironment.mWorld->getIsExterior()) + else if(current->cell->data.flags & current->cell->Interior) { test.name = ""; } diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 3e91b76b8..317dc2361 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -66,30 +66,7 @@ namespace namespace MWWorld { - ESM::ESMReader World::getEsmReader(){ - return mEsm; - } - Ptr::CellStore World::getMCurrentCell() - { - return *mCurrentCell; - } - - - ESM::Region World::getCurrentRegion() - { - return *currentRegion; - } - - - bool World::getIsExterior() - { - return isExterior; - } - void World::setIsExterior(bool set) - { - isExterior = set; - } void World::insertInteriorScripts (ESMS::CellStore& cell) { listCellScripts (mStore, cell.activators, mLocalScripts, &cell); @@ -343,7 +320,6 @@ namespace MWWorld : mSkyManager (0), mScene (renderer), mPlayerPos (0), mCurrentCell (0), mGlobalVariables (0), mSky (false), mCellChanged (false), mEnvironment (environment) { - isExterior = false; boost::filesystem::path masterPath (dataDir); masterPath /= master; @@ -634,7 +610,6 @@ namespace MWWorld adjustSky(); mCellChanged = true; - isExterior = false; //currentRegion->name = ""; } @@ -712,11 +687,11 @@ namespace MWWorld mCellChanged = true; } - void World::changeToExteriorCell (const ESM::Position& position) + + void World::changeToExteriorCell (const ESM::Position& position) { int x = 0; int y = 0; - isExterior = true; positionToIndex (position.pos[0], position.pos[1], x, y); @@ -727,21 +702,9 @@ namespace MWWorld { // first try named cells if (const ESM::Cell *cell = mStore.cells.searchExtByName (cellName)) - { - //mCellChanged = true; - - getExteriorRegion(cell->region); return cell; - } - - - return getExteriorRegion(cellName); - } - - const ESM::Cell *World::getExteriorRegion(const std::string& cellName) const - { - // didn't work -> now check for regions + // didn't work -> now check for regions std::string cellName2 = ESMS::RecListT::toLower (cellName); for (ESMS::RecListT::MapType::const_iterator iter (mStore.regions.list.begin()); @@ -749,7 +712,6 @@ namespace MWWorld { if (ESMS::RecListT::toLower (iter->second.name)==cellName2) { - *currentRegion = iter->second; if (const ESM::Cell *cell = mStore.cells.searchExtByRegion (iter->first)) return cell; @@ -757,9 +719,8 @@ namespace MWWorld } } - return 0; - } - + return 0; + } void World::markCellAsUnchanged() { mCellChanged = false; diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index 56cba9e9a..f774cd68e 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -43,12 +43,6 @@ namespace MWWorld public: typedef std::list > ScriptList; - ESM::ESMReader getEsmReader(); - Ptr::CellStore getMCurrentCell(); - ESM::Region getCurrentRegion(); - bool getIsExterior(); - void setIsExterior(bool set); - private: typedef std::map CellRenderCollection; @@ -56,7 +50,7 @@ namespace MWWorld MWRender::SkyManager* mSkyManager; MWRender::MWScene mScene; MWRender::PlayerPos *mPlayerPos; - Ptr::CellStore *mCurrentCell; // the cell, the player is in + Ptr::CellStore *mCurrentCell; // the cell, the player is in CellRenderCollection mActiveCells; CellRenderCollection mBufferedCells; // loaded, but not active (buffering not implementd yet) ESM::ESMReader mEsm; @@ -67,9 +61,7 @@ namespace MWWorld MWWorld::Globals *mGlobalVariables; bool mSky; bool mCellChanged; - bool isExterior; Environment& mEnvironment; - ESM::Region *currentRegion; // not implemented World (const World&); @@ -104,7 +96,7 @@ namespace MWWorld MWRender::PlayerPos& getPlayerPos(); - ESMS::ESMStore& getStore(); + ESMS::ESMStore& getStore(); const ScriptList& getLocalScripts() const; ///< Names and local variable state of all local scripts in active cells. @@ -154,7 +146,6 @@ namespace MWWorld void changeToExteriorCell (const ESM::Position& position); const ESM::Cell *getExterior (const std::string& cellName) const; - const ESM::Cell *getExteriorRegion (const std::string& cellName) const; ///< Return a cell matching the given name or a 0-pointer, if there is no such cell. void markCellAsUnchanged(); From be1582a88fa1ff8c5e89bf5ce4a4494bca1707aa Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Mon, 8 Nov 2010 18:01:33 -0500 Subject: [PATCH 06/12] Regional Sounds --- apps/openmw/engine.cpp | 54 +++++++++++++++++++++++++++++++++++------- apps/openmw/engine.hpp | 4 ++++ 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 46c34f1b9..8b21f6e63 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -40,6 +40,7 @@ #include #include "mwgui/class.hpp" + void OMW::Engine::executeLocalScripts() { for (MWWorld::World::ScriptList::const_iterator iter ( @@ -107,27 +108,61 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt) // Play some good 'ol tunes startRandomTitle(); } + + std::string effect; + - //If the region has changed + MWWorld::Ptr::CellStore *current = mEnvironment.mWorld->getPlayerPos().getPlayer().getCell(); - if(!(current->cell->data.flags & current->cell->Interior) && (test.name != current->cell->region)){ - test = *(mEnvironment.mWorld->getStore().regions.find(current->cell->region)); + //If the region has changed + if(!(current->cell->data.flags & current->cell->Interior) && timer.elapsed() >= 10){ + timer.restart(); + if (test.name != current->cell->region) + { + total = 0; + test = *(mEnvironment.mWorld->getStore().regions.find(current->cell->region)); + } + if(test.soundList.size() > 0) { std::vector::iterator soundIter = test.soundList.begin(); - mEnvironment.mWorld->getPlayerPos().getPlayer().getCell(); //mEnvironment.mSoundManager + if(total == 0){ + while (!(soundIter == test.soundList.end())) + { + ESM::NAME32 go = soundIter->sound; + int chance = (int) soundIter->chance; + //std::cout << "Sound: " << go.name <<" Chance:" << chance << "\n"; + soundIter++; + total += chance; + } + } + + srand ( time(NULL) ); + int r = rand() % total; //old random code + int pos = 0; + soundIter = test.soundList.begin(); while (!(soundIter == test.soundList.end())) { - ESM::NAME32 go = soundIter->sound; - char chance = soundIter->chance; - std::cout << "Sound: " << go.name <<" Chance:" << (int) chance << "\n"; + const ESM::NAME32 go = soundIter->sound; + int chance = (int) soundIter->chance; + //std::cout << "Sound: " << go.name <<" Chance:" << chance << "\n"; soundIter++; + if( r - pos < chance) + { + effect = go.name; + //play sound + std::cout << "Sound: " << go.name <<" Chance:" << chance << "\n"; + mEnvironment.mSoundManager->playSound(effect, 20.0, 1.0); + + break; + + } + pos += chance; } - } - + //mEnvironment.mSoundManager->playSound(effect, 1.0, 1.0); //printf("REGION: %s\n", test.name); } @@ -296,6 +331,7 @@ void OMW::Engine::go() MP3Lookup(); test.name = ""; + total = 0; diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index 500fe2808..54748b2c6 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -12,6 +12,8 @@ #include "mwworld/environment.hpp" #include "mwworld/ptr.hpp" +#include + namespace Compiler { @@ -62,6 +64,7 @@ namespace OMW bool mVerboseScripts; bool mNewGame; bool mUseSound; + int total; MWWorld::Environment mEnvironment; MWScript::ScriptManager *mScriptManager; @@ -69,6 +72,7 @@ namespace OMW Compiler::Context *mScriptContext; OEngine::GUI::MyGUIManager *mGuiManager; ESM::Region test; + boost::timer timer; int focusFrameCounter; static const int focusUpdateFrame = 10; From a9892161afb9b8c235996a07e65a9183bef5e690 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Thu, 11 Nov 2010 19:47:26 -0500 Subject: [PATCH 07/12] MP3 functions moved to soundmanager --- apps/openmw/engine.cpp | 51 ++++------------------------ apps/openmw/engine.hpp | 5 ++- apps/openmw/mwsound/soundmanager.cpp | 48 ++++++++++++++++++++++++-- apps/openmw/mwsound/soundmanager.hpp | 7 +++- 4 files changed, 60 insertions(+), 51 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 8b21f6e63..af8434bba 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -6,6 +6,7 @@ #include #include +#include "components/esm/records.hpp" #include #include #include @@ -41,6 +42,8 @@ #include "mwgui/class.hpp" +//using namespace ESM; + void OMW::Engine::executeLocalScripts() { for (MWWorld::World::ScriptList::const_iterator iter ( @@ -60,53 +63,14 @@ void OMW::Engine::executeLocalScripts() mIgnoreLocalPtr = MWWorld::Ptr(); } -void OMW::Engine::MP3Lookup() -{ - boost::filesystem::directory_iterator dir_iter(mDataDir / "Music/Explore/"), dir_end; - - std::string mp3extension = ".mp3"; - for(;dir_iter != dir_end; dir_iter++) - { - if(boost::filesystem::extension(*dir_iter) == mp3extension) - { - files.push_back(*dir_iter); - } - } -} - -void OMW::Engine::startRandomTitle() -{ - std::vector::iterator fileIter; - - if(files.size() > 0) - { - fileIter = files.begin(); - srand ( time(NULL) ); - int r = rand() % files.size() + 1; //old random code - for(int i = 1; i < r; i++) - { - fileIter++; - } - std::string music = fileIter->file_string(); - try - { - std::cout << "Playing " << music << "\n"; - mEnvironment.mSoundManager->streamMusic(music); - } - catch(std::exception &e) - { - std::cout << " Music Error: " << e.what() << "\n"; - } - } -} bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt) { if(! (mEnvironment.mSoundManager->isMusicPlaying())) { // Play some good 'ol tunes - startRandomTitle(); + mEnvironment.mSoundManager->startRandomTitle(); } std::string effect; @@ -120,7 +84,7 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt) if (test.name != current->cell->region) { total = 0; - test = *(mEnvironment.mWorld->getStore().regions.find(current->cell->region)); + test = (ESM::Region) *(mEnvironment.mWorld->getStore().regions.find(current->cell->region)); } if(test.soundList.size() > 0) @@ -329,7 +293,6 @@ void OMW::Engine::go() assert (!mCellName.empty()); assert (!mMaster.empty()); - MP3Lookup(); test.name = ""; total = 0; @@ -374,7 +337,7 @@ void OMW::Engine::go() mEnvironment.mSoundManager = new MWSound::SoundManager(mOgre.getRoot(), mOgre.getCamera(), mEnvironment.mWorld->getStore(), - (mDataDir / "Sound").file_string(), + (mDataDir), mUseSound); // Create script system @@ -412,7 +375,7 @@ void OMW::Engine::go() mOgre.getRoot()->addFrameListener (this); // Play some good 'ol tunes - startRandomTitle(); + mEnvironment.mSoundManager->startRandomTitle(); // Start the main rendering loop mOgre.start(); diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index 54748b2c6..89ce320a8 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -54,7 +54,7 @@ namespace OMW class Engine : private Ogre::FrameListener { - std::vector files; + //int nFiles; boost::filesystem::path mDataDir; OEngine::Render::OgreRenderer mOgre; @@ -85,8 +85,7 @@ namespace OMW /// add resources directory /// \note This function works recursively. - void OMW::Engine::MP3Lookup(); - void startRandomTitle(); + void addResourcesDirectory (const boost::filesystem::path& path); /// Load all BSA files in data directory. diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index 3dedab9ef..8bdd8e2b9 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -306,12 +306,13 @@ namespace MWSound SoundManager::SoundManager(Ogre::Root *root, Ogre::Camera *camera, const ESMS::ESMStore &store, - const std::string &soundDir, + boost::filesystem::path dataDir, bool useSound) : mData(NULL) { + MP3Lookup(dataDir / "Music/Explore/"); if(useSound) - mData = new SoundImpl(root, camera, store, soundDir); + mData = new SoundImpl(root, camera, store, (dataDir / "Sound").file_string()); } SoundManager::~SoundManager() @@ -320,6 +321,48 @@ namespace MWSound delete mData; } + void SoundManager::MP3Lookup(boost::filesystem::path dir) +{ + boost::filesystem::directory_iterator dir_iter(dir), dir_end; + + std::string mp3extension = ".mp3"; + for(;dir_iter != dir_end; dir_iter++) + { + if(boost::filesystem::extension(*dir_iter) == mp3extension) + { + files.push_back(*dir_iter); + } + } +} + + void SoundManager::startRandomTitle() +{ + std::vector::iterator fileIter; + + if(files.size() > 0) + { + fileIter = files.begin(); + srand ( time(NULL) ); + int r = rand() % files.size() + 1; //old random code + + for(int i = 1; i < r; i++) + { + fileIter++; + } + std::string music = fileIter->file_string(); + try + { + std::cout << "Playing " << music << "\n"; + streamMusic(music); + } + catch(std::exception &e) + { + std::cout << " Music Error: " << e.what() << "\n"; + } + } +} + + bool SoundManager::isMusicPlaying() { bool test = mData->music->isPlaying(); @@ -369,7 +412,6 @@ namespace MWSound void SoundManager::playSound (const std::string& soundId, float volume, float pitch) { if(!mData) return; - // Play and forget float min, max; const std::string &file = mData->lookup(soundId, volume, min, max); diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanager.hpp index 017069a63..8717bf8dd 100644 --- a/apps/openmw/mwsound/soundmanager.hpp +++ b/apps/openmw/mwsound/soundmanager.hpp @@ -4,6 +4,7 @@ #include #include +#include #include "../mwworld/ptr.hpp" #include @@ -28,12 +29,16 @@ namespace MWSound struct SoundImpl; SoundImpl *mData; + std::vector files; public: SoundManager(Ogre::Root*, Ogre::Camera*, const ESMS::ESMStore &store, - const std::string &soundDir, bool useSound); + boost::filesystem::path dataDir, bool useSound); ~SoundManager(); + + void startRandomTitle(); + void MP3Lookup(boost::filesystem::path dir); //struct SoundImpl; bool isMusicPlaying(); From 6aaedff86a2371774ecab1b26aed6d8a031b63de Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Thu, 25 Nov 2010 15:44:56 -0500 Subject: [PATCH 08/12] Preliminary NPCs --- apps/openmw/mwrender/cellimp.hpp | 11 +++++++++- apps/openmw/mwrender/exterior.cpp | 35 +++++++++++++++++++++++++++++++ apps/openmw/mwrender/exterior.hpp | 5 +++++ apps/openmw/mwrender/interior.cpp | 30 ++++++++++++++++++++++++++ apps/openmw/mwrender/interior.hpp | 7 +++++-- 5 files changed, 85 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwrender/cellimp.hpp b/apps/openmw/mwrender/cellimp.hpp index bc6f2874a..8ba158408 100644 --- a/apps/openmw/mwrender/cellimp.hpp +++ b/apps/openmw/mwrender/cellimp.hpp @@ -6,6 +6,13 @@ #include "components/esm_store/cell_store.hpp" #include "../mwworld/refdata.hpp" +#include + +namespace Ogre +{ + class SceneNode; + class Vector3; +} namespace ESM { @@ -16,7 +23,6 @@ namespace MWWorld { class Environment; } - namespace MWRender { /// Base class for cell render, that implements inserting references into a cell in a @@ -31,9 +37,12 @@ namespace MWRender /// start inserting a new reference. virtual void insertBegin (ESM::CellRef &ref) = 0; + virtual void rotateMesh(Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName[], int elements) = 0; /// insert a mesh related to the most recent insertBegin call. + virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements) = 0; virtual void insertMesh(const std::string &mesh) = 0; + /// insert a light related to the most recent insertBegin call. virtual void insertLight(float r, float g, float b, float radius) = 0; diff --git a/apps/openmw/mwrender/exterior.cpp b/apps/openmw/mwrender/exterior.cpp index 58c783d72..5603460a4 100644 --- a/apps/openmw/mwrender/exterior.cpp +++ b/apps/openmw/mwrender/exterior.cpp @@ -57,8 +57,43 @@ void ExteriorCellRender::insertBegin (ESM::CellRef &ref) insert->setOrientation(xr*yr*zr); } + +void ExteriorCellRender::rotateMesh(Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName[], int elements) +{ + assert(insert); + Ogre::SceneNode *parent = insert; + //std::cout << "ELEMENTS:" << elements; + for (int i = 0; i < elements; i++){ + if(sceneNodeName[i] != "" && parent->getChild(sceneNodeName[i])) + parent = dynamic_cast (parent->getChild(sceneNodeName[i])); + } + parent->rotate(axis, angle); +} + +void ExteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements){ + assert (insert); + //insert-> + Ogre::SceneNode *parent = insert; + for (int i = 0; i < elements; i++){ + if(sceneParent[i] != "" && parent->getChild(sceneParent[i])) + parent = dynamic_cast (parent->getChild(sceneParent[i])); + } + + npcPart = parent->createChildSceneNode(sceneNodeName); + NIFLoader::load(mesh); + MovableObject *ent = scene.getMgr()->createEntity(mesh); + + npcPart->translate(vec); + npcPart->rotate(axis, angle); + // npcPart->translate(vec); + //npcPart->rotate(axis, angle); + npcPart->attachObject(ent); + //npcPart-> + +} // insert a mesh related to the most recent insertBegin call. + void ExteriorCellRender::insertMesh(const std::string &mesh) { assert (insert); diff --git a/apps/openmw/mwrender/exterior.hpp b/apps/openmw/mwrender/exterior.hpp index 7de027672..64bd8c623 100644 --- a/apps/openmw/mwrender/exterior.hpp +++ b/apps/openmw/mwrender/exterior.hpp @@ -5,6 +5,7 @@ #include "cellimp.hpp" #include "OgreColourValue.h" +#include namespace Ogre { @@ -53,6 +54,7 @@ namespace MWRender Ogre::SceneNode *base; Ogre::SceneNode *insert; + Ogre::SceneNode *npcPart; // 0 normal, 1 more bright, 2 max int ambientMode; @@ -63,7 +65,9 @@ namespace MWRender virtual void insertBegin (ESM::CellRef &ref); /// insert a mesh related to the most recent insertBegin call. + virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements); virtual void insertMesh(const std::string &mesh); + virtual void rotateMesh(Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName[], int elements); /// insert a light related to the most recent insertBegin call. virtual void insertLight(float r, float g, float b, float radius); @@ -78,6 +82,7 @@ namespace MWRender void configureFog(); void setAmbientMode(); + public: diff --git a/apps/openmw/mwrender/interior.cpp b/apps/openmw/mwrender/interior.cpp index 1e88ecab4..676b51f18 100644 --- a/apps/openmw/mwrender/interior.cpp +++ b/apps/openmw/mwrender/interior.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "mwscene.hpp" @@ -58,6 +59,35 @@ void InteriorCellRender::insertBegin (ESM::CellRef &ref) } // insert a mesh related to the most recent insertBegin call. +void InteriorCellRender::rotateMesh(Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName[], int elements) +{ + assert(insert); + Ogre::SceneNode *parent = insert; + //std::cout << "ELEMENTS:" << elements; + for (int i = 0; i < elements; i++){ + if(sceneNodeName[i] != "" && parent->getChild(sceneNodeName[i])) + parent = dynamic_cast (parent->getChild(sceneNodeName[i])); + } + parent->rotate(axis, angle); +} +void InteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements){ + + assert (insert); + //insert-> + Ogre::SceneNode *parent = insert; + for (int i = 0; i < elements; i++){ + if(sceneParent[i] != "" && parent->getChild(sceneParent[i])) + parent = dynamic_cast (parent->getChild(sceneParent[i])); + } + + npcPart = parent->createChildSceneNode(sceneNodeName); + NIFLoader::load(mesh); + MovableObject *ent = scene.getMgr()->createEntity(mesh); + + npcPart->translate(vec); + npcPart->rotate(axis, angle); + npcPart->attachObject(ent); +} void InteriorCellRender::insertMesh(const std::string &mesh) { diff --git a/apps/openmw/mwrender/interior.hpp b/apps/openmw/mwrender/interior.hpp index ba5089eb5..1b64b0fdb 100644 --- a/apps/openmw/mwrender/interior.hpp +++ b/apps/openmw/mwrender/interior.hpp @@ -5,6 +5,7 @@ #include "cellimp.hpp" #include "OgreColourValue.h" +#include namespace Ogre { @@ -53,6 +54,7 @@ namespace MWRender Ogre::SceneNode *base; Ogre::SceneNode *insert; + Ogre::SceneNode *npcPart; // 0 normal, 1 more bright, 2 max int ambientMode; @@ -61,10 +63,10 @@ namespace MWRender /// start inserting a new reference. virtual void insertBegin (ESM::CellRef &ref); - + virtual void rotateMesh(Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName[], int elements); /// insert a mesh related to the most recent insertBegin call. virtual void insertMesh(const std::string &mesh); - + virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements); /// insert a light related to the most recent insertBegin call. virtual void insertLight(float r, float g, float b, float radius); @@ -79,6 +81,7 @@ namespace MWRender void setAmbientMode(); + public: InteriorCellRender(ESMS::CellStore &_cell, MWWorld::Environment& environment, From dfe20033ea64bddceaab8c9c816060733b6ebc6c Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Thu, 25 Nov 2010 18:36:25 -0500 Subject: [PATCH 09/12] Preliminary npcs2 --- apps/openmw/mwclass/npc.cpp | 142 ++++++++++++++++++++++++++++-- apps/openmw/mwrender/cellimp.hpp | 2 + apps/openmw/mwrender/exterior.cpp | 15 ++++ apps/openmw/mwrender/exterior.hpp | 1 + apps/openmw/mwrender/interior.cpp | 13 +++ apps/openmw/mwrender/interior.hpp | 2 + 6 files changed, 168 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index f9f99e58d..69e8207ed 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -14,6 +14,7 @@ #include "../mwrender/cellimp.hpp" #include "../mwmechanics/mechanicsmanager.hpp" +#include namespace MWClass { @@ -28,32 +29,159 @@ namespace MWClass void Npc::insertObj (const MWWorld::Ptr& ptr, MWRender::CellRenderImp& cellRender, MWWorld::Environment& environment) const { + //Ogre::SceneNode *chest; ESMS::LiveCellRef *ref = ptr.get(); + + //Store scenenodes by npc's name + bodypart [0] , npc's name + bodypart [1] + //Ex. Fargothchest , Fargothneck assert (ref->base != NULL); + std::string hairID = ref->base->hair; std::string headID = ref->base->head; + std::string npcName = ref->base->name; + //std::cout << "NPC: " << npcName << "\n"; //get the part of the bodypart id which describes the race and the gender std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4); std::string headModel = "meshes\\" + environment.mWorld->getStore().bodyParts.find(headID)->model; - MWRender::Rendering rendering (cellRender, ref->ref); + std::string hairModel = "meshes\\" + + environment.mWorld->getStore().bodyParts.find(hairID)->model; - cellRender.insertMesh (headModel); + MWRender::Rendering rendering (cellRender, ref->ref); + //TODO: define consts for each bodypart e.g. chest, foot, wrist... and put the parts in the // right place const ESM::BodyPart *bodyPart = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "chest"); - if (bodyPart) - cellRender.insertMesh("meshes\\" + bodyPart->model); - - ref->mData.setHandle (rendering.end (ref->mData.isEnabled())); - } + //bodyPart->model-> + Ogre::Vector3 pos = Ogre::Vector3( 20, 20, 20); + Ogre::Vector3 axis = Ogre::Vector3( 0, 0, 1); + Ogre::Radian angle = Ogre::Radian(0); + + std::string addresses[6] = {"", "", "", "",""}; + std::string addresses2[6] = {"", "", "", "", ""}; + std::string upperleft[5] = {"", "", "", "", ""}; + std::string upperright[5] = {"", "", "", "", ""}; + std::string neckandup[5] = {"", "", "","",""}; + int numbers = 0; + int uppernumbers = 0; + int neckNumbers = 0; + + if (bodyPart){ + + cellRender.insertMesh("meshes\\" + bodyPart->model, pos, axis, angle, npcName + "chest", addresses, numbers); + addresses2[numbers] = npcName + "chest"; + addresses[numbers++] = npcName + "chest"; + upperleft[uppernumbers] = npcName + "chest"; + upperright[uppernumbers++] = npcName + "chest"; + neckandup[neckNumbers++] = npcName + "chest"; + } + //std::cout << "GETTING NPC PART"; + //Orgre::SceneNode test = cellRender.getNpcPart(); + + const ESM::BodyPart *upperleg = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper leg"); + const ESM::BodyPart *groin = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "groin"); + const ESM::BodyPart *arm = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "upper arm"); + const ESM::BodyPart *neck = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "neck"); + const ESM::BodyPart *knee = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "knee"); + const ESM::BodyPart *ankle = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "ankle"); + const ESM::BodyPart *foot = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "foot"); + const ESM::BodyPart *foot2 = foot + 1; + const ESM::BodyPart *wrist = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "wrist"); + const ESM::BodyPart *forearm = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "forearm"); + const ESM::BodyPart *hand = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "hands.1st"); + + + Ogre::Vector3 pos2 = Ogre::Vector3( 0, .5, 75); + std::string upperarmpath[2] = {npcName + "chest", npcName + "upper arm"}; + + if (groin){ + cellRender.insertMesh("meshes\\" + groin->model, pos2, axis, Ogre::Radian(3.14), npcName + "groin", addresses, numbers); + addresses2[numbers] = npcName + "groin"; + addresses[numbers++] = npcName + "groin"; + } + + //addresses[1] = npcName + "groin"; + if(upperleg){ + cellRender.insertMesh ("meshes\\" + upperleg->model, Ogre::Vector3( 6, 0, -14), axis, Ogre::Radian(.7), npcName + "upper leg", addresses, numbers); //-18 + cellRender.insertMesh ("meshes\\" + upperleg->model, Ogre::Vector3( -6, 0, -14), axis, Ogre::Radian(0), npcName + "upper leg2", addresses2, numbers); + addresses2[numbers] = npcName + "upper leg2"; + addresses[numbers++] = npcName + "upper leg"; + } + if(knee) + { + cellRender.insertMesh ("meshes\\" + knee->model, Ogre::Vector3( 0, -2, -18), axis, Ogre::Radian(0), npcName + "knee", addresses, numbers); + //cellRender.rotateMesh(Ogre::Vector3(0, 1, 0), Ogre::Radian (1), npcName + "upper arm"); + cellRender.insertMesh ("meshes\\" + knee->model, Ogre::Vector3( 0, -2, -18), axis, Ogre::Radian(0), npcName + "knee2", addresses2, numbers); + + addresses2[numbers] = npcName + "knee2"; + addresses[numbers++] = npcName + "knee"; + } + if(ankle){ + cellRender.insertMesh ("meshes\\" + ankle->model, Ogre::Vector3( 0, 0, -18), axis, Ogre::Radian(0), npcName + "ankle", addresses, numbers); + cellRender.insertMesh ("meshes\\" + ankle->model, Ogre::Vector3( 0, 0, -18), axis, Ogre::Radian(0), npcName + "ankle2", addresses2, numbers); + + addresses2[numbers] = npcName + "ankle2"; + addresses[numbers++] = npcName + "ankle"; + } + if(foot){ + cellRender.insertMesh ("meshes\\" + foot->model, Ogre::Vector3( 0, -2, -16), axis, Ogre::Radian(3.14), npcName + "foot", addresses, numbers); + + cellRender.insertMesh ("meshes\\" + foot->model, Ogre::Vector3( 0, -2, -16), axis, Ogre::Radian(0), npcName + "foot2", addresses2, numbers); + addresses2[numbers] = npcName + "foot2"; + addresses[numbers++] = npcName + "foot"; + cellRender.scaleMesh(Ogre::Vector3(1, -1, 1), addresses, numbers); + } + + + if (arm){ + cellRender.insertMesh("meshes\\" + arm->model, Ogre::Vector3(-12.5, 0, 104), Ogre::Vector3(1, 0, .75), Ogre::Radian(3.14), npcName + "upper arm", upperleft, uppernumbers); //1, 0,.75 + //cellRender.rotateMesh(Ogre::Vector3(1, 0, 0), Ogre::Radian (.45), upperarmpath, 2); //1, 0, 1 + cellRender.insertMesh("meshes\\" + arm->model, Ogre::Vector3(12.5, 0, 105), Ogre::Vector3(-.5, 0, -.75), Ogre::Radian(3.14), npcName + "upper arm2", upperright, uppernumbers); + upperleft[uppernumbers] = npcName + "upper arm"; + upperright[uppernumbers++] = npcName + "upper arm2"; + } + + if (forearm) + { + //addresses[1] = npcName + "upper arm"; + cellRender.insertMesh("meshes\\" + forearm->model, Ogre::Vector3(-12.5, 0, 0), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "forearm", upperleft, uppernumbers); + cellRender.insertMesh("meshes\\" + forearm->model, Ogre::Vector3(-12.5, 0, 0), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "forearm2", upperright, uppernumbers); + upperleft[uppernumbers] = npcName + "forearm"; + upperright[uppernumbers++] = npcName + "forearm2"; + } + //else + // std::cout << npcName << "has no forearm"; + if (wrist) + { + cellRender.insertMesh("meshes\\" + wrist->model, Ogre::Vector3(-9.5, 0, 0), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "wrist", upperleft, uppernumbers); + cellRender.insertMesh("meshes\\" + wrist->model, Ogre::Vector3(-9.5, 0, 0), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "wrist2", upperright, uppernumbers); + upperleft[uppernumbers] = npcName + "wrist"; + upperright[uppernumbers++] = npcName + "wrist2"; + } + + + if(hand) + cellRender.insertMesh("meshes\\" + hand->model, Ogre::Vector3(-50, 0, -120), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "hands", addresses, 4); //0, 100, -100 0,0,120 + + + if(neck) + { + cellRender.insertMesh ("meshes\\" + neck->model, Ogre::Vector3( 0, 0, 120), axis, Ogre::Radian(3.14), npcName + "neck", neckandup, neckNumbers); + neckandup[neckNumbers++] = npcName + "neck"; + } + cellRender.insertMesh (headModel, Ogre::Vector3( 0, 0, 5), axis, Ogre::Radian(0), npcName + "head", neckandup, neckNumbers); + neckandup[neckNumbers++] = npcName + "head"; + cellRender.insertMesh (hairModel, Ogre::Vector3( 0, -1, 0), axis, Ogre::Radian(0), npcName + "hair", neckandup, neckNumbers); + ref->mData.setHandle (rendering.end (ref->mData.isEnabled())); + + } void Npc::enable (const MWWorld::Ptr& ptr, MWWorld::Environment& environment) const { diff --git a/apps/openmw/mwrender/cellimp.hpp b/apps/openmw/mwrender/cellimp.hpp index 8ba158408..eeaa90cd9 100644 --- a/apps/openmw/mwrender/cellimp.hpp +++ b/apps/openmw/mwrender/cellimp.hpp @@ -42,6 +42,8 @@ namespace MWRender virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements) = 0; virtual void insertMesh(const std::string &mesh) = 0; + virtual void scaleMesh(Ogre::Vector3 axis, std::string sceneNodeName[], int elements) = 0; + /// insert a light related to the most recent insertBegin call. virtual void insertLight(float r, float g, float b, float radius) = 0; diff --git a/apps/openmw/mwrender/exterior.cpp b/apps/openmw/mwrender/exterior.cpp index 5603460a4..1ef096283 100644 --- a/apps/openmw/mwrender/exterior.cpp +++ b/apps/openmw/mwrender/exterior.cpp @@ -91,6 +91,21 @@ void ExteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, //npcPart-> } + +// insert a mesh related to the most recent insertBegin call. + +void ExteriorCellRender::scaleMesh(Ogre::Vector3 axis, std::string sceneNodeName[], int elements) +{ + assert(insert); + Ogre::SceneNode *parent = insert; + //std::cout << "ELEMENTS:" << elements; + for (int i = 0; i < elements; i++){ + if(sceneNodeName[i] != "" && parent->getChild(sceneNodeName[i])) + parent = dynamic_cast (parent->getChild(sceneNodeName[i])); + } + parent->scale(axis); +} + // insert a mesh related to the most recent insertBegin call. diff --git a/apps/openmw/mwrender/exterior.hpp b/apps/openmw/mwrender/exterior.hpp index 64bd8c623..2824719d9 100644 --- a/apps/openmw/mwrender/exterior.hpp +++ b/apps/openmw/mwrender/exterior.hpp @@ -68,6 +68,7 @@ namespace MWRender virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements); virtual void insertMesh(const std::string &mesh); virtual void rotateMesh(Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName[], int elements); + virtual void scaleMesh(Ogre::Vector3 axis, std::string sceneNodeName[], int elements); /// insert a light related to the most recent insertBegin call. virtual void insertLight(float r, float g, float b, float radius); diff --git a/apps/openmw/mwrender/interior.cpp b/apps/openmw/mwrender/interior.cpp index 676b51f18..d194942cc 100644 --- a/apps/openmw/mwrender/interior.cpp +++ b/apps/openmw/mwrender/interior.cpp @@ -70,6 +70,19 @@ void InteriorCellRender::rotateMesh(Ogre::Vector3 axis, Ogre::Radian angle, std } parent->rotate(axis, angle); } +// insert a mesh related to the most recent insertBegin call. + +void InteriorCellRender::scaleMesh(Ogre::Vector3 axis, std::string sceneNodeName[], int elements) +{ + assert(insert); + Ogre::SceneNode *parent = insert; + //std::cout << "ELEMENTS:" << elements; + for (int i = 0; i < elements; i++){ + if(sceneNodeName[i] != "" && parent->getChild(sceneNodeName[i])) + parent = dynamic_cast (parent->getChild(sceneNodeName[i])); + } + parent->scale(axis); +} void InteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements){ assert (insert); diff --git a/apps/openmw/mwrender/interior.hpp b/apps/openmw/mwrender/interior.hpp index 1b64b0fdb..84a896987 100644 --- a/apps/openmw/mwrender/interior.hpp +++ b/apps/openmw/mwrender/interior.hpp @@ -64,6 +64,7 @@ namespace MWRender /// start inserting a new reference. virtual void insertBegin (ESM::CellRef &ref); virtual void rotateMesh(Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName[], int elements); + virtual void scaleMesh(Ogre::Vector3 axis, std::string sceneNodeName[], int elements); /// insert a mesh related to the most recent insertBegin call. virtual void insertMesh(const std::string &mesh); virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements); @@ -91,6 +92,7 @@ namespace MWRender virtual ~InteriorCellRender() { destroy(); } /// Make the cell visible. Load the cell if necessary. + //virtual void scaleMesh(Ogre::Vector3 axis, std::string sceneNodeName[], int elements); virtual void show(); /// Remove the cell from rendering, but don't remove it from From 467988455c9a9b6c57785933e536d7804e24b0f9 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Sun, 12 Dec 2010 22:05:47 -0500 Subject: [PATCH 10/12] Preliminary npcs3 --- apps/openmw/mwclass/npc.cpp | 75 ++++++-- apps/openmw/mwclass/npc.hpp | 4 +- apps/openmw/mwrender/cellimp.hpp | 1 + apps/openmw/mwrender/exterior.cpp | 30 ++- apps/openmw/mwrender/exterior.hpp | 4 +- apps/openmw/mwrender/interior.cpp | 27 ++- apps/openmw/mwrender/interior.hpp | 3 +- components/nifogre/ogre_nif_loader.cpp | 199 ++++++++++++++++++- components/nifogre/ogre_nif_loader.hpp | 16 +- components/nifogre/oldnpccode.txt | 256 +++++++++++++++++++++++++ 10 files changed, 577 insertions(+), 38 deletions(-) create mode 100644 components/nifogre/oldnpccode.txt diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 69e8207ed..8005acab4 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -41,7 +41,7 @@ namespace MWClass std::string hairID = ref->base->hair; std::string headID = ref->base->head; std::string npcName = ref->base->name; - //std::cout << "NPC: " << npcName << "\n"; + std::cout << "NPC: " << npcName << "\n"; //get the part of the bodypart id which describes the race and the gender std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4); @@ -64,18 +64,19 @@ namespace MWClass Ogre::Vector3 axis = Ogre::Vector3( 0, 0, 1); Ogre::Radian angle = Ogre::Radian(0); - std::string addresses[6] = {"", "", "", "",""}; - std::string addresses2[6] = {"", "", "", "", ""}; + std::string addresses[6] = {"", "", "", "","", ""}; + std::string addresses2[6] = {"", "", "", "", "", ""}; std::string upperleft[5] = {"", "", "", "", ""}; std::string upperright[5] = {"", "", "", "", ""}; std::string neckandup[5] = {"", "", "","",""}; + std::string empty[6] = {"", "", "", "","", ""}; int numbers = 0; int uppernumbers = 0; int neckNumbers = 0; if (bodyPart){ - - cellRender.insertMesh("meshes\\" + bodyPart->model, pos, axis, angle, npcName + "chest", addresses, numbers); + + cellRender.insertMesh("meshes\\" + bodyPart->model, pos, axis, angle, npcName + "chest", addresses, numbers, true); //2 0 addresses2[numbers] = npcName + "chest"; addresses[numbers++] = npcName + "chest"; upperleft[uppernumbers] = npcName + "chest"; @@ -92,11 +93,11 @@ namespace MWClass const ESM::BodyPart *knee = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "knee"); const ESM::BodyPart *ankle = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "ankle"); const ESM::BodyPart *foot = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "foot"); - const ESM::BodyPart *foot2 = foot + 1; const ESM::BodyPart *wrist = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "wrist"); const ESM::BodyPart *forearm = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "forearm"); - const ESM::BodyPart *hand = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "hands.1st"); - + const ESM::BodyPart *hand = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "hand.1st"); + const ESM::BodyPart *hands = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "hands.1st"); + std::cout << "RACE" << bodyRaceID << "\n"; Ogre::Vector3 pos2 = Ogre::Vector3( 0, .5, 75); std::string upperarmpath[2] = {npcName + "chest", npcName + "upper arm"}; @@ -109,10 +110,11 @@ namespace MWClass //addresses[1] = npcName + "groin"; if(upperleg){ - cellRender.insertMesh ("meshes\\" + upperleg->model, Ogre::Vector3( 6, 0, -14), axis, Ogre::Radian(.7), npcName + "upper leg", addresses, numbers); //-18 + cellRender.insertMesh ("meshes\\" + upperleg->model, Ogre::Vector3( 6, 0, -14), axis, Ogre::Radian(3.14), npcName + "upper leg", addresses, numbers); //-18 cellRender.insertMesh ("meshes\\" + upperleg->model, Ogre::Vector3( -6, 0, -14), axis, Ogre::Radian(0), npcName + "upper leg2", addresses2, numbers); addresses2[numbers] = npcName + "upper leg2"; addresses[numbers++] = npcName + "upper leg"; + cellRender.scaleMesh(Ogre::Vector3(1, -1, 1), addresses, numbers); } if(knee) { @@ -124,28 +126,42 @@ namespace MWClass addresses[numbers++] = npcName + "knee"; } if(ankle){ - cellRender.insertMesh ("meshes\\" + ankle->model, Ogre::Vector3( 0, 0, -18), axis, Ogre::Radian(0), npcName + "ankle", addresses, numbers); - cellRender.insertMesh ("meshes\\" + ankle->model, Ogre::Vector3( 0, 0, -18), axis, Ogre::Radian(0), npcName + "ankle2", addresses2, numbers); + + cellRender.insertMesh ("meshes\\" + ankle->model, Ogre::Vector3( 0, -1, -18), axis, Ogre::Radian(0), npcName + "ankle", addresses, numbers); //-1 + cellRender.insertMesh ("meshes\\" + ankle->model, Ogre::Vector3( 0, -1, -18), axis, Ogre::Radian(0), npcName + "ankle2", addresses2, numbers); //-1 addresses2[numbers] = npcName + "ankle2"; addresses[numbers++] = npcName + "ankle"; } if(foot){ - cellRender.insertMesh ("meshes\\" + foot->model, Ogre::Vector3( 0, -2, -16), axis, Ogre::Radian(3.14), npcName + "foot", addresses, numbers); - - cellRender.insertMesh ("meshes\\" + foot->model, Ogre::Vector3( 0, -2, -16), axis, Ogre::Radian(0), npcName + "foot2", addresses2, numbers); + //std::cout << "RACE" << bodyRaceID << "\n"; + if(bodyRaceID.compare("b_n_khajiit_m_") == 0 || bodyRaceID.compare("b_n_khajiit_f_") == 0) + { + std::cout << "BEASTRACE\n"; + cellRender.insertMesh ("meshes\\" + foot->model, Ogre::Vector3( 0, -24, -15), axis, Ogre::Radian(0), npcName + "foot", addresses, numbers); + + cellRender.insertMesh ("meshes\\" + foot->model, Ogre::Vector3( 0, -24, -15), axis, Ogre::Radian(0), npcName + "foot2", addresses2, numbers); + } + else{ + cellRender.insertMesh ("meshes\\" + foot->model, Ogre::Vector3( 0, -4, -15), axis, Ogre::Radian(0), npcName + "foot", addresses, numbers); + + cellRender.insertMesh ("meshes\\" + foot->model, Ogre::Vector3( 0, -4, -15), axis, Ogre::Radian(0), npcName + "foot2", addresses2, numbers); + } addresses2[numbers] = npcName + "foot2"; addresses[numbers++] = npcName + "foot"; - cellRender.scaleMesh(Ogre::Vector3(1, -1, 1), addresses, numbers); + //cellRender.scaleMesh(Ogre::Vector3(1, -1, 1), addresses, numbers); } if (arm){ - cellRender.insertMesh("meshes\\" + arm->model, Ogre::Vector3(-12.5, 0, 104), Ogre::Vector3(1, 0, .75), Ogre::Radian(3.14), npcName + "upper arm", upperleft, uppernumbers); //1, 0,.75 - //cellRender.rotateMesh(Ogre::Vector3(1, 0, 0), Ogre::Radian (.45), upperarmpath, 2); //1, 0, 1 + //010 + cellRender.insertMesh("meshes\\" + arm->model, Ogre::Vector3(-12.5, 0, 104), Ogre::Vector3(0, 1, 0), Ogre::Radian(-3.14 / 2), npcName + "upper arm", upperleft, uppernumbers); //1, 0,.75 + //cellRender.rotateMesh(Ogre::Vector3(1, 0, 0), Ogre::Radian (.45), upperarmpath, 2); //-.5, 0, -.75 cellRender.insertMesh("meshes\\" + arm->model, Ogre::Vector3(12.5, 0, 105), Ogre::Vector3(-.5, 0, -.75), Ogre::Radian(3.14), npcName + "upper arm2", upperright, uppernumbers); upperleft[uppernumbers] = npcName + "upper arm"; upperright[uppernumbers++] = npcName + "upper arm2"; + cellRender.scaleMesh(Ogre::Vector3(1, -1, 1), upperleft, uppernumbers); //1 -1 1 + cellRender.rotateMesh(Ogre::Vector3(0, .1, 0), Ogre::Radian(3.14/2), upperleft, uppernumbers); } if (forearm) @@ -168,8 +184,29 @@ namespace MWClass if(hand) - cellRender.insertMesh("meshes\\" + hand->model, Ogre::Vector3(-50, 0, -120), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "hands", addresses, 4); //0, 100, -100 0,0,120 - + { + //std::cout << "WE FOUND A HAND\n"; + //-50, 0, -120 + cellRender.insertMesh("meshes\\" + hand->model, Ogre::Vector3(42, 1, -110), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "hand", upperleft, uppernumbers,false); //0, 100, -100 0,0,120 + cellRender.insertMesh("meshes\\" + hand->model, Ogre::Vector3(42, 1, -110), Ogre::Vector3(0, 0,0), Ogre::Radian(3.14), npcName + "hand2", upperright, uppernumbers, false); //0, 100, -100 0,0,120 + upperleft[uppernumbers] = npcName + "hand"; + upperright[uppernumbers++] = npcName + "hand2"; + //cellRender.rotateMesh(Ogre::Vector3(0, 0,0), Ogre::Radian(3.14), upperleft, uppernumbers); + cellRender.scaleMesh(Ogre::Vector3(1, -1, 1), upperleft, uppernumbers); + cellRender.scaleMesh(Ogre::Vector3(1, -1, 1), upperright, uppernumbers); + } + if(hands) + { + //std::cout << "WE FOUND HANDS\n"; + //-50, 0, -120 + cellRender.insertMesh("meshes\\" + hands->model, Ogre::Vector3(42, 1,-110), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "hand", upperleft, uppernumbers, false); //0, 100, -100 42, 0, -110 + //cellRender.insertMesh("meshes\\" + hands->model, Ogre::Vector3(42, 0,110), Ogre::Vector3(1, 0, 0), Ogre::Radian(3.14), npcName + "hand", upperleft, uppernumbers, false); //0, 100, -100 42, 0, -110 + cellRender.insertMesh("meshes\\" + hands->model, Ogre::Vector3(42, 1, -110), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "hand2", upperright, uppernumbers, false); //0, 100, -100 0,0,120 + upperleft[uppernumbers] = npcName + "hand"; + upperright[uppernumbers++] = npcName + "hand2"; + cellRender.scaleMesh(Ogre::Vector3(1, -1, 1), upperleft, uppernumbers); + cellRender.scaleMesh(Ogre::Vector3(1, -1, 1), upperright, uppernumbers); + } if(neck) { diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index ab52f76c4..d030da20a 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -5,10 +5,12 @@ namespace MWClass { + static bool isChest; + //static ;bool isChest = false; class Npc : public MWWorld::Class { public: - + virtual std::string getId (const MWWorld::Ptr& ptr) const; ///< Return ID of \a ptr diff --git a/apps/openmw/mwrender/cellimp.hpp b/apps/openmw/mwrender/cellimp.hpp index eeaa90cd9..e7a06ac6e 100644 --- a/apps/openmw/mwrender/cellimp.hpp +++ b/apps/openmw/mwrender/cellimp.hpp @@ -39,6 +39,7 @@ namespace MWRender virtual void rotateMesh(Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName[], int elements) = 0; /// insert a mesh related to the most recent insertBegin call. + virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements, bool translateFirst) = 0; virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements) = 0; virtual void insertMesh(const std::string &mesh) = 0; diff --git a/apps/openmw/mwrender/exterior.cpp b/apps/openmw/mwrender/exterior.cpp index 1ef096283..4c597ef7e 100644 --- a/apps/openmw/mwrender/exterior.cpp +++ b/apps/openmw/mwrender/exterior.cpp @@ -69,7 +69,7 @@ void ExteriorCellRender::rotateMesh(Ogre::Vector3 axis, Ogre::Radian angle, std } parent->rotate(axis, angle); } - +/* void ExteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements){ assert (insert); //insert-> @@ -91,7 +91,35 @@ void ExteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, //npcPart-> } +*/ +void ExteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements) +{ + insertMesh(mesh, vec, axis, angle, sceneNodeName, sceneParent, elements, true); +} +void ExteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements, bool translateFirst){ + assert (insert); + //insert-> + Ogre::SceneNode *parent = insert; + for (int i = 0; i < elements; i++){ + if(sceneParent[i] != "" && parent->getChild(sceneParent[i])) + parent = dynamic_cast (parent->getChild(sceneParent[i])); + } + + npcPart = parent->createChildSceneNode(sceneNodeName); + NIFLoader::load(mesh,0,0); + MovableObject *ent = scene.getMgr()->createEntity(mesh); + //ent->extr + \ + // MovableObject *ent2 = scene.getMgr()->createEntity(bounds + // ); + //ent-> + //std::cout << mesh << bounds << "\n"; + + npcPart->translate(vec); + npcPart->rotate(axis, angle); + npcPart->attachObject(ent); +} // insert a mesh related to the most recent insertBegin call. void ExteriorCellRender::scaleMesh(Ogre::Vector3 axis, std::string sceneNodeName[], int elements) diff --git a/apps/openmw/mwrender/exterior.hpp b/apps/openmw/mwrender/exterior.hpp index 2824719d9..89cad3bb8 100644 --- a/apps/openmw/mwrender/exterior.hpp +++ b/apps/openmw/mwrender/exterior.hpp @@ -66,7 +66,9 @@ namespace MWRender /// insert a mesh related to the most recent insertBegin call. virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements); - virtual void insertMesh(const std::string &mesh); + virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements, bool translateFirst); + + virtual void insertMesh(const std::string &mesh); virtual void rotateMesh(Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName[], int elements); virtual void scaleMesh(Ogre::Vector3 axis, std::string sceneNodeName[], int elements); diff --git a/apps/openmw/mwrender/interior.cpp b/apps/openmw/mwrender/interior.cpp index d194942cc..956231cfd 100644 --- a/apps/openmw/mwrender/interior.cpp +++ b/apps/openmw/mwrender/interior.cpp @@ -83,7 +83,11 @@ void InteriorCellRender::scaleMesh(Ogre::Vector3 axis, std::string sceneNodeNam } parent->scale(axis); } -void InteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements){ +void InteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements) +{ + insertMesh(mesh, vec, axis, angle, sceneNodeName, sceneParent, elements, true); +} +void InteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements, bool translateFirst){ assert (insert); //insert-> @@ -94,11 +98,26 @@ void InteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, } npcPart = parent->createChildSceneNode(sceneNodeName); - NIFLoader::load(mesh); - MovableObject *ent = scene.getMgr()->createEntity(mesh); - + //npcPart->showBoundingBox(true); + MeshPtr good = NIFLoader::load(mesh, 0, 0); + MovableObject *ent = scene.getMgr()->createEntity(good->getName()); + //ent->extr + + // MovableObject *ent2 = scene.getMgr()->createEntity(bounds + // ); + //ent-> + //std::cout << mesh << bounds << "\n"; + + if(translateFirst){ npcPart->translate(vec); npcPart->rotate(axis, angle); + } + else{ + + npcPart->rotate(axis, angle); + npcPart->translate(vec); + } + npcPart->attachObject(ent); } diff --git a/apps/openmw/mwrender/interior.hpp b/apps/openmw/mwrender/interior.hpp index 84a896987..abb4a80c2 100644 --- a/apps/openmw/mwrender/interior.hpp +++ b/apps/openmw/mwrender/interior.hpp @@ -29,7 +29,7 @@ namespace MWRender class InteriorCellRender : public CellRender, private CellRenderImp { - + //static bool isChest; static bool lightConst; static float lightConstValue; @@ -68,6 +68,7 @@ namespace MWRender /// insert a mesh related to the most recent insertBegin call. virtual void insertMesh(const std::string &mesh); virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements); + virtual void insertMesh(const std::string &mesh, Ogre::Vector3 vec, Ogre::Vector3 axis, Ogre::Radian angle, std::string sceneNodeName, std::string sceneParent[], int elements, bool translateFirst); /// insert a light related to the most recent insertBegin call. virtual void insertLight(float r, float g, float b, float radius); diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 4c0277f89..7e7233ba1 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -21,11 +21,14 @@ */ +//loadResource->handleNode->handleNiTriShape->createSubMesh + #include "ogre_nif_loader.hpp" #include #include #include +#include "../../apps/openmw/mwclass/npc.hpp" #include "../nif/nif_file.hpp" #include "../nif/node.hpp" #include "../nif/data.hpp" @@ -325,10 +328,15 @@ void NIFLoader::findRealTexture(String &texName) texName[len-1] = 's'; } +//Handle node at top + // Convert Nif::NiTriShape to Ogre::SubMesh, attached to the given // mesh. void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std::list &vertexBoneAssignments) { + + + // cout << "s:" << shape << "\n"; NiTriShapeData *data = shape->data.getPtr(); SubMesh *sub = mesh->createSubMesh(shape->name.toString()); @@ -468,8 +476,11 @@ static void vectorMul(const Matrix &A, float *C) C[i] = a*A.v[i].array[0] + b*A.v[i].array[1] + c*A.v[i].array[2]; } + void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bounds) { + //if( MWClass::Npc.isChest) + //cout << "t:" << shape << "\n"; assert(shape != NULL); // Interpret flags @@ -719,6 +730,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou void NIFLoader::handleNode(Nif::Node *node, int flags, const Transformation *trafo, BoundsFinder &bounds, Bone *parentBone) { + stack++; + //if( MWClass::isChest) + // cout << "u:" << node << "\n"; // Accumulate the flags from all the child nodes. This works for all // the flags we currently use, at least. flags |= node->flags; @@ -810,20 +824,156 @@ void NIFLoader::handleNode(Nif::Node *node, int flags, { NodeList &list = ((NiNode*)node)->children; int n = list.length(); - for (int i=0; itrafo, bounds, bone); } } else if (node->recType == RC_NiTriShape) + { // For shapes - handleNiTriShape(dynamic_cast(node), flags, bounds); + if((isChest && stack < 10) || (isHands && counter < 3) || !(isChest || isHands)){ //less than 10 + handleNiTriShape(dynamic_cast(node), flags, bounds); + + } + if(isHands){ + //cout << "Handling Shape, Stack " << stack <<"\n"; + counter++; + } + + } + + stack--; } void NIFLoader::loadResource(Resource *resource) { + stack = 0; + counter = 0; + std::string name = resource->getName(); + //std::cout <<"NAME:" << name; + //if(name.length() >= 20) + // {std::string split = name.substr(name.length() - 20, 20); + //if(name == + //std::cout <<"NAME:" << name << "LEN: " << name.length() << "\n"; + const std::string test ="meshes\\b\\B_N_Dark Elf_M_Skins.NIF"; + const std::string test2 ="meshes\\b\\B_N_Dark Elf_M_Skins.nif"; + const std::string test3 ="meshes\\b\\B_N_Redguard_F_Skins.NIF"; + const std::string test4 ="meshes\\b\\B_N_Redguard_F_Skins.nif"; + const std::string test5 ="meshes\\b\\B_N_Dark Elf_F_Skins.nif"; + const std::string test6 ="meshes\\b\\B_N_Redguard_M_Skins.nif"; + const std::string test7 ="meshes\\b\\B_N_Wood Elf_F_Skins.nif"; + const std::string test8 ="meshes\\b\\B_N_Wood Elf_M_Skins.nif"; + const std::string test9 ="meshes\\b\\B_N_Imperial_F_Skins.nif"; + const std::string test10 ="meshes\\b\\B_N_Imperial_M_Skins.nif"; + const std::string test11 ="meshes\\b\\B_N_Khajiit_F_Skins.nif"; + const std::string test12 ="meshes\\b\\B_N_Khajiit_M_Skins.nif"; + const std::string test13 ="meshes\\b\\B_N_Argonian_F_Skins.nif"; + const std::string test14 ="meshes\\b\\B_N_Argonian_M_Skins.nif"; + const std::string test15 ="meshes\\b\\B_N_Nord_F_Skins.nif"; + const std::string test16 ="meshes\\b\\B_N_Nord_M_Skins.nif"; + const std::string test17 ="meshes\\b\\B_N_Imperial_F_Skins.nif"; + const std::string test18 ="meshes\\b\\B_N_Imperial_M_Skins.nif"; + const std::string test19 ="meshes\\b\\B_N_Orc_F_Skins.nif"; + const std::string test20 ="meshes\\b\\B_N_Orc_M_Skins.nif"; + const std::string test21 ="meshes\\b\\B_N_Breton_F_Skins.nif"; + const std::string test22 ="meshes\\b\\B_N_Breton_M_Skins.nif"; + const std::string test23 ="meshes\\b\\B_N_High Elf_F_Skins.nif"; + const std::string test24 ="meshes\\b\\B_N_High Elf_M_Skins.nif"; + + //std::cout <<"LEN1:" << test.length() << "TEST: " << test << "\n"; + + + if(name.compare(test) == 0 || name.compare(test2) == 0 || name.compare(test3) == 0 || name.compare(test4) == 0 || + name.compare(test5) == 0 || name.compare(test6) == 0 || name.compare(test7) == 0 || name.compare(test8) == 0 || name.compare(test9) == 0 || + name.compare(test10) == 0 || name.compare(test11) == 0 || name.compare(test12) == 0 || name.compare(test13) == 0 || + name.compare(test14) == 0 || name.compare(test15) == 0 || name.compare(test16) == 0 || name.compare(test17) == 0 || + name.compare(test18) == 0 || name.compare(test19) == 0 || name.compare(test20) == 0 || name.compare(test21) == 0 || + name.compare(test22) == 0 || name.compare(test23) == 0 || name.compare(test24) + + ){ + //std::cout << "Welcome Chest\n"; + isChest = true; + if(name.compare(test11) == 0 || name.compare(test12) == 0 || name.compare(test13) == 0 || name.compare(test14) == 0) + { + isBeast = true; + std::cout << "Welcome Beast\n"; + } + else + isBeast = false; + } + else + isChest = false; + const std::string hands ="meshes\\b\\B_N_Dark Elf_M_Hands.1st.NIF"; + const std::string hands2 ="meshes\\b\\B_N_Dark Elf_F_Hands.1st.NIF"; + const std::string hands3 ="meshes\\b\\B_N_Redguard_M_Hands.1st.nif"; + const std::string hands4 ="meshes\\b\\B_N_Redguard_F_Hands.1st.nif"; + const std::string hands5 ="meshes\\b\\b_n_argonian_m_hands.1st.nif"; + const std::string hands6 ="meshes\\b\\b_n_argonian_f_hands.1st.nif"; + const std::string hands7 ="meshes\\b\\B_N_Breton_M_Hand.1st.NIF"; + const std::string hands8 ="meshes\\b\\B_N_Breton_F_Hands.1st.nif"; + const std::string hands9 ="meshes\\b\\B_N_High Elf_M_Hands.1st.nif"; + const std::string hands10 ="meshes\\b\\B_N_High Elf_F_Hands.1st.nif"; + const std::string hands11 ="meshes\\b\\B_N_Nord_M_Hands.1st.nif"; + const std::string hands12 ="meshes\\b\\B_N_Nord_F_Hands.1st.nif"; + const std::string hands13 ="meshes\\b\\b_n_khajiit_m_hands.1st.nif"; + const std::string hands14 ="meshes\\b\\b_n_khajiit_f_hands.1st.nif"; + const std::string hands15 ="meshes\\b\\B_N_Orc_M_Hands.1st.nif"; + const std::string hands16 ="meshes\\b\\B_N_Orc_F_Hands.1st.nif"; + const std::string hands17 ="meshes\\b\\B_N_Wood Elf_M_Hands.1st.nif"; + const std::string hands18 ="meshes\\b\\B_N_Wood Elf_F_Hands.1st.nif"; + const std::string hands19 ="meshes\\b\\B_N_Imperial_M_Hands.1st.nif"; + const std::string hands20 ="meshes\\b\\B_N_Imperial_F_Hands.1st.nif"; + if(name.compare(hands) == 0 || name.compare(hands2) == 0 || name.compare(hands3) == 0 || name.compare(hands4) == 0 || + name.compare(hands5) == 0 || name.compare(hands6) == 0 || name.compare(hands7) == 0 || name.compare(hands8) == 0 || + name.compare(hands9) == 0 || name.compare(hands10) == 0 || name.compare(hands11) == 0 || name.compare(hands12) == 0 || + name.compare(hands13) == 0 || name.compare(hands14) == 0 || name.compare(hands15) == 0 || name.compare(hands16) == 0 || + name.compare(hands17) == 0 || name.compare(hands18) == 0 || name.compare(hands19) == 0 || name.compare(hands20) == 0) + { + std::cout << "Welcome Hands1st\n"; + isHands = true; + isChest = false; + } + else + isHands = false; + /* + else if(name.compare(test3) == 0 || name.compare(test4) == 0) + { + std::cout << "\n\n\nWelcome FRedguard Chest\n\n\n"; + isChest = true; + } + else if(name.compare(test5) == 0 || name.compare(test6) == 0) + { + std::cout << "\n\n\nWelcome FRedguard Chest\n\n\n"; + isChest = true; + } + else if(name.compare(test7) == 0 || name.compare(test8) == 0) + { + std::cout << "\n\n\nWelcome FRedguard Chest\n\n\n"; + isChest = true; + } + else if(name.compare(test9) == 0 || name.compare(test10) == 0) + { + std::cout << "\n\n\nWelcome FRedguard Chest\n\n\n"; + isChest = true; + }*/ + + //if(split== "Skins.NIF") + // std::cout << "\nSPECIAL PROPS\n"; resourceName = ""; + MeshManager *m = MeshManager::getSingletonPtr(); + // Check if the resource already exists + //MeshPtr ptr = m->load(name, "custom"); + //cout << "THISNAME: " << ptr->getName() << "\n"; + //cout << "RESOURCE:"<< resource->getName(); mesh = 0; skel.setNull(); @@ -836,6 +986,7 @@ void NIFLoader::loadResource(Resource *resource) // Look it up resourceName = mesh->getName(); + //std::cout << resourceName << "\n"; if (!vfs->isFile(resourceName)) { @@ -887,18 +1038,48 @@ void NIFLoader::loadResource(Resource *resource) // mesh->setSkeletonName(getSkeletonName()); } -MeshPtr NIFLoader::load(const std::string &name, - const std::string &group) +MeshPtr NIFLoader::load(const std::string &name, + int pieces, int pieceIndex,const std::string &group) { MeshManager *m = MeshManager::getSingletonPtr(); - // Check if the resource already exists ResourcePtr ptr = m->getByName(name, group); - if (!ptr.isNull()) - return MeshPtr(ptr); + MeshPtr resize; + + if (!ptr.isNull()){ + //if(pieces > 1) + //cout << "It exists\n"; + resize = MeshPtr(ptr); + //resize->load(); + //resize->reload(); + } + else // Nope, create a new one. + { + //if(pieces > 1) + //cout << "Creating it\n"; + resize = MeshManager::getSingleton().createManual(name, group, NIFLoader::getSingletonPtr()); + //resize->load(); + //resize->reload(); + //return 0; + ResourcePtr ptr = m->getByName(name, group); + resize = MeshPtr(ptr); + + //NIFLoader::getSingletonPtr()-> + /*ResourcePtr ptr = m->getByName(name, group); + if (!ptr.isNull()){ + if(pieces > 1) + cout << "It exists\n"; + resize = MeshPtr(ptr);*/ + //return resize; + } + return resize; +} + - // Nope, create a new one. - return MeshManager::getSingleton().createManual(name, group, NIFLoader::getSingletonPtr()); +MeshPtr NIFLoader::load(const std::string &name, + const std::string &group) +{ + return load(name, 1, 0, group); } /* More code currently not in use, from the old D source. This was diff --git a/components/nifogre/ogre_nif_loader.hpp b/components/nifogre/ogre_nif_loader.hpp index 578308f0b..c071a0dcb 100644 --- a/components/nifogre/ogre_nif_loader.hpp +++ b/components/nifogre/ogre_nif_loader.hpp @@ -67,14 +67,19 @@ namespace Mangle class NIFLoader : Ogre::ManualResourceLoader { public: + static int numberOfMeshes; 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"); + static Ogre::MeshPtr load(const std::string &name, + const std::string &group="General"); + static Ogre::MeshPtr load(const std::string &name, + int pieces, int pieceIndex, const std::string &group="General"); + + Ogre::Vector3 convertVector3(const Nif::Vector& vec); Ogre::Quaternion convertRotation(const Nif::Matrix& rot); @@ -120,6 +125,13 @@ class NIFLoader : Ogre::ManualResourceLoader std::string resourceName; std::string resourceGroup; + bool isChest; + bool isBeast; + bool isHands; + int counter; + int numbers; + int stack; + // pointer to the ogre mesh which is currently build Ogre::Mesh *mesh; diff --git a/components/nifogre/oldnpccode.txt b/components/nifogre/oldnpccode.txt new file mode 100644 index 000000000..eec9ef11e --- /dev/null +++ b/components/nifogre/oldnpccode.txt @@ -0,0 +1,256 @@ +/* //This is old + if (pieces > 1){ //pieces > 1 + MeshPtr justChest = MeshManager::getSingleton().createManual("justchest", group, NIFLoader::getSingletonPtr()); + Ogre::AxisAlignedBox bounds = resize->getBounds(); + Ogre::Vector3 width2 = bounds.getCorner(bounds.NEAR_RIGHT_BOTTOM) - bounds.getCorner(bounds.NEAR_LEFT_BOTTOM); + Ogre::Vector3 depth2 = (bounds.getCorner(bounds.FAR_LEFT_BOTTOM) - bounds.getCorner(bounds.NEAR_LEFT_BOTTOM)); + Ogre::Vector3 height2 = bounds.getCorner(bounds.NEAR_LEFT_TOP) - bounds.getCorner(bounds.NEAR_LEFT_BOTTOM); + cout << "Width:" << width2; cout << "Height:" << height2; cout << "Depth:" << depth2; + /*int width = bounds.getMaximum().x - bounds.getMinimum().x; + int height = bounds.getMaximum().y - bounds.getMinimum().y; + int depth = bounds.getMaximum().z - bounds.getMinimum().z; + int xinc = width / pieces; + int yinc = height / pieces; + int zinc = depth / pieces; + int xmincorner = bounds.getMinimum().x + xinc*pieceIndex; + int ymincorner = bounds.getMinimum().y + yinc*pieceIndex; + int zmincorner = bounds.getMinimum().z + xinc*pieceIndex;*/ + //Ogre::Vector3 bottom_left = bounds.getCorner(bounds.NEAR_LEFT_BOTTOM) + (width2 / pieces) * pieceIndex; //width2 + //Ogre::Vector3 top_right = bottom_left + (width2 / pieces) + height2 + depth2; + //Ogre::AxisAlignedBox set = AxisAlignedBox ( Ogre::Vector3(xmincorner, bounds.getMinimum().y, bounds.getMinimum().z), Ogre::Vector3(xmincorner + xinc, bounds.getMaximum().y, bounds.getMaximum().z)); + //Ogre::AxisAlignedBox set = bounds;//AxisAlignedBox(bottom_left, top_right); + //bounds.setMinimumX(xmincorner); + //bounds.setMaximumX(xmincorner + xinc); + //bounds.setMinimumY(ymincorner); + //bounds.setMaximumY(ymincorner + yinc); + //bounds.setMinimumZ(zmincorner); + //bounds.setMaximumZ(zmincorner + zinc); + //bounds.setMinimumY(bounds.getMinimum().y); + //bounds.setMaximumY( bounds.getMaximum().y; + //resize->_setBounds(set, true); + //resize->reload(); + + //Ogre::Mesh::SubMeshIterator subMeshIterator = resize->getSubMeshIterator(); + /*Ogre::Vector3* point; + Ogre::SubMesh* subMesh; + + + + size_t vertex_count = 0; + Vector3* vertices; + size_t index_count = 0; + unsigned* indices; + Vector3 position = Vector3::ZERO; + Quaternion orient = Quaternion::IDENTITY; + Vector3 scale = Vector3::UNIT_SCALE; + + + // int vertex_count = 0; + //int index_count = 0; + + bool added_shared = false; + size_t current_offset = vertex_count; + size_t shared_offset = vertex_count; + size_t next_offset = vertex_count; + size_t index_offset = index_count; + size_t prev_vert = vertex_count; + size_t prev_ind = index_count; + // Calculate how many vertices and indices we're going to need + /* + std::cout <<"FIRST CYCLE\n"; + for(int i = 0;i < resize->getNumSubMeshes();i++) + { + std::cout<< "WEHAVEMESHES\n"; + SubMesh* submesh = resize->getSubMesh(i); + + // We only need to add the shared vertices once + if(submesh->useSharedVertices) + { + if(!added_shared) + { + VertexData* vertex_data = resize->sharedVertexData; + vertex_count += vertex_data->vertexCount; + added_shared = true; + } + } + else + { + VertexData* vertex_data = submesh->vertexData; + vertex_count += vertex_data->vertexCount; + } + + // Add the indices + Ogre::IndexData* index_data = submesh->indexData; + index_count += index_data->indexCount; + } + + */ +// Vector3* vertices; + // Allocate space for the vertices and indices + /*vertices = new Vector3[vertex_count]; + indices = new unsigned[index_count]; + + int meshcounter = 0; + added_shared = false; + std::cout <<"SECOND CYCLE: " << resize->getNumSubMeshes() << "\n"; + // Run through the submeshes again, adding the data into the arrays + int i; + for(i = 0;i < resize->getNumSubMeshes();i++) + { + + SubMesh* submesh = resize->getSubMesh(i); + + Ogre::VertexData* vertex_data = submesh->useSharedVertices ? resize->sharedVertexData : submesh->vertexData; + /* + if((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared)) + { + if(submesh->useSharedVertices) + { + added_shared = true; + shared_offset = current_offset; + } + + const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION); + Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource()); + unsigned char* vertex = static_cast(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL)); + Ogre::Real* pReal; + + bool onepointexists = true; + Vector3 lastpoint; + for(size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize()) + { + posElem->baseVertexPointerToElement(vertex, &pReal); + + Vector3 pt; + pt.x = (*(pReal++)); + pt.y = (*(pReal++)); + pt.z = (*(pReal++)); + //cout << "X:" << pt.x << "Y:" <getMaterialName() << "\n"; + + if(meshcounter <= 2) + resize->destroySubMesh(i); + else if(meshcounter > 3 && meshcounter < 7) + resize->destroySubMesh(i); + //submesh->setMaterialName("BaseWhiteNoLighting"); //red + //submesh->updateMaterialUsingTextureAliases(); + //resize-> + meshcounter++; + //delete submesh; + //reakb; + }*/ + /* + vbuf->unlock(); + next_offset += vertex_data->vertexCount; + } + + Ogre::IndexData* index_data = submesh->indexData; + + size_t numTris = index_data->indexCount / 3; + unsigned short* pShort; + unsigned int* pInt; + Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer; + bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT); + if (use32bitindexes) pInt = static_cast(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); + else pShort = static_cast(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY)); + + for(size_t k = 0; k < numTris; ++k) + { + size_t offset = (submesh->useSharedVertices)?shared_offset:current_offset; + + unsigned int vindex = use32bitindexes? *pInt++ : *pShort++; + indices[index_offset + 0] = vindex + offset; + vindex = use32bitindexes? *pInt++ : *pShort++; + indices[index_offset + 1] = vindex + offset; + vindex = use32bitindexes? *pInt++ : *pShort++; + indices[index_offset + 2] = vindex + offset; + + index_offset += 3; + } + ibuf->unlock(); + current_offset = next_offset;*/ + //if (i == 3) //i!=3 i!=5 + //{ + //cout << "RETURNINGJUST\n"; + //SubMesh* test = + //test = resize->getSubMesh(i); + // cout << "s:" << shape << "\n"; + //NiTriShapeData *data = shape->data.getPtr(); + // SubMesh *sub = justChest->createSubMesh(name + "2"); + //sub = resize->getSubMesh(i); + + // int nextBuf = 0; + + // This function is just one long stream of Ogre-barf, but it works + // great. + + // Add vertices + //int numVerts = data->vertices.length / 3; + //sub->vertexData = new VertexData(); + //sub->vertexData->vertexCount = numVerts; + + //justChest->load(); + //return resize; + //} + // 0 hand thumb + // 1 hand thumb no chest on dunmer + //} + //resize->destroySubMesh(1); + /* while (subMeshIterator.hasMoreElements()) + { + resize->getNum + //resize->d + std::cout << "CHEST"; + subMesh = subMeshIterator.getNext();*/ + //std::vector::type test = + //std::vector::iterator fileIter = subMesh->extremityPoints.begin(); + + //std::vector::type test = subMesh->extremityPoints; + //void* pData = subMesh->vertexData->vertexBufferBinding->getBuffer(1)->lock(0, 1000, HardwareBuffer::HBL_DISCARD); + + + // if(set.contains( subMesh->vertexData->vertexStart)) + //delete subMesh; + //subMeshIterator.getNext(); + //delete[] subMesh; + //subMesh->extremityPoints.clear(); + //subMesh->mLodFaceList.clear(); + //resize->destroySubMesh(subMesh->indexData->indexStart); + //resize->destroySubMesh(subMesh->indexData->); + //subMesh-> + //std::cout << "THIS" << subMesh; + ///} + //subMesh->vertexData->vertexBufferBinding->getBuffer(0)->readData(subMesh->vertexData->vertexStart, sizeof Ogre::Vector3, point); + + + + //boost::filesystem::directory_iterator dir_iter(dir), dir_end; + + //return resize; From 1896a6a2e8e234ed1b2fcde6683a484db6fb3366 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Mon, 13 Dec 2010 16:01:52 -0500 Subject: [PATCH 11/12] Preliminary npcs4 --- apps/openmw/mwclass/npc.cpp | 24 ++++++++++++++++++------ components/nifogre/ogre_nif_loader.cpp | 2 +- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 8005acab4..ed4185dfb 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -104,6 +104,7 @@ namespace MWClass if (groin){ cellRender.insertMesh("meshes\\" + groin->model, pos2, axis, Ogre::Radian(3.14), npcName + "groin", addresses, numbers); + std::cout <<"GROIN" << groin->model <<"\n"; addresses2[numbers] = npcName + "groin"; addresses[numbers++] = npcName + "groin"; } @@ -187,8 +188,14 @@ namespace MWClass { //std::cout << "WE FOUND A HAND\n"; //-50, 0, -120 - cellRender.insertMesh("meshes\\" + hand->model, Ogre::Vector3(42, 1, -110), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "hand", upperleft, uppernumbers,false); //0, 100, -100 0,0,120 - cellRender.insertMesh("meshes\\" + hand->model, Ogre::Vector3(42, 1, -110), Ogre::Vector3(0, 0,0), Ogre::Radian(3.14), npcName + "hand2", upperright, uppernumbers, false); //0, 100, -100 0,0,120 + //std::cout << "WE FOUND HANDS\n"; + std::string pass; + if(hand->model.compare("b\\B_N_Dark Elf_F_Hands.1st.NIF")==0 && bodyRaceID.compare("b_n_dark elf_m_") == 0) + pass = "b\\B_N_Dark Elf_M_Hands.1st.NIF"; + else + pass = hand->model; + cellRender.insertMesh("meshes\\" + pass, Ogre::Vector3(42, 1, -110), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "hand", upperleft, uppernumbers,false); //0, 100, -100 0,0,120 + cellRender.insertMesh("meshes\\" + pass, Ogre::Vector3(42, 1, -110), Ogre::Vector3(0, 0,0), Ogre::Radian(3.14), npcName + "hand2", upperright, uppernumbers, false); //0, 100, -100 0,0,120 upperleft[uppernumbers] = npcName + "hand"; upperright[uppernumbers++] = npcName + "hand2"; //cellRender.rotateMesh(Ogre::Vector3(0, 0,0), Ogre::Radian(3.14), upperleft, uppernumbers); @@ -197,11 +204,16 @@ namespace MWClass } if(hands) { - //std::cout << "WE FOUND HANDS\n"; - //-50, 0, -120 - cellRender.insertMesh("meshes\\" + hands->model, Ogre::Vector3(42, 1,-110), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "hand", upperleft, uppernumbers, false); //0, 100, -100 42, 0, -110 + std::string pass; + if(hands->model.compare("b\\B_N_Redguard_F_Hands.1st.nif")==0 && bodyRaceID.compare("b_n_redguard_m_") == 0) + pass = "b\\B_N_Redguard_M_Hands.1st.nif"; + else if(hands->model.compare("b\\B_N_Imperial_M_Hands.1st.nif") == 0 && bodyRaceID.compare("b_n_nord_m_") == 0) + pass = "b\\B_N_Nord_M_Hands.1st.nif"; + else + pass =hands->model; //-50, 0, -120 + cellRender.insertMesh("meshes\\" + pass, Ogre::Vector3(42, 1,-110), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "hand", upperleft, uppernumbers, false); //0, 100, -100 42, 0, -110 //cellRender.insertMesh("meshes\\" + hands->model, Ogre::Vector3(42, 0,110), Ogre::Vector3(1, 0, 0), Ogre::Radian(3.14), npcName + "hand", upperleft, uppernumbers, false); //0, 100, -100 42, 0, -110 - cellRender.insertMesh("meshes\\" + hands->model, Ogre::Vector3(42, 1, -110), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "hand2", upperright, uppernumbers, false); //0, 100, -100 0,0,120 + cellRender.insertMesh("meshes\\" + pass, Ogre::Vector3(42, 1, -110), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "hand2", upperright, uppernumbers, false); //0, 100, -100 0,0,120 upperleft[uppernumbers] = npcName + "hand"; upperright[uppernumbers++] = npcName + "hand2"; cellRender.scaleMesh(Ogre::Vector3(1, -1, 1), upperleft, uppernumbers); diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 7e7233ba1..4386e6d1a 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -897,7 +897,7 @@ void NIFLoader::loadResource(Resource *resource) name.compare(test10) == 0 || name.compare(test11) == 0 || name.compare(test12) == 0 || name.compare(test13) == 0 || name.compare(test14) == 0 || name.compare(test15) == 0 || name.compare(test16) == 0 || name.compare(test17) == 0 || name.compare(test18) == 0 || name.compare(test19) == 0 || name.compare(test20) == 0 || name.compare(test21) == 0 || - name.compare(test22) == 0 || name.compare(test23) == 0 || name.compare(test24) + name.compare(test22) == 0 || name.compare(test23) == 0 || name.compare(test24) == 0 ){ //std::cout << "Welcome Chest\n"; From 60601682cdee7b8fd27f4f55108b331589a8cf23 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Tue, 21 Dec 2010 21:45:54 -0500 Subject: [PATCH 12/12] Beast races fixed --- apps/openmw/mwclass/npc.cpp | 42 +++++++++--- apps/openmw/mwrender/exterior.cpp | 65 ++++++++++++++++-- apps/openmw/mwrender/interior.cpp | 61 ++++++++++++++++- components/nifogre/ogre_nif_loader.cpp | 91 ++++++++++++++++++++------ components/nifogre/ogre_nif_loader.hpp | 6 +- 5 files changed, 223 insertions(+), 42 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index ed4185dfb..de8b6ffff 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -93,10 +93,14 @@ namespace MWClass const ESM::BodyPart *knee = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "knee"); const ESM::BodyPart *ankle = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "ankle"); const ESM::BodyPart *foot = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "foot"); + const ESM::BodyPart *feet = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "feet"); + const ESM::BodyPart *tail = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "tail"); const ESM::BodyPart *wrist = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "wrist"); const ESM::BodyPart *forearm = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "forearm"); const ESM::BodyPart *hand = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "hand.1st"); const ESM::BodyPart *hands = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "hands.1st"); + + std::cout << "RACE" << bodyRaceID << "\n"; Ogre::Vector3 pos2 = Ogre::Vector3( 0, .5, 75); @@ -104,10 +108,13 @@ namespace MWClass if (groin){ cellRender.insertMesh("meshes\\" + groin->model, pos2, axis, Ogre::Radian(3.14), npcName + "groin", addresses, numbers); - std::cout <<"GROIN" << groin->model <<"\n"; addresses2[numbers] = npcName + "groin"; addresses[numbers++] = npcName + "groin"; } + if (tail) { + cellRender.insertMesh("tail\\" + tail->model, Ogre::Vector3(0 , 0, -76), axis, Ogre::Radian(3.14), npcName + "tail", addresses, numbers, "tail"); + //std::cout << "TAIL\n"; + } //addresses[1] = npcName + "groin"; if(upperleg){ @@ -135,19 +142,25 @@ namespace MWClass addresses[numbers++] = npcName + "ankle"; } if(foot){ - //std::cout << "RACE" << bodyRaceID << "\n"; - if(bodyRaceID.compare("b_n_khajiit_m_") == 0 || bodyRaceID.compare("b_n_khajiit_f_") == 0) + if(bodyRaceID.compare("b_n_khajiit_m_") == 0) { - std::cout << "BEASTRACE\n"; - cellRender.insertMesh ("meshes\\" + foot->model, Ogre::Vector3( 0, -24, -15), axis, Ogre::Radian(0), npcName + "foot", addresses, numbers); - - cellRender.insertMesh ("meshes\\" + foot->model, Ogre::Vector3( 0, -24, -15), axis, Ogre::Radian(0), npcName + "foot2", addresses2, numbers); + feet = foot; } - else{ - cellRender.insertMesh ("meshes\\" + foot->model, Ogre::Vector3( 0, -4, -15), axis, Ogre::Radian(0), npcName + "foot", addresses, numbers); + else + { + cellRender.insertMesh ("meshes\\" + foot->model, Ogre::Vector3( 0, -4, -15), axis, Ogre::Radian(0), npcName + "foot", addresses, numbers); - cellRender.insertMesh ("meshes\\" + foot->model, Ogre::Vector3( 0, -4, -15), axis, Ogre::Radian(0), npcName + "foot2", addresses2, numbers); + cellRender.insertMesh ("meshes\\" + foot->model, Ogre::Vector3( 0, -4, -15), axis, Ogre::Radian(0), npcName + "foot2", addresses2, numbers); + addresses2[numbers] = npcName + "foot2"; + addresses[numbers++] = npcName + "foot"; } + //cellRender.scaleMesh(Ogre::Vector3(1, -1, 1), addresses, numbers); + } + if(feet){ + + cellRender.insertMesh ("foot\\" + feet->model, Ogre::Vector3( 7, 4, -16), axis, Ogre::Radian(3.14), npcName + "foot", addresses, numbers); //9, 0, -14 + + cellRender.insertMesh ("foot\\" + feet->model, Ogre::Vector3( 7, 4, -16), axis, Ogre::Radian(3.14), npcName + "foot2", addresses2, numbers); addresses2[numbers] = npcName + "foot2"; addresses[numbers++] = npcName + "foot"; //cellRender.scaleMesh(Ogre::Vector3(1, -1, 1), addresses, numbers); @@ -177,6 +190,14 @@ namespace MWClass // std::cout << npcName << "has no forearm"; if (wrist) { + if(upperleft[uppernumbers - 1].compare(npcName + "upper arm") == 0) + { + cellRender.insertMesh("meshes\\b\\B_N_Argonian_M_Forearm.nif", Ogre::Vector3(-12.5, 0, 0), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "forearm", upperleft, uppernumbers); + cellRender.insertMesh("meshes\\b\\B_N_Argonian_M_Forearm.nif", Ogre::Vector3(-12.5, 0, 0), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "forearm2", upperright, uppernumbers); + upperleft[uppernumbers] = npcName + "forearm"; + upperright[uppernumbers++] = npcName + "forearm2"; + + } cellRender.insertMesh("meshes\\" + wrist->model, Ogre::Vector3(-9.5, 0, 0), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "wrist", upperleft, uppernumbers); cellRender.insertMesh("meshes\\" + wrist->model, Ogre::Vector3(-9.5, 0, 0), Ogre::Vector3(0, 0, 0), Ogre::Radian(3.14), npcName + "wrist2", upperright, uppernumbers); upperleft[uppernumbers] = npcName + "wrist"; @@ -220,6 +241,7 @@ namespace MWClass cellRender.scaleMesh(Ogre::Vector3(1, -1, 1), upperright, uppernumbers); } + //neck will reset chest counter if(neck) { cellRender.insertMesh ("meshes\\" + neck->model, Ogre::Vector3( 0, 0, 120), axis, Ogre::Radian(3.14), npcName + "neck", neckandup, neckNumbers); diff --git a/apps/openmw/mwrender/exterior.cpp b/apps/openmw/mwrender/exterior.cpp index 4c597ef7e..28986d6d7 100644 --- a/apps/openmw/mwrender/exterior.cpp +++ b/apps/openmw/mwrender/exterior.cpp @@ -8,6 +8,9 @@ #include #include "mwscene.hpp" +#include +#include "mwscene.hpp" +#include using namespace MWRender; using namespace Ogre; @@ -107,18 +110,66 @@ void ExteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, } npcPart = parent->createChildSceneNode(sceneNodeName); - NIFLoader::load(mesh,0,0); + MeshPtr good2 = NIFLoader::load(mesh); + MovableObject *ent = scene.getMgr()->createEntity(mesh); - //ent->extr - \ - // MovableObject *ent2 = scene.getMgr()->createEntity(bounds - // ); - //ent-> - //std::cout << mesh << bounds << "\n"; + npcPart->translate(vec); npcPart->rotate(axis, angle); npcPart->attachObject(ent); + + Ogre::MeshManager *m = MeshManager::getSingletonPtr(); + const std::string beast1 ="meshes\\b\\B_N_Khajiit_F_Skins.nif"; + const std::string beast2 ="meshes\\b\\B_N_Khajiit_M_Skins.nif"; + const std::string beast3 ="meshes\\b\\B_N_Argonian_F_Skins.nif"; + const std::string beast4 ="meshes\\b\\B_N_Argonian_M_Skins.nif"; + + const std::string beasttail1 ="tail\\b\\B_N_Khajiit_F_Skins.nif"; + const std::string beasttail2 ="tail\\b\\B_N_Khajiit_M_Skins.nif"; + const std::string beasttail3 ="tail\\b\\B_N_Argonian_F_Skins.nif"; + const std::string beasttail4 ="tail\\b\\B_N_Argonian_M_Skins.nif"; + + const std::string beastfoot1 ="foot\\b\\B_N_Khajiit_F_Skins.nif"; + const std::string beastfoot2 ="foot\\b\\B_N_Khajiit_M_Skins.nif"; + const std::string beastfoot3 ="foot\\b\\B_N_Argonian_F_Skins.nif"; + const std::string beastfoot4 ="foot\\b\\B_N_Argonian_M_Skins.nif"; + if(mesh.compare(beast1) == 0 && m->getByName(beasttail1).isNull()) + { + //std::cout << "CLONINGKHAJIITF\n"; + good2->reload(); + MeshPtr tail = good2->clone(beasttail1); + good2->reload(); + MeshPtr foot = good2->clone(beastfoot1); + good2->reload(); + } + else if(mesh.compare(beast2) == 0 && m->getByName(beasttail2).isNull()) + { + //std::cout << "CLONINGKHAJIITM\n"; + good2->reload(); + MeshPtr tail = good2->clone(beasttail2); + good2->reload(); + MeshPtr foot = good2->clone(beastfoot2); + good2->reload(); + } + else if(mesh.compare(beast3) == 0 && m->getByName(beasttail3).isNull()) + { + //std::cout << "CLONINGARGONIANF\n"; + good2->reload(); + MeshPtr tail = good2->clone(beasttail3); + good2->reload(); + MeshPtr foot = good2->clone(beastfoot3); + good2->reload(); + } + else if(mesh.compare(beast4) == 0 && m->getByName(beasttail4).isNull()) + { + //std::cout << "CLONINGARGONIANM\n"; + good2->reload(); + MeshPtr tail = good2->clone(beasttail4); + good2->reload(); + MeshPtr foot = good2->clone(beastfoot4); + good2->reload(); + } } // insert a mesh related to the most recent insertBegin call. diff --git a/apps/openmw/mwrender/interior.cpp b/apps/openmw/mwrender/interior.cpp index 956231cfd..1f1eac2af 100644 --- a/apps/openmw/mwrender/interior.cpp +++ b/apps/openmw/mwrender/interior.cpp @@ -9,6 +9,10 @@ #include #include "mwscene.hpp" +#include +#include + +#include using namespace MWRender; using namespace Ogre; @@ -99,8 +103,10 @@ void InteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, npcPart = parent->createChildSceneNode(sceneNodeName); //npcPart->showBoundingBox(true); - MeshPtr good = NIFLoader::load(mesh, 0, 0); - MovableObject *ent = scene.getMgr()->createEntity(good->getName()); + + MeshPtr good2 = NIFLoader::load(mesh); + + MovableObject *ent = scene.getMgr()->createEntity(mesh); //ent->extr // MovableObject *ent2 = scene.getMgr()->createEntity(bounds @@ -119,6 +125,57 @@ void InteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec, } npcPart->attachObject(ent); + Ogre::MeshManager *m = MeshManager::getSingletonPtr(); + const std::string beast1 ="meshes\\b\\B_N_Khajiit_F_Skins.nif"; + const std::string beast2 ="meshes\\b\\B_N_Khajiit_M_Skins.nif"; + const std::string beast3 ="meshes\\b\\B_N_Argonian_F_Skins.nif"; + const std::string beast4 ="meshes\\b\\B_N_Argonian_M_Skins.nif"; + + const std::string beasttail1 ="tail\\b\\B_N_Khajiit_F_Skins.nif"; + const std::string beasttail2 ="tail\\b\\B_N_Khajiit_M_Skins.nif"; + const std::string beasttail3 ="tail\\b\\B_N_Argonian_F_Skins.nif"; + const std::string beasttail4 ="tail\\b\\B_N_Argonian_M_Skins.nif"; + + const std::string beastfoot1 ="foot\\b\\B_N_Khajiit_F_Skins.nif"; + const std::string beastfoot2 ="foot\\b\\B_N_Khajiit_M_Skins.nif"; + const std::string beastfoot3 ="foot\\b\\B_N_Argonian_F_Skins.nif"; + const std::string beastfoot4 ="foot\\b\\B_N_Argonian_M_Skins.nif"; + if(mesh.compare(beast1) == 0 && m->getByName(beasttail1).isNull()) + { + //std::cout << "CLONINGKHAJIITF\n"; + good2->reload(); + MeshPtr tail = good2->clone(beasttail1); + good2->reload(); + MeshPtr foot = good2->clone(beastfoot1); + good2->reload(); + } + else if(mesh.compare(beast2) == 0 && m->getByName(beasttail2).isNull()) + { + //std::cout << "CLONINGKHAJIITM\n"; + good2->reload(); + MeshPtr tail = good2->clone(beasttail2); + good2->reload(); + MeshPtr foot = good2->clone(beastfoot2); + good2->reload(); + } + else if(mesh.compare(beast3) == 0 && m->getByName(beasttail3).isNull()) + { + //std::cout << "CLONINGARGONIANF\n"; + good2->reload(); + MeshPtr tail = good2->clone(beasttail3); + good2->reload(); + MeshPtr foot = good2->clone(beastfoot3); + good2->reload(); + } + else if(mesh.compare(beast4) == 0 && m->getByName(beasttail4).isNull()) + { + //std::cout << "CLONINGARGONIANM\n"; + good2->reload(); + MeshPtr tail = good2->clone(beasttail4); + good2->reload(); + MeshPtr foot = good2->clone(beastfoot4); + good2->reload(); + } } void InteriorCellRender::insertMesh(const std::string &mesh) diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 4386e6d1a..fc205d387 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -55,7 +55,6 @@ using namespace Mangle::VFS; NIFLoader& NIFLoader::getSingleton() { static NIFLoader instance; - return instance; } @@ -334,8 +333,6 @@ void NIFLoader::findRealTexture(String &texName) // mesh. void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std::list &vertexBoneAssignments) { - - // cout << "s:" << shape << "\n"; NiTriShapeData *data = shape->data.getPtr(); SubMesh *sub = mesh->createSubMesh(shape->name.toString()); @@ -429,7 +426,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std for (std::list::iterator it = vertexBoneAssignments.begin(); it != vertexBoneAssignments.end(); it++) { - sub->addBoneAssignment(*it); + sub->addBoneAssignment(*it); } } @@ -782,6 +779,8 @@ void NIFLoader::handleNode(Nif::Node *node, int flags, if (!skel.isNull()) //if there is a skeleton { std::string name = node->name.toString(); + //if (isBeast && isChest) + // std::cout << "NAME: " << name << "\n"; // Quick-n-dirty workaround for the fact that several // bones may have the same name. if(!skel->hasBone(name)) @@ -840,14 +839,48 @@ void NIFLoader::handleNode(Nif::Node *node, int flags, else if (node->recType == RC_NiTriShape) { // For shapes - if((isChest && stack < 10) || (isHands && counter < 3) || !(isChest || isHands)){ //less than 10 - handleNiTriShape(dynamic_cast(node), flags, bounds); + /*For Beast Skins, Shape Bone Names + Tri Left Foot + Tri Right Foot + Tri Tail + Tri Chest + */ + if((isChest && stack < 10 ) || (isHands && counter < 3) || !(isChest || isHands)){ //(isBeast && isChest && stack < 10 && counter == skincounter ) + std::string name = node->name.toString(); + //if (isChest) + //std::cout << "NAME: " << name << "\n"; + + if(isChest && isBeast && skincounter == 0 && name.compare("Tri Chest") == 0){ + //std::cout <<"BEASTCHEST1\n"; + handleNiTriShape(dynamic_cast(node), flags, bounds); + skincounter++; + } + else if(isChest && isBeast && skincounter == 1 && name.compare("Tri Tail") == 0){ + //std::cout <<"BEASTCHEST2\n"; + handleNiTriShape(dynamic_cast(node), flags, bounds); + skincounter++; + } + else if(isChest && isBeast && skincounter == 2 && name.compare("Tri Left Foot") == 0){ + //std::cout <<"BEASTCHEST3\n"; + handleNiTriShape(dynamic_cast(node), flags, bounds); + skincounter=1000; + } + else if (!isChest || !isBeast) + { + handleNiTriShape(dynamic_cast(node), flags, bounds); + } + //if(isBeast && isChest) + //cout << "Handling Shape, Stack " << stack <<"\n"; + + + + counter++; } - if(isHands){ + /*if(isHands){ //cout << "Handling Shape, Stack " << stack <<"\n"; counter++; - } + }*/ } @@ -856,9 +889,16 @@ void NIFLoader::handleNode(Nif::Node *node, int flags, void NIFLoader::loadResource(Resource *resource) { + if(skincounter == 1000) + skincounter = 0; stack = 0; counter = 0; std::string name = resource->getName(); + if(resourceName.compare(name) != 0) + { + skincounter = 0; + resourceName = name; + } //std::cout <<"NAME:" << name; //if(name.length() >= 20) // {std::string split = name.substr(name.length() - 20, 20); @@ -905,7 +945,7 @@ void NIFLoader::loadResource(Resource *resource) if(name.compare(test11) == 0 || name.compare(test12) == 0 || name.compare(test13) == 0 || name.compare(test14) == 0) { isBeast = true; - std::cout << "Welcome Beast\n"; + //std::cout << "Welcome Beast\n"; } else isBeast = false; @@ -938,12 +978,14 @@ void NIFLoader::loadResource(Resource *resource) name.compare(hands13) == 0 || name.compare(hands14) == 0 || name.compare(hands15) == 0 || name.compare(hands16) == 0 || name.compare(hands17) == 0 || name.compare(hands18) == 0 || name.compare(hands19) == 0 || name.compare(hands20) == 0) { - std::cout << "Welcome Hands1st\n"; + //std::cout << "Welcome Hands1st\n"; isHands = true; isChest = false; } else isHands = false; + + /* else if(name.compare(test3) == 0 || name.compare(test4) == 0) { @@ -1039,25 +1081,40 @@ void NIFLoader::loadResource(Resource *resource) } MeshPtr NIFLoader::load(const std::string &name, - int pieces, int pieceIndex,const std::string &group) + const std::string &group) { MeshManager *m = MeshManager::getSingletonPtr(); // Check if the resource already exists ResourcePtr ptr = m->getByName(name, group); MeshPtr resize; - if (!ptr.isNull()){ + const std::string beast1 ="meshes\\b\\B_N_Khajiit_F_Skins.nif"; + const std::string beast2 ="meshes\\b\\B_N_Khajiit_M_Skins.nif"; + const std::string beast3 ="meshes\\b\\B_N_Argonian_F_Skins.nif"; + const std::string beast4 ="meshes\\b\\B_N_Argonian_M_Skins.nif"; + + const std::string beasttail1 ="tail\\b\\B_N_Khajiit_F_Skins.nif"; + const std::string beasttail2 ="tail\\b\\B_N_Khajiit_M_Skins.nif"; + const std::string beasttail3 ="tail\\b\\B_N_Argonian_F_Skins.nif"; + const std::string beasttail4 ="tail\\b\\B_N_Argonian_M_Skins.nif"; + + if (!ptr.isNull()){ + //if(pieces > 1) //cout << "It exists\n"; - resize = MeshPtr(ptr); + resize = MeshPtr(ptr); //resize->load(); //resize->reload(); } else // Nope, create a new one. { + resize = MeshManager::getSingleton().createManual(name, group, NIFLoader::getSingletonPtr()); + //cout <<"EXISTING" << name << "\n"; + //if(pieces > 1) //cout << "Creating it\n"; - resize = MeshManager::getSingleton().createManual(name, group, NIFLoader::getSingletonPtr()); + + //resize->load(); //resize->reload(); //return 0; @@ -1076,12 +1133,6 @@ MeshPtr NIFLoader::load(const std::string &name, } -MeshPtr NIFLoader::load(const std::string &name, - const std::string &group) -{ - return load(name, 1, 0, group); -} - /* More code currently not in use, from the old D source. This was used in the first attempt at loading NIF meshes, where each submesh in the file was given a separate bone in a skeleton. Unfortunately diff --git a/components/nifogre/ogre_nif_loader.hpp b/components/nifogre/ogre_nif_loader.hpp index c071a0dcb..b2a6b50fd 100644 --- a/components/nifogre/ogre_nif_loader.hpp +++ b/components/nifogre/ogre_nif_loader.hpp @@ -76,15 +76,13 @@ class NIFLoader : Ogre::ManualResourceLoader static Ogre::MeshPtr load(const std::string &name, const std::string &group="General"); - static Ogre::MeshPtr load(const std::string &name, - int pieces, int pieceIndex, const std::string &group="General"); Ogre::Vector3 convertVector3(const Nif::Vector& vec); Ogre::Quaternion convertRotation(const Nif::Matrix& rot); private: - NIFLoader() : resourceGroup("General") {} + NIFLoader() : resourceGroup("General") { skincounter = 0; resourceName = "";} NIFLoader(NIFLoader& n) {} void warn(std::string msg); @@ -125,9 +123,11 @@ class NIFLoader : Ogre::ManualResourceLoader std::string resourceName; std::string resourceGroup; + int skincounter; bool isChest; bool isBeast; bool isHands; + bool isFeet; int counter; int numbers; int stack;