mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-06-24 11:11:36 +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());
|
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,498 +6,236 @@
|
||||||
#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;
|
||||||
: insert(NULL)
|
|
||||||
, mRend(_rend)
|
|
||||||
, vecRotPos()
|
|
||||||
, time(0.0f)
|
|
||||||
, startTime(0.0f)
|
|
||||||
, stopTime(0.0f)
|
|
||||||
, animate(0)
|
|
||||||
, rindexI()
|
|
||||||
, tindexI()
|
|
||||||
, shapeNumber(0)
|
|
||||||
, shapeIndexI()
|
|
||||||
, shapes(NULL)
|
|
||||||
, transformations(NULL)
|
|
||||||
, textmappings(NULL)
|
|
||||||
, base(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Animation::~Animation()
|
Animation::Animation(OEngine::Render::OgreRenderer& _rend)
|
||||||
{
|
: insert(NULL)
|
||||||
}
|
, mRend(_rend)
|
||||||
|
, time(0.0f)
|
||||||
std::string Animation::getUniqueID(std::string mesh){
|
, startTime(0.0f)
|
||||||
int counter;
|
, stopTime(0.0f)
|
||||||
std::string copy = mesh;
|
, animate(0)
|
||||||
std::transform(copy.begin(), copy.end(), copy.begin(), ::tolower);
|
, rindexI()
|
||||||
if(mUniqueIDs.find(copy) == mUniqueIDs.end()){
|
, tindexI()
|
||||||
counter = mUniqueIDs[copy] = 0;
|
, shapeNumber(0)
|
||||||
}
|
, shapeIndexI()
|
||||||
else{
|
, transformations(NULL)
|
||||||
mUniqueIDs[copy] = mUniqueIDs[copy] + 1;
|
, textmappings(NULL)
|
||||||
counter = mUniqueIDs[copy];
|
, base(NULL)
|
||||||
}
|
{
|
||||||
|
|
||||||
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){
|
|
||||||
//If groupname is recognized set animate to true
|
|
||||||
//Set the start time and stop time
|
|
||||||
//How many times to loop
|
|
||||||
if(groupname == "all"){
|
|
||||||
animate = loops;
|
|
||||||
time = startTime;
|
|
||||||
}
|
|
||||||
else if(textmappings){
|
|
||||||
|
|
||||||
std::string startName = groupname + ": loop start";
|
Animation::~Animation()
|
||||||
std::string stopName = groupname + ": loop stop";
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool first = false;
|
void Animation::startScript(std::string groupname, int mode, int loops)
|
||||||
|
{
|
||||||
if(loops > 1){
|
//If groupname is recognized set animate to true
|
||||||
startName = groupname + ": loop start";
|
//Set the start time and stop time
|
||||||
stopName = groupname + ": loop stop";
|
//How many times to loop
|
||||||
|
if(groupname == "all")
|
||||||
for(std::map<std::string, float>::iterator iter = textmappings->begin(); iter != textmappings->end(); iter++){
|
{
|
||||||
|
animate = loops;
|
||||||
std::string current = iter->first.substr(0, startName.size());
|
time = startTime;
|
||||||
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){
|
|
||||||
startTime = iter->second;
|
|
||||||
animate = loops;
|
|
||||||
time = startTime;
|
|
||||||
first = true;
|
|
||||||
}
|
|
||||||
if(current2 == stopName){
|
|
||||||
stopTime = iter->second;
|
|
||||||
if(first)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!first){
|
|
||||||
startName = groupname + ": start";
|
|
||||||
stopName = groupname + ": stop";
|
|
||||||
|
|
||||||
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){
|
|
||||||
startTime = iter->second;
|
|
||||||
animate = loops;
|
|
||||||
time = startTime;
|
|
||||||
first = true;
|
|
||||||
}
|
|
||||||
if(current2 == stopName){
|
|
||||||
stopTime = iter->second;
|
|
||||||
if(first)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
void Animation::stopScript(){
|
|
||||||
animate = 0;
|
|
||||||
}
|
}
|
||||||
|
else if(textmappings)
|
||||||
|
{
|
||||||
|
std::string startName = groupname + ": loop start";
|
||||||
|
std::string stopName = groupname + ": loop stop";
|
||||||
|
|
||||||
void Animation::handleShapes(std::vector<Nif::NiTriShapeCopy>* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel){
|
bool first = false;
|
||||||
shapeNumber = 0;
|
|
||||||
|
|
||||||
if (allshapes == NULL || creaturemodel == NULL || skel == NULL)
|
if(loops > 1)
|
||||||
{
|
{
|
||||||
return;
|
startName = groupname + ": loop start";
|
||||||
|
stopName = groupname + ": loop stop";
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
startTime = iter->second;
|
||||||
|
animate = loops;
|
||||||
|
time = startTime;
|
||||||
|
first = true;
|
||||||
|
}
|
||||||
|
if(current2 == stopName)
|
||||||
|
{
|
||||||
|
stopTime = iter->second;
|
||||||
|
if(first)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Nif::NiTriShapeCopy>::iterator allshapesiter;
|
if(!first)
|
||||||
for(allshapesiter = allshapes->begin(); allshapesiter != allshapes->end(); allshapesiter++)
|
{
|
||||||
|
startName = groupname + ": start";
|
||||||
|
stopName = groupname + ": stop";
|
||||||
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
//std::map<unsigned short, PosAndRot> vecPosRot;
|
startTime = iter->second;
|
||||||
|
animate = loops;
|
||||||
Nif::NiTriShapeCopy& copy = *allshapesiter;
|
time = startTime;
|
||||||
std::vector<Ogre::Vector3>* allvertices = ©.vertices;
|
first = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//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;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if(current2 == stopName)
|
||||||
|
{
|
||||||
|
stopTime = iter->second;
|
||||||
|
if(first)
|
||||||
}
|
break;
|
||||||
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] )
|
|
||||||
{
|
|
||||||
i = j = 0;
|
|
||||||
x = 0.0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ( time >= times[count - 1] )
|
|
||||||
{
|
|
||||||
i = j = count - 1;
|
|
||||||
x = 0.0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( i < 0 || i >= count )
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
float tI = times[i];
|
|
||||||
if ( time > tI )
|
|
||||||
{
|
|
||||||
j = i + 1;
|
|
||||||
float tJ;
|
|
||||||
while ( time >= ( tJ = times[j]) )
|
|
||||||
{
|
|
||||||
i = j++;
|
|
||||||
tI = tJ;
|
|
||||||
}
|
|
||||||
x = ( time - tI ) / ( tJ - tI );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if ( time < tI )
|
|
||||||
{
|
|
||||||
j = i - 1;
|
|
||||||
float tJ;
|
|
||||||
while ( time <= ( tJ = times[j] ) )
|
|
||||||
{
|
|
||||||
i = j--;
|
|
||||||
tI = tJ;
|
|
||||||
}
|
|
||||||
x = ( time - tI ) / ( tJ - tI );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
j = i;
|
|
||||||
x = 0.0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animation::handleAnimationTransforms(){
|
|
||||||
|
void Animation::stopScript()
|
||||||
|
{
|
||||||
|
animate = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if(time <= times[0])
|
||||||
|
{
|
||||||
|
i = j = 0;
|
||||||
|
x = 0.0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(time >= times[count-1])
|
||||||
|
{
|
||||||
|
i = j = count - 1;
|
||||||
|
x = 0.0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i < 0 || (size_t)i >= count)
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
float tI = times[i];
|
||||||
|
if(time > tI)
|
||||||
|
{
|
||||||
|
j = i + 1;
|
||||||
|
float tJ;
|
||||||
|
while(time >= (tJ=times[j]))
|
||||||
|
{
|
||||||
|
i = j++;
|
||||||
|
tI = tJ;
|
||||||
|
}
|
||||||
|
x = (time-tI) / (tJ-tI);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(time < tI)
|
||||||
|
{
|
||||||
|
j = i - 1;
|
||||||
|
float tJ;
|
||||||
|
while(time <= (tJ=times[j]))
|
||||||
|
{
|
||||||
|
i = j--;
|
||||||
|
tI = tJ;
|
||||||
|
}
|
||||||
|
x = (time-tI) / (tJ-tI);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
j = i;
|
||||||
|
x = 0.0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
skel->_updateTransforms();
|
|
||||||
//skel->_notifyManualBonesDirty();
|
|
||||||
|
|
||||||
base->getAllAnimationStates()->_notifyDirty();
|
|
||||||
//base->_updateAnimation();
|
|
||||||
//base->_notifyMoved();
|
|
||||||
|
|
||||||
|
|
||||||
|
skel->_updateTransforms();
|
||||||
|
//skel->_notifyManualBonesDirty();
|
||||||
|
|
||||||
|
base->getAllAnimationStates()->_notifyDirty();
|
||||||
|
//base->_updateAnimation();
|
||||||
|
//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++){
|
{
|
||||||
if(time < iter->getStartTime() || time < startTime || time > iter->getStopTime())
|
for(iter = transformations->begin(); iter != transformations->end(); iter++)
|
||||||
{
|
{
|
||||||
|
if(time < iter->getStartTime() || time < startTime || time > iter->getStopTime())
|
||||||
|
{
|
||||||
|
slot++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float x;
|
||||||
|
float x2;
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
int rindexJ = rindexI[slot];
|
||||||
|
timeIndex(time, rtime, rindexI[slot], rindexJ, x2);
|
||||||
|
|
||||||
|
int tindexJ = tindexI[slot];
|
||||||
|
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()))
|
||||||
|
{
|
||||||
|
Ogre::Bone* bone = skel->getBone(iter->getBonename());
|
||||||
|
if(bTrans)
|
||||||
|
{
|
||||||
|
Ogre::Vector3 v1 = translist1[tindexI[slot]];
|
||||||
|
Ogre::Vector3 v2 = translist1[tindexJ];
|
||||||
|
t = (v1 + (v2 - v1) * x);
|
||||||
|
bone->setPosition(t);
|
||||||
|
}
|
||||||
|
if(bQuats)
|
||||||
|
{
|
||||||
|
r = Ogre::Quaternion::Slerp(x2, quats[rindexI[slot]], quats[rindexJ], true);
|
||||||
|
bone->setOrientation(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
slot++;
|
slot++;
|
||||||
continue;
|
}
|
||||||
}
|
skel->_updateTransforms();
|
||||||
|
|
||||||
float x;
|
|
||||||
float x2;
|
|
||||||
|
|
||||||
const std::vector<Ogre::Quaternion> & quats = iter->getQuat();
|
|
||||||
|
|
||||||
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())){
|
|
||||||
Ogre::Bone* bone = skel->getBone(iter->getBonename());
|
|
||||||
if(bTrans){
|
|
||||||
Ogre::Vector3 v1 = translist1[tindexI[slot]];
|
|
||||||
Ogre::Vector3 v2 = translist1[tindexJ];
|
|
||||||
t = (v1 + (v2 - v1) * x);
|
|
||||||
bone->setPosition(t);
|
|
||||||
|
|
||||||
}
|
|
||||||
if(bQuats){
|
|
||||||
r = Ogre::Quaternion::Slerp(x2, quats[rindexI[slot]], quats[rindexJ], true);
|
|
||||||
bone->setOrientation(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
slot++;
|
|
||||||
}
|
|
||||||
skel->_updateTransforms();
|
|
||||||
base->getAllAnimationStates()->_notifyDirty();
|
base->getAllAnimationStates()->_notifyDirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,60 +12,47 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
int animate;
|
int animate;
|
||||||
//Represents a rotation index for each bone
|
//Represents a rotation index for each bone
|
||||||
std::vector<int>rindexI;
|
std::vector<int>rindexI;
|
||||||
//Represents a translation index for each bone
|
//Represents a translation index for each bone
|
||||||
std::vector<int>tindexI;
|
std::vector<int>tindexI;
|
||||||
|
|
||||||
//Only shapes with morphing data will use a shape number
|
|
||||||
int shapeNumber;
|
|
||||||
std::vector<std::vector<int> > shapeIndexI;
|
|
||||||
|
|
||||||
//Ogre::SkeletonInstance* skel;
|
|
||||||
std::vector<Nif::NiTriShapeCopy>* shapes; //All the NiTriShapeData for a creature
|
|
||||||
|
|
||||||
|
|
||||||
|
//Only shapes with morphing data will use a shape number
|
||||||
|
int shapeNumber;
|
||||||
|
std::vector<std::vector<int> > shapeIndexI;
|
||||||
|
|
||||||
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);
|
||||||
void stopScript();
|
void stopScript();
|
||||||
|
|
||||||
|
|
||||||
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
|
@ -20,54 +20,43 @@ namespace MWRender{
|
||||||
|
|
||||||
class NpcAnimation: public Animation{
|
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
|
||||||
|
Ogre::Entity* lclavicle;
|
||||||
|
Ogre::Entity* rclavicle;
|
||||||
|
Ogre::Entity* rupperArm;
|
||||||
|
Ogre::Entity* lupperArm;
|
||||||
|
Ogre::Entity* rUpperLeg;
|
||||||
|
Ogre::Entity* lUpperLeg;
|
||||||
|
Ogre::Entity* lForearm;
|
||||||
|
Ogre::Entity* rForearm;
|
||||||
|
Ogre::Entity* lWrist;
|
||||||
|
Ogre::Entity* rWrist;
|
||||||
|
Ogre::Entity* rKnee;
|
||||||
|
Ogre::Entity* lKnee;
|
||||||
|
Ogre::Entity* neck;
|
||||||
|
Ogre::Entity* rAnkle;
|
||||||
|
Ogre::Entity* lAnkle;
|
||||||
|
Ogre::Entity* groin;
|
||||||
|
Ogre::Entity* lfoot;
|
||||||
|
Ogre::Entity* rfoot;
|
||||||
|
Ogre::Entity* hair;
|
||||||
|
Ogre::Entity* head;
|
||||||
|
|
||||||
|
Ogre::SceneNode* insert;
|
||||||
//Bounded Parts
|
|
||||||
Ogre::Entity* lclavicle;
|
|
||||||
Ogre::Entity* rclavicle;
|
|
||||||
Ogre::Entity* rupperArm;
|
|
||||||
Ogre::Entity* lupperArm;
|
|
||||||
Ogre::Entity* rUpperLeg;
|
|
||||||
Ogre::Entity* lUpperLeg;
|
|
||||||
Ogre::Entity* lForearm;
|
|
||||||
Ogre::Entity* rForearm;
|
|
||||||
Ogre::Entity* lWrist;
|
|
||||||
Ogre::Entity* rWrist;
|
|
||||||
Ogre::Entity* rKnee;
|
|
||||||
Ogre::Entity* lKnee;
|
|
||||||
Ogre::Entity* neck;
|
|
||||||
Ogre::Entity* rAnkle;
|
|
||||||
Ogre::Entity* lAnkle;
|
|
||||||
Ogre::Entity* groin;
|
|
||||||
Ogre::Entity* lfoot;
|
|
||||||
Ogre::Entity* rfoot;
|
|
||||||
Ogre::Entity* hair;
|
|
||||||
Ogre::Entity* head;
|
|
||||||
|
|
||||||
Ogre::SceneNode* insert;
|
|
||||||
bool isBeast;
|
bool isBeast;
|
||||||
bool isFemale;
|
bool isFemale;
|
||||||
std::string headModel;
|
std::string headModel;
|
||||||
std::string hairModel;
|
std::string hairModel;
|
||||||
std::string npcName;
|
std::string npcName;
|
||||||
std::string bodyRaceID;
|
std::string bodyRaceID;
|
||||||
float timeToChange;
|
float timeToChange;
|
||||||
MWWorld::ContainerStoreIterator robe;
|
MWWorld::ContainerStoreIterator robe;
|
||||||
MWWorld::ContainerStoreIterator helmet;
|
MWWorld::ContainerStoreIterator helmet;
|
||||||
MWWorld::ContainerStoreIterator shirt;
|
MWWorld::ContainerStoreIterator shirt;
|
||||||
MWWorld::ContainerStoreIterator cuirass;
|
MWWorld::ContainerStoreIterator cuirass;
|
||||||
|
@ -80,22 +69,19 @@ 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);
|
virtual void runAnimation(float timepassed);
|
||||||
void insertFootPart(int type, const std::string &mesh);
|
void updateParts();
|
||||||
virtual void runAnimation(float timepassed);
|
|
||||||
void updateParts();
|
|
||||||
void removeIndividualPart(int type);
|
void removeIndividualPart(int type);
|
||||||
void reserveIndividualPart(int type, int group, int priority);
|
void reserveIndividualPart(int type, int group, int priority);
|
||||||
|
|
||||||
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;
|
virtual void loadResource(Ogre::Resource *resource);
|
||||||
static NIFLoader& getSingleton();
|
|
||||||
static NIFLoader* getSingletonPtr();
|
|
||||||
|
|
||||||
virtual void loadResource(Ogre::Resource *resource);
|
static Ogre::MeshPtr load(const std::string &name,
|
||||||
|
const std::string &group="General");
|
||||||
static Ogre::MeshPtr load(const std::string &name,
|
|
||||||
const std::string &group="General");
|
|
||||||
//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) {}
|
|
||||||
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;
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
NIFLoader() {}
|
||||||
|
NIFLoader(NIFLoader& n) {}
|
||||||
|
|
||||||
|
void warn(const std::string &msg);
|
||||||
|
void fail(const std::string &msg);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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…
Reference in a new issue