Merge branch 'directories' into next

Conflicts:
	components/files/multidircollection.hpp
	components/nifogre/ogre_nif_loader.hpp
actorid
Marc Zinnschlag 14 years ago
commit bc92b7b1fa

@ -7,6 +7,7 @@
#include <utility>
#include <OgreVector3.h>
#include <Ogre.h>
#include "components/esm/records.hpp"
#include <components/esm_store/cell_store.hpp>
@ -92,6 +93,8 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
std::string effect;
MWWorld::Ptr::CellStore *current = mEnvironment.mWorld->getPlayer().getPlayer().getCell();
//If the region has changed
if(!(current->cell->data.flags & current->cell->Interior) && timer.elapsed() >= 10){
timer.restart();
@ -248,6 +251,11 @@ void OMW::Engine::loadBSA()
std::cout << "Adding " << iter->second.string() << std::endl;
addBSA (iter->second.string());
}
std::string m = mDataDir.string();
std::cout << "Data dir" << m << "\n";
addDir(m, mFSStrict);
}
// add resources directory
@ -345,9 +353,6 @@ void OMW::Engine::go()
mOgre.configure(!isFile(ogreCfg.c_str()), cfgUserDir, plugCfg, false);
addResourcesDirectory (mDataDir / "Meshes");
addResourcesDirectory (mDataDir / "Textures");
// This has to be added BEFORE MyGUI is initialized, as it needs
// to find core.xml here.
addResourcesDirectory(mResDir / "mygui");
@ -384,7 +389,7 @@ void OMW::Engine::go()
mOgre.getCamera(),
mEnvironment.mWorld->getStore(),
(mDataDir),
mUseSound);
mUseSound, mFSStrict);
// Create script system
mScriptContext = new MWScript::CompilerContext (MWScript::CompilerContext::Type_Full,

@ -34,7 +34,7 @@ namespace MWClass
if (!model.empty())
{
MWRender::Rendering rendering (cellRender, ref->ref);
cellRender.insertMesh ("meshes\\" + model);
cellRender.insertMesh("meshes\\" + model);
cellRender.insertActorPhysics();
ref->mData.setHandle (rendering.end (ref->mData.isEnabled()));
}

@ -95,8 +95,7 @@ namespace MWClass
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");
@ -113,8 +112,6 @@ namespace MWClass
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);
if (groin){
@ -124,10 +121,9 @@ namespace MWClass
}
if (tail) {
cellRender.insertMesh("tail\\" + tail->model, Ogre::Vector3(0 , 0, -76), axis, kOgrePi, npcName + "tail", addresses, numbers, "tail");
//std::cout << "TAIL\n";
}
//addresses[1] = npcName + "groin";
if(upperleg){
cellRender.insertMesh ("meshes\\" + upperleg->model, Ogre::Vector3( 6, 0, -16), axis, kOgrePi, npcName + "upper leg", addresses, numbers); //-18
cellRender.insertMesh ("meshes\\" + upperleg->model, Ogre::Vector3( -6, 0, -16), axis, Ogre::Radian(0), npcName + "upper leg2", addresses2, numbers);
@ -218,9 +214,6 @@ namespace MWClass
if(hand)
{
//std::cout << "WE FOUND A HAND\n";
//-50, 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";
@ -230,7 +223,6 @@ namespace MWClass
cellRender.insertMesh("meshes\\" + pass, Ogre::Vector3(42, 1, -110), Ogre::Vector3(0, 0,0), kOgrePi, 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), kOgrePi, upperleft, uppernumbers);
cellRender.scaleMesh(Ogre::Vector3(1, -1, 1), upperleft, uppernumbers);
cellRender.scaleMesh(Ogre::Vector3(1, -1, 1), upperright, uppernumbers);
}
@ -244,7 +236,6 @@ namespace MWClass
else
pass =hands->model; //-50, 0, -120
cellRender.insertMesh("meshes\\" + pass, Ogre::Vector3(42, 1,-110), Ogre::Vector3(0, 0, 0), kOgrePi, 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), kOgrePi, npcName + "hand", upperleft, uppernumbers, false); //0, 100, -100 42, 0, -110
cellRender.insertMesh("meshes\\" + pass, Ogre::Vector3(42, 1, -110), Ogre::Vector3(0, 0, 0), kOgrePi, npcName + "hand2", upperright, uppernumbers, false); //0, 100, -100 0,0,120
upperleft[uppernumbers] = npcName + "hand";
upperright[uppernumbers++] = npcName + "hand2";

@ -6,6 +6,7 @@
#include "OgreColourValue.h"
#include <OgreMath.h>
#include <Ogre.h>
namespace Ogre
{
@ -74,6 +75,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, 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);

@ -182,11 +182,11 @@ void InteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec,
void InteriorCellRender::insertMesh(const std::string &mesh)
{
assert (insert);
assert (insert);
NIFLoader::load(mesh);
MovableObject *ent = scene.getMgr()->createEntity(mesh);
insert->attachObject(ent);
NIFLoader::load(mesh);
MovableObject *ent = scene.getMgr()->createEntity(mesh);
insert->attachObject(ent);
if (mInsertMesh.empty())
mInsertMesh = mesh;

@ -84,20 +84,25 @@ namespace MWSound
// finding. It takes DOS paths (any case, \\ slashes or / slashes)
// relative to the sound dir, and translates them into full paths
// of existing files in the filesystem, if they exist.
bool FSstrict;
FileFinder::FileFinder files;
FileFinder::FileFinderStrict strict;
FileFinder::FileFinder musicpath;
FileFinder::FileFinderStrict musicpathStrict;
SoundImpl(Ogre::Root *root, Ogre::Camera *camera,
const ESMS::ESMStore &str,
const std::string &soundDir)
const std::string &soundDir, const std::string &musicDir, bool fsstrict)
: mgr(new OEManager(SoundFactoryPtr(new SOUND_FACTORY)))
, updater(mgr)
, cameraTracker(mgr)
, store(str)
, files(soundDir)
, files(soundDir), strict(soundDir)
,musicpath(musicDir), musicpathStrict(musicDir)
{
FSstrict = fsstrict;
cout << "Sound output: " << SOUND_OUT << endl;
cout << "Sound decoder: " << SOUND_IN << endl;
// Attach the camera to the camera tracker
cameraTracker.followCamera(camera);
@ -111,6 +116,8 @@ namespace MWSound
cameraTracker.unfollowCamera();
}
static std::string toMp3(std::string str)
{
std::string::size_type i = str.rfind('.');
@ -122,28 +129,76 @@ namespace MWSound
return str;
}
bool hasFile(const std::string &str)
bool hasFile(const std::string &str, bool music = false)
{
if(files.has(str)) return true;
// Not found? Try with .mp3
return files.has(toMp3(str));
if(FSstrict == false)
{
if(music)
{
if(musicpath.has(str)) return true;
// Not found? Try with .mp3
return musicpath.has(toMp3(str));
}
else
{
if(files.has(str)) return true;
return files.has(toMp3(str));
}
}
else
{
if(music)
{
if(musicpathStrict.has(str)) return true;
// Not found? Try with .mp3
return musicpathStrict.has(toMp3(str));
}
else
{
if(strict.has(str)) return true;
return strict.has(toMp3(str));
}
}
}
// Convert a Morrowind sound path (eg. Fx\funny.wav) to full path
// with proper slash conversion (eg. datadir/Sound/Fx/funny.wav)
std::string convertPath(const std::string &str)
std::string convertPath(const std::string &str, bool music = false)
{
// Search and return
if(files.has(str))
return files.lookup(str);
// Try mp3 if the wav wasn't found
std::string mp3 = toMp3(str);
if(files.has(mp3))
return files.lookup(mp3);
if(FSstrict == false)
{
// Search and return
if(music && musicpath.has(str))
return musicpath.lookup(str);
else if(files.has(str))
return files.lookup(str);
// Try mp3 if the wav wasn't found
std::string mp3 = toMp3(str);
if(music && musicpath.has(mp3))
return musicpath.lookup(mp3);
else if(files.has(mp3))
return files.lookup(mp3);
}
else
{
if(music && musicpathStrict.has(str))
return musicpathStrict.lookup(str);
else if(strict.has(str))
return strict.lookup(str);
// Try mp3 if the wav wasn't found
std::string mp3 = toMp3(str);
if(music && musicpathStrict.has(mp3))
return musicpathStrict.lookup(mp3);
else if(strict.has(str))
return strict.lookup(mp3);
}
// Give up
return "";
// Give up
return "";
}
// Convert a soundId to file name, and modify the volume
@ -304,15 +359,31 @@ namespace MWSound
}
};
void SoundManager::streamMusicFull (const std::string& filename)
{
if(!mData) return;
// Play the sound and tell it to stream, if possible. TODO:
// Store the reference, the jukebox will need to check status,
// control volume etc.
if (mData->music)
mData->music->stop();
mData->music = mData->mgr->load(filename);
mData->music->setStreaming(true);
mData->music->setVolume(0.4);
mData->music->play();
}
SoundManager::SoundManager(Ogre::Root *root, Ogre::Camera *camera,
const ESMS::ESMStore &store,
boost::filesystem::path dataDir,
bool useSound)
: mData(NULL)
bool useSound, bool fsstrict)
: mData(NULL), fsStrict (fsstrict)
{
MP3Lookup(dataDir / "Music/Explore/");
if(useSound)
mData = new SoundImpl(root, camera, store, (dataDir / "Sound").string());
mData = new SoundImpl(root, camera, store, (dataDir / "Sound").string(), (dataDir / "Music").string(), fsstrict);
}
SoundManager::~SoundManager()
@ -321,6 +392,16 @@ namespace MWSound
delete mData;
}
void SoundManager::streamMusic(const std::string& filename)
{
if(mData->hasFile(filename, true))
{
std::string fullpath = mData->convertPath(filename, true);
streamMusicFull(fullpath);
}
}
void SoundManager::MP3Lookup(boost::filesystem::path dir)
{
boost::filesystem::directory_iterator dir_iter(dir), dir_end;
@ -353,7 +434,7 @@ namespace MWSound
try
{
std::cout << "Playing " << music << "\n";
streamMusic(music);
streamMusicFull(music);
}
catch(std::exception &e)
{
@ -397,21 +478,6 @@ namespace MWSound
return !mData->isPlaying(ptr, "_say_sound");
}
void SoundManager::streamMusic (const std::string& filename)
{
if(!mData) return;
// Play the sound and tell it to stream, if possible. TODO:
// Store the reference, the jukebox will need to check status,
// control volume etc.
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)
{

@ -27,19 +27,28 @@ namespace MWSound
// Hide implementation details - engine.cpp is compiling
// enough as it is.
struct SoundImpl;
SoundImpl *mData;
std::vector<boost::filesystem::path> files;
bool fsStrict;
void streamMusicFull (const std::string& filename);
///< Play a soundifle
/// \param absolute filename
public:
SoundManager(Ogre::Root*, Ogre::Camera*, const ESMS::ESMStore &store,
boost::filesystem::path dataDir, bool useSound);
boost::filesystem::path dataDir, bool useSound, bool fsstrict);
~SoundManager();
void streamMusic(const std::string& filename);
///< Play a soundifle
/// \param filename name of a sound file in "Music/" in the data directory.
void startRandomTitle();
void MP3Lookup(boost::filesystem::path dir);
//struct SoundImpl;
bool isMusicPlaying();
SoundImpl getMData();
@ -51,9 +60,7 @@ namespace MWSound
bool sayDone (MWWorld::Ptr reference) const;
///< Is actor not speaking?
void streamMusic (const std::string& filename);
///< Play a soundifle
/// \param filename name of a sound file in "Music/" in the data directory.
void playSound (const std::string& soundId, float volume, float pitch);
///< Play a sound, independently of 3D-position

@ -23,6 +23,7 @@
#include "bsa_archive.hpp"
#include <OgreFileSystem.h>
#include <OgreArchive.h>
#include <OgreArchiveFactory.h>
#include <OgreArchiveManager.h>
@ -32,7 +33,186 @@
using namespace Ogre;
using namespace Mangle::Stream;
struct ciLessBoost : std::binary_function<std::string, std::string, bool>
{
bool operator() (const std::string & s1, const std::string & s2) const {
//case insensitive version of is_less
return lexicographical_compare(s1, s2, boost::algorithm::is_iless());
}
};
static bool fsstrict = false;
/// An OGRE Archive wrapping a BSAFile archive
class DirArchive: public Ogre::FileSystemArchive
{
boost::filesystem::path currentdir;
std::map<std::string, std::vector<std::string>, ciLessBoost> m;
unsigned int cutoff;
bool comparePortion(std::string file1, std::string file2, int start, int size) const
{
for(int i = start; i < start+size; i++)
{
char one = file1.at(i);
char two = file2.at(i);
if(tolower(one) != tolower(two) )
return false;
}
return true;
}
public:
DirArchive(const String& name)
: FileSystemArchive(name, "Dir"), currentdir (name)
{
mType = "Dir";
std::string s = name;
cutoff = s.size() + 1;
if(fsstrict == false)
populateMap(currentdir);
}
void populateMap(boost::filesystem::path d){
//need to cut off first
boost::filesystem::directory_iterator dir_iter(d), dir_end;
std::vector<std::string> filesind;
boost::filesystem::path f;
for(;dir_iter != dir_end; dir_iter++)
{
if(boost::filesystem::is_directory(*dir_iter))
populateMap(*dir_iter);
else
{
f = *dir_iter;
std::string s = f.string();
std::string small;
if(cutoff < s.size())
small = s.substr(cutoff, s.size() - cutoff);
else
small = s.substr(cutoff - 1, s.size() - cutoff);
filesind.push_back(small);
}
}
std::string small;
std::string original = d.string();
if(cutoff < original.size())
small = original.substr(cutoff, original.size() - cutoff);
else
small = original.substr(cutoff - 1, original.size() - cutoff);
m[small] = filesind;
}
bool isCaseSensitive() const { return fsstrict; }
// The archive is loaded in the constructor, and never unloaded.
void load() {}
void unload() {}
bool exists(const String& filename) {
std::string copy = filename;
for (unsigned int i = 0; i < filename.size(); i++)
{
if(copy.at(i) == '\\' ){
copy.replace(i, 1, "/");
}
}
if(copy.at(0) == '\\' || copy.at(0) == '/')
{
copy.erase(0, 1);
}
if(fsstrict == true)
{
//std::cout << "fsstrict " << copy << "\n";
return FileSystemArchive::exists(copy);
}
int last = copy.size() - 1;
int i = last;
for (;last >= 0; i--)
{
if(copy.at(i) == '/' || copy.at(i) == '\\')
break;
}
std::string folder = copy.substr(0, i); //folder with no slash
std::vector<std::string>& current = m[folder];
for(std::vector<std::string>::iterator iter = current.begin(); iter != current.end(); iter++)
{
if(comparePortion(*iter, copy, i + 1, copy.size() - i -1) == true){
return FileSystemArchive::exists(*iter);
}
}
return false;
}
DataStreamPtr open(const String& filename, bool readonly = true) const
{
std::map<std::string, std::vector<std::string>, ciLessBoost> mlocal = m;
std::string copy = filename;
for (unsigned int i = 0; i < filename.size(); i++)
{
if(copy.at(i) == '\\' ){
copy.replace(i, 1, "/");
}
}
if(copy.at(0) == '\\' || copy.at(0) == '/')
{
copy.erase(0, 1);
}
if(fsstrict == true)
{
return FileSystemArchive::open(copy, readonly);
}
int last = copy.size() - 1;
int i = last;
for (;last >= 0; i--)
{
if(copy.at(i) == '/' || copy.at(i) == '\\')
break;
}
std::string folder = copy.substr(0, i); //folder with no slash
std::vector<std::string> current = mlocal[folder];
for(std::vector<std::string>::iterator iter = current.begin(); iter != current.end(); iter++)
{
if(comparePortion(*iter, copy, i + 1, copy.size() - i -1) == true){
return FileSystemArchive::open(*iter, readonly);
}
}
DataStreamPtr p;
return p;
}
};
class BSAArchive : public Archive
{
BSAFile arc;
@ -145,7 +325,27 @@ public:
void destroyInstance( Archive* arch) { delete arch; }
};
class DirArchiveFactory : public FileSystemArchiveFactory
{
public:
const String& getType() const
{
static String name = "Dir";
return name;
}
Archive *createInstance( const String& name )
{
return new DirArchive(name);
}
void destroyInstance( Archive* arch) { delete arch; }
};
static bool init = false;
static bool init2 = false;
static void insertBSAFactory()
{
if(!init)
@ -155,6 +355,15 @@ static void insertBSAFactory()
}
}
static void insertDirFactory()
{
if(!init2)
{
ArchiveManager::getSingleton().addArchiveFactory( new DirArchiveFactory );
init2 = true;
}
}
// The function below is the only publicly exposed part of this file
void addBSA(const std::string& name, const std::string& group)
@ -163,3 +372,11 @@ void addBSA(const std::string& name, const std::string& group)
ResourceGroupManager::getSingleton().
addResourceLocation(name, "BSA", group);
}
void addDir(const std::string& name, const bool& fs, const std::string& group)
{
fsstrict = fs;
insertDirFactory();
ResourceGroupManager::getSingleton().
addResourceLocation(name, "Dir", group);
}

@ -22,6 +22,9 @@
*/
#include <string>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include <algorithm>
#ifndef _BSA_ARCHIVE_H_
#define _BSA_ARCHIVE_H_
@ -29,5 +32,6 @@
/// Add the given BSA file as an input archive in the Ogre resource
/// system.
void addBSA(const std::string& file, const std::string& group="General");
void addDir(const std::string& file, const bool& fs, const std::string& group="General");
#endif

@ -20,9 +20,9 @@ class FileFinderT
void add(const boost::filesystem::path &pth)
{
std::string file = pth.string();
std::string key = file.substr(cut);
owner->table[key] = file;
std::string file = pth.string();
std::string key = file.substr(cut);
owner->table[key] = file;
}
};
@ -50,17 +50,18 @@ public:
bool has(const std::string& file) const
{
return table.find(file) != table.end();
return table.find(file) != table.end();
}
// Find the full path from a relative path.
const std::string &lookup(const std::string& file) const
{
return table.find(file)->second;
return table.find(file)->second;
}
};
// The default is to use path_less for equality checks
typedef FileFinderT<path_less> FileFinder;
typedef FileFinderT<path_slash> FileFinderStrict;
}
#endif

@ -44,6 +44,41 @@ struct path_less
return compareString(a.c_str(), b.c_str()) < 0;
}
};
struct path_slash
{
int compareChar(char a, char b) const
{
if(a>b) return 1;
else if(a<b) return -1;
return 0;
}
int comparePathChar(char a, char b) const
{
if(a == '\\') a = '/';
if(b == '\\') b = '/';
return compareChar(a,b);
}
int compareString(const char *a, const char *b) const
{
while(*a && *b)
{
int i = comparePathChar(*a,*b);
if(i != 0) return i;
a++; b++;
}
// At this point, one or both of the chars is a null terminator.
// Normal char comparison will get the correct final result here.
return compareChar(*a,*b);
}
bool operator() (const std::string& a, const std::string& b) const
{
return compareString(a.c_str(), b.c_str()) < 0;
}
};
}
#endif

@ -23,11 +23,12 @@ namespace Files
return left<right;
std::size_t min = std::min (left.length(), right.length());
std::locale loc;
for (std::size_t i=0; i<min; ++i)
{
char l = std::tolower (left[i],std::locale());
char r = std::tolower (right[i],std::locale());
char l = std::tolower (left[i], loc);
char r = std::tolower (right[i], loc);
if (l<r)
return true;

@ -25,6 +25,7 @@
#define _NIF_DATA_H_
#include "controlled.hpp"
#include <iostream>
namespace Nif
{
@ -433,67 +434,70 @@ public:
class NiKeyframeData : public Record
{
public:
void read(NIFFile *nif)
{
// Rotations first
int count = nif->getInt();
if(count)
{
int type = nif->getInt();
if(type == 1)
nif->skip(count*4*5); // time + quaternion
else if(type == 3)
nif->skip(count*4*8); // rot1 + tension+bias+continuity
else if(type == 4)
{
for(int j=0;j<count;j++)
{
nif->getFloat(); // time
for(int i=0; i<3; i++)
{
int cnt = nif->getInt();
int type = nif->getInt();
if(type == 1)
nif->skip(cnt*4*2); // time + unknown
else if(type == 2)
nif->skip(cnt*4*4); // time + unknown vector
else nif->fail("Unknown sub-rotation type");
}
}
}
else nif->fail("Unknown rotation type in NiKeyframeData");
}
// Then translation
count = nif->getInt();
if(count)
{
int type = nif->getInt();
if(type == 1) nif->getFloatLen(count*4); // time + translation
else if(type == 2)
nif->getFloatLen(count*10); // trans1 + forward + backward
else if(type == 3)
nif->getFloatLen(count*7); // trans1 + tension,bias,continuity
else nif->fail("Unknown translation type");
}
// Finally, scalings
count = nif->getInt();
if(count)
{
int type = nif->getInt();
int size = 0;
if(type == 1) size = 2; // time+scale
else if(type == 2) size = 4; // 1 + forward + backward (floats)
else if(type == 3) size = 5; // 1 + tbc
else nif->fail("Unknown scaling type");
nif->getFloatLen(count*size);
}
}
public:
void read(NIFFile *nif)
{
// Rotations first
int count = nif->getInt();
if(count)
{
int type = nif->getInt();
if(type == 1)
nif->skip(count*4*5); // time + quaternion
else if(type == 3)
nif->skip(count*4*8); // rot1 + tension+bias+continuity
else if(type == 4)
{
for(int j=0;j<count;j++)
{
nif->getFloat(); // time
for(int i=0; i<3; i++)
{
int cnt = nif->getInt();
int type = nif->getInt();
if(type == 1)
nif->skip(cnt*4*2); // time + unknown
else if(type == 2)
nif->skip(cnt*4*4); // time + unknown vector
else nif->fail("Unknown sub-rotation type");
}
}
}
else nif->fail("Unknown rotation type in NiKeyframeData");
}
// Then translation
count = nif->getInt();
if(count)
{
int type = nif->getInt();
if(type == 1)
nif->getFloatLen(count*4); // time + translation
else if(type == 2)
nif->getFloatLen(count*10); // trans1 + forward + backward
else if(type == 3)
nif->getFloatLen(count*7); // trans1 + tension,bias,continuity
else nif->fail("Unknown translation type");
}
// Finally, scalings
count = nif->getInt();
if(count)
{
int type = nif->getInt();
int size = 0;
if(type == 1) size = 2; // time+scale
else if(type == 2) size = 4; // 1 + forward + backward (floats)
else if(type == 3) size = 5; // 1 + tbc
else nif->fail("Unknown scaling type");
nif->getFloatLen(count*size);
}
}
};
} // Namespace

@ -81,11 +81,11 @@ Vector3 NIFLoader::convertVector3(const Nif::Vector& vec)
Quaternion NIFLoader::convertRotation(const Nif::Matrix& rot)
{
Real matrix[3][3];
for (int i=0; i<3; i++)
for (int j=0; j<3; j++)
matrix[i][j] = rot.v[i].array[j];
return Quaternion(Matrix3(matrix));
}
@ -265,7 +265,7 @@ void NIFLoader::createMaterial(const String &name,
}
else
pass->setDepthWriteEnabled(true); */
// Add transparency if NiAlphaProperty was present
if (alphaFlags != -1)
@ -346,16 +346,16 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
sub->vertexData = new VertexData();
sub->vertexData->vertexCount = numVerts;
sub->useSharedVertices = false;
VertexDeclaration *decl = sub->vertexData->vertexDeclaration;
decl->addElement(nextBuf, 0, VET_FLOAT3, VES_POSITION);
HardwareVertexBufferSharedPtr vbuf =
HardwareBufferManager::getSingleton().createVertexBuffer(
VertexElement::getTypeSize(VET_FLOAT3),
numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
vbuf->writeData(0, vbuf->getSizeInBytes(), data->vertices.ptr, true);
VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding;
bind->setBinding(nextBuf++, vbuf);
@ -692,7 +692,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
if (verIndex < data->normals.length)
{
Vector3 absNormalsPos = vecRot * Vector3(ptrNormals + verIndex *3);
for (int j=0; j<3; j++)
(ptrNormals + verIndex*3)[j] = absNormalsPos[j];
}
@ -852,7 +852,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
}
for (; i<n; i++)
{
if (list.has(i))
handleNode(&list[i], flags, node->trafo, bounds, bone);
}
@ -867,7 +867,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
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";
@ -894,15 +894,15 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
//if(isBeast && isChest)
//cout << "Handling Shape, Stack " << stack <<"\n";
counter++;
}
/*if(isHands){
//cout << "Handling Shape, Stack " << stack <<"\n";
counter++;
}*/
}
stack--;
@ -923,7 +923,7 @@ void NIFLoader::loadResource(Resource *resource)
//std::cout <<"NAME:" << name;
//if(name.length() >= 20)
// {std::string split = name.substr(name.length() - 20, 20);
//if(name ==
//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";
@ -951,15 +951,15 @@ void NIFLoader::loadResource(Resource *resource)
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) == 0
){
//std::cout << "Welcome Chest\n";
isChest = true;
@ -1028,7 +1028,7 @@ void NIFLoader::loadResource(Resource *resource)
std::cout << "\n\n\nWelcome FRedguard Chest\n\n\n";
isChest = true;
}*/
//if(split== "Skins.NIF")
// std::cout << "\nSPECIAL PROPS\n";
resourceName = "";
@ -1100,14 +1100,14 @@ void NIFLoader::loadResource(Resource *resource)
// mesh->setSkeletonName(getSkeletonName());
}
MeshPtr NIFLoader::load(const std::string &name,
MeshPtr NIFLoader::load(const std::string &name,
const std::string &group)
{
MeshManager *m = MeshManager::getSingletonPtr();
// Check if the resource already exists
ResourcePtr ptr = m->getByName(name, group);
MeshPtr resize;
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";
@ -1118,8 +1118,8 @@ MeshPtr NIFLoader::load(const std::string &name,
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 (!ptr.isNull()){
//if(pieces > 1)
//cout << "It exists\n";
resize = MeshPtr(ptr);
@ -1130,17 +1130,17 @@ MeshPtr NIFLoader::load(const std::string &name,
{
resize = MeshManager::getSingleton().createManual(name, group, NIFLoader::getSingletonPtr());
//cout <<"EXISTING" << name << "\n";
//if(pieces > 1)
//cout << "Creating it\n";
//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()){
@ -1151,7 +1151,7 @@ MeshPtr NIFLoader::load(const std::string &name,
}
return resize;
}
/* 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

@ -73,11 +73,11 @@ class NIFLoader : Ogre::ManualResourceLoader
virtual void loadResource(Ogre::Resource *resource);
static Ogre::MeshPtr load(const std::string &name,
static Ogre::MeshPtr load(const std::string &name,
const std::string &group="General");
Ogre::Vector3 convertVector3(const Nif::Vector& vec);
Ogre::Quaternion convertRotation(const Nif::Matrix& rot);
@ -113,7 +113,7 @@ class NIFLoader : Ogre::ManualResourceLoader
{
return resourceName + ".skel";
}
// This is the interface to the Ogre resource system. It allows us to
// load NIFs from BSAs, in the file system and in any other place we
// tell Ogre to look (eg. in zip or rar files.) It's also used to
@ -131,8 +131,7 @@ class NIFLoader : Ogre::ManualResourceLoader
int counter;
int numbers;
int stack;
std::multimap<std::string,std::string> MaterialMap;
std::multimap<std::string,std::string> MaterialMap;
// pointer to the ogre mesh which is currently build
Ogre::Mesh *mesh;

Loading…
Cancel
Save