diff --git a/components/nif/niffile.cpp b/components/nif/niffile.cpp index 0c590e2cb5..b950f74e4c 100644 --- a/components/nif/niffile.cpp +++ b/components/nif/niffile.cpp @@ -182,6 +182,8 @@ namespace Nif { "NiBlendPoint3Interpolator", &construct }, { "NiBlendTransformInterpolator", &construct }, + { "bhkCompressedMeshShape", &construct }, + { "bhkCompressedMeshShapeData", &construct }, }; } diff --git a/components/nif/physics.cpp b/components/nif/physics.cpp index 6342740c94..d6d063e8a9 100644 --- a/components/nif/physics.cpp +++ b/components/nif/physics.cpp @@ -71,6 +71,46 @@ namespace Nif mNormal = nif->getVector3(); } + void bhkMeshMaterial::read(NIFStream* nif) + { + mHavokMaterial.read(nif); + mHavokFilter.read(nif); + } + + void bhkQsTransform::read(NIFStream* nif) + { + mTranslation = nif->getVector4(); + mRotation = nif->getQuaternion(); + } + + void bhkCMSBigTri::read(NIFStream* nif) + { + for (int i = 0; i < 3; i++) + mTriangle[i] = nif->getUShort(); + mMaterial = nif->getUInt(); + mWeldingInfo = nif->getUShort(); + } + + void bhkCMSChunk::read(NIFStream* nif) + { + mTranslation = nif->getVector4(); + mMaterialIndex = nif->getUInt(); + mReference = nif->getUShort(); + mTransformIndex = nif->getUShort(); + size_t numVertices = nif->getUInt(); + if (numVertices) + nif->getUShorts(mVertices, numVertices); + size_t numIndices = nif->getUInt(); + if (numIndices) + nif->getUShorts(mIndices, numIndices); + size_t numStrips = nif->getUInt(); + if (numStrips) + nif->getUShorts(mStrips, numStrips); + size_t numInfos = nif->getUInt(); + if (numInfos) + nif->getUShorts(mWeldingInfos, numInfos); + } + void bhkRigidBodyCInfo::read(NIFStream* nif) { if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0)) @@ -327,6 +367,68 @@ namespace Nif filter.read(nif); } + void bhkCompressedMeshShape::read(NIFStream* nif) + { + mTarget.read(nif); + mUserData = nif->getUInt(); + mRadius = nif->getFloat(); + nif->getFloat(); // Unknown + mScale = nif->getVector4(); + nif->getFloat(); // Radius + nif->getVector4(); // Scale + mData.read(nif); + } + + void bhkCompressedMeshShape::post(Reader& nif) + { + mTarget.post(nif); + mData.post(nif); + } + + void bhkCompressedMeshShapeData::read(NIFStream* nif) + { + mBitsPerIndex = nif->getUInt(); + mBitsPerWIndex = nif->getUInt(); + mMaskWIndex = nif->getUInt(); + mMaskIndex = nif->getUInt(); + mError = nif->getFloat(); + mAabbMin = nif->getVector4(); + mAabbMax = nif->getVector4(); + mWeldingType = nif->getChar(); + mMaterialType = nif->getChar(); + nif->skip(nif->getUInt() * 4); // Unused + nif->skip(nif->getUInt() * 4); // Unused + nif->skip(nif->getUInt() * 4); // Unused + + size_t numMaterials = nif->getUInt(); + mMaterials.resize(numMaterials); + for (bhkMeshMaterial& material : mMaterials) + material.read(nif); + + nif->getUInt(); // Unused + size_t numTransforms = nif->getUInt(); + + mChunkTransforms.resize(numTransforms); + for (bhkQsTransform& transform : mChunkTransforms) + transform.read(nif); + + size_t numBigVertices = nif->getUInt(); + if (numBigVertices) + nif->getVector4s(mBigVerts, numBigVertices); + + size_t numBigTriangles = nif->getUInt(); + mBigTris.resize(numBigTriangles); + for (bhkCMSBigTri& tri : mBigTris) + tri.read(nif); + + size_t numChunks = nif->getUInt(); + mChunks.resize(numChunks); + for (bhkCMSChunk& chunk : mChunks) + chunk.read(nif); + + nif->getUInt(); // Unused + } + void bhkRigidBody::read(NIFStream* nif) { bhkEntity::read(nif); diff --git a/components/nif/physics.hpp b/components/nif/physics.hpp index 90d1ab7c0d..cdabcd8bd1 100644 --- a/components/nif/physics.hpp +++ b/components/nif/physics.hpp @@ -96,6 +96,41 @@ namespace Nif void read(NIFStream* nif); }; + struct bhkMeshMaterial + { + HavokMaterial mHavokMaterial; + HavokFilter mHavokFilter; + void read(NIFStream* nif); + }; + + struct bhkQsTransform + { + osg::Vec4f mTranslation; + osg::Quat mRotation; + void read(NIFStream* nif); + }; + + struct bhkCMSBigTri + { + unsigned short mTriangle[3]; + unsigned int mMaterial; + unsigned short mWeldingInfo; + void read(NIFStream* nif); + }; + + struct bhkCMSChunk + { + osg::Vec4f mTranslation; + unsigned int mMaterialIndex; + unsigned short mReference; + unsigned short mTransformIndex; + std::vector mVertices; + std::vector mIndices; + std::vector mStrips; + std::vector mWeldingInfos; + void read(NIFStream* nif); + }; + enum class hkMotionType : uint8_t { Motion_Invalid = 0, @@ -354,6 +389,34 @@ namespace Nif void read(NIFStream* nif) override; }; + struct bhkCompressedMeshShape : public bhkShape + { + NodePtr mTarget; + unsigned int mUserData; + float mRadius; + osg::Vec4f mScale; + bhkCompressedMeshShapeDataPtr mData; + void read(NIFStream* nif) override; + void post(Reader& nif) override; + }; + + struct bhkCompressedMeshShapeData : public bhkRefObject + { + unsigned int mBitsPerIndex, mBitsPerWIndex; + unsigned int mMaskWIndex, mMaskIndex; + float mError; + osg::Vec4f mAabbMin, mAabbMax; + char mWeldingType; + char mMaterialType; + std::vector mMaterials; + std::vector mChunkTransforms; + std::vector mBigVerts; + std::vector mBigTris; + std::vector mChunks; + + void read(NIFStream* nif) override; + }; + struct bhkRigidBody : public bhkEntity { bhkRigidBodyCInfo mInfo; diff --git a/components/nif/record.hpp b/components/nif/record.hpp index 7315d0bdc7..0a4cf3a8b0 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -157,6 +157,8 @@ namespace Nif RC_NiBlendFloatInterpolator, RC_NiBlendPoint3Interpolator, RC_NiBlendTransformInterpolator, + RC_bhkCompressedMeshShape, + RC_bhkCompressedMeshShapeData, }; /// Base class for all records diff --git a/components/nif/recordptr.hpp b/components/nif/recordptr.hpp index 5fa0d7d203..bf5c8a9ba2 100644 --- a/components/nif/recordptr.hpp +++ b/components/nif/recordptr.hpp @@ -145,6 +145,7 @@ namespace Nif struct NiBlendInterpolator; struct NiDefaultAVObjectPalette; struct NiControllerSequence; + struct bhkCompressedMeshShapeData; using NodePtr = RecordPtrT; using ExtraPtr = RecordPtrT; @@ -179,6 +180,7 @@ namespace Nif using NiControllerManagerPtr = RecordPtrT; using NiBlendInterpolatorPtr = RecordPtrT; using NiDefaultAVObjectPalettePtr = RecordPtrT; + using bhkCompressedMeshShapeDataPtr = RecordPtrT; using NodeList = RecordListT; using PropertyList = RecordListT;