/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /*********************************************************************************************** *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** *********************************************************************************************** * * * Project Name : WW3D * * * * $Archive:: /Commando/Code/ww3d2/animobj.h $* * * * Author:: Greg_h * * * * $Modtime:: 12/10/01 11:18a $* * * * $Revision:: 4 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * Animatable3DObjClass::Base_Update -- animation update function for the base pose * * Animatable3DObjClass::Anim_Update -- Update function for a single animation * * Animatable3DObjClass::Blend_Update -- update function for a blend of two animations * * Animatable3DObjClass::Combo_Update -- Animation update for a combination of anims * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #if defined(_MSC_VER) #pragma once #endif #ifndef ANIMOBJ_H #define ANIMOBJ_H #include "always.h" #include "composite.h" #include "htree.h" class SkinClass; class RenderInfoClass; /** ** Animatable3DObjClass ** This class performs some of the work necessary to implement hierarchical animation. ** It implements much of the bone and animation interface of RenderObjClass. */ class Animatable3DObjClass : public CompositeRenderObjClass { public: Animatable3DObjClass(const char * htree_name); Animatable3DObjClass(const Animatable3DObjClass & src); Animatable3DObjClass & operator = (const Animatable3DObjClass &); virtual ~Animatable3DObjClass(void); ///////////////////////////////////////////////////////////////////////////// // Render Object Interface - Rendering ///////////////////////////////////////////////////////////////////////////// virtual void Render(RenderInfoClass & rinfo); virtual void Special_Render(SpecialRenderInfoClass & rinfo); ///////////////////////////////////////////////////////////////////////////// // Render Object Interface - "Scene Graph" ///////////////////////////////////////////////////////////////////////////// virtual void Set_Transform(const Matrix3D &m); virtual void Set_Position(const Vector3 &v); ///////////////////////////////////////////////////////////////////////////// // Render Object Interface - Hierarchical Animation ///////////////////////////////////////////////////////////////////////////// virtual void Set_Animation(void); virtual void Set_Animation( HAnimClass * motion, float frame, int anim_mode = ANIM_MODE_MANUAL); virtual void Set_Animation( HAnimClass * motion0, float frame0, HAnimClass * motion1, float frame1, float percentage); virtual void Set_Animation( HAnimComboClass * anim_combo); virtual HAnimClass * Peek_Animation( void ); virtual bool Is_Animation_Complete( void ) const; virtual int Get_Num_Bones(void); virtual const char * Get_Bone_Name(int bone_index); virtual int Get_Bone_Index(const char * bonename); virtual const Matrix3D & Get_Bone_Transform(const char * bonename); virtual const Matrix3D & Get_Bone_Transform(int boneindex); virtual void Capture_Bone(int boneindex); virtual void Release_Bone(int boneindex); virtual bool Is_Bone_Captured(int boneindex) const; virtual void Control_Bone(int bindex,const Matrix3D & objtm,bool world_space_translation = false); virtual const HTreeClass * Get_HTree(void) const { return HTree; } // // Simple bone evaluation methods for when the caller doesn't want // to update the heirarchy, but needs to know the transform of // a bone at a given frame. // virtual bool Simple_Evaluate_Bone(int boneindex, Matrix3D *tm) const; virtual bool Simple_Evaluate_Bone(int boneindex, float frame, Matrix3D *tm) const; // (gth) TESTING DYNAMICALLY SWAPPING SKELETONS! virtual void Set_HTree(HTreeClass * htree); protected: // internally used to compute the current frame if the object is in ANIM_MODE_MANUAL float Compute_Current_Frame(void) const; // Update the sub-object transforms according to the current anim state and root transform. virtual void Update_Sub_Object_Transforms(void); // Update the transforms using the base pose only void Base_Update(const Matrix3D & root); // Update the transforms using a single frame of motion data void Anim_Update( const Matrix3D & root, HAnimClass * motion, float frame); // Update the transforms blending two frames of motion data void Blend_Update( const Matrix3D & root, HAnimClass * motion0, float frame0, HAnimClass * motion1, float frame1, float percentage); // Update the transforms with an AnimationCombination void Combo_Update( const Matrix3D & root, HAnimComboClass *anim); // flag to kep track of whether the hierarchy tree transforms are currently valid bool Is_Hierarchy_Valid(void) const { return IsTreeValid; } void Set_Hierarchy_Valid(bool onoff) const { IsTreeValid = onoff; } // Progress anims for single anim (loop and once) void Single_Anim_Progress( void ); // Release any anims void Release( void ); protected: // Is the hierarchy tree currently valid mutable bool IsTreeValid; // Hierarchy Tree HTreeClass * HTree; // Animation state for the next frame. When we add more flexible motion // compositing, add a new state and its associated data to the union below enum { NONE = 0, BASE_POSE, SINGLE_ANIM, DOUBLE_ANIM, MULTIPLE_ANIM, }; int CurMotionMode; union { // CurMotionMode == SINGLE_ANIM struct { HAnimClass * Motion; float Frame; float PrevFrame; int AnimMode; mutable int LastSyncTime; } ModeAnim; // CurMotionMode == DOUBLE_ANIM struct { HAnimClass * Motion0; HAnimClass * Motion1; float Frame0; float Frame1; float PrevFrame0; float PrevFrame1; float Percentage; } ModeInterp; // CurMotionMode == MULTIPLE_ANIM struct { HAnimComboClass * AnimCombo; } ModeCombo; }; friend class SkinClass; }; /*********************************************************************************************** * Animatable3DObjClass::Base_Update -- animation update function for the base pose * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/2/99 GTH : Created. * *=============================================================================================*/ inline void Animatable3DObjClass::Base_Update(const Matrix3D & root) { /* ** This method simply puts the meshes in the base pose's configuration */ if (HTree) { HTree->Base_Update(root); } Set_Hierarchy_Valid(true); } /*********************************************************************************************** * Animatable3DObjClass::Anim_Update -- Update function for a single animation * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/2/99 GTH : Created. * *=============================================================================================*/ inline void Animatable3DObjClass::Anim_Update(const Matrix3D & root,HAnimClass * motion,float frame) { /* ** Apply motion to the base pose */ if ((motion) && (HTree)) { HTree->Anim_Update(root,motion,frame); } Set_Hierarchy_Valid(true); } /*********************************************************************************************** * Animatable3DObjClass::Blend_Update -- update function for a blend of two animations * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/2/99 GTH : Created. * *=============================================================================================*/ inline void Animatable3DObjClass::Blend_Update ( const Matrix3D & root, HAnimClass * motion0, float frame0, HAnimClass * motion1, float frame1, float percentage ) { /* ** Apply motion to the base pose */ if (HTree) { HTree->Blend_Update(root,motion0,frame0,motion1,frame1,percentage); } Set_Hierarchy_Valid(true); } /*********************************************************************************************** * Animatable3DObjClass::Combo_Update -- Animation update for a combination of anims * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 3/2/99 GTH : Created. * *=============================================================================================*/ inline void Animatable3DObjClass::Combo_Update( const Matrix3D & root, HAnimComboClass *anim ) { if (HTree) { HTree->Combo_Update(root, anim); } Set_Hierarchy_Valid(true); } #endif //ANIMOBJ_H