From 31d971e076fb6a09ca208d297899abdb677daeab Mon Sep 17 00:00:00 2001 From: Nicolay Korslund Date: Wed, 13 Jan 2010 15:28:28 +0100 Subject: [PATCH] Started porting old meshloader.d --- nifogre/ogre_nif_loader.cpp | 97 +++++++++++++++++++++++++++++++-- old_d_version/ogre/meshloader.d | 6 +- 2 files changed, 95 insertions(+), 8 deletions(-) diff --git a/nifogre/ogre_nif_loader.cpp b/nifogre/ogre_nif_loader.cpp index 2c53cc65dc..303c4e87b0 100644 --- a/nifogre/ogre_nif_loader.cpp +++ b/nifogre/ogre_nif_loader.cpp @@ -26,6 +26,7 @@ #include "../mangle/vfs/servers/ogre_vfs.h" #include "../nif/nif_file.h" +#include "../nif/node.h" // For warning messages #include @@ -48,6 +49,78 @@ static void warn(const string &msg) cout << "WARNING (NIF): " << msg << endl; } +static void handleNiTriShape(Mesh *mesh, NiTriShape *shape, int flags) +{ + // Interpret flags + bool hidden = (flags & 0x01) != 0; // Not displayed + bool collide = (flags & 0x02) != 0; // Use mesh for collision + bool bbcollide = (flags & 0x04) != 0; // Use bounding box for collision + + // Bounding box collision isn't implemented, always use mesh for now. + if(bbcollide) + { + collide = true; + bbcollide = false; + } + + // If the object was marked "NCO" earlier, it shouldn't collide with + // anything. + if(flags & 0x800) + { collide = false; bbcollide = false; } + + // Skip the entire material phase for hidden nodes + if(hidden) goto nomaterial; + + nomaterial: +} + +static void handleNode(Mesh* mesh, Node *node, int flags) +{ + // Accumulate the flags from all the child nodes. This works for all + // the flags we currently use, at least. + flags |= node->flags; + + // Check for extra data + Extra *e = node; + while(!e->extra.empty()) + { + // Get the next extra data in the list + e = e.extra.getPtr(); + assert(e != NULL); + + if(e->recType == RC_NiStringExtraData) + { + // String markers may contain important information + // affecting the entire subtree of this node + NiStringExtraData *sd = (NiStringExtraData*)e; + + if(sd->string == "NCO") + // No collision. Use an internal flag setting to mark this. + flags |= 0x800; + else if(sd->string == "MRK") + // Marker objects. These are only visible in the + // editor. Until and unless we add an editor component to + // the engine, just skip this entire node. + return; + } + } + + // For NiNodes, loop through children + if(node->recType == RC_NiNode) + { + NodeList &list = ((NiNode*)node)->children; + int n = list.length(); + for(int i=0; irecType == RC_NiTriShape) + // For shapes + handleNiTriShape(mesh, (NiTriShape*)node, flags); +} + void NIFLoader::loadResource(Resource *resource) { // Set up the VFS if it hasn't been done already @@ -66,13 +139,27 @@ void NIFLoader::loadResource(Resource *resource) } // Load the NIF - cout << "Loading " << name << endl; NIFFile nif(vfs->open(name), name); - int n = nif.numRecords(); - cout << "Number of records: " << n << endl; - if(n) - cout << "First record type: " << nif.getRecord(0)->recName.toString() << endl; + if(nif.numRecords() < 1) + { + warn("Found no records in " + name); + return; + } + + // The first record is assumed to be the root node + Record *r = nif.getRecord(0); + assert(r != NULL); + + if(r->recType != RC_NiNode) + { + warn("First record in " + name + " was not a NiNode, but a " + + r->recName.toString() + ". Skipping file."); + return; + } + + // Handle the node + handleNode(mesh, (Node*)r, 0); } MeshPtr NIFLoader::load(const char* name, const char* group) diff --git a/old_d_version/ogre/meshloader.d b/old_d_version/ogre/meshloader.d index 9ab521398e..a6668597b4 100644 --- a/old_d_version/ogre/meshloader.d +++ b/old_d_version/ogre/meshloader.d @@ -157,8 +157,8 @@ struct MeshLoader auto cont = data.controller; while(cont !is null) { - auto kc = cast(NiKeyframeController)data.controller; - auto pc = cast(NiPathController)data.controller; + auto kc = cast(NiKeyframeController)cont; + auto pc = cast(NiPathController)cont; if(kc !is null) { /* @@ -350,7 +350,7 @@ struct MeshLoader if( vertices[i+2] > maxZ) maxZ = vertices[i+2]; } - // TODO: Get the node world transformation, needed to set up + // Get the node world transformation, needed to set up // the collision shape properly. float[3] trans; float[9] matrix;