//===========================================================================// // 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 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< 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 parentNode; Stuff::ChainOf childrenNodes; // all my anim iterators blend with their iterator blend value Stuff::ChainOf 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 iteratorHierarchy; Stuff::SlotOf 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); }; }