mirror of
https://github.com/OpenMW/openmw.git
synced 2025-11-10 14:56:40 +00:00
bhkListShape contains a list of subshape references that need to be resolved after initial parsing. Without calling postRecordList(), the mSubshapes list would contain unresolved RecordPtrs. This adds the missing post() override to properly load subshape data, consistent with other NIF record types that contain RecordPtr lists.
1040 lines
28 KiB
C++
1040 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 bhkListShape::post(Reader& nif)
|
|
{
|
|
postRecordList(nif, mSubshapes);
|
|
}
|
|
|
|
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
|