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.
319 lines
8.2 KiB
C++
319 lines
8.2 KiB
C++
//===========================================================================//
|
|
// File: AnimIteratorManager.hpp
|
|
// Project: MechWarrior 4
|
|
// Contents:
|
|
//---------------------------------------------------------------------------//
|
|
// 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
|
|
|
|
|
|
#include <MW4\MW4AnimationSystem.hpp>
|
|
|
|
|
|
namespace MW4Animation {
|
|
|
|
struct ChannelApplication
|
|
{
|
|
bool hasPosition;
|
|
bool hasRotation;
|
|
bool hasVelocity;
|
|
bool hasAngularVelocity;
|
|
bool hasTrigger;
|
|
|
|
ChannelApplication()
|
|
{
|
|
hasPosition = false;
|
|
hasRotation = false;
|
|
hasVelocity = false;
|
|
hasTrigger = false;
|
|
hasAngularVelocity = false;
|
|
|
|
positionValue = Stuff::Point3D::Identity;
|
|
velocityValue = Stuff::Point3D::Identity;
|
|
angularVelocityValue = Stuff::Vector3D::Identity;
|
|
rotationValue = Stuff::UnitQuaternion::Identity;
|
|
triggerValue = 0;
|
|
};
|
|
|
|
// only one of these will be used
|
|
// Union keyword doesn't function
|
|
// for some reason, oh well, there
|
|
// is only one of these ever in the
|
|
// world.
|
|
Stuff::Point3D positionValue;
|
|
Stuff::Point3D velocityValue;
|
|
Stuff::Vector3D angularVelocityValue;
|
|
Stuff::UnitQuaternion rotationValue;
|
|
int triggerValue;
|
|
|
|
};
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
|
|
// this can be optimized to use a static memory set for all the joints
|
|
|
|
#if defined(MW4_ANIMATION_DEBUG)
|
|
static int TabCount = 0;
|
|
static int BlendCount = 0;
|
|
#endif
|
|
|
|
#define MAX_BUFFER_JOINTS 70
|
|
|
|
class BlendBuffer
|
|
{
|
|
|
|
//##########################################################################
|
|
// Memory Allocation Support
|
|
//
|
|
private:
|
|
static Stuff::MemoryBlock *AllocatedMemory;
|
|
|
|
public:
|
|
void*
|
|
operator new(size_t)
|
|
{return AllocatedMemory->New();}
|
|
void
|
|
operator delete(void *where)
|
|
{AllocatedMemory->Delete(where);}
|
|
|
|
//##########################################################################
|
|
// execution Support
|
|
//
|
|
public:
|
|
|
|
enum {
|
|
DefaultFlagBit = 0,
|
|
PositionDirtyFlagBit,
|
|
VelocityDirtyFlagBit,
|
|
AngularVelocityDirtyFlagBit,
|
|
RotationDirtyFlagBit,
|
|
TriggerDirtyFlagBit
|
|
};
|
|
|
|
enum {
|
|
PositionDirtyFlag = 1<<PositionDirtyFlagBit,
|
|
VelocityDirtyFlag = 1<<VelocityDirtyFlagBit,
|
|
AngularVelocityDirtyFlag = 1<<AngularVelocityDirtyFlagBit,
|
|
RotationDirtyFlag = 1<<RotationDirtyFlagBit,
|
|
TriggerDirtyFlag = 1<<TriggerDirtyFlagBit
|
|
};
|
|
|
|
BlendBuffer(int number_of_joints)
|
|
{
|
|
#if defined(MW4_ANIMATION_DEBUG)
|
|
++BlendCount;
|
|
#endif
|
|
|
|
Verify(number_of_joints > 0);
|
|
numberOfJoints = number_of_joints;
|
|
|
|
Verify(number_of_joints < MAX_BUFFER_JOINTS);
|
|
|
|
for (int i = 0; i < numberOfJoints; ++i)
|
|
{
|
|
dirtyFlags[i] = 0;
|
|
}
|
|
}
|
|
|
|
~BlendBuffer()
|
|
{
|
|
|
|
}
|
|
|
|
static void
|
|
InitializeClass();
|
|
|
|
static void
|
|
TerminateClass();
|
|
|
|
|
|
int numberOfJoints;
|
|
|
|
BYTE dirtyFlags[MAX_BUFFER_JOINTS];
|
|
Stuff::Point3D positionBuffer[MAX_BUFFER_JOINTS];
|
|
Stuff::Point3D velocityBuffer[MAX_BUFFER_JOINTS];
|
|
Stuff::UnitQuaternion rotationBuffer[MAX_BUFFER_JOINTS];
|
|
Stuff::Vector3D angularVelocityBuffer[MAX_BUFFER_JOINTS];
|
|
int triggerBuffer[MAX_BUFFER_JOINTS];
|
|
|
|
void SetDirtyPosition(int joint_number)
|
|
{
|
|
Verify(joint_number >= 0);
|
|
Verify(joint_number < numberOfJoints);
|
|
dirtyFlags[joint_number] |= PositionDirtyFlag;
|
|
}
|
|
|
|
void SetDirtyVelocity(int joint_number)
|
|
{
|
|
Verify(joint_number >= 0);
|
|
Verify(joint_number < numberOfJoints);
|
|
dirtyFlags[joint_number] |= VelocityDirtyFlag;
|
|
}
|
|
|
|
void SetDirtyAngularVelocity(int joint_number)
|
|
{
|
|
Verify(joint_number >= 0);
|
|
Verify(joint_number < numberOfJoints);
|
|
dirtyFlags[joint_number] |= AngularVelocityDirtyFlag;
|
|
}
|
|
|
|
void SetDirtyRotation(int joint_number)
|
|
{
|
|
Verify(joint_number >= 0);
|
|
Verify(joint_number < numberOfJoints);
|
|
dirtyFlags[joint_number] |= RotationDirtyFlag;
|
|
}
|
|
|
|
void SetDirtyTrigger(int joint_number)
|
|
{
|
|
Verify(joint_number >= 0);
|
|
Verify(joint_number < numberOfJoints);
|
|
dirtyFlags[joint_number] |= TriggerDirtyFlag;
|
|
}
|
|
|
|
bool IsPositionDirty(int joint_number)
|
|
{
|
|
Verify(joint_number >= 0);
|
|
Verify(joint_number < numberOfJoints);
|
|
return (dirtyFlags[joint_number]&PositionDirtyFlag) != 0;
|
|
}
|
|
bool IsVelocityDirty(int joint_number)
|
|
{
|
|
Verify(joint_number >= 0);
|
|
Verify(joint_number < numberOfJoints);
|
|
return (dirtyFlags[joint_number]&VelocityDirtyFlag) != 0;
|
|
}
|
|
bool IsAngularVelocityDirty(int joint_number)
|
|
{
|
|
Verify(joint_number >= 0);
|
|
Verify(joint_number < numberOfJoints);
|
|
return (dirtyFlags[joint_number]&AngularVelocityDirtyFlag) != 0;
|
|
}
|
|
bool IsRotationDirty(int joint_number)
|
|
{
|
|
Verify(joint_number >= 0);
|
|
Verify(joint_number < numberOfJoints);
|
|
return (dirtyFlags[joint_number]&RotationDirtyFlag) != 0;
|
|
}
|
|
bool IsTriggerDirty(int joint_number)
|
|
{
|
|
Verify(joint_number >= 0);
|
|
Verify(joint_number < numberOfJoints);
|
|
return (dirtyFlags[joint_number]&TriggerDirtyFlag) != 0;
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
|
|
class AnimHierarchyNode:
|
|
public Stuff::Plug
|
|
{
|
|
//##########################################################################
|
|
// Memory Allocation Support
|
|
//
|
|
private:
|
|
static Stuff::MemoryBlock *AllocatedMemory;
|
|
|
|
public:
|
|
void*
|
|
operator new(size_t)
|
|
{return AllocatedMemory->New();}
|
|
void
|
|
operator delete(void *where)
|
|
{AllocatedMemory->Delete(where);}
|
|
|
|
static void
|
|
InitializeClass();
|
|
|
|
static void
|
|
TerminateClass();
|
|
|
|
|
|
public:
|
|
|
|
|
|
AnimHierarchyNode(Stuff::Scalar blend_value);
|
|
~AnimHierarchyNode();
|
|
|
|
void SetBlendValue(Stuff::Scalar blend_value)
|
|
{blendValue = blend_value;}
|
|
|
|
// all the AnimHierarchyNodes on my level blend with
|
|
// this value...
|
|
Stuff::Scalar blendValue;
|
|
|
|
Stuff::SlotOf<AnimHierarchyNode*> parentNode;
|
|
Stuff::ChainOf<AnimHierarchyNode*> childrenNodes;
|
|
|
|
// all my anim iterators blend with their iterator blend value
|
|
Stuff::ChainOf<AnimIterator*> animIterators;
|
|
};
|
|
|
|
//
|
|
//#############################################################################
|
|
//#############################################################################
|
|
//
|
|
|
|
class AnimHierarchyIteratorManager:
|
|
public Stuff::Plug
|
|
{
|
|
public:
|
|
|
|
typedef void
|
|
(*UserDefinedApplyChannelFunction)(
|
|
ChannelApplication &channel_data,
|
|
int joint_index,
|
|
void *user_data
|
|
);
|
|
|
|
AnimHierarchyIteratorManager(UserDefinedApplyChannelFunction apply_function, void *user_data);
|
|
~AnimHierarchyIteratorManager();
|
|
|
|
UserDefinedApplyChannelFunction applyFunction;
|
|
void *userData;
|
|
|
|
|
|
Stuff::SlotOf<AnimHierarchyNode*> iteratorHierarchy;
|
|
Stuff::SlotOf<AnimHierarchyNode*> currentLayer;
|
|
|
|
AnimHierarchyNode *PushLayer(Stuff::Scalar blend_value);
|
|
void PopLayer();
|
|
void UndoPush();
|
|
void AddAnimToCurrentLayer(AnimIterator *interator);
|
|
|
|
|
|
void BlendAndApply(
|
|
int total_joint_count,
|
|
void *override_user_data = NULL,
|
|
UserDefinedApplyChannelFunction override_apply_function = NULL
|
|
);
|
|
|
|
static bool doTransitionBlend;
|
|
|
|
void Blend(AnimHierarchyNode *current_node, BlendBuffer *blend_result);
|
|
void Apply(BlendBuffer *blend_result, void *user_data, UserDefinedApplyChannelFunction apply_function);
|
|
void Combine(BlendBuffer *target_buffer, BlendBuffer *new_buffer, Stuff::Scalar percent);
|
|
void AnimCombine(BlendBuffer *target_buffer, AnimIterator *anim_iterator, Stuff::Scalar percent);
|
|
|
|
};
|
|
}
|
|
|