Finished data.h, extra.h and node.h

pull/7/head
Nicolay Korslund 15 years ago
parent c0d9bdb499
commit f773ef4b45

@ -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;i<verts;i++)
{
// Number of vertices matching vertex 'i'
short num = nif->getUshort();
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;i<bones;i++)
{
nif->getMatrix(); // 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; i<morphCount; i++)
{
int magic = nif->getInt();
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;j<count;j++)
{
nif->getFloat(); // 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);
}
}
};

@ -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; i<keynum; i++)
{
nif->getFloat(); // 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

@ -61,6 +61,10 @@ class NIFFile
/// Record list
std::vector<Record*> 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<class X> const X* getPtr() { return (const X*)inp->getPtr(sizeof(X)); }
template<class X> X getType() { return *getPtr<X>(); }
unsigned short getUshort() { return getType<unsigned short>(); }
unsigned short getShort() { return getType<unsigned short>(); }
int getInt() { return getType<int>(); }
float getFloat() { return getType<float>(); }
char getByte() { return getType<char>(); }

@ -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<Camera>();
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

@ -37,7 +37,7 @@ struct Property : Named
void read(NIFFile *nif)
{
Named::read(nif);
flags = nif->getUshort();
flags = nif->getShort();
}
};

@ -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<Node> NodePtr;
typedef RecordPtrT<Extra> ExtraPtr;
typedef RecordPtrT<Controller> ControllerPtr;
typedef RecordPtrT<NiPixelData> NiPixelDataPtr;
typedef RecordPtrT<NiColorData> NiColorDataPtr;
typedef RecordPtrT<NiTriShapeData> NiTriShapeDataPtr;
typedef RecordPtrT<NiSkinInstance> NiSkinInstancePtr;
typedef RecordPtrT<NiSourceTexture> NiSourceTexturePtr;
typedef RecordPtrT<NiRotatingParticlesData> NiRotatingParticlesDataPtr;
typedef RecordPtrT<NiAutoNormalParticlesData> NiAutoNormalParticlesDataPtr;
typedef RecordListT<Node> NodeList;
typedef RecordListT<Property> PropertyList;

Loading…
Cancel
Save