mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 21:49:55 +00:00
NIF: implemented NiNode and NiTriShape
This commit is contained in:
parent
2d92d39f05
commit
4128462add
5 changed files with 193 additions and 13 deletions
|
@ -53,14 +53,17 @@ void NIFFile::parse()
|
|||
{
|
||||
SString rec = getString();
|
||||
|
||||
cout << i << ": " << rec.toString() << endl;
|
||||
cout << endl << i << ": " << rec.toString() << endl;
|
||||
|
||||
Node r;
|
||||
r.read(this);
|
||||
cout << r.name.toString() << endl;
|
||||
cout << r.extra.getIndex() << endl;
|
||||
cout << r.controller.getIndex() << endl;
|
||||
Record *r;
|
||||
|
||||
break;
|
||||
// This can be heavily optimized later if needed. For example, a
|
||||
// hash table or a FSM-based parser could be used to look up
|
||||
// node names.
|
||||
if(rec == "NiNode") r = new NiNode;
|
||||
else if(rec == "NiTriShape") r = new NiTriShape;
|
||||
else break;
|
||||
|
||||
r->read(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include "record.h"
|
||||
#include "nif_types.h"
|
||||
|
||||
using namespace Mangle::Stream;
|
||||
|
||||
|
@ -107,7 +108,9 @@ class NIFFile
|
|||
|
||||
****************************************************/
|
||||
|
||||
template<class X> X getType() { return *((X*)inp->getPtr(sizeof(X))); }
|
||||
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>(); }
|
||||
int getInt() { return getType<int>(); }
|
||||
|
||||
template<class X>
|
||||
|
@ -119,6 +122,11 @@ class NIFFile
|
|||
|
||||
SString getString() { return getArray<char>(); }
|
||||
|
||||
const Vector *getVector() { return getPtr<Vector>(); }
|
||||
const Matrix *getMatrix() { return getPtr<Matrix>(); }
|
||||
const Transformation *getTrafo() { return getPtr<Transformation>(); }
|
||||
|
||||
// For fixed-size strings where you already know the size
|
||||
const char *getString(int size)
|
||||
{ return (const char*)inp->getPtr(size); }
|
||||
};
|
||||
|
|
66
nif/nif_types.h
Normal file
66
nif/nif_types.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
OpenMW - The completely unofficial reimplementation of Morrowind
|
||||
Copyright (C) 2008-2010 Nicolay Korslund
|
||||
Email: < korslund@gmail.com >
|
||||
WWW: http://openmw.sourceforge.net/
|
||||
|
||||
This file (nif_types.h) is part of the OpenMW package.
|
||||
|
||||
OpenMW is distributed as free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License
|
||||
version 3, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
version 3 along with this program. If not, see
|
||||
http://www.gnu.org/licenses/ .
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _NIF_TYPES_H_
|
||||
#define _NIF_TYPES_H_
|
||||
|
||||
// Common types used in NIF files
|
||||
|
||||
namespace Nif
|
||||
{
|
||||
|
||||
/* These packing #pragmas aren't really necessary on 32 bit
|
||||
machines. I haven't tested on 64 bit yet. In any case it doesn't
|
||||
hurt to include them. We can't allow any compiler-generated padding
|
||||
in any of these structs, since they are used to interface directly
|
||||
with raw data from the NIF files.
|
||||
*/
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
|
||||
struct Vector
|
||||
{
|
||||
float array[3];
|
||||
};
|
||||
|
||||
struct Vector4
|
||||
{
|
||||
float array[4];
|
||||
};
|
||||
|
||||
struct Matrix
|
||||
{
|
||||
Vector v[3];
|
||||
};
|
||||
|
||||
struct Transformation
|
||||
{
|
||||
Vector pos;
|
||||
Matrix rotation;
|
||||
float scale;
|
||||
Vector velocity;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
} // Namespace
|
||||
#endif
|
50
nif/node.h
50
nif/node.h
|
@ -35,11 +35,59 @@ namespace Nif
|
|||
*/
|
||||
struct Node : Named
|
||||
{
|
||||
// Not done
|
||||
// Node flags. Interpretation depends somewhat on the type of node.
|
||||
int flags;
|
||||
const Transformation *trafo;
|
||||
PropertyList props;
|
||||
|
||||
// Bounding box info
|
||||
bool hasBounds;
|
||||
const Vector *boundPos;
|
||||
const Matrix *boundRot;
|
||||
const Vector *boundXYZ;
|
||||
|
||||
void read(NIFFile *nif)
|
||||
{
|
||||
Named::read(nif);
|
||||
|
||||
flags = nif->getUshort();
|
||||
trafo = nif->getTrafo();
|
||||
props.read(nif);
|
||||
|
||||
hasBounds = nif->getInt();
|
||||
if(hasBounds)
|
||||
{
|
||||
nif->getInt();
|
||||
boundPos = nif->getVector();
|
||||
boundRot = nif->getMatrix();
|
||||
boundXYZ = nif->getVector();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct NiNode : Node
|
||||
{
|
||||
NodeList children;
|
||||
NodeList effects;
|
||||
|
||||
void read(NIFFile *nif)
|
||||
{
|
||||
Node::read(nif);
|
||||
children.read(nif);
|
||||
effects.read(nif);
|
||||
}
|
||||
};
|
||||
|
||||
struct NiTriShape : Node
|
||||
{
|
||||
NiTriShapeDataPtr data;
|
||||
NiSkinInstancePtr skin;
|
||||
|
||||
void read(NIFFile *nif)
|
||||
{
|
||||
Node::read(nif);
|
||||
data.read(nif);
|
||||
skin.read(nif);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -25,9 +25,15 @@
|
|||
#define _NIF_RECORD_PTR_H_
|
||||
|
||||
#include "nif_file.h"
|
||||
#include <vector>
|
||||
|
||||
namespace Nif
|
||||
{
|
||||
|
||||
/** A reference to another record. It is read as an index from the
|
||||
NIF, and later looked up in the index table to get an actual
|
||||
pointer.
|
||||
*/
|
||||
template <class X>
|
||||
class RecordPtrT
|
||||
{
|
||||
|
@ -53,7 +59,7 @@ class RecordPtrT
|
|||
}
|
||||
|
||||
/// Look up the actual object from the index
|
||||
X* operator->()
|
||||
X* getPtr()
|
||||
{
|
||||
// Have we found the pointer already?
|
||||
if(ptr == NULL)
|
||||
|
@ -69,20 +75,69 @@ class RecordPtrT
|
|||
return ptr;
|
||||
}
|
||||
|
||||
/// Syntactic sugar
|
||||
X* operator->() { return getPtr(); }
|
||||
X& get() { return *getPtr(); }
|
||||
|
||||
/// Pointers are allowed to be empty
|
||||
bool empty() { return index == -1; }
|
||||
|
||||
int getIndex() { return index; }
|
||||
};
|
||||
|
||||
/** A list of references to other records. These are read as a list,
|
||||
and later converted to pointers as needed. Not an optimized
|
||||
implementation.
|
||||
*/
|
||||
template <class X>
|
||||
class RecordListT
|
||||
{
|
||||
typedef RecordPtrT<X> Ptr;
|
||||
std::vector<Ptr> list;
|
||||
|
||||
public:
|
||||
|
||||
void read(NIFFile *nif)
|
||||
{
|
||||
int len = nif->getInt();
|
||||
list.resize(len);
|
||||
|
||||
assert(len >= 0 && len < 1000);
|
||||
for(int i=0;i<len;i++)
|
||||
list[i].read(nif);
|
||||
}
|
||||
|
||||
X& operator[](int index)
|
||||
{
|
||||
assert(index >= 0 && index < list.size());
|
||||
return list[index].get();
|
||||
}
|
||||
|
||||
bool has(int index)
|
||||
{
|
||||
assert(index >= 0 && index < list.size());
|
||||
return !list[index].empty();
|
||||
}
|
||||
|
||||
int length() { return list.size(); }
|
||||
};
|
||||
|
||||
|
||||
class Extra;
|
||||
class Controller;
|
||||
class Node;
|
||||
class Extra;
|
||||
class Property;
|
||||
class Controller;
|
||||
class NiTriShapeData;
|
||||
class NiSkinInstance;
|
||||
|
||||
typedef RecordPtrT<Node> NodePtr;
|
||||
typedef RecordPtrT<Extra> ExtraPtr;
|
||||
typedef RecordPtrT<Controller> ControllerPtr;
|
||||
typedef RecordPtrT<Node> NodePtr;
|
||||
typedef RecordPtrT<NiTriShapeData> NiTriShapeDataPtr;
|
||||
typedef RecordPtrT<NiSkinInstance> NiSkinInstancePtr;
|
||||
|
||||
typedef RecordListT<Node> NodeList;
|
||||
typedef RecordListT<Property> PropertyList;
|
||||
|
||||
} // Namespace
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue