Merge 'remotes/trunk'
[0ad.git] / source / graphics / UnitAnimation.h
blob00e4db78390add80050d3bed8514b9d52424c53c
1 /* Copyright (C) 2023 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
18 #ifndef INCLUDED_UNITANIMATION
19 #define INCLUDED_UNITANIMATION
21 #include "ps/CStr.h"
22 #include "simulation2/system/Entity.h"
24 #include <vector>
26 class CUnit;
27 class CModel;
28 class CSkeletonAnim;
29 class CObjectEntry;
31 /**
32 * Deals with synchronisation issues between raw animation data (CModel, CSkeletonAnim)
33 * and the simulation system (via CUnit), providing a simple fire-and-forget API to play animations.
34 * (This is really just a component of CUnit and could probably be merged back into that class.)
36 class CUnitAnimation
38 NONCOPYABLE(CUnitAnimation);
39 public:
40 /**
41 * Construct for a given unit, defaulting to the "idle" animation.
43 CUnitAnimation(entity_id_t ent, CModel* model, CObjectEntry* object);
45 /**
46 * Start playing an animation.
47 * The unit's actor defines the available animations, and if more than one is available
48 * then one is picked at random (with a new random choice each loop).
49 * By default, animations start immediately and run at the given speed with no syncing.
50 * Use SetAnimationSync after this to force a specific timing, if it needs to match the
51 * simulation timing.
52 * Alternatively, set @p desync to a non-zero value (e.g. 0.05) to slightly randomise the
53 * offset and speed, so units don't all move in lockstep.
54 * @param name animation's name ("idle", "walk", etc)
55 * @param once if true then the animation freezes on its last frame; otherwise it loops
56 * @param speed fraction of actor-defined speed to play back at (should typically be 1.0)
57 * @param desync maximum fraction of length/speed to randomly adjust timings (or 0.0 for no desyncing)
58 * @param actionSound sound group name to be played at the 'action' point in the animation, or empty string
60 void SetAnimationState(const CStr& name, bool once, float speed, float desync, const CStrW& actionSound);
62 /**
63 * Adjust the speed of the current animation, so that Update(repeatTime) will do a
64 * complete animation loop.
65 * @param repeatTime time for complete loop of animation, in msec
67 void SetAnimationSyncRepeat(float repeatTime);
69 /**
70 * Adjust the offset of the current animation, so that Update(actionTime) will advance it
71 * to the 'action' point defined in the actor.
72 * This must be called after SetAnimationSyncRepeat sets the speed.
73 * @param actionTime time between now and when the action should occur, in msec
75 void SetAnimationSyncOffset(float actionTime);
77 /**
78 * Advance the animation state.
79 * @param time advance time in msec
81 void Update(float time);
83 /**
84 * Regenerate internal animation state from the models in the current unit.
85 * This should be called whenever the unit is changed externally, to keep this in sync.
87 void ReloadUnit(CModel* model, const CObjectEntry* object);
89 /**
90 * Reload animation so any changes take immediate effect.
92 void ReloadAnimation();
94 private:
96 /**
97 * Picks a new animation ID from our current state
99 void PickAnimationID();
101 struct SModelAnimState
103 CModel* model;
104 CSkeletonAnim* anim;
105 const CObjectEntry* object;
106 float time;
107 bool pastLoadPos;
108 bool pastActionPos;
109 bool pastSoundPos;
112 std::vector<SModelAnimState> m_AnimStates;
115 * True if all the current AnimStates are static, so Update() doesn't need
116 * to do any work at all
118 bool m_AnimStatesAreStatic;
120 void AddModel(CModel* model, const CObjectEntry* object);
122 entity_id_t m_Entity;
123 CModel* m_Model;
124 const CObjectEntry* m_Object;
125 CStr m_State;
126 CStr m_AnimationID = "";
127 bool m_Looping;
128 float m_OriginalSpeed;
129 float m_Speed;
130 float m_SyncRepeatTime;
131 float m_Desync;
132 CStrW m_ActionSound;
135 #endif // INCLUDED_UNITANIMATION