Remove the NIF loader and code to manually transform the vertices

This currently breaks just about everything. They should come back as it's all
reimplemented, though.
actorid
Chris Robinson 13 years ago
parent 9995dff943
commit 386ac56bda

@ -75,11 +75,8 @@ void OMW::Engine::executeLocalScripts()
localScripts.setIgnore (MWWorld::Ptr()); localScripts.setIgnore (MWWorld::Ptr());
} }
void OMW::Engine::setAnimationVerbose(bool animverbose){ void OMW::Engine::setAnimationVerbose(bool animverbose)
if(animverbose){ {
NifOgre::NIFLoader::getSingletonPtr()->setOutputAnimFiles(true);
NifOgre::NIFLoader::getSingletonPtr()->setVerbosePath(mCfgMgr.getLogPath().string());
}
} }
bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)

@ -6,13 +6,13 @@
#include <OgreBone.h> #include <OgreBone.h>
#include <OgreSubMesh.h> #include <OgreSubMesh.h>
namespace MWRender{ namespace MWRender {
std::map<std::string, int> Animation::mUniqueIDs;
Animation::Animation(OEngine::Render::OgreRenderer& _rend) std::map<std::string, int> Animation::mUniqueIDs;
Animation::Animation(OEngine::Render::OgreRenderer& _rend)
: insert(NULL) : insert(NULL)
, mRend(_rend) , mRend(_rend)
, vecRotPos()
, time(0.0f) , time(0.0f)
, startTime(0.0f) , startTime(0.0f)
, stopTime(0.0f) , stopTime(0.0f)
@ -21,96 +21,82 @@ namespace MWRender{
, tindexI() , tindexI()
, shapeNumber(0) , shapeNumber(0)
, shapeIndexI() , shapeIndexI()
, shapes(NULL)
, transformations(NULL) , transformations(NULL)
, textmappings(NULL) , textmappings(NULL)
, base(NULL) , base(NULL)
{ {
} }
Animation::~Animation()
{
}
std::string Animation::getUniqueID(std::string mesh){
int counter;
std::string copy = mesh;
std::transform(copy.begin(), copy.end(), copy.begin(), ::tolower);
if(mUniqueIDs.find(copy) == mUniqueIDs.end()){
counter = mUniqueIDs[copy] = 0;
}
else{
mUniqueIDs[copy] = mUniqueIDs[copy] + 1;
counter = mUniqueIDs[copy];
}
std::stringstream out; Animation::~Animation()
if(counter > 99 && counter < 1000) {
out << "0";
else if(counter > 9)
out << "00";
else
out << "000";
out << counter;
return out.str();
} }
void Animation::startScript(std::string groupname, int mode, int loops){
void Animation::startScript(std::string groupname, int mode, int loops)
{
//If groupname is recognized set animate to true //If groupname is recognized set animate to true
//Set the start time and stop time //Set the start time and stop time
//How many times to loop //How many times to loop
if(groupname == "all"){ if(groupname == "all")
{
animate = loops; animate = loops;
time = startTime; time = startTime;
} }
else if(textmappings){ else if(textmappings)
{
std::string startName = groupname + ": loop start"; std::string startName = groupname + ": loop start";
std::string stopName = groupname + ": loop stop"; std::string stopName = groupname + ": loop stop";
bool first = false; bool first = false;
if(loops > 1){ if(loops > 1)
{
startName = groupname + ": loop start"; startName = groupname + ": loop start";
stopName = groupname + ": loop stop"; stopName = groupname + ": loop stop";
for(std::map<std::string, float>::iterator iter = textmappings->begin(); iter != textmappings->end(); iter++){ for(std::map<std::string, float>::iterator iter = textmappings->begin(); iter != textmappings->end(); iter++)
{
std::string current = iter->first.substr(0, startName.size()); std::string current = iter->first.substr(0, startName.size());
std::transform(current.begin(), current.end(), current.begin(), ::tolower); std::transform(current.begin(), current.end(), current.begin(), ::tolower);
std::string current2 = iter->first.substr(0, stopName.size()); std::string current2 = iter->first.substr(0, stopName.size());
std::transform(current2.begin(), current2.end(), current2.begin(), ::tolower); std::transform(current2.begin(), current2.end(), current2.begin(), ::tolower);
if(current == startName){ if(current == startName)
{
startTime = iter->second; startTime = iter->second;
animate = loops; animate = loops;
time = startTime; time = startTime;
first = true; first = true;
} }
if(current2 == stopName){ if(current2 == stopName)
{
stopTime = iter->second; stopTime = iter->second;
if(first) if(first)
break; break;
} }
} }
} }
if(!first){
if(!first)
{
startName = groupname + ": start"; startName = groupname + ": start";
stopName = groupname + ": stop"; stopName = groupname + ": stop";
for(std::map<std::string, float>::iterator iter = textmappings->begin(); iter != textmappings->end(); iter++){ for(std::map<std::string, float>::iterator iter = textmappings->begin(); iter != textmappings->end(); iter++)
{
std::string current = iter->first.substr(0, startName.size()); std::string current = iter->first.substr(0, startName.size());
std::transform(current.begin(), current.end(), current.begin(), ::tolower); std::transform(current.begin(), current.end(), current.begin(), ::tolower);
std::string current2 = iter->first.substr(0, stopName.size()); std::string current2 = iter->first.substr(0, stopName.size());
std::transform(current2.begin(), current2.end(), current2.begin(), ::tolower); std::transform(current2.begin(), current2.end(), current2.begin(), ::tolower);
if(current == startName){ if(current == startName)
{
startTime = iter->second; startTime = iter->second;
animate = loops; animate = loops;
time = startTime; time = startTime;
first = true; first = true;
} }
if(current2 == stopName){ if(current2 == stopName)
{
stopTime = iter->second; stopTime = iter->second;
if(first) if(first)
break; break;
@ -120,308 +106,73 @@ namespace MWRender{
} }
} }
void Animation::stopScript(){
animate = 0;
}
void Animation::handleShapes(std::vector<Nif::NiTriShapeCopy>* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel){
shapeNumber = 0;
if (allshapes == NULL || creaturemodel == NULL || skel == NULL)
{
return;
}
std::vector<Nif::NiTriShapeCopy>::iterator allshapesiter;
for(allshapesiter = allshapes->begin(); allshapesiter != allshapes->end(); allshapesiter++)
{
//std::map<unsigned short, PosAndRot> vecPosRot;
Nif::NiTriShapeCopy& copy = *allshapesiter;
std::vector<Ogre::Vector3>* allvertices = &copy.vertices;
//std::set<unsigned int> vertices;
//std::set<unsigned int> normals;
//std::vector<Nif::NiSkinData::BoneInfoCopy> boneinfovector = copy.boneinfo;
std::map<int, std::vector<Nif::NiSkinData::IndividualWeight> >* verticesToChange = &copy.vertsToWeights;
//std::cout << "Name " << copy.sname << "\n";
Ogre::HardwareVertexBufferSharedPtr vbuf = creaturemodel->getMesh()->getSubMesh(copy.sname)->vertexData->vertexBufferBinding->getBuffer(0);
Ogre::Real* pReal = static_cast<Ogre::Real*>(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
std::vector<Ogre::Vector3> initialVertices = copy.morph.getInitialVertices();
//Each shape has multiple indices
if(initialVertices.size() )
{
if(copy.vertices.size() == initialVertices.size())
{
//Create if it doesn't already exist
if(shapeIndexI.size() == static_cast<std::size_t> (shapeNumber))
{
std::vector<int> vec;
shapeIndexI.push_back(vec);
}
if(time >= copy.morph.getStartTime() && time <= copy.morph.getStopTime()){
float x;
for (unsigned int i = 0; i < copy.morph.getAdditionalVertices().size(); i++){
int j = 0;
if(shapeIndexI[shapeNumber].size() <= i)
shapeIndexI[shapeNumber].push_back(0);
if(timeIndex(time,copy.morph.getRelevantTimes()[i],(shapeIndexI[shapeNumber])[i], j, x)){
int indexI = (shapeIndexI[shapeNumber])[i];
std::vector<Ogre::Vector3> relevantData = (copy.morph.getRelevantData()[i]);
float v1 = relevantData[indexI].x;
float v2 = relevantData[j].x;
float t = v1 + (v2 - v1) * x;
if ( t < 0 ) t = 0;
if ( t > 1 ) t = 1;
if( t != 0 && initialVertices.size() == copy.morph.getAdditionalVertices()[i].size())
{
for (unsigned int v = 0; v < initialVertices.size(); v++){
initialVertices[v] += ((copy.morph.getAdditionalVertices()[i])[v]) * t;
}
}
}
}
allvertices = &initialVertices;
}
shapeNumber++;
}
}
if(verticesToChange->size() > 0){
for(std::map<int, std::vector<Nif::NiSkinData::IndividualWeight> >::iterator iter = verticesToChange->begin();
iter != verticesToChange->end(); iter++)
{
std::vector<Nif::NiSkinData::IndividualWeight> inds = iter->second;
int verIndex = iter->first;
Ogre::Vector3 currentVertex = (*allvertices)[verIndex];
Nif::NiSkinData::BoneInfoCopy* boneinfocopy = &(allshapesiter->boneinfo[inds[0].boneinfocopyindex]);
Ogre::Bone *bonePtr = 0;
Ogre::Vector3 vecPos;
Ogre::Quaternion vecRot;
std::map<Nif::NiSkinData::BoneInfoCopy*, PosAndRot>::iterator result = vecRotPos.find(boneinfocopy);
if(result == vecRotPos.end()){
bonePtr = skel->getBone(boneinfocopy->bonename);
vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
PosAndRot both;
both.vecPos = vecPos;
both.vecRot = vecRot;
vecRotPos[boneinfocopy] = both;
}
else{
PosAndRot both = result->second;
vecPos = both.vecPos;
vecRot = both.vecRot;
}
Ogre::Vector3 absVertPos = (vecPos + vecRot * currentVertex) * inds[0].weight;
for(std::size_t i = 1; i < inds.size(); i++){
boneinfocopy = &(allshapesiter->boneinfo[inds[i].boneinfocopyindex]);
result = vecRotPos.find(boneinfocopy);
if(result == vecRotPos.end()){
bonePtr = skel->getBone(boneinfocopy->bonename);
vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
PosAndRot both;
both.vecPos = vecPos;
both.vecRot = vecRot;
vecRotPos[boneinfocopy] = both;
}
else{
PosAndRot both = result->second;
vecPos = both.vecPos;
vecRot = both.vecRot;
}
absVertPos += (vecPos + vecRot * currentVertex) * inds[i].weight;
}
Ogre::Real* addr = (pReal + 3 * verIndex);
*addr = absVertPos.x;
*(addr+1) = absVertPos.y;
*(addr+2) = absVertPos.z;
}
}
else
{
//Ogre::Bone *bonePtr = creaturemodel->getSkeleton()->getBone(copy.bonename);
Ogre::Quaternion shaperot = copy.trafo.rotation;
Ogre::Vector3 shapetrans = copy.trafo.trans;
float shapescale = copy.trafo.scale;
std::vector<std::string> boneSequence = copy.boneSequence;
Ogre::Vector3 transmult;
Ogre::Quaternion rotmult;
float scale;
if(boneSequence.size() > 0){
std::vector<std::string>::iterator boneSequenceIter = boneSequence.begin();
if(skel->hasBone(*boneSequenceIter)){
Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter);
transmult = bonePtr->getPosition();
rotmult = bonePtr->getOrientation();
scale = bonePtr->getScale().x;
boneSequenceIter++;
for(; boneSequenceIter != boneSequence.end(); boneSequenceIter++)
{
if(skel->hasBone(*boneSequenceIter)){
Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter);
// Computes C = B + AxC*scale
transmult = transmult + rotmult * bonePtr->getPosition();
rotmult = rotmult * bonePtr->getOrientation();
scale = scale * bonePtr->getScale().x;
}
//std::cout << "Bone:" << *boneSequenceIter << " ";
}
transmult = transmult + rotmult * shapetrans;
rotmult = rotmult * shaperot;
scale = shapescale * scale;
//std::cout << "Position: " << transmult << "Rotation: " << rotmult << "\n";
}
}
else
{
transmult = shapetrans;
rotmult = shaperot;
scale = shapescale;
}
// Computes C = B + AxC*scale
// final_vector = old_vector + old_rotation*new_vector*old_scale/
for(unsigned int i = 0; i < allvertices->size(); i++){
Ogre::Vector3 current = transmult + rotmult * (*allvertices)[i];
Ogre::Real* addr = pReal + i * 3;
*addr = current.x;
*(addr+1) = current.y;
*(addr + 2) = current.z;
}/*
for(int i = 0; i < allnormals.size(); i++){
Ogre::Vector3 current =rotmult * allnormals[i];
Ogre::Real* addr = pRealNormal + i * 3;
*addr = current.x;
*(addr+1) = current.y;
*(addr + 2) = current.z;
}*/ void Animation::stopScript()
{
animate = 0;
}
}
vbuf->unlock();
} bool Animation::timeIndex(float time, const std::vector<float> &times, int &i, int &j, float &x)
{
size_t count;
if((count=times.size()) == 0)
return false;
} if(time <= times[0])
bool Animation::timeIndex( float time, const std::vector<float> & times, int & i, int & j, float & x ){
int count;
if ( (count = times.size()) > 0 )
{
if ( time <= times[0] )
{ {
i = j = 0; i = j = 0;
x = 0.0; x = 0.0;
return true; return true;
} }
if ( time >= times[count - 1] ) if(time >= times[count-1])
{ {
i = j = count - 1; i = j = count - 1;
x = 0.0; x = 0.0;
return true; return true;
} }
if ( i < 0 || i >= count ) if(i < 0 || (size_t)i >= count)
i = 0; i = 0;
float tI = times[i]; float tI = times[i];
if ( time > tI ) if(time > tI)
{ {
j = i + 1; j = i + 1;
float tJ; float tJ;
while ( time >= ( tJ = times[j]) ) while(time >= (tJ=times[j]))
{ {
i = j++; i = j++;
tI = tJ; tI = tJ;
} }
x = ( time - tI ) / ( tJ - tI ); x = (time-tI) / (tJ-tI);
return true; return true;
} }
else if ( time < tI )
if(time < tI)
{ {
j = i - 1; j = i - 1;
float tJ; float tJ;
while ( time <= ( tJ = times[j] ) ) while(time <= (tJ=times[j]))
{ {
i = j--; i = j--;
tI = tJ; tI = tJ;
} }
x = ( time - tI ) / ( tJ - tI ); x = (time-tI) / (tJ-tI);
return true; return true;
} }
else
{
j = i; j = i;
x = 0.0; x = 0.0;
return true; return true;
}
}
else
return false;
} }
void Animation::handleAnimationTransforms(){ void Animation::handleAnimationTransforms()
{
Ogre::SkeletonInstance* skel = base->getSkeleton(); Ogre::SkeletonInstance* skel = base->getSkeleton();
Ogre::Bone* b = skel->getRootBone(); Ogre::Bone* b = skel->getRootBone();
b->setOrientation(Ogre::Real(.3),Ogre::Real(.3),Ogre::Real(.3), Ogre::Real(.3)); //This is a trick b->setOrientation(Ogre::Real(.3),Ogre::Real(.3),Ogre::Real(.3), Ogre::Real(.3)); //This is a trick
@ -432,13 +183,12 @@ namespace MWRender{
//base->_updateAnimation(); //base->_updateAnimation();
//base->_notifyMoved(); //base->_notifyMoved();
std::vector<Nif::NiKeyframeData>::iterator iter; std::vector<Nif::NiKeyframeData>::iterator iter;
int slot = 0; int slot = 0;
if(transformations){ if(transformations)
for(iter = transformations->begin(); iter != transformations->end(); iter++){ {
for(iter = transformations->begin(); iter != transformations->end(); iter++)
{
if(time < iter->getStartTime() || time < startTime || time > iter->getStopTime()) if(time < iter->getStartTime() || time < startTime || time > iter->getStopTime())
{ {
slot++; slot++;
@ -448,56 +198,44 @@ namespace MWRender{
float x; float x;
float x2; float x2;
const std::vector<Ogre::Quaternion> & quats = iter->getQuat(); const std::vector<Ogre::Quaternion> &quats = iter->getQuat();
const std::vector<float> &ttime = iter->gettTime();
const std::vector<float> & ttime = iter->gettTime(); const std::vector<float> &rtime = iter->getrTime();
const std::vector<Ogre::Vector3> &translist1 = iter->getTranslist1();
const std::vector<float> & rtime = iter->getrTime();
int rindexJ = rindexI[slot]; int rindexJ = rindexI[slot];
timeIndex(time, rtime, rindexI[slot], rindexJ, x2); timeIndex(time, rtime, rindexI[slot], rindexJ, x2);
int tindexJ = tindexI[slot];
const std::vector<Ogre::Vector3> & translist1 = iter->getTranslist1();
int tindexJ = tindexI[slot];
timeIndex(time, ttime, tindexI[slot], tindexJ, x); timeIndex(time, ttime, tindexI[slot], tindexJ, x);
Ogre::Vector3 t; Ogre::Vector3 t;
Ogre::Quaternion r; Ogre::Quaternion r;
bool bTrans = translist1.size() > 0; bool bTrans = translist1.size() > 0;
bool bQuats = quats.size() > 0; bool bQuats = quats.size() > 0;
if(skel->hasBone(iter->getBonename()))
if(skel->hasBone(iter->getBonename())){ {
Ogre::Bone* bone = skel->getBone(iter->getBonename()); Ogre::Bone* bone = skel->getBone(iter->getBonename());
if(bTrans){ if(bTrans)
{
Ogre::Vector3 v1 = translist1[tindexI[slot]]; Ogre::Vector3 v1 = translist1[tindexI[slot]];
Ogre::Vector3 v2 = translist1[tindexJ]; Ogre::Vector3 v2 = translist1[tindexJ];
t = (v1 + (v2 - v1) * x); t = (v1 + (v2 - v1) * x);
bone->setPosition(t); bone->setPosition(t);
} }
if(bQuats){ if(bQuats)
{
r = Ogre::Quaternion::Slerp(x2, quats[rindexI[slot]], quats[rindexJ], true); r = Ogre::Quaternion::Slerp(x2, quats[rindexI[slot]], quats[rindexJ], true);
bone->setOrientation(r); bone->setOrientation(r);
} }
} }
slot++; slot++;
} }
skel->_updateTransforms(); skel->_updateTransforms();
base->getAllAnimationStates()->_notifyDirty(); base->getAllAnimationStates()->_notifyDirty();
} }
} }
} }

@ -12,25 +12,19 @@
namespace MWRender{ namespace MWRender {
struct PosAndRot{ struct PosAndRot {
Ogre::Quaternion vecRot; Ogre::Quaternion vecRot;
Ogre::Vector3 vecPos; Ogre::Vector3 vecPos;
}; };
class Animation{ class Animation {
protected:
protected:
Ogre::SceneNode* insert; Ogre::SceneNode* insert;
OEngine::Render::OgreRenderer &mRend; OEngine::Render::OgreRenderer &mRend;
std::map<Nif::NiSkinData::BoneInfoCopy*, PosAndRot> vecRotPos;
static std::map<std::string, int> mUniqueIDs; static std::map<std::string, int> mUniqueIDs;
float time; float time;
float startTime; float startTime;
float stopTime; float stopTime;
@ -44,20 +38,13 @@ class Animation{
int shapeNumber; int shapeNumber;
std::vector<std::vector<int> > shapeIndexI; std::vector<std::vector<int> > shapeIndexI;
//Ogre::SkeletonInstance* skel;
std::vector<Nif::NiTriShapeCopy>* shapes; //All the NiTriShapeData for a creature
std::vector<Nif::NiKeyframeData>* transformations; std::vector<Nif::NiKeyframeData>* transformations;
std::map<std::string,float>* textmappings; std::map<std::string,float>* textmappings;
Ogre::Entity* base; Ogre::Entity* base;
void handleShapes(std::vector<Nif::NiTriShapeCopy>* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel);
void handleAnimationTransforms(); void handleAnimationTransforms();
bool timeIndex( float time, const std::vector<float> & times, int & i, int & j, float & x ); bool timeIndex( float time, const std::vector<float> & times, int & i, int & j, float & x );
std::string getUniqueID(std::string mesh);
public: public:
Animation(OEngine::Render::OgreRenderer& _rend); Animation(OEngine::Render::OgreRenderer& _rend);
virtual void runAnimation(float timepassed) = 0; virtual void runAnimation(float timepassed) = 0;
void startScript(std::string groupname, int mode, int loops); void startScript(std::string groupname, int mode, int loops);
@ -65,7 +52,7 @@ class Animation{
virtual ~Animation(); virtual ~Animation();
}; };
} }
#endif #endif

@ -12,20 +12,22 @@ using namespace Ogre;
using namespace NifOgre; using namespace NifOgre;
namespace MWRender{ namespace MWRender{
CreatureAnimation::~CreatureAnimation(){ CreatureAnimation::~CreatureAnimation()
{
} }
CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend): Animation(_rend){
CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend): Animation(_rend)
{
insert = ptr.getRefData().getBaseNode(); insert = ptr.getRefData().getBaseNode();
MWWorld::LiveCellRef<ESM::Creature> *ref = MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
ptr.get<ESM::Creature>();
assert (ref->base != NULL); assert (ref->base != NULL);
if(!ref->base->model.empty()){ if(!ref->base->model.empty())
const std::string &mesh = "meshes\\" + ref->base->model; {
std::string meshNumbered = mesh + getUniqueID(mesh) + ">|"; std::string mesh = "meshes\\" + ref->base->model;
NifOgre::NIFLoader::load(meshNumbered);
base = mRend.getScene()->createEntity(meshNumbered); NifOgre::NIFLoader::load(mesh);
base = mRend.getScene()->createEntity(mesh);
base->setVisibilityFlags(RV_Actors); base->setVisibilityFlags(RV_Actors);
bool transparent = false; bool transparent = false;
@ -48,33 +50,22 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, OEngine::Render::O
} }
base->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main); base->setRenderQueueGroup(transparent ? RQG_Alpha : RQG_Main);
std::string meshZero = mesh + "0000>|";
if((transformations = (NIFLoader::getSingletonPtr())->getAnim(meshZero))){
for(std::size_t init = 0; init < transformations->size(); init++){
rindexI.push_back(0);
tindexI.push_back(0);
}
stopTime = transformations->begin()->getStopTime();
startTime = transformations->begin()->getStartTime();
shapes = (NIFLoader::getSingletonPtr())->getShapes(meshZero);
}
textmappings = NIFLoader::getSingletonPtr()->getTextIndices(meshZero);
insert->attachObject(base); insert->attachObject(base);
} }
} }
void CreatureAnimation::runAnimation(float timepassed){ void CreatureAnimation::runAnimation(float timepassed)
vecRotPos.clear(); {
if(animate > 0){ if(animate > 0)
{
//Add the amount of time passed to time //Add the amount of time passed to time
//Handle the animation transforms dependent on time //Handle the animation transforms dependent on time
//Handle the shapes dependent on animation transforms //Handle the shapes dependent on animation transforms
time += timepassed; time += timepassed;
if(time >= stopTime){ if(time >= stopTime)
{
animate--; animate--;
//std::cout << "Stopping the animation\n"; //std::cout << "Stopping the animation\n";
if(animate == 0) if(animate == 0)
@ -84,8 +75,7 @@ void CreatureAnimation::runAnimation(float timepassed){
} }
handleAnimationTransforms(); handleAnimationTransforms();
handleShapes(shapes, base, base->getSkeleton());
} }
} }
} }

File diff suppressed because it is too large Load Diff

@ -22,20 +22,9 @@ class NpcAnimation: public Animation{
private: private:
MWWorld::InventoryStore& inv; MWWorld::InventoryStore& inv;
int mStateID; int mStateID;
//Free Parts
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> chest;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> skirt;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> lhand;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> rhand;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> tail;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> lFreeFoot;
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> rFreeFoot;
int partslots[27]; //Each part slot is taken by clothing, armor, or is empty int partslots[27]; //Each part slot is taken by clothing, armor, or is empty
int partpriorities[27]; int partpriorities[27];
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> zero;
//Bounded Parts //Bounded Parts
Ogre::Entity* lclavicle; Ogre::Entity* lclavicle;
@ -80,12 +69,10 @@ private:
MWWorld::ContainerStoreIterator rightglove; MWWorld::ContainerStoreIterator rightglove;
MWWorld::ContainerStoreIterator skirtiter; MWWorld::ContainerStoreIterator skirtiter;
public: public:
NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv); NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv);
virtual ~NpcAnimation(); virtual ~NpcAnimation();
Ogre::Entity* insertBoundedPart(const std::string &mesh, std::string bonename); Ogre::Entity* insertBoundedPart(const std::string &mesh, const std::string &bonename);
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> insertFreePart(const std::string &mesh, const std::string& suffix);
void insertFootPart(int type, const std::string &mesh);
virtual void runAnimation(float timepassed); virtual void runAnimation(float timepassed);
void updateParts(); void updateParts();
void removeIndividualPart(int type); void removeIndividualPart(int type);
@ -94,8 +81,7 @@ private:
bool addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh); bool addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh);
void removePartGroup(int group); void removePartGroup(int group);
void addPartGroup(int group, int priority, std::vector<ESM::PartReference>& parts); void addPartGroup(int group, int priority, std::vector<ESM::PartReference>& parts);
}; };
} }
#endif #endif

@ -64,28 +64,13 @@ static bool fsstrict = false;
/// An OGRE Archive wrapping a BSAFile archive /// An OGRE Archive wrapping a BSAFile archive
class DirArchive: public Ogre::FileSystemArchive class DirArchive: public Ogre::FileSystemArchive
{ {
boost::filesystem::path currentdir; boost::filesystem::path currentdir;
std::map<std::string, std::vector<std::string>, ciLessBoost> m; std::map<std::string, std::vector<std::string>, ciLessBoost> m;
unsigned int cutoff; unsigned int cutoff;
bool findFile(const String& filename, std::string& copy) const bool findFile(const String& filename, std::string& copy) const
{ {
{ copy = filename;
String passed = filename;
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
else if(filename.at(filename.length() - 2) == '"')
passed = filename.substr(0, filename.length() - 9);
else if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<'
|| filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':'
|| filename.at(filename.length() - 1) == '|')
passed = filename.substr(0, filename.length() - 2);
copy = passed;
}
std::replace(copy.begin(), copy.end(), '\\', '/'); std::replace(copy.begin(), copy.end(), '\\', '/');
if(copy.at(0) == '/') if(copy.at(0) == '/')
@ -225,46 +210,23 @@ public:
// OGRE's fault. You should NOT expect an open() command not to // OGRE's fault. You should NOT expect an open() command not to
// have any side effects on the archive, and hence this function // have any side effects on the archive, and hence this function
// should not have been declared const in the first place. // should not have been declared const in the first place.
BSAFile *narc = (BSAFile*)&arc; BSAFile *narc = const_cast<BSAFile*>(&arc);
String passed = filename;
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':')
passed = filename.substr(0, filename.length() - 6);
else if(filename.at(filename.length() - 2) == '"')
passed = filename.substr(0, filename.length() - 9);
else if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<'
|| filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':'
|| filename.at(filename.length() - 1) == '|')
passed = filename.substr(0, filename.length() - 2);
// Open the file // Open the file
StreamPtr strm = narc->getFile(passed.c_str()); StreamPtr strm = narc->getFile(filename.c_str());
// Wrap it into an Ogre::DataStream. // Wrap it into an Ogre::DataStream.
return DataStreamPtr(new Mangle2OgreStream(strm)); return DataStreamPtr(new Mangle2OgreStream(strm));
} }
bool exists(const String& filename) { bool exists(const String& filename) {
return cexists(filename); return arc.exists(filename.c_str());
} }
// Check if the file exists.
bool cexists(const String& filename) const { bool cexists(const String& filename) const {
String passed = filename; return arc.exists(filename.c_str());
if(filename.at(filename.length() - 2) == '>' || filename.at(filename.length() - 2) == ':') }
passed = filename.substr(0, filename.length() - 6);
else if(filename.at(filename.length() - 2) == '"')
passed = filename.substr(0, filename.length() - 9);
else if(filename.at(filename.length() - 1) == '*' || filename.at(filename.length() - 1) == '?' || filename.at(filename.length() - 1) == '<'
|| filename.at(filename.length() - 1) == '"' || filename.at(filename.length() - 1) == '>' || filename.at(filename.length() - 1) == ':'
|| filename.at(filename.length() - 1) == '|')
passed = filename.substr(0, filename.length() - 2);
return arc.exists(passed.c_str());
}
time_t getModifiedTime(const String&) { return 0; } time_t getModifiedTime(const String&) { return 0; }
// This is never called as far as I can see. // This is never called as far as I can see.

@ -326,12 +326,6 @@ public:
Ogre::Vector3 trans; // Translation Ogre::Vector3 trans; // Translation
float scale; // Probably scale (always 1) float scale; // Probably scale (always 1)
}; };
struct BoneTrafoCopy
{
Ogre::Quaternion rotation;
Ogre::Vector3 trans;
float scale;
};
struct VertWeight struct VertWeight
{ {
@ -339,26 +333,12 @@ public:
float weight; float weight;
}; };
struct BoneInfo struct BoneInfo
{ {
BoneTrafo trafo; BoneTrafo trafo;
Ogre::Vector4 unknown; Ogre::Vector4 unknown;
std::vector<VertWeight> weights; std::vector<VertWeight> weights;
}; };
struct BoneInfoCopy
{
std::string bonename;
unsigned short bonehandle;
BoneTrafoCopy trafo;
Ogre::Vector4 unknown;
//std::vector<VertWeight> weights;
};
struct IndividualWeight
{
float weight;
unsigned int boneinfocopyindex;
};
BoneTrafo trafo; BoneTrafo trafo;
std::vector<BoneInfo> bones; std::vector<BoneInfo> bones;

@ -110,20 +110,6 @@ public:
} }
}; };
struct NiTriShapeCopy
{
std::string sname;
std::vector<std::string> boneSequence;
Nif::NiSkinData::BoneTrafoCopy trafo;
//Ogre::Quaternion initialBoneRotation;
//Ogre::Vector3 initialBoneTranslation;
std::vector<Ogre::Vector3> vertices;
std::vector<Ogre::Vector3> normals;
std::vector<Nif::NiSkinData::BoneInfoCopy> boneinfo;
std::map<int, std::vector<Nif::NiSkinData::IndividualWeight> > vertsToWeights;
Nif::NiMorphData morph;
};
struct NiNode : Node struct NiNode : Node
{ {
NodeList children; NodeList children;
@ -184,28 +170,6 @@ struct NiTriShape : Node
data.post(nif); data.post(nif);
skin.post(nif); skin.post(nif);
} }
NiTriShapeCopy clone()
{
NiTriShapeCopy copy;
copy.sname = name;
float *ptr = (float*)&data->vertices[0];
float *ptrNormals = (float*)&data->normals[0];
int numVerts = data->vertices.size() / 3;
for(int i = 0; i < numVerts; i++)
{
float *current = (float*) (ptr + i * 3);
copy.vertices.push_back(Ogre::Vector3(*current, *(current + 1), *(current + 2)));
if(ptrNormals)
{
float *currentNormals = (float*) (ptrNormals + i * 3);
copy.normals.push_back(Ogre::Vector3(*currentNormals, *(currentNormals + 1), *(currentNormals + 2)));
}
}
return copy;
}
}; };
struct NiCamera : Node struct NiCamera : Node

@ -79,7 +79,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
// of the early stages of development. Right now we WANT to catch // of the early stages of development. Right now we WANT to catch
// every error as early and intrusively as possible, as it's most // every error as early and intrusively as possible, as it's most
// likely a sign of incomplete code rather than faulty input. // likely a sign of incomplete code rather than faulty input.
Nif::NIFFile nif(resourceName); Nif::NIFFile nif(resourceName.substr(0, resourceName.length()-7));
if (nif.numRecords() < 1) if (nif.numRecords() < 1)
{ {
warn("Found no records in NIF."); warn("Found no records in NIF.");

File diff suppressed because it is too large Load Diff

@ -67,12 +67,9 @@ namespace Nif
namespace NifOgre namespace NifOgre
{ {
/** Manual resource loader for NIF meshes. This is the main class /** Manual resource loader for NIF meshes. This is the main class
responsible for translating the internal NIF mesh structure into responsible for translating the internal NIF mesh structure into
something Ogre can use. Later it will also handle the insertion of something Ogre can use.
collision meshes into Bullet / OgreBullet.
You have to insert meshes manually into Ogre like this: You have to insert meshes manually into Ogre like this:
@ -86,93 +83,18 @@ namespace NifOgre
*/ */
class NIFLoader : Ogre::ManualResourceLoader class NIFLoader : Ogre::ManualResourceLoader
{ {
public: public:
static int numberOfMeshes;
static NIFLoader& getSingleton();
static NIFLoader* getSingletonPtr();
virtual void loadResource(Ogre::Resource *resource); 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"); const std::string &group="General");
//void insertMeshInsideBase(Ogre::Mesh* mesh);
std::vector<Nif::NiKeyframeData>* getAnim(std::string name);
std::vector<Nif::NiTriShapeCopy>* getShapes(std::string name);
std::map<std::string, float>* getTextIndices(std::string name);
void setOutputAnimFiles(bool output);
void setVerbosePath(std::string path);
private: private:
NIFLoader() {}
NIFLoader() : resourceName(""), resourceGroup("General"), flip(false), mNormaliseNormals(false),
mFlipVertexWinding(false), mOutputAnimFiles(false), inTheSkeletonTree(false) {}
NIFLoader(NIFLoader& n) {} NIFLoader(NIFLoader& n) {}
void calculateTransform(); void warn(const std::string &msg);
void fail(const std::string &msg);
void warn(std::string msg);
void fail(std::string msg);
void handleNode( Nif::Node *node, int flags,
const Nif::Transformation *trafo, BoundsFinder &bounds, Ogre::Bone *parentBone, std::vector<std::string> boneSequence);
void handleNiTriShape(Nif::NiTriShape *shape, int flags, BoundsFinder &bounds, Nif::Transformation original, std::vector<std::string> boneSequence);
void createOgreSubMesh(Nif::NiTriShape *shape, const Ogre::String &material, std::list<Ogre::VertexBoneAssignment> &vertexBoneAssignments);
void createMaterial(const Ogre::String &name,
const Ogre::Vector3 &ambient,
const Ogre::Vector3 &diffuse,
const Ogre::Vector3 &specular,
const Ogre::Vector3 &emissive,
float glossiness, float alpha,
int alphaFlags, float alphaTest,
const Ogre::String &texName);
void findRealTexture(Ogre::String &texName);
Ogre::String getUniqueName(const Ogre::String &input);
//returns the skeleton name of this mesh
std::string getSkeletonName()
{
return resourceName + ".skel";
}
std::string verbosePath;
std::string resourceName;
std::string resourceGroup;
Ogre::Matrix4 mTransform;
Ogre::AxisAlignedBox mBoundingBox;
bool flip;
bool mNormaliseNormals;
bool mFlipVertexWinding;
bool bNiTri;
bool mOutputAnimFiles;
std::multimap<std::string,std::string> MaterialMap;
// pointer to the ogre mesh which is currently build
Ogre::Mesh *mesh;
Ogre::SkeletonPtr mSkel;
Ogre::Vector3 vector;
std::vector<Nif::NiTriShapeCopy> shapes;
std::string name;
std::string triname;
std::vector<Nif::NiKeyframeData> allanim;
std::map<std::string,float> textmappings;
std::map<std::string,std::map<std::string,float>,ciLessBoost> alltextmappings;
std::map<std::string,std::vector<Nif::NiKeyframeData>,ciLessBoost> allanimmap;
std::map<std::string,std::vector<Nif::NiTriShapeCopy>,ciLessBoost> allshapesmap;
std::vector<Nif::NiKeyframeData> mAnim;
std::vector<Nif::NiTriShapeCopy> mS;
std::vector<Ogre::SubMesh*> needBoneAssignments;
bool inTheSkeletonTree;
}; };
} }

@ -336,7 +336,7 @@ namespace Physic
char uniqueID[8]; char uniqueID[8];
sprintf( uniqueID, "%07.3f", scale ); sprintf( uniqueID, "%07.3f", scale );
std::string sid = uniqueID; std::string sid = uniqueID;
std::string outputstring = mesh + uniqueID + "\"|"; std::string outputstring = mesh + uniqueID;
//std::cout << "The string" << outputstring << "\n"; //std::cout << "The string" << outputstring << "\n";
//get the shape from the .nif //get the shape from the .nif

Loading…
Cancel
Save