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.
611 lines
17 KiB
C++
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);
|
|
}
|
|
|
|
|
|
}
|
|
|