From f773ef4b4567f13c094bcec7eee423163598b14a Mon Sep 17 00:00:00 2001 From: Nicolay Korslund Date: Thu, 7 Jan 2010 19:11:03 +0100 Subject: [PATCH] Finished data.h, extra.h and node.h --- nif/data.h | 115 ++++++++++++++++++++++++++++++++++++++++++----- nif/extra.h | 109 ++++++++++++++++++++++++++++++++++++++++++++ nif/nif_file.h | 10 ++--- nif/node.h | 53 +++++++++++++++++++++- nif/property.h | 2 +- nif/record_ptr.h | 6 +++ 6 files changed, 277 insertions(+), 18 deletions(-) diff --git a/nif/data.h b/nif/data.h index 6b9d57fa47..a8c4aba088 100644 --- a/nif/data.h +++ b/nif/data.h @@ -91,7 +91,7 @@ struct ShapeData : Record void read(NIFFile *nif) { - int verts = nif->getUshort(); + int verts = nif->getShort(); if(nif->getInt()) vertices = nif->getFloatLen(verts*3); @@ -105,7 +105,7 @@ struct ShapeData : Record if(nif->getInt()) colors = nif->getFloatLen(verts*4); - int uvs = nif->getUshort(); + int uvs = nif->getShort(); // Only the first 6 bits are used as a count. I think the rest are // flags of some sort. @@ -125,7 +125,7 @@ struct NiTriShapeData : ShapeData { ShapeData::read(nif); - int tris = nif->getUshort(); + int tris = nif->getShort(); if(tris) { // We have three times as many vertices as triangles, so this @@ -137,13 +137,13 @@ struct NiTriShapeData : ShapeData // Read the match list, which lists the vertices that are equal to // vertices. We don't actually need need this for anything, so // just skip it. - int verts = nif->getUshort(); + int verts = nif->getShort(); if(verts) { for(int i=0;igetUshort(); + short num = nif->getShort(); nif->skip(num*sizeof(short)); } } @@ -159,11 +159,11 @@ struct NiAutoNormalParticlesData : ShapeData ShapeData::read(nif); // Should always match the number of vertices - activeCount = nif->getUshort(); + activeCount = nif->getShort(); // Skip all the info, we don't support particles yet nif->getFloat(); // Active radius ? - nif->getUshort(); // Number of valid entries in the following arrays ? + nif->getShort(); // Number of valid entries in the following arrays ? if(nif->getInt()) // Particle sizes @@ -192,7 +192,7 @@ struct NiPosData : Record int count = nif->getInt(); int type = nif->getInt(); if(type != 1 && type != 2) - fail("Cannot handle NiPosData type"); + nif->fail("Cannot handle NiPosData type"); // TODO: Could make structs of these. Seems to be identical to // translation in NiKeyframeData. @@ -208,7 +208,7 @@ struct NiPosData : Record } } } -} +}; struct NiUVData : Record { @@ -297,8 +297,8 @@ struct NiColorData : Record nif->getInt(); // always 1 // Skip the data - assert(ColorData.sizeof = 4*5); - nif->skip(ColorData.sizeof * count); + assert(sizeof(ColorData) == 4*5); + nif->skip(sizeof(ColorData) * count); } }; @@ -323,6 +323,28 @@ struct NiSkinData : Record { void read(NIFFile *nif) { + // Not really decoded fully. + nif->getMatrix(); // global skin rotation? + nif->getVector(); // skin translation + nif->getFloat(); // probably scale (always 1) + + int bones = nif->getInt(); + nif->getInt(); // -1 + + for(int i=0;igetMatrix(); // skin rotation offset from this bone + nif->getVector(); // translation + nif->getFloat(); // scale + + nif->getVector4(); + + // Number of vertex weights + int count = nif->getShort(); + + // Each weight is a vertex index (short) and a weight (float) + nif->skip(count*6); + } } }; @@ -330,6 +352,20 @@ struct NiMorphData : Record { void read(NIFFile *nif) { + int morphCount = nif->getInt(); + int vertCount = nif->getInt(); + nif->getByte(); + + for(int i=0; igetInt(); + nif->getInt(); + if(magic) + // Time, data, forward, backward tangents + nif->getFloatLen(4*magic); + + nif->getFloatLen(vertCount*3); + } } }; @@ -337,6 +373,63 @@ struct NiKeyframeData : Record { void read(NIFFile *nif) { + // Rotations first + int count = nif->getInt(); + if(count) + { + int type = nif->getInt(); + + if(type == 1) + nif->skip(count*4*5); // time + quaternion + else if(type == 3) + nif->skip(count*4*8); // rot1 + tension+bias+continuity + else if(type == 4) + { + for(int j=0;jgetFloat(); // time + for(int i=0; i<3; i++) + { + int cnt = nif->getInt(); + int type = nif->getInt(); + if(type == 1) + nif->skip(cnt*4*2); // time + unknown + else if(type == 2) + nif->skip(cnt*4*4); // time + unknown vector + else nif->fail("Unknown sub-rotation type"); + } + } + } + else nif->fail("Unknown rotation type in NiKeyframeData"); + } + + // Then translation + count = nif->getInt(); + if(count) + { + int type = nif->getInt(); + + if(type == 1) nif->getFloatLen(count*4); // time + translation + else if(type == 2) + nif->getFloatLen(count*10); // trans1 + forward + backward + else if(type == 3) + nif->getFloatLen(count*7); // trans1 + tension,bias,continuity + else nif->fail("Unknown translation type"); + } + + // Finally, scalings + count = nif->getInt(); + if(count) + { + int type = nif->getInt(); + + int size; + if(type == 1) size = 2; // time+scale + else if(type == 2) size = 4; // 1 + forward + backward (floats) + else if(type == 3) size = 5; // 1 + tbc + else nif->fail("Unknown scaling type"); + nif->getFloatLen(count*size); + } } }; diff --git a/nif/extra.h b/nif/extra.h index 57ea666349..9de15494de 100644 --- a/nif/extra.h +++ b/nif/extra.h @@ -42,5 +42,114 @@ struct Extra : Record void read(NIFFile *nif) { extra.read(nif); } }; +struct NiVertWeigthsExtraData : Extra +{ + void read(NIFFile *nif) + { + Extra::read(nif); + + // We should have s*4+2 == i, for some reason. Might simply be the + // size of the rest of the record, unhelpful as that may be. + int i = nif->getInt(); + int s = nif->getShort(); + + nif->getFloatLen(s); + } +}; + +struct NiTextKeyExtraData : Extra +{ + void read(NIFFile *nif) + { + Extra::read(nif); + + nif->getInt(); // 0 + + int keynum = nif->getInt(); + for(int i=0; igetFloat(); // time + nif->getString(); // key text + } + } +}; + +struct NiStringExtraData : Extra +{ + /* Two known meanings: + "MRK" - marker, only visible in the editor, not rendered in-game + "NCO" - no collision + */ + SString string; + + void read(NIFFile *nif) + { + Extra::read(nif); + + nif->getInt(); // size of string + 4. Really useful... + string = nif->getString(); + } +}; + +struct NiParticleGrowFade : Extra +{ + void read(NIFFile *nif) + { + Extra::read(nif); + + // Two floats. + nif->skip(8); + } +}; + +struct NiParticleColorModifier : Extra +{ + NiColorDataPtr data; + + void read(NIFFile *nif) + { + Extra::read(nif); + data.read(nif); + } +}; + +struct NiGravity : Extra +{ + void read(NIFFile *nif) + { + Extra::read(nif); + + // two floats, one int, six floats + nif->skip(9*4); + } +}; + +// NiPinaColada +struct NiPlanarCollider : Extra +{ + void read(NIFFile *nif) + { + Extra::read(nif); + + // (I think) 4 floats + 4 vectors + nif->skip(4*16); + } +}; + +struct NiParticleRotation : Extra +{ + void read(NIFFile *nif) + { + Extra::read(nif); + + /* + byte (0 or 1) + float (1) + float*3 + */ + nif->skip(17); + } +}; + } // Namespace #endif diff --git a/nif/nif_file.h b/nif/nif_file.h index 94b93658e5..68fd6edcac 100644 --- a/nif/nif_file.h +++ b/nif/nif_file.h @@ -61,6 +61,10 @@ class NIFFile /// Record list std::vector records; + /// Parse the file + void parse(); + + public: /// Used for error handling void fail(const std::string &msg) { @@ -69,10 +73,6 @@ class NIFFile throw str_exception(err); } - /// Parse the file - void parse(); - - public: /// Open a NIF stream. The name is used for error messages. NIFFile(StreamPtr nif, const std::string &name) : filename(name) @@ -112,7 +112,7 @@ class NIFFile template const X* getPtr() { return (const X*)inp->getPtr(sizeof(X)); } template X getType() { return *getPtr(); } - unsigned short getUshort() { return getType(); } + unsigned short getShort() { return getType(); } int getInt() { return getType(); } float getFloat() { return getType(); } char getByte() { return getType(); } diff --git a/nif/node.h b/nif/node.h index 571a462469..2b94a54435 100644 --- a/nif/node.h +++ b/nif/node.h @@ -50,7 +50,7 @@ struct Node : Named { Named::read(nif); - flags = nif->getUshort(); + flags = nif->getShort(); trafo = nif->getTrafo(); props.read(nif); @@ -91,5 +91,56 @@ struct NiTriShape : Node } }; +struct NiCamera : Node +{ + struct Camera + { + // Camera frustrum + float left, right, top, bottom, near, far; + + // Viewport + float vleft, vright, vtop, vbottom; + + // Level of detail modifier + float LOD; + }; + + const Camera *cam; + + void read(NIFFile *nif) + { + Node::read(nif); + + nif->getPtr(); + + nif->getInt(); // -1 + nif->getInt(); // 0 + } +}; + +struct NiAutoNormalParticles : Node +{ + NiAutoNormalParticlesDataPtr data; + + void read(NIFFile *nif) + { + Node::read(nif); + data.read(nif); + nif->getInt(); // -1 + } +}; + +struct NiRotatingParticles : Node +{ + NiRotatingParticlesDataPtr data; + + void read(NIFFile *nif) + { + Node::read(nif); + data.read(nif); + nif->getInt(); // -1 + } +}; + } // Namespace #endif diff --git a/nif/property.h b/nif/property.h index fb3dac65df..d22cfcc984 100644 --- a/nif/property.h +++ b/nif/property.h @@ -37,7 +37,7 @@ struct Property : Named void read(NIFFile *nif) { Named::read(nif); - flags = nif->getUshort(); + flags = nif->getShort(); } }; diff --git a/nif/record_ptr.h b/nif/record_ptr.h index 9f33ab36d9..8cf54a1040 100644 --- a/nif/record_ptr.h +++ b/nif/record_ptr.h @@ -128,17 +128,23 @@ class Extra; class Property; class Controller; class NiPixelData; +class NiColorData; class NiTriShapeData; class NiSkinInstance; class NiSourceTexture; +class NiRotatingParticlesData; +class NiAutoNormalParticlesData; typedef RecordPtrT NodePtr; typedef RecordPtrT ExtraPtr; typedef RecordPtrT ControllerPtr; typedef RecordPtrT NiPixelDataPtr; +typedef RecordPtrT NiColorDataPtr; typedef RecordPtrT NiTriShapeDataPtr; typedef RecordPtrT NiSkinInstancePtr; typedef RecordPtrT NiSourceTexturePtr; +typedef RecordPtrT NiRotatingParticlesDataPtr; +typedef RecordPtrT NiAutoNormalParticlesDataPtr; typedef RecordListT NodeList; typedef RecordListT PropertyList;