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

1036 lines
28 KiB
C++

#include "physics.hpp"
#include "data.hpp"
#include "node.hpp"
#include <array>
namespace Nif
{
/// Non-record data types
void bhkWorldObjCInfoProperty::read(NIFStream* nif)
{
nif->read(mData);
nif->read(mSize);
nif->read(mCapacityAndFlags);
}
void bhkWorldObjectCInfo::read(NIFStream* nif)
{
nif->skip(4); // Unused
mPhaseType = static_cast<BroadPhaseType>(nif->get<uint8_t>());
nif->skip(3); // Unused
mProperty.read(nif);
}
void HavokMaterial::read(NIFStream* nif)
{
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB_OLD)
nif->skip(4); // Unknown
nif->read(mMaterial);
}
void HavokFilter::read(NIFStream* nif)
{
nif->read(mLayer);
nif->read(mFlags);
nif->read(mGroup);
}
void hkSubPartData::read(NIFStream* nif)
{
mHavokFilter.read(nif);
nif->read(mNumVertices);
mHavokMaterial.read(nif);
}
void bhkEntityCInfo::read(NIFStream* nif)
{
mResponseType = static_cast<hkResponseType>(nif->get<uint8_t>());
nif->skip(1); // Unused
nif->read(mProcessContactDelay);
}
void hkpMoppCode::read(NIFStream* nif)
{
uint32_t dataSize;
nif->read(dataSize);
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
nif->read(mOffset);
if (nif->getBethVersion() > NIFFile::BethVersion::BETHVER_FO3)
nif->read(mBuildType);
nif->readVector(mData, dataSize);
}
void TriangleData::read(NIFStream* nif)
{
nif->readArray(mTriangle);
nif->read(mWeldingInfo);
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB)
nif->read(mNormal);
}
void bhkMeshMaterial::read(NIFStream* nif)
{
mHavokMaterial.read(nif);
mHavokFilter.read(nif);
}
void bhkQsTransform::read(NIFStream* nif)
{
nif->read(mTranslation);
nif->read(mRotation);
}
void bhkCMSBigTri::read(NIFStream* nif)
{
nif->readArray(mTriangle);
nif->read(mMaterial);
nif->read(mWeldingInfo);
}
void bhkCMSChunk::read(NIFStream* nif)
{
nif->read(mTranslation);
nif->read(mMaterialIndex);
nif->read(mReference);
nif->read(mTransformIndex);
nif->readVector(mVertices, nif->get<uint32_t>());
nif->readVector(mIndices, nif->get<uint32_t>());
nif->readVector(mStrips, nif->get<uint32_t>());
nif->readVector(mWeldingInfos, nif->get<uint32_t>());
}
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->get<uint8_t>());
nif->skip(1); // Unused
nif->read(mProcessContactDelay);
}
}
if (nif->getBethVersion() < 83)
nif->skip(4); // Unused
nif->read(mTranslation);
nif->read(mRotation);
nif->read(mLinearVelocity);
nif->read(mAngularVelocity);
// A bit hacky, but this is the only instance where a 3x3 matrix has padding.
for (int i = 0; i < 3; i++)
{
nif->read(mInertiaTensor.mValues[i], 3);
nif->skip(4); // Padding
}
nif->read(mCenter);
nif->read(mMass);
nif->read(mLinearDamping);
nif->read(mAngularDamping);
if (nif->getBethVersion() >= 83)
{
if (nif->getBethVersion() != NIFFile::BethVersion::BETHVER_FO4)
nif->read(mTimeFactor);
nif->read(mGravityFactor);
}
nif->read(mFriction);
if (nif->getBethVersion() >= 83)
nif->read(mRollingFrictionMult);
nif->read(mRestitution);
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
{
nif->read(mMaxLinearVelocity);
nif->read(mMaxAngularVelocity);
if (nif->getBethVersion() != NIFFile::BethVersion::BETHVER_FO4)
nif->read(mPenetrationDepth);
}
mMotionType = static_cast<hkMotionType>(nif->get<uint8_t>());
if (nif->getBethVersion() < 83)
mDeactivatorType = static_cast<hkDeactivatorType>(nif->get<uint8_t>());
else
nif->read(mEnableDeactivation);
mSolverDeactivation = static_cast<hkSolverDeactivation>(nif->get<uint8_t>());
if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_FO4)
{
nif->skip(1);
nif->read(mPenetrationDepth);
nif->read(mTimeFactor);
nif->skip(4);
mResponseType = static_cast<hkResponseType>(nif->get<uint8_t>());
nif->skip(1); // Unused
nif->read(mProcessContactDelay);
}
mQualityType = static_cast<hkQualityType>(nif->get<uint8_t>());
if (nif->getBethVersion() >= 83)
{
nif->read(mAutoRemoveLevel);
nif->read(mResponseModifierFlags);
nif->read(mNumContactPointShapeKeys);
nif->read(mForceCollidedOntoPPU);
}
if (nif->getBethVersion() == NIFFile::BethVersion::BETHVER_FO4)
nif->skip(3); // Unused
else
nif->skip(12); // Unused
}
void bhkConstraintCInfo::read(NIFStream* nif)
{
nif->get<uint32_t>(); // Number of entities, unused
mEntityA.read(nif);
mEntityB.read(nif);
mPriority = static_cast<ConstraintPriority>(nif->get<uint32_t>());
}
void bhkConstraintCInfo::post(Reader& nif)
{
mEntityA.post(nif);
mEntityB.post(nif);
}
void bhkPositionConstraintMotor::read(NIFStream* nif)
{
nif->read(mMinForce);
nif->read(mMaxForce);
nif->read(mTau);
nif->read(mDamping);
nif->read(mProportionalRecoveryVelocity);
nif->read(mConstantRecoveryVelocity);
nif->read(mEnabled);
}
void bhkVelocityConstraintMotor::read(NIFStream* nif)
{
nif->read(mMinForce);
nif->read(mMaxForce);
nif->read(mTau);
nif->read(mTargetVelocity);
nif->read(mUseVelocityTarget);
nif->read(mEnabled);
}
void bhkSpringDamperConstraintMotor::read(NIFStream* nif)
{
nif->read(mMinForce);
nif->read(mMaxForce);
nif->read(mSpringConstant);
nif->read(mSpringDamping);
nif->read(mEnabled);
}
void bhkConstraintMotorCInfo::read(NIFStream* nif)
{
mType = static_cast<hkMotorType>(nif->get<uint8_t>());
switch (mType)
{
case hkMotorType::Motor_Position:
mPositionMotor.read(nif);
break;
case hkMotorType::Motor_Velocity:
mVelocityMotor.read(nif);
break;
case hkMotorType::Motor_SpringDamper:
mSpringDamperMotor.read(nif);
break;
case hkMotorType::Motor_None:
default:
break;
}
}
void bhkRagdollConstraintCInfo::read(NIFStream* nif)
{
if (nif->getBethVersion() <= 16)
{
nif->read(mDataA.mPivot);
nif->read(mDataA.mPlane);
nif->read(mDataA.mTwist);
nif->read(mDataB.mPivot);
nif->read(mDataB.mPlane);
nif->read(mDataB.mTwist);
}
else
{
nif->read(mDataA.mTwist);
nif->read(mDataA.mPlane);
nif->read(mDataA.mMotor);
nif->read(mDataA.mPivot);
nif->read(mDataB.mTwist);
nif->read(mDataB.mPlane);
nif->read(mDataB.mMotor);
nif->read(mDataB.mPivot);
}
nif->read(mConeMaxAngle);
nif->read(mPlaneMinAngle);
nif->read(mPlaneMaxAngle);
nif->read(mTwistMinAngle);
nif->read(mTwistMaxAngle);
nif->read(mMaxFriction);
if (nif->getVersion() >= NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() > 16)
mMotor.read(nif);
}
void bhkHingeConstraintCInfo::read(NIFStream* nif)
{
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB)
{
nif->read(mDataA.mPivot);
nif->read(mDataA.mPerpAxis1);
nif->read(mDataA.mPerpAxis2);
nif->read(mDataB.mPivot);
nif->read(mDataB.mAxis);
}
else
{
nif->read(mDataA.mAxis);
nif->read(mDataA.mPerpAxis1);
nif->read(mDataA.mPerpAxis2);
nif->read(mDataA.mPivot);
nif->read(mDataB.mAxis);
nif->read(mDataB.mPerpAxis1);
nif->read(mDataB.mPerpAxis2);
nif->read(mDataB.mPivot);
}
}
void bhkLimitedHingeConstraintCInfo::read(NIFStream* nif)
{
if (nif->getBethVersion() <= 16)
{
nif->read(mDataA.mPivot);
nif->read(mDataA.mAxis);
nif->read(mDataA.mPerpAxis1);
nif->read(mDataA.mPerpAxis2);
nif->read(mDataB.mPivot);
nif->read(mDataB.mAxis);
nif->read(mDataB.mPerpAxis2);
}
else
{
nif->read(mDataA.mAxis);
nif->read(mDataA.mPerpAxis1);
nif->read(mDataA.mPerpAxis2);
nif->read(mDataA.mPivot);
nif->read(mDataB.mAxis);
nif->read(mDataB.mPerpAxis1);
nif->read(mDataB.mPerpAxis2);
nif->read(mDataB.mPivot);
}
nif->read(mMinAngle);
nif->read(mMaxAngle);
nif->read(mMaxFriction);
if (nif->getVersion() >= NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() > 16)
mMotor.read(nif);
}
void bhkBallAndSocketConstraintCInfo::read(NIFStream* nif)
{
nif->read(mPivotA);
nif->read(mPivotB);
}
void bhkStiffSpringConstraintCInfo::read(NIFStream* nif)
{
nif->read(mPivotA);
nif->read(mPivotB);
nif->read(mLength);
}
void bhkPrismaticConstraintCInfo::read(NIFStream* nif)
{
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB)
{
nif->read(mDataA.mPivot);
nif->read(mDataA.mRotation);
nif->read(mDataA.mPlane);
nif->read(mDataA.mSliding);
nif->read(mDataB.mSliding);
nif->read(mDataB.mPivot);
nif->read(mDataB.mRotation);
nif->read(mDataB.mPlane);
}
else
{
nif->read(mDataA.mSliding);
nif->read(mDataA.mRotation);
nif->read(mDataA.mPlane);
nif->read(mDataA.mPivot);
nif->read(mDataB.mSliding);
nif->read(mDataB.mRotation);
nif->read(mDataB.mPlane);
nif->read(mDataB.mPivot);
}
nif->read(mMinDistance);
nif->read(mMaxDistance);
nif->read(mFriction);
if (nif->getVersion() >= NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() >= 17)
mMotor.read(nif);
}
void bhkMalleableConstraintCInfo::read(NIFStream* nif)
{
mType = static_cast<hkConstraintType>(nif->get<uint32_t>());
mInfo.read(nif);
switch (mType)
{
case hkConstraintType::BallAndSocket:
mBallAndSocketInfo.read(nif);
break;
case hkConstraintType::Hinge:
mHingeInfo.read(nif);
break;
case hkConstraintType::LimitedHinge:
mLimitedHingeInfo.read(nif);
break;
case hkConstraintType::Prismatic:
mPrismaticInfo.read(nif);
break;
case hkConstraintType::Ragdoll:
mRagdollInfo.read(nif);
break;
case hkConstraintType::StiffSpring:
mStiffSpringInfo.read(nif);
break;
default:
throw Nif::Exception(
"Unrecognized constraint type in bhkMalleableConstraint", nif->getFile().getFilename());
}
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB)
{
nif->read(mTau);
nif->read(mDamping);
}
else
{
nif->read(mStrength);
}
}
void bhkWrappedConstraintData::read(NIFStream* nif)
{
mType = static_cast<hkConstraintType>(nif->get<uint32_t>());
mInfo.read(nif);
switch (mType)
{
case hkConstraintType::BallAndSocket:
mBallAndSocketInfo.read(nif);
break;
case hkConstraintType::Hinge:
mHingeInfo.read(nif);
break;
case hkConstraintType::LimitedHinge:
mLimitedHingeInfo.read(nif);
break;
case hkConstraintType::Prismatic:
mPrismaticInfo.read(nif);
break;
case hkConstraintType::Ragdoll:
mRagdollInfo.read(nif);
break;
case hkConstraintType::StiffSpring:
mStiffSpringInfo.read(nif);
break;
case hkConstraintType::Malleable:
mMalleableInfo.read(nif);
break;
default:
throw Nif::Exception(
"Unrecognized constraint type in bhkWrappedConstraintData", nif->getFile().getFilename());
}
}
void bhkConstraintChainCInfo::read(NIFStream* nif)
{
readRecordList(nif, mEntities);
mInfo.read(nif);
}
void bhkConstraintChainCInfo::post(Reader& nif)
{
postRecordList(nif, mEntities);
}
/// Record types
void bhkCollisionObject::read(NIFStream* nif)
{
NiCollisionObject::read(nif);
nif->read(mFlags);
mBody.read(nif);
}
void bhkNPCollisionObject::read(NIFStream* nif)
{
NiCollisionObject::read(nif);
nif->read(mFlags);
mData.read(nif);
nif->read(mBodyID);
}
void bhkNPCollisionObject::post(Reader& nif)
{
NiCollisionObject::post(nif);
mData.post(nif);
}
void bhkBlendCollisionObject::read(NIFStream* nif)
{
bhkCollisionObject::read(nif);
nif->read(mHeirGain);
nif->read(mVelGain);
if (nif->getBethVersion() <= 8)
nif->skip(8); // Unknown
}
void bhkPhysicsSystem::read(NIFStream* nif)
{
nif->readVector(mData, nif->get<uint32_t>());
}
void bhkRagdollSystem::read(NIFStream* nif)
{
nif->readVector(mData, nif->get<uint32_t>());
}
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
nif->read(mScale);
mMopp.read(nif);
}
void bhkNiTriStripsShape::read(NIFStream* nif)
{
mHavokMaterial.read(nif);
nif->read(mRadius);
nif->skip(20); // Unused
nif->read(mGrowBy);
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
nif->read(mScale);
readRecordList(nif, mData);
uint32_t numFilters;
nif->read(numFilters);
mHavokFilters.resize(numFilters);
for (HavokFilter& filter : mHavokFilters)
filter.read(nif);
}
void bhkNiTriStripsShape::post(Reader& nif)
{
postRecordList(nif, mData);
}
void bhkPackedNiTriStripsShape::read(NIFStream* nif)
{
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB)
{
uint16_t numSubshapes;
nif->read(numSubshapes);
mSubshapes.resize(numSubshapes);
for (hkSubPartData& subshape : mSubshapes)
subshape.read(nif);
}
nif->read(mUserData);
nif->skip(4); // Unused
nif->read(mRadius);
nif->skip(4); // Unused
nif->read(mScale);
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)
{
uint32_t numTriangles;
nif->read(numTriangles);
mTriangles.resize(numTriangles);
for (uint32_t i = 0; i < numTriangles; i++)
mTriangles[i].read(nif);
uint32_t numVertices;
nif->read(numVertices);
bool compressed = false;
if (nif->getVersion() >= NIFFile::NIFVersion::VER_BGS)
nif->read(compressed);
if (!compressed)
nif->readVector(mVertices, numVertices);
else
nif->skip(6 * numVertices); // Half-precision vectors are not currently supported
if (nif->getVersion() >= NIFFile::NIFVersion::VER_BGS)
{
uint16_t numSubshapes;
nif->read(numSubshapes);
mSubshapes.resize(numSubshapes);
for (hkSubPartData& subshape : mSubshapes)
subshape.read(nif);
}
}
void bhkSphereRepShape::read(NIFStream* nif)
{
mHavokMaterial.read(nif);
}
void bhkConvexShape::read(NIFStream* nif)
{
bhkSphereRepShape::read(nif);
nif->read(mRadius);
}
void bhkConvexListShape::read(NIFStream* nif)
{
readRecordList(nif, mSubShapes);
mMaterial.read(nif);
nif->read(mRadius);
nif->skip(8); // Unknown
mChildShapeProperty.read(nif);
nif->read(mUseCachedAABB);
nif->read(mClosestPointMinDistance);
}
void bhkConvexListShape::post(Reader& nif)
{
postRecordList(nif, mSubShapes);
}
void bhkConvexSweepShape::read(NIFStream* nif)
{
mShape.read(nif);
mMaterial.read(nif);
nif->read(mRadius);
nif->skip(12); // Unknown
}
void bhkConvexSweepShape::post(Reader& nif)
{
mShape.post(nif);
}
void bhkConvexVerticesShape::read(NIFStream* nif)
{
bhkConvexShape::read(nif);
mVerticesProperty.read(nif);
mNormalsProperty.read(nif);
nif->readVector(mVertices, nif->get<uint32_t>());
nif->readVector(mNormals, nif->get<uint32_t>());
}
void bhkConvexTransformShape::read(NIFStream* nif)
{
mShape.read(nif);
mHavokMaterial.read(nif);
nif->read(mRadius);
nif->skip(8); // Unused
std::array<float, 16> mat;
nif->readArray(mat);
mTransform.set(mat.data());
}
void bhkConvexTransformShape::post(Reader& nif)
{
mShape.post(nif);
}
void bhkBoxShape::read(NIFStream* nif)
{
bhkConvexShape::read(nif);
nif->skip(8); // Unused
nif->read(mExtents);
nif->skip(4); // Unused
}
void bhkCapsuleShape::read(NIFStream* nif)
{
bhkConvexShape::read(nif);
nif->skip(8); // Unused
nif->read(mPoint1);
nif->read(mRadius1);
nif->read(mPoint2);
nif->read(mRadius2);
}
void bhkCylinderShape::read(NIFStream* nif)
{
bhkConvexShape::read(nif);
nif->skip(8); // Unused
nif->read(mVertexA);
nif->read(mVertexB);
nif->read(mCylinderRadius);
nif->skip(12); // Unused
}
void bhkHeightfieldShape::read(NIFStream* nif)
{
mHavokMaterial.read(nif);
}
void bhkPlaneShape::read(NIFStream* nif)
{
bhkHeightfieldShape::read(nif);
nif->skip(12); // Unused
mPlane = osg::Plane(nif->get<osg::Vec4f>());
nif->read(mExtents);
nif->read(mCenter);
}
void bhkMeshShape::read(NIFStream* nif)
{
nif->skip(8); // Unknown
nif->read(mRadius);
nif->skip(8); // Unknown
nif->read(mScale);
mShapeProperties.resize(nif->get<uint32_t>());
for (bhkWorldObjCInfoProperty& property : mShapeProperties)
property.read(nif);
nif->skip(12); // Unknown
readRecordList(nif, mDataList);
}
void bhkMeshShape::post(Reader& nif)
{
postRecordList(nif, mDataList);
}
void bhkMultiSphereShape::read(NIFStream* nif)
{
bhkSphereRepShape::read(nif);
mShapeProperty.read(nif);
nif->readVector(mSpheres, nif->get<uint32_t>());
}
void bhkListShape::read(NIFStream* nif)
{
readRecordList(nif, mSubshapes);
mHavokMaterial.read(nif);
mChildShapeProperty.read(nif);
mChildFilterProperty.read(nif);
uint32_t numFilters;
nif->read(numFilters);
mHavokFilters.resize(numFilters);
for (HavokFilter& filter : mHavokFilters)
filter.read(nif);
}
void bhkCompressedMeshShape::read(NIFStream* nif)
{
mTarget.read(nif);
nif->read(mUserData);
nif->read(mRadius);
nif->skip(4); // Unknown
nif->read(mScale);
nif->skip(4); // Radius
nif->skip(16); // Scale
mData.read(nif);
}
void bhkCompressedMeshShape::post(Reader& nif)
{
mTarget.post(nif);
mData.post(nif);
}
void bhkCompressedMeshShapeData::read(NIFStream* nif)
{
nif->read(mBitsPerIndex);
nif->read(mBitsPerWIndex);
nif->read(mMaskWIndex);
nif->read(mMaskIndex);
nif->read(mError);
nif->read(mAabbMin);
nif->read(mAabbMax);
nif->read(mWeldingType);
nif->read(mMaterialType);
nif->skip(nif->get<uint32_t>() * 4); // Unused
nif->skip(nif->get<uint32_t>() * 4); // Unused
nif->skip(nif->get<uint32_t>() * 4); // Unused
uint32_t numMaterials;
nif->read(numMaterials);
mMaterials.resize(numMaterials);
for (bhkMeshMaterial& material : mMaterials)
material.read(nif);
nif->skip(4); // Unused
uint32_t numTransforms;
nif->read(numTransforms);
mChunkTransforms.resize(numTransforms);
for (bhkQsTransform& transform : mChunkTransforms)
transform.read(nif);
nif->readVector(mBigVerts, nif->get<uint32_t>());
uint32_t numBigTriangles;
nif->read(numBigTriangles);
mBigTris.resize(numBigTriangles);
for (bhkCMSBigTri& tri : mBigTris)
tri.read(nif);
uint32_t numChunks;
nif->read(numChunks);
mChunks.resize(numChunks);
for (bhkCMSChunk& chunk : mChunks)
chunk.read(nif);
nif->skip(4); // Unused
}
void bhkRigidBody::read(NIFStream* nif)
{
bhkEntity::read(nif);
mInfo.read(nif);
readRecordList(nif, mConstraints);
if (nif->getBethVersion() < 76)
nif->read(mBodyFlags);
else
mBodyFlags = nif->get<uint16_t>();
}
void bhkAabbPhantom::read(NIFStream* nif)
{
bhkPhantom::read(nif);
nif->skip(8); // Unused
nif->read(mAabbMin);
nif->read(mAabbMax);
}
void bhkSimpleShapePhantom::read(NIFStream* nif)
{
bhkShapePhantom::read(nif);
nif->skip(8); // Unused
std::array<float, 16> mat;
nif->readArray(mat);
mTransform.set(mat.data());
}
void bhkConstraint::read(NIFStream* nif)
{
mInfo.read(nif);
}
void bhkConstraint::post(Reader& nif)
{
mInfo.post(nif);
}
void bhkRagdollConstraint::read(NIFStream* nif)
{
bhkConstraint::read(nif);
mConstraint.read(nif);
}
void bhkHingeConstraint::read(NIFStream* nif)
{
bhkConstraint::read(nif);
mConstraint.read(nif);
}
void bhkLimitedHingeConstraint::read(NIFStream* nif)
{
bhkConstraint::read(nif);
mConstraint.read(nif);
}
void bhkBallAndSocketConstraint::read(NIFStream* nif)
{
bhkConstraint::read(nif);
mConstraint.read(nif);
}
void bhkBallSocketConstraintChain::read(NIFStream* nif)
{
uint32_t numPivots = nif->get<uint32_t>();
if (numPivots % 2 != 0)
throw Nif::Exception(
"Invalid number of constraints in bhkBallSocketConstraintChain", nif->getFile().getFilename());
mConstraints.resize(numPivots / 2);
for (bhkBallAndSocketConstraintCInfo& info : mConstraints)
info.read(nif);
nif->read(mTau);
nif->read(mDamping);
nif->read(mConstraintForceMixing);
nif->read(mMaxErrorDistance);
mConstraintChainInfo.read(nif);
}
void bhkBallSocketConstraintChain::post(Reader& nif)
{
mConstraintChainInfo.post(nif);
}
void bhkStiffSpringConstraint::read(NIFStream* nif)
{
bhkConstraint::read(nif);
mConstraint.read(nif);
}
void bhkPrismaticConstraint::read(NIFStream* nif)
{
bhkConstraint::read(nif);
mConstraint.read(nif);
}
void bhkMalleableConstraint::read(NIFStream* nif)
{
bhkConstraint::read(nif);
mConstraint.read(nif);
}
void bhkBreakableConstraint::read(NIFStream* nif)
{
bhkConstraint::read(nif);
mConstraint.read(nif);
nif->read(mThreshold);
nif->read(mRemoveWhenBroken);
}
void bhkUnaryAction::read(NIFStream* nif)
{
mEntity.read(nif);
nif->skip(8); // Unused
}
void bhkUnaryAction::post(Reader& nif)
{
mEntity.post(nif);
}
void bhkLiquidAction::read(NIFStream* nif)
{
nif->skip(12); // Unused
nif->read(mInitialStickForce);
nif->read(mStickStrength);
nif->read(mNeighborDistance);
nif->read(mNeighborStrength);
}
void bhkOrientHingedBodyAction::read(NIFStream* nif)
{
bhkUnaryAction::read(nif);
nif->skip(8); // Unused
nif->read(mHingeAxisLS);
nif->read(mForwardLS);
nif->read(mStrength);
nif->read(mDamping);
nif->skip(8); // Unused
}
void bhkRagdollTemplate::read(NIFStream* nif)
{
Extra::read(nif);
readRecordList(nif, mBones);
}
void bhkRagdollTemplate::post(Reader& nif)
{
Extra::post(nif);
postRecordList(nif, mBones);
}
void bhkRagdollTemplateData::read(NIFStream* nif)
{
nif->read(mName);
nif->read(mMass);
nif->read(mRestitution);
nif->read(mFriction);
nif->read(mRadius);
mHavokMaterial.read(nif);
mConstraints.resize(nif->get<uint32_t>());
for (bhkWrappedConstraintData& constraint : mConstraints)
constraint.read(nif);
}
void bhkPoseArray::BoneTransform::read(NIFStream* nif)
{
nif->read(mTranslation);
nif->read(mRotation);
nif->read(mScale);
}
void bhkPoseArray::read(NIFStream* nif)
{
nif->readVector(mBones, nif->get<uint32_t>());
mPoses.resize(nif->get<uint32_t>());
for (std::vector<BoneTransform>& pose : mPoses)
{
pose.resize(nif->get<uint32_t>());
for (BoneTransform& transform : pose)
transform.read(nif);
}
}
} // Namespace