pull/21/head
Marc Zinnschlag 13 years ago
parent e35aee0f89
commit 9b910dda94

@ -38,18 +38,17 @@ namespace MWClass
void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const void Npc::insertObject(const MWWorld::Ptr& ptr, MWWorld::PhysicsSystem& physics, MWWorld::Environment& environment) const
{ {
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref = ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref =
ptr.get<ESM::NPC>(); ptr.get<ESM::NPC>();
const std::string &model = ref->base->model;
assert (ref->base != NULL); assert (ref->base != NULL);
std::string headID = ref->base->head; std::string headID = ref->base->head;
std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4); std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4);
bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_"; bool beast = bodyRaceID == "b_n_khajiit_m_" || bodyRaceID == "b_n_khajiit_f_" || bodyRaceID == "b_n_argonian_m_" || bodyRaceID == "b_n_argonian_f_";
std::string smodel = "meshes\\base_anim.nif"; std::string smodel = "meshes\\base_anim.nif";
if(beast) if(beast)
smodel = "meshes\\base_animkna.nif"; smodel = "meshes\\base_animkna.nif";

@ -18,7 +18,7 @@ namespace MWRender{
mUniqueIDs[copy] = mUniqueIDs[copy] + 1; mUniqueIDs[copy] = mUniqueIDs[copy] + 1;
counter = mUniqueIDs[copy]; counter = mUniqueIDs[copy];
} }
std::stringstream out; std::stringstream out;
if(counter > 99 && counter < 1000) if(counter > 99 && counter < 1000)
out << "0"; out << "0";
@ -38,7 +38,7 @@ namespace MWRender{
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";
@ -49,7 +49,7 @@ namespace MWRender{
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());
@ -71,9 +71,9 @@ namespace MWRender{
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());
@ -92,9 +92,9 @@ namespace MWRender{
} }
} }
} }
} }
} }
void Animation::stopScript(){ void Animation::stopScript(){
animate = 0; animate = 0;
@ -103,24 +103,21 @@ namespace MWRender{
void Animation::handleShapes(std::vector<Nif::NiTriShapeCopy>* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel){ void Animation::handleShapes(std::vector<Nif::NiTriShapeCopy>* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel){
bool useHandles = skel == creaturemodel->getSkeleton(); bool useHandles = skel == creaturemodel->getSkeleton();
shapeNumber = 0; shapeNumber = 0;
std::vector<Nif::NiTriShapeCopy>::iterator allshapesiter; std::vector<Nif::NiTriShapeCopy>::iterator allshapesiter;
for(allshapesiter = allshapes->begin(); allshapesiter != allshapes->end(); allshapesiter++) for(allshapesiter = allshapes->begin(); allshapesiter != allshapes->end(); allshapesiter++)
{ {
//std::map<unsigned short, PosAndRot> vecPosRot; //std::map<unsigned short, PosAndRot> vecPosRot;
Nif::NiTriShapeCopy& copy = *allshapesiter; Nif::NiTriShapeCopy& copy = *allshapesiter;
std::vector<Ogre::Vector3>* allvertices = &copy.vertices; std::vector<Ogre::Vector3>* allvertices = &copy.vertices;
std::vector<Ogre::Vector3>* allnormals = &copy.normals;
//std::set<unsigned int> vertices; //std::set<unsigned int> vertices;
//std::set<unsigned int> normals; //std::set<unsigned int> normals;
//std::vector<Nif::NiSkinData::BoneInfoCopy> boneinfovector = copy.boneinfo; //std::vector<Nif::NiSkinData::BoneInfoCopy> boneinfovector = copy.boneinfo;
std::map<int, std::vector<Nif::NiSkinData::IndividualWeight>>* verticesToChange = &copy.vertsToWeights; std::map<int, std::vector<Nif::NiSkinData::IndividualWeight> >* verticesToChange = &copy.vertsToWeights;
//std::cout << "Name " << copy.sname << "\n"; //std::cout << "Name " << copy.sname << "\n";
Ogre::HardwareVertexBufferSharedPtr vbuf = creaturemodel->getMesh()->getSubMesh(copy.sname)->vertexData->vertexBufferBinding->getBuffer(0); 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)); Ogre::Real* pReal = static_cast<Ogre::Real*>(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
@ -135,7 +132,7 @@ namespace MWRender{
if(copy.vertices.size() == initialVertices.size()) if(copy.vertices.size() == initialVertices.size())
{ {
//Create if it doesn't already exist //Create if it doesn't already exist
if(shapeIndexI.size() == shapeNumber) if(shapeIndexI.size() == static_cast<std::size_t> (shapeNumber))
{ {
std::vector<int> vec; std::vector<int> vec;
shapeIndexI.push_back(vec); shapeIndexI.push_back(vec);
@ -165,10 +162,10 @@ namespace MWRender{
} }
} }
allvertices = &initialVertices; allvertices = &initialVertices;
} }
shapeNumber++; shapeNumber++;
@ -177,8 +174,8 @@ namespace MWRender{
if(verticesToChange->size() > 0){ if(verticesToChange->size() > 0){
for(std::map<int, std::vector<Nif::NiSkinData::IndividualWeight>>::iterator iter = verticesToChange->begin(); for(std::map<int, std::vector<Nif::NiSkinData::IndividualWeight> >::iterator iter = verticesToChange->begin();
iter != verticesToChange->end(); iter++) iter != verticesToChange->end(); iter++)
{ {
std::vector<Nif::NiSkinData::IndividualWeight> inds = iter->second; std::vector<Nif::NiSkinData::IndividualWeight> inds = iter->second;
@ -192,15 +189,15 @@ namespace MWRender{
} }
else else
bonePtr = skel->getBone(boneinfocopy->bonename); bonePtr = skel->getBone(boneinfocopy->bonename);
Ogre::Vector3 vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans; Ogre::Vector3 vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
Ogre::Quaternion vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation; Ogre::Quaternion vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
/*if(vecPosRot.find(boneinfocopy->bonehandle) == vecPosRot.end()){ /*if(vecPosRot.find(boneinfocopy->bonehandle) == vecPosRot.end()){
vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans; vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation; vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
if(useHandles){ if(useHandles){
PosAndRot both; PosAndRot both;
both.vecPos = vecPos; both.vecPos = vecPos;
@ -215,9 +212,9 @@ namespace MWRender{
}*/ }*/
Ogre::Vector3 absVertPos = (vecPos + vecRot * currentVertex) * inds[0].weight; Ogre::Vector3 absVertPos = (vecPos + vecRot * currentVertex) * inds[0].weight;
for(int i = 1; i < inds.size(); i++){
for(std::size_t i = 1; i < inds.size(); i++){
boneinfocopy = &(allshapesiter->boneinfo[inds[i].boneinfocopyindex]); boneinfocopy = &(allshapesiter->boneinfo[inds[i].boneinfocopyindex]);
if(useHandles) if(useHandles)
bonePtr = skel->getBone(boneinfocopy->bonehandle); bonePtr = skel->getBone(boneinfocopy->bonehandle);
@ -229,7 +226,7 @@ namespace MWRender{
/*if(vecPosRot.find(boneinfocopy->bonehandle) == vecPosRot.end()){ /*if(vecPosRot.find(boneinfocopy->bonehandle) == vecPosRot.end()){
vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans; vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans;
vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation; vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation;
if(useHandles){ if(useHandles){
PosAndRot both; PosAndRot both;
both.vecPos = vecPos; both.vecPos = vecPos;
@ -243,24 +240,25 @@ namespace MWRender{
vecRot = both.vecRot; vecRot = both.vecRot;
}*/ }*/
absVertPos += (vecPos + vecRot * currentVertex) * inds[i].weight; absVertPos += (vecPos + vecRot * currentVertex) * inds[i].weight;
} }
Ogre::Real* addr = (pReal + 3 * verIndex); Ogre::Real* addr = (pReal + 3 * verIndex);
*addr = absVertPos.x; *addr = absVertPos.x;
*(addr+1) = absVertPos.y; *(addr+1) = absVertPos.y;
*(addr+2) = absVertPos.z; *(addr+2) = absVertPos.z;
} }
/*for (unsigned int i = 0; i < boneinfovector.size(); i++) #if 0
for (unsigned int i = 0; i < boneinfovector.size(); i++)
{ {
Nif::NiSkinData::BoneInfoCopy boneinfo = boneinfovector[i]; Nif::NiSkinData::BoneInfoCopy boneinfo = boneinfovector[i];
if(skel->hasBone(boneinfo.bonename)){ if(skel->hasBone(boneinfo.bonename)){
Ogre::Bone *bonePtr = skel->getBone(boneinfo.bonename); Ogre::Bone *bonePtr = skel->getBone(boneinfo.bonename);
Ogre::Vector3 vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfo.trafo.trans; Ogre::Vector3 vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfo.trafo.trans;
Ogre::Quaternion vecRot = bonePtr->_getDerivedOrientation() * boneinfo.trafo.rotation; Ogre::Quaternion vecRot = bonePtr->_getDerivedOrientation() * boneinfo.trafo.rotation;
for (unsigned int j=0; j < boneinfo.weights.size(); j++) for (unsigned int j=0; j < boneinfo.weights.size(); j++)
{ {
unsigned int verIndex = boneinfo.weights[j].vertex; unsigned int verIndex = boneinfo.weights[j].vertex;
@ -273,12 +271,12 @@ namespace MWRender{
*addr = absVertPos.x; *addr = absVertPos.x;
*(addr+1) = absVertPos.y; *(addr+1) = absVertPos.y;
*(addr+2) = absVertPos.z; *(addr+2) = absVertPos.z;
} }
else else
{ {
Ogre::Vector3 absVertPos = vecPos + vecRot * allvertices[verIndex]; Ogre::Vector3 absVertPos = vecPos + vecRot * allvertices[verIndex];
absVertPos = absVertPos * boneinfo.weights[j].weight; absVertPos = absVertPos * boneinfo.weights[j].weight;
Ogre::Vector3 old = Ogre::Vector3(pReal + 3 * verIndex); Ogre::Vector3 old = Ogre::Vector3(pReal + 3 * verIndex);
@ -287,12 +285,12 @@ namespace MWRender{
*addr = absVertPos.x; *addr = absVertPos.x;
*(addr+1) = absVertPos.y; *(addr+1) = absVertPos.y;
*(addr+2) = absVertPos.z; *(addr+2) = absVertPos.z;
//std::cout << "Vertex" << verIndex << "Weight: " << boneinfo.weights[i].weight << "was seen twice\n"; //std::cout << "Vertex" << verIndex << "Weight: " << boneinfo.weights[i].weight << "was seen twice\n";
} }
/*if(normals.find(verIndex) == normals.end()) if(normals.find(verIndex) == normals.end())
{ {
Ogre::Vector3 absNormalsPos = vecRot * allnormals[verIndex]; Ogre::Vector3 absNormalsPos = vecRot * allnormals[verIndex];
absNormalsPos = absNormalsPos * boneinfo.weights[j].weight; absNormalsPos = absNormalsPos * boneinfo.weights[j].weight;
@ -314,16 +312,16 @@ namespace MWRender{
*(addr+1) = absNormalsPos.y; *(addr+1) = absNormalsPos.y;
*(addr+2) = absNormalsPos.z; *(addr+2) = absNormalsPos.z;
}*/ }
#endif
//} //}
//} //}
//} //Comment out //} //Comment out
; ;
} }
else else
{ {
//Ogre::Bone *bonePtr = creaturemodel->getSkeleton()->getBone(copy.bonename); //Ogre::Bone *bonePtr = creaturemodel->getSkeleton()->getBone(copy.bonename);
@ -337,9 +335,9 @@ namespace MWRender{
float scale; float scale;
if(skel->hasBone(*boneSequenceIter)){ if(skel->hasBone(*boneSequenceIter)){
Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter); Ogre::Bone *bonePtr = skel->getBone(*boneSequenceIter);
transmult = bonePtr->getPosition(); transmult = bonePtr->getPosition();
rotmult = bonePtr->getOrientation(); rotmult = bonePtr->getOrientation();
@ -368,13 +366,13 @@ namespace MWRender{
rotmult = shaperot; rotmult = shaperot;
scale = shapescale; scale = shapescale;
} }
// Computes C = B + AxC*scale // Computes C = B + AxC*scale
// final_vector = old_vector + old_rotation*new_vector*old_scale/ // final_vector = old_vector + old_rotation*new_vector*old_scale/
for(unsigned int i = 0; i < allvertices->size(); i++){ for(unsigned int i = 0; i < allvertices->size(); i++){
Ogre::Vector3 current = transmult + rotmult * (*allvertices)[i]; Ogre::Vector3 current = transmult + rotmult * (*allvertices)[i];
Ogre::Real* addr = pReal + i * 3; Ogre::Real* addr = pReal + i * 3;
@ -414,10 +412,10 @@ namespace MWRender{
x = 0.0; x = 0.0;
return true; return true;
} }
if ( i < 0 || i >= count ) if ( i < 0 || i >= count )
i = 0; i = 0;
float tI = times[i]; float tI = times[i];
if ( time > tI ) if ( time > tI )
{ {
@ -457,11 +455,11 @@ namespace MWRender{
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
skel->_updateTransforms(); skel->_updateTransforms();
//skel->_notifyManualBonesDirty(); //skel->_notifyManualBonesDirty();
@ -474,7 +472,7 @@ namespace MWRender{
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->_updateTransforms();
// skel->_notifyManualBonesDirty(); // skel->_notifyManualBonesDirty();
@ -492,17 +490,17 @@ namespace MWRender{
slot++; slot++;
//iter++; //iter++;
continue; continue;
} }
float x; float x;
float x2; float x2;
std::vector<Ogre::Quaternion> quats = iter->getQuat(); std::vector<Ogre::Quaternion> quats = iter->getQuat();
std::vector<float> ttime = iter->gettTime(); std::vector<float> ttime = iter->gettTime();
std::vector<float>::iterator ttimeiter = ttime.begin(); std::vector<float>::iterator ttimeiter = ttime.begin();
std::vector<float> rtime = iter->getrTime(); std::vector<float> rtime = iter->getrTime();
int rindexJ = 0; int rindexJ = 0;
timeIndex(time, rtime, rindexI[slot], rindexJ, x2); timeIndex(time, rtime, rindexI[slot], rindexJ, x2);
@ -516,15 +514,15 @@ namespace MWRender{
//std::cout << "X: " << x << " X2: " << x2 << "\n"; //std::cout << "X: " << x << " X2: " << x2 << "\n";
Ogre::Vector3 t; Ogre::Vector3 t;
Ogre::Quaternion r; Ogre::Quaternion r;
bool bTrans = translist1.size() > 0; bool bTrans = translist1.size() > 0;
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);
} }
bool bQuats = quats.size() > 0; bool bQuats = quats.size() > 0;
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);
@ -538,15 +536,15 @@ namespace MWRender{
if(bQuats) if(bQuats)
bone->setOrientation(r); bone->setOrientation(r);
skel->_updateTransforms(); skel->_updateTransforms();
//skel->_notifyManualBonesDirty(); //skel->_notifyManualBonesDirty();
base->getAllAnimationStates()->_notifyDirty(); base->getAllAnimationStates()->_notifyDirty();
//base->_updateAnimation(); //base->_updateAnimation();
base->_notifyMoved(); base->_notifyMoved();
} }
for(int i = 0; i < entityparts.size(); i++){ for(std::size_t i = 0; i < entityparts.size(); i++){
skel = entityparts[i]->getSkeleton(); skel = entityparts[i]->getSkeleton();
if(skel->hasBone(iter->getBonename())){ if(skel->hasBone(iter->getBonename())){
Ogre::Bone* bone = skel->getBone(iter->getBonename()); Ogre::Bone* bone = skel->getBone(iter->getBonename());
@ -554,17 +552,17 @@ namespace MWRender{
bone->setPosition(t); bone->setPosition(t);
if(bQuats) if(bQuats)
bone->setOrientation(r); bone->setOrientation(r);
skel->_updateTransforms(); skel->_updateTransforms();
//skel->_notifyManualBonesDirty(); //skel->_notifyManualBonesDirty();
entityparts[i]->getAllAnimationStates()->_notifyDirty(); entityparts[i]->getAllAnimationStates()->_notifyDirty();
// entityparts[i]->_updateAnimation(); // entityparts[i]->_updateAnimation();
entityparts[i]->_notifyMoved(); entityparts[i]->_notifyMoved();
} }
} }
slot++; slot++;
} }
} }
} }
} }

@ -14,7 +14,7 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, MWWorld::Environme
ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *ref = ESMS::LiveCellRef<ESM::Creature, MWWorld::RefData> *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; const std::string &mesh = "meshes\\" + ref->base->model;
std::string meshNumbered = mesh + getUniqueID(mesh) + ">|"; std::string meshNumbered = mesh + getUniqueID(mesh) + ">|";
@ -22,9 +22,9 @@ CreatureAnimation::CreatureAnimation(const MWWorld::Ptr& ptr, MWWorld::Environme
base = mRend.getScene()->createEntity(meshNumbered); base = mRend.getScene()->createEntity(meshNumbered);
std::string meshZero = mesh + "0000>|"; std::string meshZero = mesh + "0000>|";
if(transformations = (NIFLoader::getSingletonPtr())->getAnim(meshZero)){ if((transformations = (NIFLoader::getSingletonPtr())->getAnim(meshZero))){
for(int init = 0; init < transformations->size(); init++){ for(std::size_t init = 0; init < transformations->size(); init++){
rindexI.push_back(0); rindexI.push_back(0);
tindexI.push_back(0); tindexI.push_back(0);
} }
@ -53,10 +53,10 @@ void CreatureAnimation::runAnimation(float timepassed){
else else
time = startTime + (time - stopTime); time = startTime + (time - stopTime);
} }
handleAnimationTransforms(); handleAnimationTransforms();
handleShapes(shapes, base, base->getSkeleton()); handleShapes(shapes, base, base->getSkeleton());
} }
} }
} }

@ -13,7 +13,7 @@ NpcAnimation::~NpcAnimation(){
NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend): Animation(_env,_rend){ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,OEngine::Render::OgreRenderer& _rend): Animation(_env,_rend){
ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref = ESMS::LiveCellRef<ESM::NPC, MWWorld::RefData> *ref =
ptr.get<ESM::NPC>(); ptr.get<ESM::NPC>();
//Part selection on last character of the file string //Part selection on last character of the file string
// " Tri Chest // " Tri Chest
// * Tri Tail // * Tri Tail
@ -35,10 +35,10 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
std::string hairID = ref->base->hair; std::string hairID = ref->base->hair;
std::string headID = ref->base->head; std::string headID = ref->base->head;
std::string npcName = ref->base->name; std::string npcName = ref->base->name;
//ESMStore::Races r = //ESMStore::Races r =
const ESM::Race* race = mEnvironment.mWorld->getStore().races.find(ref->base->race); const ESM::Race* race = mEnvironment.mWorld->getStore().races.find(ref->base->race);
std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4); std::string bodyRaceID = headID.substr(0, headID.find_last_of("head_") - 4);
char secondtolast = bodyRaceID.at(bodyRaceID.length() - 2); char secondtolast = bodyRaceID.at(bodyRaceID.length() - 2);
bool female = tolower(secondtolast) == 'f'; bool female = tolower(secondtolast) == 'f';
@ -51,7 +51,7 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
std::cout << " Sex: Male" << " Height: " << race->data.height.male << "\n"; std::cout << " Sex: Male" << " Height: " << race->data.height.male << "\n";
}*/ }*/
std::string smodel = "meshes\\base_anim.nif"; std::string smodel = "meshes\\base_anim.nif";
if(beast) if(beast)
@ -61,25 +61,25 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
assert(insert); assert(insert);
NifOgre::NIFLoader::load(smodel); NifOgre::NIFLoader::load(smodel);
base = mRend.getScene()->createEntity(smodel); base = mRend.getScene()->createEntity(smodel);
base->setSkipAnimationStateUpdate(true); //Magical line of code, this makes the bones base->setSkipAnimationStateUpdate(true); //Magical line of code, this makes the bones
//stay in the same place when we skipanim, or open a gui window //stay in the same place when we skipanim, or open a gui window
if(transformations = (NIFLoader::getSingletonPtr())->getAnim(smodel)){ if((transformations = (NIFLoader::getSingletonPtr())->getAnim(smodel))){
for(unsigned int init = 0; init < transformations->size(); init++){ for(unsigned int init = 0; init < transformations->size(); init++){
rindexI.push_back(0); rindexI.push_back(0);
tindexI.push_back(0); tindexI.push_back(0);
} }
stopTime = transformations->begin()->getStopTime(); stopTime = transformations->begin()->getStopTime();
startTime = transformations->begin()->getStartTime(); startTime = transformations->begin()->getStartTime();
} }
textmappings = NIFLoader::getSingletonPtr()->getTextIndices(smodel); textmappings = NIFLoader::getSingletonPtr()->getTextIndices(smodel);
insert->attachObject(base); insert->attachObject(base);
if(female) if(female)
insert->scale(race->data.height.female, race->data.height.female, race->data.height.female); insert->scale(race->data.height.female, race->data.height.female, race->data.height.female);
else else
@ -108,18 +108,18 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
forearml = mEnvironment.mWorld->getStore().bodyParts.search ("b_n_argonian_m_forearm"); //We need two forearml = mEnvironment.mWorld->getStore().bodyParts.search ("b_n_argonian_m_forearm"); //We need two
if(!handl) if(!handl)
handl = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hands"); handl = mEnvironment.mWorld->getStore().bodyParts.search (bodyRaceID + "hands");
//const ESM::BodyPart* claviclel = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "clavicle"); //const ESM::BodyPart* claviclel = environment.mWorld->getStore().bodyParts.search (bodyRaceID + "clavicle");
//const ESM::BodyPart* clavicler = claviclel; //const ESM::BodyPart* clavicler = claviclel;
const ESM::BodyPart* handr = handl; const ESM::BodyPart* handr = handl;
const ESM::BodyPart* forearmr = forearml; const ESM::BodyPart* forearmr = forearml;
const ESM::BodyPart* wristr = wristl; const ESM::BodyPart* wristr = wristl;
const ESM::BodyPart* armr = arml; const ESM::BodyPart* armr = arml;
if(upperleg){ if(upperleg){
insertBoundedPart("meshes\\" + upperleg->model + "*|", "Left Upper Leg"); insertBoundedPart("meshes\\" + upperleg->model + "*|", "Left Upper Leg");
insertBoundedPart("meshes\\" + upperleg->model, "Right Upper Leg"); insertBoundedPart("meshes\\" + upperleg->model, "Right Upper Leg");
} }
if(foot){ if(foot){
if(bodyRaceID.compare("b_n_khajiit_m_") == 0) if(bodyRaceID.compare("b_n_khajiit_m_") == 0)
@ -139,10 +139,10 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
{ {
insertBoundedPart("meshes\\" + knee->model + "*|", "Left Knee"); //e insertBoundedPart("meshes\\" + knee->model + "*|", "Left Knee"); //e
insertBoundedPart("meshes\\" + knee->model, "Right Knee"); //e insertBoundedPart("meshes\\" + knee->model, "Right Knee"); //e
} }
if(ankle){ if(ankle){
insertBoundedPart("meshes\\" + ankle->model + "*|", "Left Ankle"); //Ogre::Quaternion(Ogre::Radian(3.14 / 4), Ogre::Vector3(1, 0, 0)),blank); //1,0,0, blank); insertBoundedPart("meshes\\" + ankle->model + "*|", "Left Ankle"); //Ogre::Quaternion(Ogre::Radian(3.14 / 4), Ogre::Vector3(1, 0, 0)),blank); //1,0,0, blank);
insertBoundedPart("meshes\\" + ankle->model, "Right Ankle"); insertBoundedPart("meshes\\" + ankle->model, "Right Ankle");
} }
@ -167,17 +167,17 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
if(wristl) if(wristl)
insertBoundedPart("meshes\\" + wristl->model + "*|", "Left Wrist"); insertBoundedPart("meshes\\" + wristl->model + "*|", "Left Wrist");
/*if(claviclel) /*if(claviclel)
insertBoundedPart("meshes\\" + claviclel->model + "*|", "Left Clavicle", base); insertBoundedPart("meshes\\" + claviclel->model + "*|", "Left Clavicle", base);
if(clavicler) if(clavicler)
insertBoundedPart("meshes\\" + clavicler->model , "Right Clavicle", base);*/ insertBoundedPart("meshes\\" + clavicler->model , "Right Clavicle", base);*/
if(neck) if(neck)
{ {
insertBoundedPart("meshes\\" + neck->model, "Neck"); insertBoundedPart("meshes\\" + neck->model, "Neck");
@ -186,19 +186,19 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
insertBoundedPart("meshes\\" + head->model, "Head"); insertBoundedPart("meshes\\" + head->model, "Head");
if(hair) if(hair)
insertBoundedPart("meshes\\" + hair->model, "Head"); insertBoundedPart("meshes\\" + hair->model, "Head");
if (chest){ if (chest){
insertFreePart("meshes\\" + chest->model, ">\"", insert); insertFreePart("meshes\\" + chest->model, ">\"", insert);
} }
if (handr){ if (handr){
insertFreePart("meshes\\" + handr->model , ">?", insert); insertFreePart("meshes\\" + handr->model , ">?", insert);
} }
if (handl){ if (handl){
insertFreePart("meshes\\" + handl->model, ">>", insert); insertFreePart("meshes\\" + handl->model, ">>", insert);
} }
if(tail){ if(tail){
insertFreePart("meshes\\" + tail->model, ">*", insert); insertFreePart("meshes\\" + tail->model, ">*", insert);
@ -215,16 +215,16 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, MWWorld::Environment& _env,O
Ogre::Entity* NpcAnimation::insertBoundedPart(const std::string &mesh, std::string bonename){ Ogre::Entity* NpcAnimation::insertBoundedPart(const std::string &mesh, std::string bonename){
NIFLoader::load(mesh); NIFLoader::load(mesh);
Entity* ent = mRend.getScene()->createEntity(mesh); Entity* ent = mRend.getScene()->createEntity(mesh);
base->attachObjectToBone(bonename, ent); base->attachObjectToBone(bonename, ent);
return ent; return ent;
} }
void NpcAnimation::insertFreePart(const std::string &mesh, const std::string suffix, Ogre::SceneNode* insert){ void NpcAnimation::insertFreePart(const std::string &mesh, const std::string suffix, Ogre::SceneNode* insert){
std::string meshNumbered = mesh + getUniqueID(mesh + suffix) + suffix; std::string meshNumbered = mesh + getUniqueID(mesh + suffix) + suffix;
NIFLoader::load(meshNumbered); NIFLoader::load(meshNumbered);
Ogre::Entity* ent = mRend.getScene()->createEntity(meshNumbered); Ogre::Entity* ent = mRend.getScene()->createEntity(meshNumbered);
/*MaterialPtr material = ent->getSubEntity(0)->getMaterial(); /*MaterialPtr material = ent->getSubEntity(0)->getMaterial();
material->removeAllTechniques(); material->removeAllTechniques();
@ -234,7 +234,7 @@ void NpcAnimation::insertFreePart(const std::string &mesh, const std::string suf
pass2->setVertexProgram("Ogre/HardwareSkinningTwoWeights"); pass2->setVertexProgram("Ogre/HardwareSkinningTwoWeights");
pass2->setColourWriteEnabled(false); pass2->setColourWriteEnabled(false);
//tech->setSchemeName("blahblah");*/ //tech->setSchemeName("blahblah");*/
insert->attachObject(ent); insert->attachObject(ent);
entityparts.push_back(ent); entityparts.push_back(ent);
@ -244,7 +244,7 @@ void NpcAnimation::insertFreePart(const std::string &mesh, const std::string suf
handleShapes(shapes, ent, base->getSkeleton()); handleShapes(shapes, ent, base->getSkeleton());
} }
} }
@ -256,10 +256,10 @@ void NpcAnimation::runAnimation(float timepassed){
//3. Handle the shapes dependent on animation transforms //3. Handle the shapes dependent on animation transforms
if(animate > 0){ if(animate > 0){
time += timepassed; time += timepassed;
if(time > stopTime){ if(time > stopTime){
animate--; animate--;
if(animate == 0) if(animate == 0)
time = stopTime; time = stopTime;
else else
@ -270,21 +270,21 @@ void NpcAnimation::runAnimation(float timepassed){
Ogre::Vector3 current = insert->_getWorldAABB().getCenter(); Ogre::Vector3 current = insert->_getWorldAABB().getCenter();
//This is the attempt at npc physics //This is the attempt at npc physics
//mEnvironment.mWorld->setObjectPhysicsPosition(insert->getName(), current); //mEnvironment.mWorld->setObjectPhysicsPosition(insert->getName(), current);
/*if(base->hasSkeleton()) /*if(base->hasSkeleton())
{ {
Ogre::Quaternion boneQuat = rotate; Ogre::Quaternion boneQuat = rotate;
Ogre::Vector3 boneTrans = trans; Ogre::Vector3 boneTrans = trans;
mEnvironment.mWorld->setObjectPhysicsPosition(insert->getName(), boneTrans + insert->getPosition()); mEnvironment.mWorld->setObjectPhysicsPosition(insert->getName(), boneTrans + insert->getPosition());
//mEnvironment.mWorld->setObjectPhysicsRotation(insert->getName(), boneQuat * insert->getOrientation()); //mEnvironment.mWorld->setObjectPhysicsRotation(insert->getName(), boneQuat * insert->getOrientation());
}*/ }*/
std::vector<std::vector<Nif::NiTriShapeCopy>*>::iterator shapepartsiter = shapeparts.begin(); std::vector<std::vector<Nif::NiTriShapeCopy>*>::iterator shapepartsiter = shapeparts.begin();
std::vector<Ogre::Entity*>::iterator entitypartsiter = entityparts.begin(); std::vector<Ogre::Entity*>::iterator entitypartsiter = entityparts.begin();
while(shapepartsiter != shapeparts.end()) while(shapepartsiter != shapeparts.end())
@ -292,12 +292,12 @@ void NpcAnimation::runAnimation(float timepassed){
std::vector<Nif::NiTriShapeCopy>* shapes = *shapepartsiter; std::vector<Nif::NiTriShapeCopy>* shapes = *shapepartsiter;
Ogre::Entity* theentity = *entitypartsiter; Ogre::Entity* theentity = *entitypartsiter;
/* /*
Pass* pass = theentity->getSubEntity(0)->getMaterial()->getBestTechnique()->getPass(0); Pass* pass = theentity->getSubEntity(0)->getMaterial()->getBestTechnique()->getPass(0);
if (pass->hasVertexProgram() && pass->getVertexProgram()->isSkeletalAnimationIncluded()) if (pass->hasVertexProgram() && pass->getVertexProgram()->isSkeletalAnimationIncluded())
std::cout << "It's hardware\n"; std::cout << "It's hardware\n";
else else
std::cout << "It's software\n";*/ std::cout << "It's software\n";*/
handleShapes(shapes, theentity, theentity->getSkeleton()); handleShapes(shapes, theentity, theentity->getSkeleton());
shapepartsiter++; shapepartsiter++;
entitypartsiter++; entitypartsiter++;
@ -305,4 +305,4 @@ void NpcAnimation::runAnimation(float timepassed){
} }
} }
} }

@ -22,7 +22,7 @@ namespace MWRender {
RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine, MWWorld::Environment& environment) RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine, MWWorld::Environment& environment)
:mRendering(_rend), mObjects(mRendering), mDebugging(engine), mActors(mRendering, environment) :mRendering(_rend), mObjects(mRendering), mActors(mRendering, environment), mDebugging(engine)
{ {
mRendering.createScene("PlayerCam", 55, 5); mRendering.createScene("PlayerCam", 55, 5);
mSkyManager = MWRender::SkyManager::create(mRendering.getWindow(), mRendering.getCamera(), resDir); mSkyManager = MWRender::SkyManager::create(mRendering.getWindow(), mRendering.getCamera(), resDir);

@ -103,7 +103,7 @@ struct NiTriShapeCopy
std::vector<Ogre::Vector3> vertices; std::vector<Ogre::Vector3> vertices;
std::vector<Ogre::Vector3> normals; std::vector<Ogre::Vector3> normals;
std::vector<Nif::NiSkinData::BoneInfoCopy> boneinfo; std::vector<Nif::NiSkinData::BoneInfoCopy> boneinfo;
std::map<int, std::vector<Nif::NiSkinData::IndividualWeight>> vertsToWeights; std::map<int, std::vector<Nif::NiSkinData::IndividualWeight> > vertsToWeights;
Nif::NiMorphData morph; Nif::NiMorphData morph;
}; };
@ -158,13 +158,13 @@ struct NiTriShape : Node
{ {
float *current = (float*) (ptr + i * 3); float *current = (float*) (ptr + i * 3);
copy.vertices.push_back(Ogre::Vector3(*current, *(current + 1), *(current + 2))); copy.vertices.push_back(Ogre::Vector3(*current, *(current + 1), *(current + 2)));
if(ptrNormals){ if(ptrNormals){
float *currentNormals = (float*) (ptrNormals + i * 3); float *currentNormals = (float*) (ptrNormals + i * 3);
copy.normals.push_back(Ogre::Vector3(*currentNormals, *(currentNormals + 1), *(currentNormals + 2))); copy.normals.push_back(Ogre::Vector3(*currentNormals, *(currentNormals + 1), *(currentNormals + 2)));
} }
} }
return copy; return copy;
} }

@ -222,7 +222,7 @@ void NIFLoader::createMaterial(const String &name,
//Hardware Skinning code, textures may be the wrong color if enabled //Hardware Skinning code, textures may be the wrong color if enabled
/*if(!mSkel.isNull()){ /*if(!mSkel.isNull()){
material->removeAllTechniques(); material->removeAllTechniques();
Ogre::Technique* tech = material->createTechnique(); Ogre::Technique* tech = material->createTechnique();
//tech->setSchemeName("blahblah"); //tech->setSchemeName("blahblah");
Pass* pass = tech->createPass(); Pass* pass = tech->createPass();
@ -234,8 +234,8 @@ void NIFLoader::createMaterial(const String &name,
// will automatically be loaded when needed. If not (such as for // will automatically be loaded when needed. If not (such as for
// internal NIF textures that we might support later), we should // internal NIF textures that we might support later), we should
// already have inserted a manual loader for the texture. // already have inserted a manual loader for the texture.
if (!texName.empty()) if (!texName.empty())
{ {
Pass *pass = material->getTechnique(0)->getPass(0); Pass *pass = material->getTechnique(0)->getPass(0);
@ -295,8 +295,8 @@ void NIFLoader::createMaterial(const String &name,
material->setSpecular(specular.array[0], specular.array[1], specular.array[2], alpha); material->setSpecular(specular.array[0], specular.array[1], specular.array[2], alpha);
material->setSelfIllumination(emissive.array[0], emissive.array[1], emissive.array[2]); material->setSelfIllumination(emissive.array[0], emissive.array[1], emissive.array[2]);
material->setShininess(glossiness); material->setShininess(glossiness);
} }
// Takes a name and adds a unique part to it. This is just used to // Takes a name and adds a unique part to it. This is just used to
@ -359,7 +359,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
HardwareBufferManager::getSingleton().createVertexBuffer( HardwareBufferManager::getSingleton().createVertexBuffer(
VertexElement::getTypeSize(VET_FLOAT3), VertexElement::getTypeSize(VET_FLOAT3),
numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
if(flip) if(flip)
{ {
float *datamod = new float[data->vertices.length]; float *datamod = new float[data->vertices.length];
@ -381,7 +381,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
{ {
vbuf->writeData(0, vbuf->getSizeInBytes(), data->vertices.ptr, false); vbuf->writeData(0, vbuf->getSizeInBytes(), data->vertices.ptr, false);
} }
VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding; VertexBufferBinding* bind = sub->vertexData->vertexBufferBinding;
bind->setBinding(nextBuf++, vbuf); bind->setBinding(nextBuf++, vbuf);
@ -392,7 +392,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( vbuf = HardwareBufferManager::getSingleton().createVertexBuffer(
VertexElement::getTypeSize(VET_FLOAT3), VertexElement::getTypeSize(VET_FLOAT3),
numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);
if(flip) if(flip)
{ {
Quaternion rotation = mTransform.extractQuaternion(); Quaternion rotation = mTransform.extractQuaternion();
@ -456,10 +456,10 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
if(flip) if(flip)
{ {
float *datamod = new float[data->uvlist.length]; float *datamod = new float[data->uvlist.length];
for(unsigned int i = 0; i < data->uvlist.length; i+=2){ for(unsigned int i = 0; i < data->uvlist.length; i+=2){
float x = *(data->uvlist.ptr + i); float x = *(data->uvlist.ptr + i);
float y = *(data->uvlist.ptr + i + 1); float y = *(data->uvlist.ptr + i + 1);
datamod[i] =x; datamod[i] =x;
@ -474,10 +474,10 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
// Triangle faces - The total number of triangle points // Triangle faces - The total number of triangle points
int numFaces = data->triangles.length; int numFaces = data->triangles.length;
if (numFaces) if (numFaces)
{ {
sub->indexData->indexCount = numFaces; sub->indexData->indexCount = numFaces;
sub->indexData->indexStart = 0; sub->indexData->indexStart = 0;
HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton(). HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
@ -508,14 +508,14 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std
index += 3; index += 3;
} }
ibuf->writeData(0, ibuf->getSizeInBytes(), datamod, false); ibuf->writeData(0, ibuf->getSizeInBytes(), datamod, false);
} }
else else
ibuf->writeData(0, ibuf->getSizeInBytes(), data->triangles.ptr, false); ibuf->writeData(0, ibuf->getSizeInBytes(), data->triangles.ptr, false);
sub->indexData->indexBuffer = ibuf; sub->indexData->indexBuffer = ibuf;
} }
@ -753,9 +753,9 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
//use niskindata for the position of vertices. //use niskindata for the position of vertices.
if (!shape->skin.empty()) if (!shape->skin.empty())
{ {
// vector that stores if the position of a vertex is absolute // vector that stores if the position of a vertex is absolute
std::vector<bool> vertexPosAbsolut(numVerts,false); std::vector<bool> vertexPosAbsolut(numVerts,false);
std::vector<Ogre::Vector3> vertexPosOriginal(numVerts, Ogre::Vector3::ZERO); std::vector<Ogre::Vector3> vertexPosOriginal(numVerts, Ogre::Vector3::ZERO);
@ -791,7 +791,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
bonePtr = mSkel->getBone(shape->skin->bones[boneIndex].name.toString()); bonePtr = mSkel->getBone(shape->skin->bones[boneIndex].name.toString());
// final_vector = old_vector + old_rotation*new_vector*old_scale // final_vector = old_vector + old_rotation*new_vector*old_scale
Nif::NiSkinData::BoneInfoCopy boneinfocopy; Nif::NiSkinData::BoneInfoCopy boneinfocopy;
boneinfocopy.trafo.rotation = convertRotation(it->trafo->rotation); boneinfocopy.trafo.rotation = convertRotation(it->trafo->rotation);
@ -841,7 +841,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
Vector3 absNormalsPos = vecRot * Vector3(ptrNormals + verIndex *3); Vector3 absNormalsPos = vecRot * Vector3(ptrNormals + verIndex *3);
absNormalsPos = absNormalsPos * (it->weights.ptr + i)->weight; absNormalsPos = absNormalsPos * (it->weights.ptr + i)->weight;
vertexNormalOriginal[verIndex] = Vector3(ptrNormals + verIndex *3); vertexNormalOriginal[verIndex] = Vector3(ptrNormals + verIndex *3);
for (int j=0; j<3; j++) for (int j=0; j<3; j++)
(ptrNormals + verIndex*3)[j] = absNormalsPos[j]; (ptrNormals + verIndex*3)[j] = absNormalsPos[j];
} }
@ -868,7 +868,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
absNormalsPos = absNormalsPos * (it->weights.ptr + i)->weight; absNormalsPos = absNormalsPos * (it->weights.ptr + i)->weight;
Vector3 oldNormal = Vector3(ptrNormals + verIndex *3); Vector3 oldNormal = Vector3(ptrNormals + verIndex *3);
absNormalsPos = absNormalsPos + oldNormal; absNormalsPos = absNormalsPos + oldNormal;
for (int j=0; j<3; j++) for (int j=0; j<3; j++)
(ptrNormals + verIndex*3)[j] = absNormalsPos[j]; (ptrNormals + verIndex*3)[j] = absNormalsPos[j];
} }
@ -879,19 +879,19 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
vba.boneIndex = bonePtr->getHandle(); vba.boneIndex = bonePtr->getHandle();
vba.vertexIndex = verIndex; vba.vertexIndex = verIndex;
vba.weight = (it->weights.ptr + i)->weight; vba.weight = (it->weights.ptr + i)->weight;
vertexBoneAssignments.push_back(vba); vertexBoneAssignments.push_back(vba);
} }
boneIndex++; boneIndex++;
} }
} }
else else
{ {
copy.boneSequence = boneSequence; copy.boneSequence = boneSequence;
// Rotate, scale and translate all the vertices, // Rotate, scale and translate all the vertices,
const Matrix &rot = shape->trafo->rotation; const Matrix &rot = shape->trafo->rotation;
@ -902,7 +902,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
copy.trafo.rotation = convertRotation(original.rotation); copy.trafo.rotation = convertRotation(original.rotation);
copy.trafo.scale = original.scale; copy.trafo.scale = original.scale;
//We don't use velocity for anything yet, so it does not need to be saved //We don't use velocity for anything yet, so it does not need to be saved
// Computes C = B + AxC*scale // Computes C = B + AxC*scale
for (int i=0; i<numVerts; i++) for (int i=0; i<numVerts; i++)
{ {
@ -911,7 +911,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou
mBoundingBox.merge(absVertPos); mBoundingBox.merge(absVertPos);
ptr += 3; ptr += 3;
} }
// Remember to rotate all the vertex normals as well // Remember to rotate all the vertex normals as well
if (data->normals.length) if (data->normals.length)
{ {
@ -955,7 +955,7 @@ void NIFLoader::calculateTransform()
// Calculate transform // Calculate transform
Matrix4 transform = Matrix4::IDENTITY; Matrix4 transform = Matrix4::IDENTITY;
transform = Matrix4::getScale(vector) * transform; transform = Matrix4::getScale(vector) * transform;
// Check whether we have to flip vertex winding. // Check whether we have to flip vertex winding.
// We do have to, if we changed our right hand base. // We do have to, if we changed our right hand base.
// We can test it by using the cross product from X and Y and see, if it is a non-negative // We can test it by using the cross product from X and Y and see, if it is a non-negative
@ -963,7 +963,7 @@ void NIFLoader::calculateTransform()
// but the test is cheap either way. // but the test is cheap either way.
Matrix3 m3; Matrix3 m3;
transform.extract3x3Matrix(m3); transform.extract3x3Matrix(m3);
if (m3.GetColumn(0).crossProduct(m3.GetColumn(1)).dotProduct(m3.GetColumn(2)) < 0) if (m3.GetColumn(0).crossProduct(m3.GetColumn(1)).dotProduct(m3.GetColumn(2)) < 0)
{ {
mFlipVertexWinding = true; mFlipVertexWinding = true;
@ -1003,39 +1003,38 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
} }
if (e->recType == RC_NiTextKeyExtraData){ if (e->recType == RC_NiTextKeyExtraData){
Nif::NiTextKeyExtraData* extra = dynamic_cast<Nif::NiTextKeyExtraData*> (e); Nif::NiTextKeyExtraData* extra = dynamic_cast<Nif::NiTextKeyExtraData*> (e);
std::ofstream file; std::ofstream file;
if(mOutputAnimFiles){ if(mOutputAnimFiles){
std::string cut = ""; std::string cut = "";
for(unsigned int i = 0; i < name.length(); i++) for(unsigned int i = 0; i < name.length(); i++)
{ {
if(!(name.at(i) == '\\' || name.at(i) == '/' || name.at(i) == '>' || name.at(i) == '<' || name.at(i) == '?' || name.at(i) == '*' || name.at(i) == '|' || name.at(i) == ':' || name.at(i) == '"')) if(!(name.at(i) == '\\' || name.at(i) == '/' || name.at(i) == '>' || name.at(i) == '<' || name.at(i) == '?' || name.at(i) == '*' || name.at(i) == '|' || name.at(i) == ':' || name.at(i) == '"'))
{ {
cut += name.at(i); cut += name.at(i);
} }
} }
std::cout << "Outputting " << cut << "\n"; std::cout << "Outputting " << cut << "\n";
file.open((verbosePath + "/Indices" + cut + ".txt").c_str()); file.open((verbosePath + "/Indices" + cut + ".txt").c_str());
} }
for(std::vector<Nif::NiTextKeyExtraData::TextKey>::iterator textiter = extra->list.begin(); textiter != extra->list.end(); textiter++)
{
std::string text = textiter->text.toString();
replace(text.begin(), text.end(), '\n', '/');
text.erase(std::remove(text.begin(), text.end(), '\r'), text.end()); for(std::vector<Nif::NiTextKeyExtraData::TextKey>::iterator textiter = extra->list.begin(); textiter != extra->list.end(); textiter++)
int i = 0; {
std::string text = textiter->text.toString();
replace(text.begin(), text.end(), '\n', '/');
text.erase(std::remove(text.begin(), text.end(), '\r'), text.end());
std::size_t i = 0;
while(i < text.length()){ while(i < text.length()){
while(i < text.length() && text.at(i) == '/' ){ while(i < text.length() && text.at(i) == '/' ){
i++; i++;
} }
int first = i; std::size_t first = i;
int length = 0; int length = 0;
while(i < text.length() && text.at(i) != '/' ){ while(i < text.length() && text.at(i) != '/' ){
i++; i++;
@ -1045,15 +1044,15 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
//length = text.length() - first; //length = text.length() - first;
std::string sub = text.substr(first, length); std::string sub = text.substr(first, length);
if(mOutputAnimFiles) if(mOutputAnimFiles)
file << "Time: " << textiter->time << "|" << sub << "\n"; file << "Time: " << textiter->time << "|" << sub << "\n";
textmappings[sub] = textiter->time; textmappings[sub] = textiter->time;
} }
} }
} }
file.close(); file.close();
} }
} }
Bone *bone = 0; Bone *bone = 0;
@ -1064,7 +1063,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
//FIXME: "Bip01" isn't every time the root bone //FIXME: "Bip01" isn't every time the root bone
if (node->name == "Bip01" || node->name == "Root Bone") //root node, create a skeleton if (node->name == "Bip01" || node->name == "Root Bone") //root node, create a skeleton
{ {
mSkel = SkeletonManager::getSingleton().create(getSkeletonName(), resourceGroup, true); mSkel = SkeletonManager::getSingleton().create(getSkeletonName(), resourceGroup, true);
} }
@ -1072,7 +1071,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
{ {
std::string name = node->name.toString(); std::string name = node->name.toString();
boneSequence.push_back(name); boneSequence.push_back(name);
// Quick-n-dirty workaround for the fact that several // Quick-n-dirty workaround for the fact that several
// bones may have the same name. // bones may have the same name.
if(!mSkel->hasBone(name)) if(!mSkel->hasBone(name))
@ -1125,7 +1124,7 @@ void NIFLoader::handleNode(Nif::Node *node, int flags,
else if (node->recType == RC_NiTriShape && bNiTri) else if (node->recType == RC_NiTriShape && bNiTri)
{ {
std::string nodename = node->name.toString(); std::string nodename = node->name.toString();
if (triname == "") if (triname == "")
{ {
handleNiTriShape(dynamic_cast<NiTriShape*>(node), flags, bounds, original, boneSequence); handleNiTriShape(dynamic_cast<NiTriShape*>(node), flags, bounds, original, boneSequence);
@ -1172,12 +1171,12 @@ void NIFLoader::loadResource(Resource *resource)
baddin = true; baddin = true;
bNiTri = true; bNiTri = true;
std::string sub = name.substr(name.length() - 6, 4); std::string sub = name.substr(name.length() - 6, 4);
if(sub.compare("0000") != 0) if(sub.compare("0000") != 0)
addAnim = false; addAnim = false;
} }
switch(name.at(name.length() - 1)) switch(name.at(name.length() - 1))
{ {
case '"': case '"':
@ -1253,33 +1252,30 @@ void NIFLoader::loadResource(Resource *resource)
// Handle the node // Handle the node
std::vector<std::string> boneSequence; std::vector<std::string> boneSequence;
handleNode(node, 0, NULL, bounds, 0, boneSequence); handleNode(node, 0, NULL, bounds, 0, boneSequence);
if(addAnim) if(addAnim)
{ {
for(int i = 0; i < nif.numRecords(); i++) for(int i = 0; i < nif.numRecords(); i++)
{ {
Nif::NiKeyframeController *f = dynamic_cast<Nif::NiKeyframeController*>(nif.getRecord(i)); Nif::NiKeyframeController *f = dynamic_cast<Nif::NiKeyframeController*>(nif.getRecord(i));
Nif::Node *n = dynamic_cast<Nif::Node*>(nif.getRecord(i)); if(f != NULL)
if(f != NULL) {
{ hasAnim = true;
hasAnim = true; Nif::Node *o = dynamic_cast<Nif::Node*>(f->target.getPtr());
Nif::Node *o = dynamic_cast<Nif::Node*>(f->target.getPtr()); Nif::NiKeyframeDataPtr data = f->data;
Nif::NiKeyframeDataPtr data = f->data;
if (f->timeStart == 10000000000000000)
if (f->timeStart == 10000000000000000) continue;
continue; data->setBonename(o->name.toString());
data->setBonename(o->name.toString()); data->setStartTime(f->timeStart);
data->setStartTime(f->timeStart); data->setStopTime(f->timeStop);
data->setStopTime(f->timeStop);
allanim.push_back(data.get());
allanim.push_back(data.get()); }
}
} }
} }
// set the bounding value. // set the bounding value.
@ -1290,18 +1286,18 @@ void NIFLoader::loadResource(Resource *resource)
mesh->_setBoundingSphereRadius(bounds.getRadius()); mesh->_setBoundingSphereRadius(bounds.getRadius());
} }
if(hasAnim && addAnim){ if(hasAnim && addAnim){
allanimmap[name] = allanim; allanimmap[name] = allanim;
alltextmappings[name] = textmappings; alltextmappings[name] = textmappings;
} }
if(!mSkel.isNull() && shapes.size() > 0 && addAnim) if(!mSkel.isNull() && shapes.size() > 0 && addAnim)
{ {
allshapesmap[name] = shapes; allshapesmap[name] = shapes;
} }
if(flip){ if(flip){
mesh->_setBounds(mBoundingBox, false); mesh->_setBounds(mBoundingBox, false);
} }
if (!mSkel.isNull()) if (!mSkel.isNull())
{ {
@ -1310,7 +1306,7 @@ void NIFLoader::loadResource(Resource *resource)
} }
void NIFLoader::addInMesh(Ogre::Mesh* input){ void NIFLoader::addInMesh(Ogre::Mesh* input){
addin.push_back(input); addin.push_back(input);
} }
@ -1318,7 +1314,7 @@ void NIFLoader::addInMesh(Ogre::Mesh* input){
MeshPtr NIFLoader::load(const std::string &name, MeshPtr NIFLoader::load(const std::string &name,
const std::string &group) const std::string &group)
{ {
MeshManager *m = MeshManager::getSingletonPtr(); MeshManager *m = MeshManager::getSingletonPtr();
// Check if the resource already exists // Check if the resource already exists
ResourcePtr ptr = m->getByName(name, group); ResourcePtr ptr = m->getByName(name, group);
@ -1335,26 +1331,26 @@ MeshPtr NIFLoader::load(const std::string &name,
/* /*
This function shares much of the same code handleShapes() in MWRender::Animation This function shares much of the same code handleShapes() in MWRender::Animation
This function also creates new position and normal buffers for submeshes. This function also creates new position and normal buffers for submeshes.
This function points to existing texture and IndexData buffers This function points to existing texture and IndexData buffers
*/ */
std::vector<Nif::NiKeyframeData>* NIFLoader::getAnim(std::string lowername){ std::vector<Nif::NiKeyframeData>* NIFLoader::getAnim(std::string lowername){
std::map<std::string,std::vector<Nif::NiKeyframeData>,ciLessBoost>::iterator iter = allanimmap.find(lowername); std::map<std::string,std::vector<Nif::NiKeyframeData>,ciLessBoost>::iterator iter = allanimmap.find(lowername);
std::vector<Nif::NiKeyframeData>* pass = 0; std::vector<Nif::NiKeyframeData>* pass = 0;
if(iter != allanimmap.end()) if(iter != allanimmap.end())
pass = &(iter->second); pass = &(iter->second);
return pass; return pass;
} }
std::vector<Nif::NiTriShapeCopy>* NIFLoader::getShapes(std::string lowername){ std::vector<Nif::NiTriShapeCopy>* NIFLoader::getShapes(std::string lowername){
std::map<std::string,std::vector<Nif::NiTriShapeCopy>,ciLessBoost>::iterator iter = allshapesmap.find(lowername); std::map<std::string,std::vector<Nif::NiTriShapeCopy>,ciLessBoost>::iterator iter = allshapesmap.find(lowername);
std::vector<Nif::NiTriShapeCopy>* pass = 0; std::vector<Nif::NiTriShapeCopy>* pass = 0;
if(iter != allshapesmap.end()) if(iter != allshapesmap.end())
pass = &(iter->second); pass = &(iter->second);
return pass; return pass;
} }
std::map<std::string, float>* NIFLoader::getTextIndices(std::string lowername){ std::map<std::string, float>* NIFLoader::getTextIndices(std::string lowername){

@ -79,7 +79,7 @@ namespace Mangle
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
@ -109,7 +109,7 @@ class NIFLoader : Ogre::ManualResourceLoader
const std::string &group="General"); const std::string &group="General");
//void insertMeshInsideBase(Ogre::Mesh* mesh); //void insertMeshInsideBase(Ogre::Mesh* mesh);
std::vector<Nif::NiKeyframeData>* getAnim(std::string name); std::vector<Nif::NiKeyframeData>* getAnim(std::string name);
std::vector<Nif::NiTriShapeCopy>* getShapes(std::string name); std::vector<Nif::NiTriShapeCopy>* getShapes(std::string name);
std::map<std::string, float>* getTextIndices(std::string name); std::map<std::string, float>* getTextIndices(std::string name);
void addInMesh(Ogre::Mesh* input); void addInMesh(Ogre::Mesh* input);
@ -121,12 +121,12 @@ class NIFLoader : Ogre::ManualResourceLoader
void setVerbosePath(std::string path); void setVerbosePath(std::string path);
private: private:
NIFLoader() : mNormaliseNormals(false), resourceGroup("General"), resourceName(""), flip(false), NIFLoader() : resourceName(""), resourceGroup("General"), flip(false), mNormaliseNormals(false),
mFlipVertexWinding(false), mOutputAnimFiles(false) {} mFlipVertexWinding(false), mOutputAnimFiles(false) {}
NIFLoader(NIFLoader& n) {} NIFLoader(NIFLoader& n) {}
void calculateTransform(); void calculateTransform();
void warn(std::string msg); void warn(std::string msg);
void fail(std::string msg); void fail(std::string msg);
@ -167,7 +167,7 @@ class NIFLoader : Ogre::ManualResourceLoader
std::string verbosePath; std::string verbosePath;
std::string resourceName; std::string resourceName;
std::string resourceGroup; std::string resourceGroup;
Ogre::Matrix4 mTransform; Ogre::Matrix4 mTransform;
Ogre::AxisAlignedBox mBoundingBox; Ogre::AxisAlignedBox mBoundingBox;
bool flip; bool flip;
bool mNormaliseNormals; bool mNormaliseNormals;
@ -184,14 +184,14 @@ class NIFLoader : Ogre::ManualResourceLoader
std::string name; std::string name;
std::string triname; std::string triname;
std::vector<Nif::NiKeyframeData> allanim; std::vector<Nif::NiKeyframeData> allanim;
std::map<std::string,float> textmappings; std::map<std::string,float> textmappings;
std::map<std::string,std::map<std::string,float>,ciLessBoost> alltextmappings; 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::NiKeyframeData>,ciLessBoost> allanimmap;
std::map<std::string,std::vector<Nif::NiTriShapeCopy>,ciLessBoost> allshapesmap; std::map<std::string,std::vector<Nif::NiTriShapeCopy>,ciLessBoost> allshapesmap;
std::vector<Ogre::Mesh*> addin; std::vector<Ogre::Mesh*> addin;
std::vector<Nif::NiKeyframeData> mAnim; std::vector<Nif::NiKeyframeData> mAnim;
std::vector<Nif::NiTriShapeCopy> mS; std::vector<Nif::NiTriShapeCopy> mS;
}; };
} }

Loading…
Cancel
Save