Files
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

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);
};
}