From 27166b4ee4b311d030ff46547f2a9e576060958a Mon Sep 17 00:00:00 2001 From: Armin Preiml Date: Sat, 21 Aug 2010 19:40:08 +0200 Subject: [PATCH] added bone assignment, skeleton is disabled for meshes Skeleton isn't assigned to the meshes for now, because it crashes on some. --- components/nifogre/ogre_nif_loader.cpp | 87 ++++++++++++++++---------- components/nifogre/ogre_nif_loader.hpp | 4 +- 2 files changed, 57 insertions(+), 34 deletions(-) diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index b935f49f8..5053fbd7d 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -30,9 +30,12 @@ #include "../nif/node.hpp" #include "../nif/data.hpp" #include "../nif/property.hpp" +#include "../nif/controller.hpp" +#include "../nif/extra.hpp" #include #include +#include // For warning messages #include @@ -170,7 +173,8 @@ public: }; // Conversion of blend / test mode from NIF -> OGRE. -/* Not in use yet, so let's comment it out. +// Not in use yet, so let's comment it out. +/* static SceneBlendFactor getBlendFactor(int mode) { switch(mode) @@ -191,9 +195,9 @@ static SceneBlendFactor getBlendFactor(int mode) return SBF_SOURCE_ALPHA; } } -*/ -/* This is also unused + +// This is also unused static CompareFunction getTestMode(int mode) { switch(mode) @@ -218,7 +222,7 @@ void NIFLoader::createMaterial(const String &name, const Vector &specular, const Vector &emissive, float glossiness, float alpha, - float alphaFlags, float alphaTest, + int alphaFlags, float alphaTest, const String &texName) { MaterialPtr material = MaterialManager::getSingleton().create(name, resourceGroup); @@ -234,32 +238,33 @@ void NIFLoader::createMaterial(const String &name, /*TextureUnitState *txt =*/ pass->createTextureUnitState(texName); - /* As of yet UNTESTED code from Chris: - pass->setTextureFiltering(Ogre::TFO_ANISOTROPIC); + // As of yet UNTESTED code from Chris: + /*pass->setTextureFiltering(Ogre::TFO_ANISOTROPIC); pass->setDepthFunction(Ogre::CMPF_LESS_EQUAL); pass->setDepthCheckEnabled(true); // Add transparency if NiAlphaProperty was present - if(alphaFlags != -1) - { - if((alphaFlags&1)) - { + if (alphaFlags != -1) + { + std::cout << "Alpha flags set!" << endl; + if ((alphaFlags&1)) + { pass->setDepthWriteEnabled(false); pass->setSceneBlending(getBlendFactor((alphaFlags>>1)&0xf), getBlendFactor((alphaFlags>>5)&0xf)); - } + } else - pass->setDepthWriteEnabled(true); + pass->setDepthWriteEnabled(true); - if((alphaFlags>>9)&1) - pass->setAlphaRejectSettings(getTestMode((alphaFlags>>10)&0x7), - alphaTest); + if ((alphaFlags>>9)&1) + pass->setAlphaRejectSettings(getTestMode((alphaFlags>>10)&0x7), + alphaTest); pass->setTransparentSortingEnabled(!((alphaFlags>>13)&1)); - } + } else - pass->setDepthWriteEnabled(true); - */ + pass->setDepthWriteEnabled(true); */ + // Add transparency if NiAlphaProperty was present if (alphaFlags != -1) @@ -322,7 +327,7 @@ void NIFLoader::findRealTexture(String &texName) // Convert Nif::NiTriShape to Ogre::SubMesh, attached to the given // mesh. -void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material) +void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material, std::list &vertexBoneAssignments) { NiTriShapeData *data = shape->data.getPtr(); SubMesh *sub = mesh->createSubMesh(shape->name.toString()); @@ -410,6 +415,14 @@ void NIFLoader::createOgreSubMesh(NiTriShape *shape, const String &material) // Set material if one was given if (!material.empty()) sub->setMaterialName(material); + + //add vertex bone assignments + + for (std::list::iterator it = vertexBoneAssignments.begin(); + it != vertexBoneAssignments.end(); it++) + { + sub->addBoneAssignment(*it); + } } // Helper math functions. Reinventing linear algebra for the win! @@ -595,12 +608,13 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou float *ptr = (float*)data->vertices.ptr; float *optr = ptr; + std::list vertexBoneAssignments; + //use niskindata for the position of vertices. if (!shape->skin.empty()) { // vector that stores if the position if a vertex is absolute std::vector vertexPosAbsolut(numVerts,false); - float *ptrNormals = (float*)data->normals.ptr; //the bone from skin->bones[boneIndex] is linked to skin->data->bones[boneIndex] @@ -654,16 +668,18 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou (ptrNormals + verIndex*3)[j] = absNormalsPos[j]; } - - //TODO: create vbas, and give them to createOgreSubMesh - vertexPosAbsolut[verIndex] = true; } + + VertexBoneAssignment vba; + vba.boneIndex = bonePtr->getHandle(); + vba.vertexIndex = verIndex; + vba.weight = (it->weights.ptr + i)->weight; + + vertexBoneAssignments.push_back(vba); } boneIndex++; - //it->trafo (pos, rot, scale) of the vertex - //it->weights array containt the vertices linked to the bone and the weight } } else @@ -696,7 +712,7 @@ void NIFLoader::handleNiTriShape(NiTriShape *shape, int flags, BoundsFinder &bou bounds.add(optr, numVerts); // Create the submesh - createOgreSubMesh(shape, material); + createOgreSubMesh(shape, material, vertexBoneAssignments); } } @@ -737,9 +753,16 @@ void NIFLoader::handleNode(Nif::Node *node, int flags, // create skeleton or add bones if (node->recType == RC_NiNode) { - if (node->name == "Bip01") //root node, create a skeleton + //FIXME: "Bip01" isn't every time the root bone + if (node->name == "Bip01" || node->name == "Root Bone") //root node, create a skeleton { skel = SkeletonManager::getSingleton().create(getSkeletonName(), resourceGroup, true); + + /*if (node->extra->recType == RC_NiTextKeyExtraData ) + { + //TODO: Get animation names + std::cout << node->name.toString() << " is root bone and has textkeyextradata!\n"; + }*/ } if (!skel.isNull()) //if there is a skeleton @@ -845,17 +868,17 @@ void NIFLoader::loadResource(Resource *resource) // Handle the node handleNode(node, 0, NULL, bounds, 0); - //set skeleton -// if (!skel.isNull()) -// mesh->setSkeletonName(getSkeletonName()); - - // Finally, set the bounding value. + // set the bounding value. if (bounds.isValid()) { mesh->_setBounds(AxisAlignedBox(bounds.minX(), bounds.minY(), bounds.minZ(), bounds.maxX(), bounds.maxY(), bounds.maxZ())); mesh->_setBoundingSphereRadius(bounds.getRadius()); } + + // set skeleton +// if (!skel.isNull()) +// mesh->setSkeletonName(getSkeletonName()); } MeshPtr NIFLoader::load(const std::string &name, diff --git a/components/nifogre/ogre_nif_loader.hpp b/components/nifogre/ogre_nif_loader.hpp index aea8d3a8d..578308f0b 100644 --- a/components/nifogre/ogre_nif_loader.hpp +++ b/components/nifogre/ogre_nif_loader.hpp @@ -90,7 +90,7 @@ class NIFLoader : Ogre::ManualResourceLoader void handleNiTriShape(Nif::NiTriShape *shape, int flags, BoundsFinder &bounds); - void createOgreSubMesh(Nif::NiTriShape *shape, const Ogre::String &material); + void createOgreSubMesh(Nif::NiTriShape *shape, const Ogre::String &material, std::list &vertexBoneAssignments); void createMaterial(const Ogre::String &name, const Nif::Vector &ambient, @@ -98,7 +98,7 @@ class NIFLoader : Ogre::ManualResourceLoader const Nif::Vector &specular, const Nif::Vector &emissive, float glossiness, float alpha, - float alphaFlags, float alphaTest, + int alphaFlags, float alphaTest, const Ogre::String &texName); void findRealTexture(Ogre::String &texName);