mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-06-23 18:41:39 +00:00
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.
This commit is contained in:
parent
9995dff943
commit
386ac56bda
13 changed files with 873 additions and 2615 deletions
|
@ -75,11 +75,8 @@ void OMW::Engine::executeLocalScripts()
|
|||
localScripts.setIgnore (MWWorld::Ptr());
|
||||
}
|
||||
|
||||
void OMW::Engine::setAnimationVerbose(bool animverbose){
|
||||
if(animverbose){
|
||||
NifOgre::NIFLoader::getSingletonPtr()->setOutputAnimFiles(true);
|
||||
NifOgre::NIFLoader::getSingletonPtr()->setVerbosePath(mCfgMgr.getLogPath().string());
|
||||
}
|
||||
void OMW::Engine::setAnimationVerbose(bool animverbose)
|
||||
{
|
||||
}
|
||||
|
||||
bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
#include <OgreBone.h>
|
||||
#include <OgreSubMesh.h>
|
||||
|
||||
namespace MWRender{
|
||||
std::map<std::string, int> Animation::mUniqueIDs;
|
||||
namespace MWRender {
|
||||
|
||||
Animation::Animation(OEngine::Render::OgreRenderer& _rend)
|
||||
std::map<std::string, int> Animation::mUniqueIDs;
|
||||
|
||||
Animation::Animation(OEngine::Render::OgreRenderer& _rend)
|
||||
: insert(NULL)
|
||||
, mRend(_rend)
|
||||
, vecRotPos()
|
||||
, time(0.0f)
|
||||
, startTime(0.0f)
|
||||
, stopTime(0.0f)
|
||||
|
@ -21,96 +21,82 @@ namespace MWRender{
|
|||
, tindexI()
|
||||
, shapeNumber(0)
|
||||
, shapeIndexI()
|
||||
, shapes(NULL)
|
||||
, transformations(NULL)
|
||||
, textmappings(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;
|
||||
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){
|
||||
|
||||
Animation::~Animation()
|
||||
{
|
||||
}
|
||||
|
||||
void Animation::startScript(std::string groupname, int mode, int loops)
|
||||
{
|
||||
//If groupname is recognized set animate to true
|
||||
//Set the start time and stop time
|
||||
//How many times to loop
|
||||
if(groupname == "all"){
|
||||
if(groupname == "all")
|
||||
{
|
||||
animate = loops;
|
||||
time = startTime;
|
||||
}
|
||||
else if(textmappings){
|
||||
|
||||
else if(textmappings)
|
||||
{
|
||||
std::string startName = groupname + ": loop start";
|
||||
std::string stopName = groupname + ": loop stop";
|
||||
|
||||
bool first = false;
|
||||
|
||||
if(loops > 1){
|
||||
if(loops > 1)
|
||||
{
|
||||
startName = groupname + ": loop start";
|
||||
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::transform(current.begin(), current.end(), current.begin(), ::tolower);
|
||||
std::string current2 = iter->first.substr(0, stopName.size());
|
||||
std::transform(current2.begin(), current2.end(), current2.begin(), ::tolower);
|
||||
|
||||
if(current == startName){
|
||||
if(current == startName)
|
||||
{
|
||||
startTime = iter->second;
|
||||
animate = loops;
|
||||
time = startTime;
|
||||
first = true;
|
||||
}
|
||||
if(current2 == stopName){
|
||||
if(current2 == stopName)
|
||||
{
|
||||
stopTime = iter->second;
|
||||
if(first)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!first){
|
||||
|
||||
if(!first)
|
||||
{
|
||||
startName = groupname + ": start";
|
||||
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::transform(current.begin(), current.end(), current.begin(), ::tolower);
|
||||
std::string current2 = iter->first.substr(0, stopName.size());
|
||||
std::transform(current2.begin(), current2.end(), current2.begin(), ::tolower);
|
||||
|
||||
if(current == startName){
|
||||
if(current == startName)
|
||||
{
|
||||
startTime = iter->second;
|
||||
animate = loops;
|
||||
time = startTime;
|
||||
first = true;
|
||||
}
|
||||
if(current2 == stopName){
|
||||
if(current2 == stopName)
|
||||
{
|
||||
stopTime = iter->second;
|
||||
if(first)
|
||||
break;
|
||||
|
@ -120,308 +106,73 @@ namespace MWRender{
|
|||
|
||||
}
|
||||
|
||||
}
|
||||
void Animation::stopScript(){
|
||||
}
|
||||
|
||||
|
||||
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 = ©.vertices;
|
||||
}
|
||||
|
||||
|
||||
bool Animation::timeIndex(float time, const std::vector<float> ×, int &i, int &j, float &x)
|
||||
{
|
||||
size_t count;
|
||||
if((count=times.size()) == 0)
|
||||
return false;
|
||||
|
||||
//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 = ©.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;
|
||||
|
||||
}*/
|
||||
|
||||
}
|
||||
vbuf->unlock();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
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] )
|
||||
if(time <= times[0])
|
||||
{
|
||||
i = j = 0;
|
||||
x = 0.0;
|
||||
return true;
|
||||
}
|
||||
if ( time >= times[count - 1] )
|
||||
if(time >= times[count-1])
|
||||
{
|
||||
i = j = count - 1;
|
||||
x = 0.0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( i < 0 || i >= count )
|
||||
if(i < 0 || (size_t)i >= count)
|
||||
i = 0;
|
||||
|
||||
float tI = times[i];
|
||||
if ( time > tI )
|
||||
if(time > tI)
|
||||
{
|
||||
j = i + 1;
|
||||
float tJ;
|
||||
while ( time >= ( tJ = times[j]) )
|
||||
while(time >= (tJ=times[j]))
|
||||
{
|
||||
i = j++;
|
||||
tI = tJ;
|
||||
}
|
||||
x = ( time - tI ) / ( tJ - tI );
|
||||
x = (time-tI) / (tJ-tI);
|
||||
return true;
|
||||
}
|
||||
else if ( time < tI )
|
||||
|
||||
if(time < tI)
|
||||
{
|
||||
j = i - 1;
|
||||
float tJ;
|
||||
while ( time <= ( tJ = times[j] ) )
|
||||
while(time <= (tJ=times[j]))
|
||||
{
|
||||
i = j--;
|
||||
tI = tJ;
|
||||
}
|
||||
x = ( time - tI ) / ( tJ - tI );
|
||||
x = (time-tI) / (tJ-tI);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
j = i;
|
||||
x = 0.0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
void Animation::handleAnimationTransforms(){
|
||||
|
||||
|
||||
void Animation::handleAnimationTransforms()
|
||||
{
|
||||
Ogre::SkeletonInstance* skel = base->getSkeleton();
|
||||
|
||||
|
||||
Ogre::Bone* b = skel->getRootBone();
|
||||
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->_notifyMoved();
|
||||
|
||||
|
||||
|
||||
|
||||
std::vector<Nif::NiKeyframeData>::iterator iter;
|
||||
int slot = 0;
|
||||
if(transformations){
|
||||
for(iter = transformations->begin(); iter != transformations->end(); iter++){
|
||||
if(transformations)
|
||||
{
|
||||
for(iter = transformations->begin(); iter != transformations->end(); iter++)
|
||||
{
|
||||
if(time < iter->getStartTime() || time < startTime || time > iter->getStopTime())
|
||||
{
|
||||
slot++;
|
||||
|
@ -448,56 +198,44 @@ namespace MWRender{
|
|||
float x;
|
||||
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> &rtime = iter->getrTime();
|
||||
const std::vector<Ogre::Vector3> &translist1 = iter->getTranslist1();
|
||||
|
||||
const std::vector<float> & ttime = iter->gettTime();
|
||||
|
||||
|
||||
const std::vector<float> & rtime = iter->getrTime();
|
||||
int rindexJ = rindexI[slot];
|
||||
|
||||
timeIndex(time, rtime, rindexI[slot], rindexJ, x2);
|
||||
|
||||
int tindexJ = tindexI[slot];
|
||||
|
||||
|
||||
const std::vector<Ogre::Vector3> & translist1 = iter->getTranslist1();
|
||||
|
||||
timeIndex(time, ttime, tindexI[slot], tindexJ, x);
|
||||
|
||||
Ogre::Vector3 t;
|
||||
Ogre::Quaternion r;
|
||||
|
||||
bool bTrans = translist1.size() > 0;
|
||||
|
||||
|
||||
bool bQuats = quats.size() > 0;
|
||||
|
||||
if(skel->hasBone(iter->getBonename())){
|
||||
if(skel->hasBone(iter->getBonename()))
|
||||
{
|
||||
Ogre::Bone* bone = skel->getBone(iter->getBonename());
|
||||
if(bTrans){
|
||||
if(bTrans)
|
||||
{
|
||||
Ogre::Vector3 v1 = translist1[tindexI[slot]];
|
||||
Ogre::Vector3 v2 = translist1[tindexJ];
|
||||
t = (v1 + (v2 - v1) * x);
|
||||
bone->setPosition(t);
|
||||
|
||||
}
|
||||
if(bQuats){
|
||||
if(bQuats)
|
||||
{
|
||||
r = Ogre::Quaternion::Slerp(x2, quats[rindexI[slot]], quats[rindexJ], true);
|
||||
bone->setOrientation(r);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
slot++;
|
||||
}
|
||||
skel->_updateTransforms();
|
||||
base->getAllAnimationStates()->_notifyDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,25 +12,19 @@
|
|||
|
||||
|
||||
|
||||
namespace MWRender{
|
||||
namespace MWRender {
|
||||
|
||||
struct PosAndRot{
|
||||
struct PosAndRot {
|
||||
Ogre::Quaternion vecRot;
|
||||
Ogre::Vector3 vecPos;
|
||||
};
|
||||
|
||||
class Animation{
|
||||
|
||||
protected:
|
||||
class Animation {
|
||||
protected:
|
||||
Ogre::SceneNode* insert;
|
||||
OEngine::Render::OgreRenderer &mRend;
|
||||
std::map<Nif::NiSkinData::BoneInfoCopy*, PosAndRot> vecRotPos;
|
||||
static std::map<std::string, int> mUniqueIDs;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
float time;
|
||||
float startTime;
|
||||
float stopTime;
|
||||
|
@ -44,20 +38,13 @@ class Animation{
|
|||
int shapeNumber;
|
||||
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::map<std::string,float>* textmappings;
|
||||
Ogre::Entity* base;
|
||||
void handleShapes(std::vector<Nif::NiTriShapeCopy>* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel);
|
||||
void handleAnimationTransforms();
|
||||
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);
|
||||
virtual void runAnimation(float timepassed) = 0;
|
||||
void startScript(std::string groupname, int mode, int loops);
|
||||
|
@ -65,7 +52,7 @@ class Animation{
|
|||
|
||||
|
||||
virtual ~Animation();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -12,20 +12,22 @@ using namespace Ogre;
|
|||
using namespace NifOgre;
|
||||
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();
|
||||
MWWorld::LiveCellRef<ESM::Creature> *ref =
|
||||
ptr.get<ESM::Creature>();
|
||||
MWWorld::LiveCellRef<ESM::Creature> *ref = ptr.get<ESM::Creature>();
|
||||
|
||||
assert (ref->base != NULL);
|
||||
if(!ref->base->model.empty()){
|
||||
const std::string &mesh = "meshes\\" + ref->base->model;
|
||||
std::string meshNumbered = mesh + getUniqueID(mesh) + ">|";
|
||||
NifOgre::NIFLoader::load(meshNumbered);
|
||||
base = mRend.getScene()->createEntity(meshNumbered);
|
||||
if(!ref->base->model.empty())
|
||||
{
|
||||
std::string mesh = "meshes\\" + ref->base->model;
|
||||
|
||||
NifOgre::NIFLoader::load(mesh);
|
||||
base = mRend.getScene()->createEntity(mesh);
|
||||
base->setVisibilityFlags(RV_Actors);
|
||||
|
||||
bool transparent = false;
|
||||
|
@ -48,33 +50,22 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, OEngine::Render::O
|
|||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void CreatureAnimation::runAnimation(float timepassed){
|
||||
vecRotPos.clear();
|
||||
if(animate > 0){
|
||||
void CreatureAnimation::runAnimation(float timepassed)
|
||||
{
|
||||
if(animate > 0)
|
||||
{
|
||||
//Add the amount of time passed to time
|
||||
|
||||
//Handle the animation transforms dependent on time
|
||||
|
||||
//Handle the shapes dependent on animation transforms
|
||||
time += timepassed;
|
||||
if(time >= stopTime){
|
||||
if(time >= stopTime)
|
||||
{
|
||||
animate--;
|
||||
//std::cout << "Stopping the animation\n";
|
||||
if(animate == 0)
|
||||
|
@ -84,8 +75,7 @@ void CreatureAnimation::runAnimation(float timepassed){
|
|||
}
|
||||
|
||||
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:
|
||||
MWWorld::InventoryStore& inv;
|
||||
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 partpriorities[27];
|
||||
std::pair<Ogre::Entity*, std::vector<Nif::NiTriShapeCopy>*> zero;
|
||||
|
||||
|
||||
|
||||
//Bounded Parts
|
||||
Ogre::Entity* lclavicle;
|
||||
|
@ -80,12 +69,10 @@ private:
|
|||
MWWorld::ContainerStoreIterator rightglove;
|
||||
MWWorld::ContainerStoreIterator skirtiter;
|
||||
|
||||
public:
|
||||
public:
|
||||
NpcAnimation(const MWWorld::Ptr& ptr, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv);
|
||||
virtual ~NpcAnimation();
|
||||
Ogre::Entity* insertBoundedPart(const std::string &mesh, 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);
|
||||
Ogre::Entity* insertBoundedPart(const std::string &mesh, const std::string &bonename);
|
||||
virtual void runAnimation(float timepassed);
|
||||
void updateParts();
|
||||
void removeIndividualPart(int type);
|
||||
|
@ -94,8 +81,7 @@ private:
|
|||
bool addOrReplaceIndividualPart(int type, int group, int priority, const std::string &mesh);
|
||||
void removePartGroup(int group);
|
||||
void addPartGroup(int group, int priority, std::vector<ESM::PartReference>& parts);
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -64,28 +64,13 @@ 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 findFile(const String& filename, std::string& copy) const
|
||||
{
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
copy = filename;
|
||||
std::replace(copy.begin(), copy.end(), '\\', '/');
|
||||
|
||||
if(copy.at(0) == '/')
|
||||
|
@ -225,46 +210,23 @@ public:
|
|||
// OGRE's fault. You should NOT expect an open() command not to
|
||||
// have any side effects on the archive, and hence this function
|
||||
// should not have been declared const in the first place.
|
||||
BSAFile *narc = (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);
|
||||
|
||||
BSAFile *narc = const_cast<BSAFile*>(&arc);
|
||||
|
||||
// Open the file
|
||||
StreamPtr strm = narc->getFile(passed.c_str());
|
||||
StreamPtr strm = narc->getFile(filename.c_str());
|
||||
|
||||
// Wrap it into an Ogre::DataStream.
|
||||
return DataStreamPtr(new Mangle2OgreStream(strm));
|
||||
}
|
||||
|
||||
bool exists(const String& filename) {
|
||||
return cexists(filename);
|
||||
}
|
||||
bool exists(const String& filename) {
|
||||
return arc.exists(filename.c_str());
|
||||
}
|
||||
|
||||
// Check if the file exists.
|
||||
bool cexists(const String& filename) const {
|
||||
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);
|
||||
return arc.exists(filename.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
return arc.exists(passed.c_str());
|
||||
}
|
||||
time_t getModifiedTime(const String&) { return 0; }
|
||||
|
||||
// This is never called as far as I can see.
|
||||
|
|
|
@ -326,12 +326,6 @@ public:
|
|||
Ogre::Vector3 trans; // Translation
|
||||
float scale; // Probably scale (always 1)
|
||||
};
|
||||
struct BoneTrafoCopy
|
||||
{
|
||||
Ogre::Quaternion rotation;
|
||||
Ogre::Vector3 trans;
|
||||
float scale;
|
||||
};
|
||||
|
||||
struct VertWeight
|
||||
{
|
||||
|
@ -339,26 +333,12 @@ public:
|
|||
float weight;
|
||||
};
|
||||
|
||||
|
||||
struct BoneInfo
|
||||
{
|
||||
BoneTrafo trafo;
|
||||
Ogre::Vector4 unknown;
|
||||
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;
|
||||
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
|
||||
{
|
||||
NodeList children;
|
||||
|
@ -184,28 +170,6 @@ struct NiTriShape : Node
|
|||
data.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
|
||||
|
|
|
@ -79,7 +79,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource)
|
|||
// of the early stages of development. Right now we WANT to catch
|
||||
// every error as early and intrusively as possible, as it's most
|
||||
// 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)
|
||||
{
|
||||
warn("Found no records in NIF.");
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -67,12 +67,9 @@ namespace Nif
|
|||
|
||||
namespace NifOgre
|
||||
{
|
||||
|
||||
|
||||
/** Manual resource loader for NIF meshes. This is the main class
|
||||
responsible for translating the internal NIF mesh structure into
|
||||
something Ogre can use. Later it will also handle the insertion of
|
||||
collision meshes into Bullet / OgreBullet.
|
||||
something Ogre can use.
|
||||
|
||||
You have to insert meshes manually into Ogre like this:
|
||||
|
||||
|
@ -86,93 +83,18 @@ namespace NifOgre
|
|||
*/
|
||||
class NIFLoader : Ogre::ManualResourceLoader
|
||||
{
|
||||
public:
|
||||
static int numberOfMeshes;
|
||||
static NIFLoader& getSingleton();
|
||||
static NIFLoader* getSingletonPtr();
|
||||
|
||||
public:
|
||||
virtual void loadResource(Ogre::Resource *resource);
|
||||
|
||||
static Ogre::MeshPtr load(const std::string &name,
|
||||
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:
|
||||
|
||||
NIFLoader() : resourceName(""), resourceGroup("General"), flip(false), mNormaliseNormals(false),
|
||||
mFlipVertexWinding(false), mOutputAnimFiles(false), inTheSkeletonTree(false) {}
|
||||
private:
|
||||
NIFLoader() {}
|
||||
NIFLoader(NIFLoader& n) {}
|
||||
|
||||
void calculateTransform();
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
void warn(const std::string &msg);
|
||||
void fail(const std::string &msg);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -336,7 +336,7 @@ namespace Physic
|
|||
char uniqueID[8];
|
||||
sprintf( uniqueID, "%07.3f", scale );
|
||||
std::string sid = uniqueID;
|
||||
std::string outputstring = mesh + uniqueID + "\"|";
|
||||
std::string outputstring = mesh + uniqueID;
|
||||
//std::cout << "The string" << outputstring << "\n";
|
||||
|
||||
//get the shape from the .nif
|
||||
|
|
Loading…
Reference in a new issue