Something went wrong. Try again.
OpenMW is an open implementation of the Morrowind engine
Something went wrong. Try again.
13 kB · 544 lines
C++
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545#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;
const NiNode* findRootCollisionNode(bool recursive) const; };
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;
void read(NIFStream* nif); };
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 { enum class BillboardMode : uint16_t { AlwaysFaceCamera = 0, RotateAboutUp = 1, RigidFaceCamera = 2, AlwaysFaceCenter = 3, RigidFaceCenter = 4, BSRotateAboutUp = 5, }; BillboardMode 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; uint16_t mNumVertices; 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