|
|
|
#ifndef OPENMW_COMPONENTS_NIF_NODE_HPP
|
|
|
|
#define OPENMW_COMPONENTS_NIF_NODE_HPP
|
|
|
|
|
|
|
|
#include <array>
|
|
|
|
#include <unordered_map>
|
|
|
|
|
|
|
|
#include <osg/Plane>
|
|
|
|
|
|
|
|
#include "base.hpp"
|
|
|
|
|
|
|
|
class btCollisionShape;
|
|
|
|
|
|
|
|
namespace Nif
|
|
|
|
{
|
|
|
|
|
|
|
|
struct NiNode;
|
|
|
|
|
|
|
|
struct BoundingVolume
|
|
|
|
{
|
|
|
|
enum Type : uint32_t
|
|
|
|
{
|
|
|
|
BASE_BV = 0xFFFFFFFF,
|
|
|
|
SPHERE_BV = 0,
|
|
|
|
BOX_BV = 1,
|
|
|
|
CAPSULE_BV = 2,
|
|
|
|
LOZENGE_BV = 3,
|
|
|
|
UNION_BV = 4,
|
|
|
|
HALFSPACE_BV = 5
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NiBoxBV
|
|
|
|
{
|
|
|
|
osg::Vec3f mCenter;
|
|
|
|
Matrix3 mAxes;
|
|
|
|
osg::Vec3f mExtents;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NiCapsuleBV
|
|
|
|
{
|
|
|
|
osg::Vec3f mCenter, mAxis;
|
|
|
|
float mExtent{ 0.f }, mRadius{ 0.f };
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NiLozengeBV
|
|
|
|
{
|
|
|
|
float mRadius{ 0.f }, mExtent0{ 0.f }, mExtent1{ 0.f };
|
|
|
|
osg::Vec3f mCenter, mAxis0, mAxis1;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NiHalfSpaceBV
|
|
|
|
{
|
|
|
|
osg::Plane mPlane;
|
|
|
|
osg::Vec3f mOrigin;
|
|
|
|
};
|
|
|
|
|
|
|
|
uint32_t mType{ BASE_BV };
|
|
|
|
osg::BoundingSpheref mSphere;
|
|
|
|
NiBoxBV mBox;
|
|
|
|
NiCapsuleBV mCapsule;
|
|
|
|
NiLozengeBV mLozenge;
|
|
|
|
std::vector<BoundingVolume> mChildren;
|
|
|
|
NiHalfSpaceBV mHalfSpace;
|
|
|
|
|
|
|
|
void read(NIFStream* nif);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NiSequenceStreamHelper : NiObjectNET
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
// NiAVObject is an object that is a part of the main NIF tree. It has
|
|
|
|
// a parent node (unless it's the root) and transformation relative to its parent.
|
|
|
|
struct NiAVObject : NiObjectNET
|
|
|
|
{
|
|
|
|
enum Flags
|
|
|
|
{
|
|
|
|
Flag_Hidden = 0x0001,
|
|
|
|
Flag_MeshCollision = 0x0002,
|
|
|
|
Flag_BBoxCollision = 0x0004,
|
|
|
|
Flag_ActiveCollision = 0x0020
|
|
|
|
};
|
|
|
|
|
|
|
|
// Node flags. Interpretation depends on the record type.
|
|
|
|
uint32_t mFlags;
|
|
|
|
NiTransform mTransform;
|
|
|
|
osg::Vec3f mVelocity;
|
|
|
|
NiPropertyList mProperties;
|
|
|
|
BoundingVolume mBounds;
|
|
|
|
NiCollisionObjectPtr mCollision;
|
|
|
|
// Parent nodes for the node. Only types derived from NiNode can be parents.
|
|
|
|
std::vector<NiNode*> mParents;
|
|
|
|
bool mIsBone{ false };
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
void post(Reader& nif) override;
|
|
|
|
|
|
|
|
void setBone();
|
|
|
|
bool isHidden() const { return mFlags & Flag_Hidden; }
|
|
|
|
bool hasMeshCollision() const { return mFlags & Flag_MeshCollision; }
|
|
|
|
bool hasBBoxCollision() const { return mFlags & Flag_BBoxCollision; }
|
|
|
|
bool collisionActive() const { return mFlags & Flag_ActiveCollision; }
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NiNode : NiAVObject
|
|
|
|
{
|
|
|
|
enum BSAnimFlags
|
|
|
|
{
|
|
|
|
AnimFlag_AutoPlay = 0x0020
|
|
|
|
};
|
|
|
|
|
|
|
|
enum BSParticleFlags
|
|
|
|
{
|
|
|
|
ParticleFlag_AutoPlay = 0x0020,
|
|
|
|
ParticleFlag_LocalSpace = 0x0080
|
|
|
|
};
|
|
|
|
|
|
|
|
NiAVObjectList mChildren;
|
|
|
|
NiAVObjectList mEffects;
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
void post(Reader& nif) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NiGeometry : NiAVObject
|
|
|
|
{
|
|
|
|
/* Possible flags:
|
|
|
|
0x40 - mesh has no vertex normals ?
|
|
|
|
|
|
|
|
Only flags included in 0x47 (ie. 0x01, 0x02, 0x04 and 0x40) have
|
|
|
|
been observed so far.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct MaterialData
|
|
|
|
{
|
|
|
|
std::vector<std::string> mNames;
|
|
|
|
std::vector<int> mExtra;
|
|
|
|
int32_t mActive{ -1 };
|
|
|
|
bool mNeedsUpdate{ false };
|
|
|
|
|
|
|
|
void read(NIFStream* nif);
|
|
|
|
};
|
|
|
|
|
|
|
|
NiGeometryDataPtr mData;
|
|
|
|
NiSkinInstancePtr mSkin;
|
|
|
|
MaterialData mMaterial;
|
|
|
|
BSShaderPropertyPtr mShaderProperty;
|
|
|
|
NiAlphaPropertyPtr mAlphaProperty;
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
void post(Reader& nif) override;
|
|
|
|
|
|
|
|
virtual std::unique_ptr<btCollisionShape> getCollisionShape() const
|
|
|
|
{
|
|
|
|
throw std::runtime_error("NiGeometry::getCollisionShape() called on base class");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Abstract triangle-based geometry
|
|
|
|
struct NiTriBasedGeom : NiGeometry
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NiTriShape : NiTriBasedGeom
|
|
|
|
{
|
|
|
|
std::unique_ptr<btCollisionShape> getCollisionShape() const override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BSSegmentedTriShape : NiTriShape
|
|
|
|
{
|
|
|
|
struct SegmentData
|
|
|
|
{
|
|
|
|
uint8_t mFlags;
|
|
|
|
uint32_t mStartIndex;
|
|
|
|
uint32_t mNumTriangles;
|
|
|
|
|
|
|
|
void read(NIFStream* nif);
|
|
|
|
};
|
|
|
|
|
|
|
|
std::vector<SegmentData> mSegments;
|
|
|
|
|
|
|
|
void read(NIFStream* nif);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NiTriStrips : NiTriBasedGeom
|
|
|
|
{
|
|
|
|
std::unique_ptr<btCollisionShape> getCollisionShape() const override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NiLines : NiTriBasedGeom
|
|
|
|
{
|
|
|
|
std::unique_ptr<btCollisionShape> getCollisionShape() const override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NiParticles : NiGeometry
|
|
|
|
{
|
|
|
|
std::unique_ptr<btCollisionShape> getCollisionShape() const override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BSLODTriShape : NiTriShape
|
|
|
|
{
|
|
|
|
std::array<uint32_t, 3> mLOD;
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NiCamera : NiAVObject
|
|
|
|
{
|
|
|
|
uint16_t mCameraFlags{ 0 };
|
|
|
|
// Camera frustum
|
|
|
|
float mLeft, mRight, mTop, mBottom, mNearDist, mFarDist;
|
|
|
|
bool mOrthographic{ false };
|
|
|
|
// Viewport
|
|
|
|
float mVLeft, mVRight, mVTop, mVBottom;
|
|
|
|
float mLODAdjust;
|
|
|
|
NiAVObjectPtr mScene;
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
void post(Reader& nif) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
// A node used as the base to switch between child nodes, such as for LOD levels.
|
|
|
|
struct NiSwitchNode : NiNode
|
|
|
|
{
|
|
|
|
uint16_t mSwitchFlags;
|
|
|
|
uint32_t mInitialIndex;
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NiLODNode : NiSwitchNode
|
|
|
|
{
|
|
|
|
struct LODRange
|
|
|
|
{
|
|
|
|
float mMinRange;
|
|
|
|
float mMaxRange;
|
|
|
|
};
|
|
|
|
|
|
|
|
osg::Vec3f mLODCenter;
|
|
|
|
std::vector<LODRange> mLODLevels;
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NiFltAnimationNode : NiSwitchNode
|
|
|
|
{
|
|
|
|
enum Flags
|
|
|
|
{
|
|
|
|
Flag_Swing = 0x40
|
|
|
|
};
|
|
|
|
|
|
|
|
float mDuration;
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
|
|
|
|
bool swing() const { return mFlags & Flag_Swing; }
|
|
|
|
};
|
|
|
|
|
|
|
|
// Abstract
|
|
|
|
struct NiAccumulator : Record
|
|
|
|
{
|
|
|
|
void read(NIFStream* nif) override {}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Node children sorters
|
|
|
|
struct NiClusterAccumulator : NiAccumulator
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NiAlphaAccumulator : NiClusterAccumulator
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NiSortAdjustNode : NiNode
|
|
|
|
{
|
|
|
|
enum class SortingMode : uint32_t
|
|
|
|
{
|
|
|
|
Inherit,
|
|
|
|
Off,
|
|
|
|
Subsort,
|
|
|
|
};
|
|
|
|
|
|
|
|
SortingMode mMode;
|
|
|
|
NiAccumulatorPtr mSubSorter;
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
void post(Reader& nif) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NiBillboardNode : NiNode
|
|
|
|
{
|
|
|
|
int mMode;
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct NiDefaultAVObjectPalette : Record
|
|
|
|
{
|
|
|
|
NiAVObjectPtr mScene;
|
|
|
|
std::unordered_map<std::string, NiAVObjectPtr> mObjects;
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
void post(Reader& nif) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BSTreeNode : NiNode
|
|
|
|
{
|
|
|
|
NiAVObjectList mBones1, mBones2;
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
void post(Reader& nif) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BSMultiBoundNode : NiNode
|
|
|
|
{
|
|
|
|
enum class BSCPCullingType : uint32_t
|
|
|
|
{
|
|
|
|
Normal,
|
|
|
|
AllPass,
|
|
|
|
AllFail,
|
|
|
|
IgnoreMultiBounds,
|
|
|
|
ForceMultiBoundsNoUpdate,
|
|
|
|
};
|
|
|
|
|
|
|
|
BSMultiBoundPtr mMultiBound;
|
|
|
|
BSCPCullingType mCullingType;
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
void post(Reader& nif) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BSVertexDesc
|
|
|
|
{
|
|
|
|
uint8_t mVertexDataSize;
|
|
|
|
uint8_t mDynamicVertexSize;
|
|
|
|
uint8_t mUV1Offset;
|
|
|
|
uint8_t mUV2Offset;
|
|
|
|
uint8_t mNormalOffset;
|
|
|
|
uint8_t mTangentOffset;
|
|
|
|
uint8_t mColorOffset;
|
|
|
|
uint8_t mSkinningDataOffset;
|
|
|
|
uint8_t mLandscapeDataOffset;
|
|
|
|
uint8_t mEyeDataOffset;
|
|
|
|
uint16_t mFlags;
|
|
|
|
|
|
|
|
enum VertexAttribute
|
|
|
|
{
|
|
|
|
Vertex = 0x0001,
|
|
|
|
UVs = 0x0002,
|
|
|
|
UVs_2 = 0x0004,
|
|
|
|
Normals = 0x0008,
|
|
|
|
Tangents = 0x0010,
|
|
|
|
Vertex_Colors = 0x0020,
|
|
|
|
Skinned = 0x0040,
|
|
|
|
Land_Data = 0x0080,
|
|
|
|
Eye_Data = 0x0100,
|
|
|
|
Instance = 0x0200,
|
|
|
|
Full_Precision = 0x0400,
|
|
|
|
};
|
|
|
|
|
|
|
|
void read(NIFStream* nif);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BSVertexData
|
|
|
|
{
|
|
|
|
osg::Vec4f mVertex; // Bitangent X is stored in the fourth component
|
|
|
|
std::array<Misc::float16_t, 4> mHalfVertex; // Ditto
|
|
|
|
std::array<Misc::float16_t, 2> mUV;
|
|
|
|
std::array<char, 4> mNormal; // Bitangent Y is stored in the fourth component
|
|
|
|
std::array<char, 4> mTangent; // Bitangent Z is stored in the fourth component
|
|
|
|
std::array<char, 4> mVertColor;
|
|
|
|
std::array<Misc::float16_t, 4> mBoneWeights;
|
|
|
|
std::array<char, 4> mBoneIndices;
|
|
|
|
float mEyeData;
|
|
|
|
|
|
|
|
void read(NIFStream* nif, uint16_t flags);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BSTriShape : NiAVObject
|
|
|
|
{
|
|
|
|
osg::BoundingSpheref mBoundingSphere;
|
|
|
|
std::array<float, 6> mBoundMinMax;
|
|
|
|
RecordPtrT<Record> mSkin;
|
|
|
|
BSShaderPropertyPtr mShaderProperty;
|
|
|
|
NiAlphaPropertyPtr mAlphaProperty;
|
|
|
|
BSVertexDesc mVertDesc;
|
|
|
|
uint32_t mDataSize;
|
|
|
|
std::vector<BSVertexData> mVertData;
|
|
|
|
std::vector<unsigned short> mTriangles;
|
|
|
|
uint32_t mParticleDataSize;
|
|
|
|
std::vector<Misc::float16_t> mParticleVerts;
|
|
|
|
std::vector<Misc::float16_t> mParticleNormals;
|
|
|
|
std::vector<unsigned short> mParticleTriangles;
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
void post(Reader& nif) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BSDynamicTriShape : BSTriShape
|
|
|
|
{
|
|
|
|
uint32_t mDynamicDataSize;
|
|
|
|
std::vector<osg::Vec4f> mDynamicData;
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BSMeshLODTriShape : BSTriShape
|
|
|
|
{
|
|
|
|
std::array<uint32_t, 3> mLOD;
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BSSubIndexTriShape : BSTriShape
|
|
|
|
{
|
|
|
|
struct SubSegment
|
|
|
|
{
|
|
|
|
uint32_t mStartIndex;
|
|
|
|
uint32_t mNumPrimitives;
|
|
|
|
uint32_t mArrayIndex;
|
|
|
|
|
|
|
|
void read(NIFStream* nif);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Segment
|
|
|
|
{
|
|
|
|
uint32_t mStartIndex;
|
|
|
|
uint32_t mNumPrimitives;
|
|
|
|
uint32_t mParentArrayIndex;
|
|
|
|
std::vector<SubSegment> mSubSegments;
|
|
|
|
|
|
|
|
void read(NIFStream* nif);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SubSegmentDataRecord
|
|
|
|
{
|
|
|
|
uint32_t mUserSlotID;
|
|
|
|
uint32_t mMaterial;
|
|
|
|
std::vector<float> mExtraData;
|
|
|
|
|
|
|
|
void read(NIFStream* nif);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SubSegmentData
|
|
|
|
{
|
|
|
|
std::vector<uint32_t> mArrayIndices;
|
|
|
|
std::vector<SubSegmentDataRecord> mDataRecords;
|
|
|
|
std::string mSSFFile;
|
|
|
|
|
|
|
|
void read(NIFStream* nif);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Segmentation
|
|
|
|
{
|
|
|
|
uint32_t mNumPrimitives;
|
|
|
|
uint32_t mNumTotalSegments;
|
|
|
|
std::vector<Segment> mSegments;
|
|
|
|
SubSegmentData mSubSegmentData;
|
|
|
|
|
|
|
|
void read(NIFStream* nif);
|
|
|
|
};
|
|
|
|
|
|
|
|
std::vector<BSSegmentedTriShape::SegmentData> mSegments; // SSE
|
|
|
|
Segmentation mSegmentation; // FO4
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BSValueNode : NiNode
|
|
|
|
{
|
|
|
|
enum Flags
|
|
|
|
{
|
|
|
|
Flag_BillboardWorldZ = 0x1,
|
|
|
|
Flag_UsePlayerAdjust = 0x2,
|
|
|
|
};
|
|
|
|
|
|
|
|
uint32_t mValue;
|
|
|
|
uint8_t mValueFlags;
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BSOrderedNode : NiNode
|
|
|
|
{
|
|
|
|
osg::Vec4f mAlphaSortBound;
|
|
|
|
bool mStaticBound;
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BSRangeNode : NiNode
|
|
|
|
{
|
|
|
|
uint8_t mMin, mMax;
|
|
|
|
uint8_t mCurrent;
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BSResourceID
|
|
|
|
{
|
|
|
|
uint32_t mFileHash;
|
|
|
|
std::array<char, 4> mExtension;
|
|
|
|
uint32_t mDirectoryHash;
|
|
|
|
|
|
|
|
void read(NIFStream* nif);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BSDistantObjectInstance
|
|
|
|
{
|
|
|
|
BSResourceID mResourceID;
|
|
|
|
std::vector<osg::Matrixf> mTransforms;
|
|
|
|
|
|
|
|
void read(NIFStream* nif);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BSShaderTextureArray
|
|
|
|
{
|
|
|
|
std::vector<std::vector<std::string>> mTextureArrays;
|
|
|
|
|
|
|
|
void read(NIFStream* nif);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BSDistantObjectInstancedNode : BSMultiBoundNode
|
|
|
|
{
|
|
|
|
std::vector<BSDistantObjectInstance> mInstances;
|
|
|
|
std::array<BSShaderTextureArray, 3> mShaderTextureArrays;
|
|
|
|
|
|
|
|
void read(NIFStream* nif) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif
|