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/controller.cpp

641 lines
18 KiB
C++

#include "controller.hpp"
#include "controlled.hpp"
#include "data.hpp"
#include "node.hpp"
#include "recordptr.hpp"
namespace Nif
{
void Controller::read(NIFStream* nif)
{
next.read(nif);
flags = nif->getUShort();
frequency = nif->getFloat();
phase = nif->getFloat();
timeStart = nif->getFloat();
timeStop = nif->getFloat();
target.read(nif);
}
void Controller::post(Reader& nif)
{
Record::post(nif);
next.post(nif);
target.post(nif);
}
void ControlledBlock::read(NIFStream* nif)
{
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 103))
mTargetName = nif->getSizedString();
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 106))
mInterpolator.read(nif);
if (nif->getVersion() <= NIFStream::generateVersion(20, 5, 0, 0))
mController.read(nif);
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 103))
return;
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 110))
{
mBlendInterpolator.read(nif);
mBlendIndex = nif->getUShort();
}
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 106) && nif->getBethVersion() > 0)
mPriority = nif->getChar();
if (nif->getVersion() >= NIFStream::generateVersion(10, 2, 0, 0)
&& nif->getVersion() <= NIFStream::generateVersion(20, 1, 0, 0))
{
mStringPalette.read(nif);
mNodeNameOffset = nif->getUInt();
mPropertyTypeOffset = nif->getUInt();
mControllerTypeOffset = nif->getUInt();
mControllerIdOffset = nif->getUInt();
mInterpolatorIdOffset = nif->getUInt();
}
else
{
mNodeName = nif->getString();
mPropertyType = nif->getString();
mControllerType = nif->getString();
mControllerId = nif->getString();
mInterpolatorId = nif->getString();
}
}
void ControlledBlock::post(Reader& nif)
{
mInterpolator.post(nif);
mController.post(nif);
mBlendInterpolator.post(nif);
mStringPalette.post(nif);
// TODO: probably should fill the strings with string palette contents here
}
void NiSequence::read(NIFStream* nif)
{
mName = nif->getString();
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 103))
{
mAccumRootName = nif->getString();
mTextKeys.read(nif);
}
size_t numControlledBlocks = nif->getUInt();
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 106))
mArrayGrowBy = nif->getUInt();
mControlledBlocks.resize(numControlledBlocks);
for (ControlledBlock& block : mControlledBlocks)
block.read(nif);
}
void NiSequence::post(Reader& nif)
{
mTextKeys.post(nif);
for (ControlledBlock& block : mControlledBlocks)
block.post(nif);
}
void NiControllerSequence::read(NIFStream* nif)
{
NiSequence::read(nif);
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 103))
return;
mWeight = nif->getFloat();
mTextKeys.read(nif);
mExtrapolationMode = static_cast<Controller::ExtrapolationMode>(nif->getUInt());
mFrequency = nif->getFloat();
if (nif->getVersion() <= NIFStream::generateVersion(10, 4, 0, 1))
mPhase = nif->getFloat();
mStartTime = nif->getFloat();
mStopTime = nif->getFloat();
mPlayBackwards = nif->getVersion() == NIFStream::generateVersion(10, 1, 0, 106) && nif->getBoolean();
mManager.read(nif);
mAccumRootName = nif->getString();
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 113)
&& nif->getVersion() <= NIFStream::generateVersion(20, 1, 0, 0))
mStringPalette.read(nif);
else if (nif->getVersion() >= NIFFile::NIFVersion::VER_BGS && nif->getBethVersion() >= 24)
{
size_t numAnimNotes = 1;
if (nif->getBethVersion() >= 29)
numAnimNotes = nif->getUShort();
nif->skip(4 * numAnimNotes); // BSAnimNotes links
}
}
void NiControllerSequence::post(Reader& nif)
{
NiSequence::post(nif);
mManager.post(nif);
mStringPalette.post(nif);
}
void NiInterpController::read(NIFStream* nif)
{
Controller::read(nif);
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 104)
&& nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 108))
mManagerControlled = nif->getBoolean();
}
void NiSingleInterpController::read(NIFStream* nif)
{
NiInterpController::read(nif);
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 104))
mInterpolator.read(nif);
}
void NiSingleInterpController::post(Reader& nif)
{
NiInterpController::post(nif);
mInterpolator.post(nif);
}
void NiParticleSystemController::read(NIFStream* nif)
{
Controller::read(nif);
velocity = nif->getFloat();
velocityRandom = nif->getFloat();
verticalDir = nif->getFloat();
verticalAngle = nif->getFloat();
horizontalDir = nif->getFloat();
horizontalAngle = nif->getFloat();
/*normal?*/ nif->getVector3();
color = nif->getVector4();
size = nif->getFloat();
startTime = nif->getFloat();
stopTime = nif->getFloat();
nif->getChar();
emitRate = nif->getFloat();
lifetime = nif->getFloat();
lifetimeRandom = nif->getFloat();
emitFlags = nif->getUShort();
offsetRandom = nif->getVector3();
emitter.read(nif);
/* Unknown Short, 0?
* Unknown Float, 1.0?
* Unknown Int, 1?
* Unknown Int, 0?
* Unknown Short, 0?
*/
nif->skip(16);
numParticles = nif->getUShort();
activeCount = nif->getUShort();
particles.resize(numParticles);
for (size_t i = 0; i < particles.size(); i++)
{
particles[i].velocity = nif->getVector3();
nif->getVector3(); /* unknown */
particles[i].lifetime = nif->getFloat();
particles[i].lifespan = nif->getFloat();
particles[i].timestamp = nif->getFloat();
nif->getUShort(); /* unknown */
particles[i].vertex = nif->getUShort();
}
nif->getUInt(); /* -1? */
affectors.read(nif);
colliders.read(nif);
nif->getChar();
}
void NiParticleSystemController::post(Reader& nif)
{
Controller::post(nif);
emitter.post(nif);
affectors.post(nif);
colliders.post(nif);
}
void NiMaterialColorController::read(NIFStream* nif)
{
NiPoint3InterpController::read(nif);
// Two bits that correspond to the controlled material color.
// 00: Ambient
// 01: Diffuse
// 10: Specular
// 11: Emissive
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
mTargetColor = nif->getUShort() & 3;
else
mTargetColor = (flags >> 4) & 3;
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 103))
mData.read(nif);
}
void NiMaterialColorController::post(Reader& nif)
{
NiPoint3InterpController::post(nif);
mData.post(nif);
}
void NiLookAtController::read(NIFStream* nif)
{
Controller::read(nif);
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 0))
lookAtFlags = nif->getUShort();
target.read(nif);
}
void NiLookAtController::post(Reader& nif)
{
Controller::post(nif);
target.post(nif);
}
void NiPathController::read(NIFStream* nif)
{
Controller::read(nif);
bankDir = nif->getInt();
maxBankAngle = nif->getFloat();
smoothing = nif->getFloat();
followAxis = nif->getShort();
posData.read(nif);
floatData.read(nif);
}
void NiPathController::post(Reader& nif)
{
Controller::post(nif);
posData.post(nif);
floatData.post(nif);
}
void NiUVController::read(NIFStream* nif)
{
Controller::read(nif);
uvSet = nif->getUShort();
data.read(nif);
}
void NiUVController::post(Reader& nif)
{
Controller::post(nif);
data.post(nif);
}
void NiKeyframeController::read(NIFStream* nif)
{
NiSingleInterpController::read(nif);
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 103))
mData.read(nif);
}
void NiKeyframeController::post(Reader& nif)
{
NiSingleInterpController::post(nif);
mData.post(nif);
}
void NiMultiTargetTransformController::read(NIFStream* nif)
{
NiInterpController::read(nif);
size_t numTargets = nif->getUShort();
std::vector<NodePtr> targets;
targets.resize(numTargets);
for (size_t i = 0; i < targets.size(); i++)
targets[i].read(nif);
mExtraTargets = targets;
}
void NiMultiTargetTransformController::post(Reader& nif)
{
NiInterpController::post(nif);
postRecordList(nif, mExtraTargets);
}
void NiAlphaController::read(NIFStream* nif)
{
NiFloatInterpController::read(nif);
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 103))
mData.read(nif);
}
void NiAlphaController::post(Reader& nif)
{
NiFloatInterpController::post(nif);
mData.post(nif);
}
void NiRollController::read(NIFStream* nif)
{
NiSingleInterpController::read(nif);
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 103))
mData.read(nif);
}
void NiRollController::post(Reader& nif)
{
NiSingleInterpController::post(nif);
mData.post(nif);
}
void NiGeomMorpherController::read(NIFStream* nif)
{
NiInterpController::read(nif);
if (nif->getVersion() >= NIFFile::NIFVersion::VER_OB_OLD)
mUpdateNormals = nif->getUShort() & 1;
mData.read(nif);
if (nif->getVersion() >= NIFFile::NIFVersion::VER_MW)
{
mAlwaysActive = nif->getChar();
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 106))
{
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB)
{
readRecordList(nif, mInterpolators);
if (nif->getVersion() >= NIFStream::generateVersion(10, 2, 0, 0) && nif->getBethVersion() > 9)
{
unsigned int numUnknown = nif->getUInt();
nif->skip(4 * numUnknown);
}
}
else
{
std::vector<NiInterpolatorPtr> interpolators;
size_t numInterps = nif->getUInt();
interpolators.resize(numInterps);
mWeights.resize(numInterps);
for (size_t i = 0; i < numInterps; i++)
{
interpolators[i].read(nif);
mWeights[i] = nif->getFloat();
}
mInterpolators = interpolators;
}
}
}
}
void NiGeomMorpherController::post(Reader& nif)
{
NiInterpController::post(nif);
mData.post(nif);
postRecordList(nif, mInterpolators);
}
void NiVisController::read(NIFStream* nif)
{
NiBoolInterpController::read(nif);
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 103))
mData.read(nif);
}
void NiVisController::post(Reader& nif)
{
NiBoolInterpController::post(nif);
mData.post(nif);
}
void NiFlipController::read(NIFStream* nif)
{
NiFloatInterpController::read(nif);
mTexSlot = nif->getUInt();
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 103))
{
timeStart = nif->getFloat();
mDelta = nif->getFloat();
}
readRecordList(nif, mSources);
}
void NiFlipController::post(Reader& nif)
{
NiFloatInterpController::post(nif);
postRecordList(nif, mSources);
}
void bhkBlendController::read(NIFStream* nif)
{
Controller::read(nif);
nif->getUInt(); // Zero
}
void NiControllerManager::read(NIFStream* nif)
{
Controller::read(nif);
mCumulative = nif->getBoolean();
readRecordList(nif, mSequences);
mObjectPalette.read(nif);
}
void NiControllerManager::post(Reader& nif)
{
Controller::post(nif);
postRecordList(nif, mSequences);
mObjectPalette.post(nif);
}
void NiPoint3Interpolator::read(NIFStream* nif)
{
defaultVal = nif->getVector3();
data.read(nif);
}
void NiPoint3Interpolator::post(Reader& nif)
{
data.post(nif);
}
void NiBoolInterpolator::read(NIFStream* nif)
{
defaultVal = nif->getBoolean();
data.read(nif);
}
void NiBoolInterpolator::post(Reader& nif)
{
data.post(nif);
}
void NiFloatInterpolator::read(NIFStream* nif)
{
defaultVal = nif->getFloat();
data.read(nif);
}
void NiFloatInterpolator::post(Reader& nif)
{
data.post(nif);
}
void NiTransformInterpolator::read(NIFStream* nif)
{
defaultPos = nif->getVector3();
defaultRot = nif->getQuaternion();
defaultScale = nif->getFloat();
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 109))
{
if (!nif->getBoolean())
defaultPos = osg::Vec3f();
if (!nif->getBoolean())
defaultRot = osg::Quat();
if (!nif->getBoolean())
defaultScale = 1.f;
}
data.read(nif);
}
void NiTransformInterpolator::post(Reader& nif)
{
data.post(nif);
}
void NiColorInterpolator::read(NIFStream* nif)
{
defaultVal = nif->getVector4();
data.read(nif);
}
void NiColorInterpolator::post(Reader& nif)
{
data.post(nif);
}
void NiBlendInterpolator::read(NIFStream* nif)
{
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 112))
mManagerControlled = nif->getChar() & 1;
size_t numInterps = 0;
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 109))
{
numInterps = nif->getUShort();
mArrayGrowBy = nif->getUShort();
}
else
{
numInterps = nif->getChar();
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 112))
{
mWeightThreshold = nif->getFloat();
if (!mManagerControlled)
{
mInterpCount = nif->getChar();
mSingleIndex = nif->getChar();
mHighPriority = nif->getChar();
mNextHighPriority = nif->getChar();
mSingleTime = nif->getFloat();
mHighWeightsSum = nif->getFloat();
mNextHighWeightsSum = nif->getFloat();
mHighEaseSpinner = nif->getFloat();
}
}
}
if (!mManagerControlled)
{
mItems.resize(numInterps);
for (Item& item : mItems)
item.read(nif);
}
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 111))
{
mManagerControlled = nif->getBoolean();
mWeightThreshold = nif->getFloat();
mOnlyUseHighestWeight = nif->getBoolean();
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 109))
{
mInterpCount = nif->getUShort();
mSingleIndex = nif->getUShort();
}
else
{
mInterpCount = nif->getChar();
mSingleIndex = nif->getChar();
}
if (nif->getVersion() >= NIFStream::generateVersion(10, 1, 0, 108))
{
mSingleInterpolator.read(nif);
mSingleTime = nif->getFloat();
}
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 109))
{
mHighPriority = nif->getInt();
mNextHighPriority = nif->getInt();
}
else
{
mHighPriority = nif->getChar();
mNextHighPriority = nif->getChar();
}
}
}
void NiBlendInterpolator::post(Reader& nif)
{
for (Item& item : mItems)
item.post(nif);
mSingleInterpolator.post(nif);
}
void NiBlendInterpolator::Item::read(NIFStream* nif)
{
mInterpolator.read(nif);
mWeight = nif->getFloat();
mNormalizedWeight = nif->getFloat();
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 109))
mPriority = nif->getInt();
else
mPriority = nif->getChar();
mEaseSpinner = nif->getFloat();
}
void NiBlendInterpolator::Item::post(Reader& nif)
{
mInterpolator.post(nif);
}
void NiBlendBoolInterpolator::read(NIFStream* nif)
{
NiBlendInterpolator::read(nif);
mValue = nif->getChar() != 0;
}
void NiBlendFloatInterpolator::read(NIFStream* nif)
{
NiBlendInterpolator::read(nif);
mValue = nif->getFloat();
}
void NiBlendPoint3Interpolator::read(NIFStream* nif)
{
NiBlendInterpolator::read(nif);
mValue = nif->getVector3();
}
void NiBlendTransformInterpolator::read(NIFStream* nif)
{
NiBlendInterpolator::read(nif);
if (nif->getVersion() <= NIFStream::generateVersion(10, 1, 0, 109))
{
mPosValue = nif->getVector3();
mRotValue = nif->getQuaternion();
mScaleValue = nif->getFloat();
if (!nif->getBoolean())
mPosValue = osg::Vec3f();
if (!nif->getBoolean())
mRotValue = osg::Quat();
if (!nif->getBoolean())
mScaleValue = 1.f;
}
}
}