Files
firestorm/Gameleap/code/mw4/Code/MW4/AnimIterator.hpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

611 lines
17 KiB
C++

//===========================================================================//
// File: AnimIterator.hpp
// Project: MechWarrior 4
// Contents:
// This defines the iterator classes for animation. The iterators
// can walk keyframes forward and backward by an absolute or relitive
// frame, percent, or time. Got it?
//---------------------------------------------------------------------------//
// Date Who Modification //
// -------- --- ---------------------------------------------------------- //
// 07/01/98 JSE Initial coding,
//---------------------------------------------------------------------------//
// Copyright (C) 1998, Fasa Interactive, Inc.
// All Rights reserved worldwide
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL
//===========================================================================//
#pragma once
namespace MW4Animation {
class AnimIterator;
}
#include <MW4\MW4AnimationSystem.hpp>
#include <MW4\AnimInstance.hpp>
namespace MW4Animation {
//#############################################################################
//####################### AnimIterator #########################
//#############################################################################
class AnimIterator :
public Stuff::Plug
{
private:
Stuff::Scalar currentTime;
Stuff::Scalar velocityScale;
AnimData *animationData;
BYTE *nextFrame;
Stuff::Scalar blendValue;
bool skipChannels;
public:
AnimInstance *animationInstance;
enum{
MaxKeyFrame=255
};
public:
// note: you must reset the animation to the start
// or end before animating.
AnimIterator(AnimInstance *animation_instance);
~AnimIterator();
//skips everything but velocity!
void SkipChannels()
{
//skipChannels = true;
}
void DontSkipChannels()
{
//skipChannels = false;
}
bool DoISkipChannels()
{
return skipChannels;
}
void SetVelocityScale(Stuff::Scalar vel_scale)
{
velocityScale = vel_scale;
}
Stuff::Scalar GetVelocityScale()
{
return velocityScale;
}
Stuff::Scalar GetBlendValue()
{
return blendValue;
}
void SetBlendValue(Stuff::Scalar blend_value)
{
Verify(blend_value >= 0);
blendValue = blend_value;
}
AnimData* GetAnimData()
{
return animationData;
}
//----------------------------------------
// Convert to and from absolute channels
//----------------------------------------
int
ToAbsoluteChannel(
BYTE joint_number,
BYTE channel_number
);
void FromAbsoluteChannel(
int absolute_Channel,
BYTE& joint_number,
BYTE& channel_number
);
//------------------------------
// Get counts if you need them
//------------------------------
BYTE GetJointCount();
BYTE GetJointChannelCount(BYTE joint_number);
int GetAnimChannelCount();
int GetKeyFrameCount(int absolute_channel_number);
//------------------------------
// Get frames and indexes.
//------------------------------
// -1 means that there are no more keyframes in that direction
int GetForwardFrameIndex(int absolute_channel_number);
int GetReverseFrameIndex(int absolute_channel_number);
// NULL means that there are no more keyframes in that direction
BaseKeyframe * GetForwardKeyFrame(int absolute_channel_number);
BaseKeyframe * GetReverseKeyFrame(int absolute_channel_number);
// If there is only one keyframe these will return the same keyframe
BaseKeyframe * GetFirstKeyFrame(int absolute_channel_number);
BaseKeyframe * GetLastKeyFrame(int absolute_channel_number);
// A little diffrent from getfirst, this gets the keyframe at the start position
// if a keyframe is out of range ( less than or greater than the time span of the
// animation, than this will find the first real keyframe.
// If there is only one keyframe these will return the same keyframe
BaseKeyframe * GetStartKeyFrame(int absolute_channel_number);
BaseKeyframe * GetStopKeyFrame(int absolute_channel_number);
// NULL means that there is no such keyframe
BaseKeyframe * GetKeyFrame(int absolute_channel_number, int index);
// NULL means that there are no more keyframes in that direction
BaseKeyframeTime * GetForwardKeyFrameTime(int absolute_channel_number);
BaseKeyframeTime * GetReverseKeyFrameTime(int absolute_channel_number);
// If there is only one keyframe these will return the same keyframe
BaseKeyframeTime * GetFirstKeyFrameTime(int absolute_channel_number);
BaseKeyframeTime * GetLastKeyFrameTime(int absolute_channel_number);
// A little diffrent from getfirst, this gets the keyframe at the start position
// if a keyframe is out of range ( less than or greater than the time span of the
// animation, than this will find the first real keyframe.
// If there is only one keyframe these will return the same keyframe
BaseKeyframeTime * GetStartKeyFrameTime(int absolute_channel_number);
BaseKeyframeTime * GetStopKeyFrameTime(int absolute_channel_number);
// NULL means that there is no such keyframe
BaseKeyframeTime * GetKeyFrameTime(int absolute_channel_number, int index);
//-----------------------------------------------------------------------
// Reset start makes the animation snap to start, end goes to the end
// use this instead of settime if you want to go the beginning
// it's cheaper.
//-----------------------------------------------------------------------
void ResetStart();
void ResetEnd();
// all of the frame methods down here treat frame 0 as the frame
// at starttime, not keyframe index 0, like above. a frame down
// here is more of an intangeble thing.
// time down here is also reletive to startTime
//
// percents are 1.0 > 0
// Carryover functions
// these are the "smart" functions, they figure out back or forward.
Stuff::Scalar GetCarryOverTime();
int GetCarryOverFrame(int frames_per_second);
Stuff::Scalar GetCarryOverPosition();
// forward carryovers
Stuff::Scalar GetCarryOverTimeForward();
int GetCarryOverFrameForward(int frames_per_second);
Stuff::Scalar GetCarryOverPositionForward();
// reverse carryovers
Stuff::Scalar GetCarryOverTimeReverse();
int GetCarryOverFrameReverse(int frames_per_second);
Stuff::Scalar GetCarryOverPositionReverse();
Stuff::Scalar GetRealTime()
{
return currentTime;
}
//------------------------------
// Absolute Settings, adjusted though, so time at the start
// of an anim is 0
//------------------------------
void SetTime(Stuff::Scalar time);
Stuff::Scalar GetTime();
void SetFrame(int frame, int frames_per_second);
int GetFrame(int frames_per_second);
void SetPosition(Stuff::Scalar percentage_of_animation);
Stuff::Scalar GetPosition();
//------------------------------
// Relative Settings
//------------------------------
// The Move commands check to see if the number is going forward or backward
// the increment/decrement commands assume the command is in the correct direction
bool MoveTime(Stuff::Scalar time_slice);
bool MoveFrame(int frame_count, int frames_per_second);
bool MovePosition(Stuff::Scalar percent);
// Don't pass zeros to increment/decrement functions or I'll kick your ass!!!
bool IncrementTime(Stuff::Scalar time_slice);
bool DecrementTime(Stuff::Scalar time_slice);
bool IncrementFrame(int frame_count, int frames_per_second);
bool DecrementFrame(int frame_count, int frames_per_second);
bool IncrementPosition(Stuff::Scalar percent);
bool DecrementPosition(Stuff::Scalar percent);
BaseKeyframe * GetKeyFrameAtTime(int absolute_channel_number, Stuff::Scalar time);
BaseKeyframe * GetKeyFrameAtFrame(int absolute_channel_number, int frame, int frames_per_second);
BaseKeyframe * GetKeyFrameAtPosition(int absolute_channel_number, Stuff::Scalar percentage_of_animation);
BaseKeyframeTime * GetKeyFrameTimeAtTime(int absolute_channel_number, Stuff::Scalar time);
BaseKeyframeTime * GetKeyFrameTimeAtFrame(int absolute_channel_number, int frame, int frames_per_second);
BaseKeyframeTime * GetKeyFrameTimeAtPosition(int absolute_channel_number, Stuff::Scalar percentage_of_animation);
public:
void
TestInstance() const
{}
static bool
TestClass()
{return true;}
};
// Inlines
//
//#############################################################################
//#############################################################################
//
inline BYTE
AnimIterator::GetJointCount()
{
Check_Pointer(animationData);
return animationData->GetJointCount();
}
//
//#############################################################################
//#############################################################################
//
inline BYTE
AnimIterator::GetJointChannelCount(BYTE joint_number)
{
Verify(joint_number < animationData->GetJointCount());
return animationData->animJointBlock[joint_number].channelsUsed;
}
//
//#############################################################################
//#############################################################################
//
inline int
AnimIterator::GetAnimChannelCount()
{
Check_Pointer(animationData);
return animationData->GetChannelCount();
}
//
//#############################################################################
//#############################################################################
//
inline int
AnimIterator::GetKeyFrameCount(int absolute_channel_number)
{
Verify(absolute_channel_number < animationData->GetChannelCount());
return animationData->animChannelBlock[absolute_channel_number].keyframeCount;
}
//
//#############################################################################
//#############################################################################
//
inline Stuff::Scalar
AnimIterator::GetTime()
{
return currentTime -= animationData->animHeaderBlock->startTime;
}
//
//#############################################################################
//#############################################################################
//
inline void
AnimIterator::SetFrame(int frame, int frames_per_second)
{
Verify(frames_per_second > 0);
SetTime((Stuff::Scalar)frame / frames_per_second);
}
//
//#############################################################################
//#############################################################################
//
inline int
AnimIterator::GetFrame(int frames_per_second)
{
Verify(frames_per_second > 0);
return (int)(GetTime()*frames_per_second);
}
//
//#############################################################################
//#############################################################################
//
inline void
AnimIterator::SetPosition(Stuff::Scalar percentage_of_animation)
{
if (percentage_of_animation == 0.0f)
{
ResetStart();
return;
}
Verify(percentage_of_animation > 0.0f);
Verify(percentage_of_animation <= 1.0f);
SetTime(
Stuff::Lerp(
0.0f,
animationData->animHeaderBlock->endTime-animationData->animHeaderBlock->startTime,
percentage_of_animation
)
);
}
//
//#############################################################################
//#############################################################################
//
inline Stuff::Scalar
AnimIterator::GetPosition()
{
Verify((animationData->animHeaderBlock->endTime -
animationData->animHeaderBlock->startTime) != 0.0f);
Stuff::Scalar percent =
(currentTime-animationData->animHeaderBlock->startTime) /
(animationData->animHeaderBlock->endTime -
animationData->animHeaderBlock->startTime);
Verify(percent >= 0.0f);
Verify(percent <= 1.0f);
return percent;
}
//
//#############################################################################
//#############################################################################
//
inline bool
AnimIterator::MoveFrame(int frame_count, int frames_per_second)
{
Verify(frame_count != 0);
Verify(frames_per_second > 0);
return MoveTime((Stuff::Scalar)frame_count / frames_per_second);
}
//
//#############################################################################
//#############################################################################
//
inline bool
AnimIterator::MovePosition(Stuff::Scalar percent)
{
Verify((animationData->animHeaderBlock->endTime -
animationData->animHeaderBlock->startTime) != 0.0f);
Stuff::Scalar time =
(animationData->animHeaderBlock->endTime -
animationData->animHeaderBlock->startTime) * percent;
Verify(time > 0.0f);
Verify(time <= 1.0f);
return MoveTime(time);
}
//
//#############################################################################
//#############################################################################
//
inline bool
AnimIterator::IncrementFrame(int frame_count, int frames_per_second)
{
Verify(frame_count != 0);
Verify(frames_per_second > 0);
return IncrementTime((Stuff::Scalar)frame_count / frames_per_second);
}
//
//#############################################################################
//#############################################################################
//
inline bool
AnimIterator::DecrementFrame(int frame_count, int frames_per_second)
{
Verify(frame_count != 0);
Verify(frames_per_second > 0);
return DecrementTime((Stuff::Scalar)frame_count / frames_per_second);
}
//
//#############################################################################
//#############################################################################
//
inline bool
AnimIterator::IncrementPosition(Stuff::Scalar percent)
{
Verify((animationData->animHeaderBlock->endTime -
animationData->animHeaderBlock->startTime) != 0.0f);
Stuff::Scalar time =
(animationData->animHeaderBlock->endTime -
animationData->animHeaderBlock->startTime) * percent;
//Verify(time > 0.0f);
//Verify(time <= 1.0f);
return IncrementTime(time);
}
//
//#############################################################################
//#############################################################################
//
inline bool
AnimIterator::DecrementPosition(Stuff::Scalar percent)
{
Verify((animationData->animHeaderBlock->endTime -
animationData->animHeaderBlock->startTime) != 0.0f);
Stuff::Scalar time =
(animationData->animHeaderBlock->endTime -
animationData->animHeaderBlock->startTime) * percent;
//Verify(time > 0.0f);
//Verify(time <= 1.0f);
return DecrementTime(time);
}
//
//#############################################################################
//#############################################################################
//
inline BaseKeyframe *
AnimIterator::GetKeyFrameAtFrame(int absolute_channel_number, int frame, int frames_per_second)
{
Verify(frames_per_second > 0);
return GetKeyFrameAtTime(absolute_channel_number, (Stuff::Scalar)frame / frames_per_second);
}
//
//#############################################################################
//#############################################################################
//
inline BaseKeyframe *
AnimIterator::GetKeyFrameAtPosition(int absolute_channel_number, Stuff::Scalar percentage_of_animation)
{
Verify((animationData->animHeaderBlock->endTime -
animationData->animHeaderBlock->startTime) != 0.0f);
Stuff::Scalar time =
(animationData->animHeaderBlock->endTime -
animationData->animHeaderBlock->startTime) * percentage_of_animation;
Verify(time > 0.0f);
Verify(time <= 1.0f);
return GetKeyFrameAtTime(absolute_channel_number, time);
}
//
//#############################################################################
//#############################################################################
//
inline BaseKeyframeTime *
AnimIterator::GetKeyFrameTimeAtFrame(int absolute_channel_number, int frame, int frames_per_second)
{
Verify(frames_per_second > 0);
return GetKeyFrameTimeAtTime(absolute_channel_number, (Stuff::Scalar)frame / frames_per_second);
}
//
//#############################################################################
//#############################################################################
//
inline BaseKeyframeTime *
AnimIterator::GetKeyFrameTimeAtPosition(int absolute_channel_number, Stuff::Scalar percentage_of_animation)
{
Verify((animationData->animHeaderBlock->endTime -
animationData->animHeaderBlock->startTime) != 0.0f);
Stuff::Scalar time =
(animationData->animHeaderBlock->endTime -
animationData->animHeaderBlock->startTime) * percentage_of_animation;
Verify(time > 0.0f);
Verify(time <= 1.0f);
return GetKeyFrameTimeAtTime(absolute_channel_number, time);
}
}