mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 18:26:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			530 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			530 lines
		
	
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #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
 |