mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2024-12-28 00:15:06 +00:00
444 lines
13 KiB
C++
444 lines
13 KiB
C++
#include "physics.hpp"
|
|
|
|
#include "data.hpp"
|
|
#include "node.hpp"
|
|
|
|
namespace Nif
|
|
{
|
|
|
|
/// Non-record data types
|
|
|
|
void bhkWorldObjCInfoProperty::read(NIFStream* nif)
|
|
{
|
|
mData = nif->getUInt();
|
|
mSize = nif->getUInt();
|
|
mCapacityAndFlags = nif->getUInt();
|
|
}
|
|
|
|
void bhkWorldObjectCInfo::read(NIFStream* nif)
|
|
{
|
|
nif->skip(4); // Unused
|
|
mPhaseType = static_cast<BroadPhaseType>(nif->getChar());
|
|
nif->skip(3); // Unused
|
|
mProperty.read(nif);
|
|
}
|
|
|
|
void HavokMaterial::read(NIFStream* nif)
|
|
{
|
|
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB_OLD)
|
|
nif->skip(4); // Unknown
|
|
mMaterial = nif->getUInt();
|
|
}
|
|
|
|
void HavokFilter::read(NIFStream* nif)
|
|
{
|
|
mLayer = nif->getChar();
|
|
mFlags = nif->getChar();
|
|
mGroup = nif->getUShort();
|
|
}
|
|
|
|
void hkSubPartData::read(NIFStream* nif)
|
|
{
|
|
mHavokFilter.read(nif);
|
|
mNumVertices = nif->getUInt();
|
|
mHavokMaterial.read(nif);
|
|
}
|
|
|
|
void hkpMoppCode::read(NIFStream* nif)
|
|
{
|
|
unsigned int size = nif->getUInt();
|
|
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
|
mOffset = nif->getVector4();
|
|
if (nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3)
|
|
nif->getChar(); // MOPP data build type
|
|
if (size)
|
|
nif->getChars(mData, size);
|
|
}
|
|
|
|
void bhkEntityCInfo::read(NIFStream* nif)
|
|
{
|
|
mResponseType = static_cast<hkResponseType>(nif->getChar());
|
|
nif->skip(1); // Unused
|
|
mProcessContactDelay = nif->getUShort();
|
|
}
|
|
|
|
void TriangleData::read(NIFStream* nif)
|
|
{
|
|
for (int i = 0; i < 3; i++)
|
|
mTriangle[i] = nif->getUShort();
|
|
mWeldingInfo = nif->getUShort();
|
|
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB)
|
|
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))
|
|
{
|
|
nif->skip(4); // Unused
|
|
mHavokFilter.read(nif);
|
|
nif->skip(4); // Unused
|
|
if (nif->getBethVersion() != NIFFile::BethVersion::BETHVER_FO4)
|
|
{
|
|
if (nif->getBethVersion() >= 83)
|
|
nif->skip(4); // Unused
|
|
mResponseType = static_cast<hkResponseType>(nif->getChar());
|
|
nif->skip(1); // Unused
|
|
mProcessContactDelay = nif->getUShort();
|
|
}
|
|
}
|
|
if (nif->getBethVersion() < 83)
|
|
nif->skip(4); // Unused
|
|
mTranslation = nif->getVector4();
|
|
mRotation = nif->getQuaternion();
|
|
mLinearVelocity = nif->getVector4();
|
|
mAngularVelocity = nif->getVector4();
|
|
for (int i = 0; i < 3; i++)
|
|
for (int j = 0; j < 4; j++)
|
|
mInertiaTensor[i][j] = nif->getFloat();
|
|
mCenter = nif->getVector4();
|
|
mMass = nif->getFloat();
|
|
mLinearDamping = nif->getFloat();
|
|
mAngularDamping = nif->getFloat();
|
|
if (nif->getBethVersion() >= 83)
|
|
{
|
|
if (nif->getBethVersion() != NIFFile::BethVersion::BETHVER_FO4)
|
|
mTimeFactor = nif->getFloat();
|
|
mGravityFactor = nif->getFloat();
|
|
}
|
|
mFriction = nif->getFloat();
|
|
if (nif->getBethVersion() >= 83)
|
|
mRollingFrictionMult = nif->getFloat();
|
|
mRestitution = nif->getFloat();
|
|
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
|
{
|
|
mMaxLinearVelocity = nif->getFloat();
|
|
mMaxAngularVelocity = nif->getFloat();
|
|
if (nif->getBethVersion() != NIFFile::BethVersion::BETHVER_FO4)
|
|
mPenetrationDepth = nif->getFloat();
|
|
}
|
|
mMotionType = static_cast<hkMotionType>(nif->getChar());
|
|
if (nif->getBethVersion() < 83)
|
|
mDeactivatorType = static_cast<hkDeactivatorType>(nif->getChar());
|
|
else
|
|
mEnableDeactivation = nif->getBoolean();
|
|
mSolverDeactivation = static_cast<hkSolverDeactivation>(nif->getChar());
|
|
if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_FO4)
|
|
{
|
|
nif->skip(1);
|
|
mPenetrationDepth = nif->getFloat();
|
|
mTimeFactor = nif->getFloat();
|
|
nif->skip(4);
|
|
mResponseType = static_cast<hkResponseType>(nif->getChar());
|
|
nif->skip(1); // Unused
|
|
mProcessContactDelay = nif->getUShort();
|
|
}
|
|
mQualityType = static_cast<hkQualityType>(nif->getChar());
|
|
if (nif->getBethVersion() >= 83)
|
|
{
|
|
mAutoRemoveLevel = nif->getChar();
|
|
mResponseModifierFlags = nif->getChar();
|
|
mNumContactPointShapeKeys = nif->getChar();
|
|
mForceCollidedOntoPPU = nif->getBoolean();
|
|
}
|
|
if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_FO4)
|
|
nif->skip(3); // Unused
|
|
else
|
|
nif->skip(12); // Unused
|
|
}
|
|
|
|
/// Record types
|
|
|
|
void bhkCollisionObject::read(NIFStream* nif)
|
|
{
|
|
NiCollisionObject::read(nif);
|
|
mFlags = nif->getUShort();
|
|
mBody.read(nif);
|
|
}
|
|
|
|
void bhkWorldObject::read(NIFStream* nif)
|
|
{
|
|
mShape.read(nif);
|
|
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB_OLD)
|
|
nif->skip(4); // Unknown
|
|
mHavokFilter.read(nif);
|
|
mWorldObjectInfo.read(nif);
|
|
}
|
|
|
|
void bhkWorldObject::post(Reader& nif)
|
|
{
|
|
mShape.post(nif);
|
|
}
|
|
|
|
void bhkEntity::read(NIFStream* nif)
|
|
{
|
|
bhkWorldObject::read(nif);
|
|
mInfo.read(nif);
|
|
}
|
|
|
|
void bhkBvTreeShape::read(NIFStream* nif)
|
|
{
|
|
mShape.read(nif);
|
|
}
|
|
|
|
void bhkBvTreeShape::post(Reader& nif)
|
|
{
|
|
mShape.post(nif);
|
|
}
|
|
|
|
void bhkMoppBvTreeShape::read(NIFStream* nif)
|
|
{
|
|
bhkBvTreeShape::read(nif);
|
|
nif->skip(12); // Unused
|
|
mScale = nif->getFloat();
|
|
mMopp.read(nif);
|
|
}
|
|
|
|
void bhkNiTriStripsShape::read(NIFStream* nif)
|
|
{
|
|
mHavokMaterial.read(nif);
|
|
mRadius = nif->getFloat();
|
|
nif->skip(20); // Unused
|
|
mGrowBy = nif->getUInt();
|
|
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
|
|
mScale = nif->getVector4();
|
|
readRecordList(nif, mData);
|
|
unsigned int numFilters = nif->getUInt();
|
|
nif->getUInts(mFilters, numFilters);
|
|
}
|
|
|
|
void bhkNiTriStripsShape::post(Reader& nif)
|
|
{
|
|
postRecordList(nif, mData);
|
|
}
|
|
|
|
void bhkPackedNiTriStripsShape::read(NIFStream* nif)
|
|
{
|
|
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB)
|
|
{
|
|
mSubshapes.resize(nif->getUShort());
|
|
for (hkSubPartData& subshape : mSubshapes)
|
|
subshape.read(nif);
|
|
}
|
|
mUserData = nif->getUInt();
|
|
nif->skip(4); // Unused
|
|
mRadius = nif->getFloat();
|
|
nif->skip(4); // Unused
|
|
mScale = nif->getVector4();
|
|
nif->skip(20); // Duplicates of the two previous fields
|
|
mData.read(nif);
|
|
}
|
|
|
|
void bhkPackedNiTriStripsShape::post(Reader& nif)
|
|
{
|
|
mData.post(nif);
|
|
}
|
|
|
|
void hkPackedNiTriStripsData::read(NIFStream* nif)
|
|
{
|
|
unsigned int numTriangles = nif->getUInt();
|
|
mTriangles.resize(numTriangles);
|
|
for (unsigned int i = 0; i < numTriangles; i++)
|
|
mTriangles[i].read(nif);
|
|
|
|
unsigned int numVertices = nif->getUInt();
|
|
bool compressed = false;
|
|
if (nif->getVersion() >= NIFFile::NIFVersion::VER_BGS)
|
|
compressed = nif->getBoolean();
|
|
if (!compressed)
|
|
nif->getVector3s(mVertices, numVertices);
|
|
else
|
|
nif->skip(6 * numVertices); // Half-precision vectors are not currently supported
|
|
if (nif->getVersion() >= NIFFile::NIFVersion::VER_BGS)
|
|
{
|
|
mSubshapes.resize(nif->getUShort());
|
|
for (hkSubPartData& subshape : mSubshapes)
|
|
subshape.read(nif);
|
|
}
|
|
}
|
|
|
|
void bhkSphereRepShape::read(NIFStream* nif)
|
|
{
|
|
mHavokMaterial.read(nif);
|
|
}
|
|
|
|
void bhkConvexShape::read(NIFStream* nif)
|
|
{
|
|
bhkSphereRepShape::read(nif);
|
|
mRadius = nif->getFloat();
|
|
}
|
|
|
|
void bhkConvexVerticesShape::read(NIFStream* nif)
|
|
{
|
|
bhkConvexShape::read(nif);
|
|
mVerticesProperty.read(nif);
|
|
mNormalsProperty.read(nif);
|
|
unsigned int numVertices = nif->getUInt();
|
|
if (numVertices)
|
|
nif->getVector4s(mVertices, numVertices);
|
|
unsigned int numNormals = nif->getUInt();
|
|
if (numNormals)
|
|
nif->getVector4s(mNormals, numNormals);
|
|
}
|
|
|
|
void bhkConvexTransformShape::read(NIFStream* nif)
|
|
{
|
|
mShape.read(nif);
|
|
mHavokMaterial.read(nif);
|
|
mRadius = nif->getFloat();
|
|
nif->skip(8); // Unused
|
|
std::vector<float> mat;
|
|
nif->getFloats(mat, 16);
|
|
mTransform.set(mat.data());
|
|
}
|
|
|
|
void bhkConvexTransformShape::post(Reader& nif)
|
|
{
|
|
mShape.post(nif);
|
|
}
|
|
|
|
void bhkBoxShape::read(NIFStream* nif)
|
|
{
|
|
bhkConvexShape::read(nif);
|
|
nif->skip(8); // Unused
|
|
mExtents = nif->getVector3();
|
|
nif->skip(4); // Unused
|
|
}
|
|
|
|
void bhkCapsuleShape::read(NIFStream* nif)
|
|
{
|
|
bhkConvexShape::read(nif);
|
|
nif->skip(8); // Unused
|
|
mPoint1 = nif->getVector3();
|
|
mRadius1 = nif->getFloat();
|
|
mPoint2 = nif->getVector3();
|
|
mRadius2 = nif->getFloat();
|
|
}
|
|
|
|
void bhkListShape::read(NIFStream* nif)
|
|
{
|
|
readRecordList(nif, mSubshapes);
|
|
mHavokMaterial.read(nif);
|
|
mChildShapeProperty.read(nif);
|
|
mChildFilterProperty.read(nif);
|
|
unsigned int numFilters = nif->getUInt();
|
|
mHavokFilters.resize(numFilters);
|
|
for (HavokFilter& filter : mHavokFilters)
|
|
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);
|
|
mInfo.read(nif);
|
|
readRecordList(nif, mConstraints);
|
|
if (nif->getBethVersion() < 76)
|
|
mBodyFlags = nif->getUInt();
|
|
else
|
|
mBodyFlags = nif->getUShort();
|
|
}
|
|
|
|
} // Namespace
|