You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw/components/nif/physics.cpp

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