mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 05:26:39 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			989 lines
		
	
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			989 lines
		
	
	
	
		
			26 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
 | 
						|
    }
 | 
						|
 | 
						|
} // Namespace
 |