From 0712bba49b5858bbffda700b2d94f4ff6c4cb1f2 Mon Sep 17 00:00:00 2001 From: Jason Hooks Date: Thu, 12 Jan 2012 16:03:07 -0500 Subject: [PATCH] Changing a few things around with handleshapes --- apps/openmw/mwrender/animation.cpp | 106 +++++++++++++++++++++---- apps/openmw/mwrender/animation.hpp | 5 ++ components/nif/data.hpp | 8 +- components/nif/node.hpp | 1 + components/nifogre/ogre_nif_loader.cpp | 33 +++++--- 5 files changed, 129 insertions(+), 24 deletions(-) diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index e315530122..5105d12b4b 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -97,21 +97,25 @@ namespace MWRender{ } void Animation::handleShapes(std::vector* allshapes, Ogre::Entity* creaturemodel, Ogre::SkeletonInstance *skel){ + bool useHandles = skel == creaturemodel->getSkeleton(); shapeNumber = 0; + std::vector::iterator allshapesiter; for(allshapesiter = allshapes->begin(); allshapesiter != allshapes->end(); allshapesiter++) { + //std::map vecPosRot; Nif::NiTriShapeCopy& copy = *allshapesiter; - std::vector allvertices = copy.vertices; - std::vector allnormals = copy.normals; + std::vector* allvertices = ©.vertices; + std::vector* allnormals = ©.normals; - std::set vertices; + //std::set vertices; //std::set normals; - std::vector boneinfovector = copy.boneinfo; + //std::vector boneinfovector = copy.boneinfo; + std::map>* verticesToChange = ©.vertsToWeights; //std::cout << "Name " << copy.sname << "\n"; Ogre::HardwareVertexBufferSharedPtr vbuf = creaturemodel->getMesh()->getSubMesh(copy.sname)->vertexData->vertexBufferBinding->getBuffer(0); @@ -161,17 +165,91 @@ namespace MWRender{ } - allvertices = initialVertices; + allvertices = &initialVertices; } shapeNumber++; } } - if(boneinfovector.size() > 0){ + if(verticesToChange->size() > 0){ + + for(std::map>::iterator iter = verticesToChange->begin(); + iter != verticesToChange->end(); iter++) + { + std::vector 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; + if(useHandles) + { + bonePtr = skel->getBone(boneinfocopy->bonehandle); + } + else + bonePtr = skel->getBone(boneinfocopy->bonename); + + Ogre::Vector3 vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans; + Ogre::Quaternion vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation; + + + /*if(vecPosRot.find(boneinfocopy->bonehandle) == vecPosRot.end()){ + vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans; + vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation; + + if(useHandles){ + PosAndRot both; + both.vecPos = vecPos; + both.vecRot = vecRot; + vecPosRot[boneinfocopy->bonehandle] = both; + } + } + else{ + PosAndRot both = vecPosRot[boneinfocopy->bonehandle]; + vecPos = both.vecPos; + vecRot = both.vecRot; + }*/ + Ogre::Vector3 absVertPos = (vecPos + vecRot * currentVertex) * inds[0].weight; + + + for(int i = 1; i < inds.size(); i++){ + boneinfocopy = &(allshapesiter->boneinfo[inds[i].boneinfocopyindex]); + if(useHandles) + bonePtr = skel->getBone(boneinfocopy->bonehandle); + else + bonePtr = skel->getBone(boneinfocopy->bonename); + vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans; + vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation; + + /*if(vecPosRot.find(boneinfocopy->bonehandle) == vecPosRot.end()){ + vecPos = bonePtr->_getDerivedPosition() + bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.trans; + vecRot = bonePtr->_getDerivedOrientation() * boneinfocopy->trafo.rotation; + + if(useHandles){ + PosAndRot both; + both.vecPos = vecPos; + both.vecRot = vecRot; + vecPosRot[boneinfocopy->bonehandle] = both; + } + } + else{ + PosAndRot both = vecPosRot[boneinfocopy->bonehandle]; + 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; + } - for (unsigned int i = 0; i < boneinfovector.size(); i++) + /*for (unsigned int i = 0; i < boneinfovector.size(); i++) { Nif::NiSkinData::BoneInfoCopy boneinfo = boneinfovector[i]; if(skel->hasBone(boneinfo.bonename)){ @@ -234,14 +312,14 @@ namespace MWRender{ }*/ - } - } + //} + //} - } + //} //Comment out - - } + ; + } else { //Ogre::Bone *bonePtr = creaturemodel->getSkeleton()->getBone(copy.bonename); @@ -293,8 +371,8 @@ namespace MWRender{ // 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]; + 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; diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 14b18bf543..15c25707c8 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -15,6 +15,11 @@ namespace MWRender{ +struct PosAndRot{ + Ogre::Quaternion vecRot; + Ogre::Vector3 vecPos; +}; + class Animation{ protected: diff --git a/components/nif/data.hpp b/components/nif/data.hpp index 892e98003b..9e28e15344 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -390,9 +390,15 @@ public: struct BoneInfoCopy { std::string bonename; + unsigned short bonehandle; BoneTrafoCopy trafo; Vector4 unknown; - std::vector weights; + //std::vector weights; + }; + struct IndividualWeight + { + float weight; + unsigned int boneinfocopyindex; }; const BoneTrafo *trafo; diff --git a/components/nif/node.hpp b/components/nif/node.hpp index 02387d2194..bbceb866e0 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -103,6 +103,7 @@ struct NiTriShapeCopy std::vector vertices; std::vector normals; std::vector boneinfo; + std::map> vertsToWeights; Nif::NiMorphData morph; }; diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index c1d05ef2f9..b6f09eaff6 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -355,7 +355,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std HardwareVertexBufferSharedPtr vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( VertexElement::getTypeSize(VET_FLOAT3), - numVerts, HardwareBuffer::HBU_DYNAMIC); + numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); if(flip) { @@ -388,7 +388,7 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std decl->addElement(nextBuf, 0, VET_FLOAT3, VES_NORMAL); vbuf = HardwareBufferManager::getSingleton().createVertexBuffer( VertexElement::getTypeSize(VET_FLOAT3), - numVerts, HardwareBuffer::HBU_DYNAMIC,true); + numVerts, HardwareBuffer::HBU_STATIC_WRITE_ONLY, false); if(flip) { @@ -751,7 +751,6 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou if (!shape->skin.empty()) { - //Bone assignments are stored in submeshes, so we don't need to copy them // vector that stores if the position of a vertex is absolute @@ -791,10 +790,12 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou // final_vector = old_vector + old_rotation*new_vector*old_scale - Nif::NiSkinData::BoneInfoCopy boneinfo; - boneinfo.trafo.rotation = convertRotation(it->trafo->rotation); - boneinfo.trafo.trans = convertVector3(it->trafo->trans); - boneinfo.bonename = shape->skin->bones[boneIndex].name.toString(); + Nif::NiSkinData::BoneInfoCopy boneinfocopy; + boneinfocopy.trafo.rotation = convertRotation(it->trafo->rotation); + boneinfocopy.trafo.trans = convertVector3(it->trafo->trans); + boneinfocopy.bonename = shape->skin->bones[boneIndex].name.toString(); + boneinfocopy.bonehandle = bonePtr->getHandle(); + copy.boneinfo.push_back(boneinfocopy); for (unsigned int i=0; iweights.length; i++) { vecPos = bonePtr->_getDerivedPosition() + @@ -802,7 +803,21 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou vecRot = bonePtr->_getDerivedOrientation() * convertRotation(it->trafo->rotation); unsigned int verIndex = (it->weights.ptr + i)->vertex; - boneinfo.weights.push_back(*(it->weights.ptr + i)); + //boneinfo.weights.push_back(*(it->weights.ptr + i)); + Nif::NiSkinData::IndividualWeight ind; + ind.weight = (it->weights.ptr + i)->weight; + ind.boneinfocopyindex = copy.boneinfo.size() - 1; + if(copy.vertsToWeights.find(verIndex) == copy.vertsToWeights.end()) + { + std::vector blank; + blank.push_back(ind); + copy.vertsToWeights[verIndex] = blank; + } + else + { + copy.vertsToWeights[verIndex].push_back(ind); + } + //Check if the vertex is relativ, FIXME: Is there a better solution? if (vertexPosAbsolut[verIndex] == false) { @@ -865,7 +880,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou vertexBoneAssignments.push_back(vba); } - copy.boneinfo.push_back(boneinfo); + boneIndex++; }