Merge branch '164-crash-on-patching-and-possibly-right-after-login' into main/gingo...
[ryzomcore.git] / ryzom / client / src / animation.cpp
blob5968f6c555c384fcb36b73d8311ff35e47813e63
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program 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 Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "stdpch.h"
22 /////////////
23 // INCLUDE //
24 /////////////
25 // misc
26 #include "nel/misc/debug.h"
27 // Georges
28 #include "nel/georges/u_form_elm.h"
29 #include "nel/georges/u_form.h"
30 #include "nel/georges/u_form_loader.h"
31 // client
32 #include "animation.h"
33 #include "animation_misc.h"
34 #include "debug_client.h"
35 #include "client_cfg.h"
36 #include "entity_animation_manager.h" // \todo GUIGUI : added to recompile animations at loading (to do better ?).
38 #ifdef DEBUG_NEW
39 #define new DEBUG_NEW
40 #endif
42 ///////////
43 // USING //
44 ///////////
46 using namespace NLGEORGES;
47 using namespace NLSOUND;
48 using namespace std;
50 ////////////
51 // METHOD //
52 ////////////
53 // STATIC
54 std::set<std::string> CAnimation::MissingAnim;
56 //-----------------------------------------------
57 // CAnimation :
58 // Constructor.
59 //-----------------------------------------------
60 CAnimation::CAnimation()
62 _SoundAnim = -1;
63 _Animation = UnknownAnim;
64 _Rot = 0.0;
65 _Sheet = NULL;
67 }// CAnimation //
69 //-----------------------------------------------
70 // Destructor
71 //-----------------------------------------------
72 CAnimation::~CAnimation()
74 }// ~CAnimation //
77 //-----------------------------------------------
78 // init
79 //-----------------------------------------------
80 void CAnimation::init(CAnimationSheet *sheet, NL3D::UAnimationSet *animationSet)
82 _Sheet = sheet;
84 _FXSet.init(&sheet->FXSet, animationSet);
87 string animName = _Sheet->AnimNames.get(_Sheet->IdAnim);
88 computeAnimation(animationSet, animName);
89 }// init //
91 //-----------------------------------------------
92 // computeAnimation :
93 //-----------------------------------------------
94 void CAnimation::computeAnimation(NL3D::UAnimationSet *animationSet, const std::string &animName)
96 // Check animationSet.
97 if(animationSet == 0)
99 nlwarning("CAnimation:computeAnimation: Animation Set is NULL.");
100 return;
102 // ...
103 uint id = animationSet->getAnimationIdByName(animName);
104 if(id == NL3D::UAnimationSet::NotFound)
106 _Animation = animationSet->addAnimation(animName.c_str(), animName.c_str(), ClientCfg.DisplayMissingAnimFile);
107 if(_Animation == NL3D::UAnimationSet::NotFound)
109 // Up to 100 missing animation kept.
110 if(MissingAnim.size() < 100)
112 std::pair<std::set<std::string>::iterator, bool> result = MissingAnim.insert(animName);
113 if(result.second)
114 nlwarning("CAnimation::computeAnimation: Animation '%s' NOT FOUND.", animName.c_str());
117 else
119 if(CAnimationMisc::getAnimationLength(animationSet, _Animation) == 0.0)
120 nlwarning("CAnimation::computeAnimation: Animation '%s' LENGTH IS 0.", animName.c_str());
121 // Must store name for reload (or if the sound is not currently enabled)
122 _SoundAnimName= animName;
123 // Sound Process.
124 CSoundAnimManager *sndMngr = CSoundAnimManager::instance();
125 if(sndMngr)
127 std::string animNameNotConst = animName;
128 _SoundAnim = sndMngr->loadAnimation(animNameNotConst);
132 else
134 _Animation = id;
135 // Must store name for reload (or if the sound is not currently enabled)
136 _SoundAnimName= animName;
137 // Sound Process.
138 CSoundAnimManager *sndMngr = CSoundAnimManager::instance();
139 if(sndMngr)
141 std::string animNameNotConst = animName;
142 _SoundAnim = sndMngr->getAnimationFromName(animNameNotConst);
145 // Get the rotation in the animation.
146 _Rot = CAnimationMisc::getAnimationRotation(animationSet, _Animation);
147 }// computeAnimation //
149 //-----------------------------------------------
150 // Return the next animation to play or -1
151 //-----------------------------------------------
152 sint8 CAnimation::getNextAnim(const vector<bool> &animFilterStates) const
154 if(_Sheet)
156 if(_Sheet->Next.empty())
157 return -1;
158 else
160 static vector<sint8> filteredNextAnim;
161 static vector<uint16> filteredNextWeight;
162 filteredNextAnim.clear();
163 filteredNextWeight.clear();
165 // compute the filtered weight sum, and filtered next anim list
166 uint32 weightSum = 0;
167 uint i;
168 for( i=0; i<_Sheet->NextWeight.size(); ++i)
170 sint8 nextAnim= _Sheet->Next[i];
171 if(nextAnim<(sint)animFilterStates.size() && animFilterStates[nextAnim])
173 uint16 nw= _Sheet->NextWeight[i];
174 weightSum += nw;
175 filteredNextAnim.push_back(nextAnim);
176 filteredNextWeight.push_back(nw);
180 // if no filter match, abort
181 if(filteredNextAnim.empty())
182 return -1;
184 // choose a random number between 1 and weightsum
185 uint32 randWeight = rand()%weightSum + 1;
187 // "concatenate" weights of each index, when the random value is reached we'll have the index to use
188 uint32 w = 0;
189 for( i=0; i<filteredNextWeight.size(); ++i)
191 w += filteredNextWeight[i];
192 if( randWeight <= w )
194 return filteredNextAnim[i];
197 nlwarning("<CAnimation::getNextAnim> can't choose next anim, rand=%d weigthSum=%d weightCount=%d",randWeight,weightSum,_Sheet->NextWeight.size());
201 return -1;
202 }// getNextAnim //
205 //-----------------------------------------------
206 // resetSoundAnim
207 //-----------------------------------------------
208 void CAnimation::resetSoundAnim()
210 _SoundAnim=CSoundAnimationNoId;
213 //-----------------------------------------------
214 // reloadAnimation() with stored name
215 //-----------------------------------------------
216 void CAnimation::reloadSoundAnim()
218 CSoundAnimManager *sndMngr = CSoundAnimManager::instance();
219 // don't need to reload if already loaded
220 if(sndMngr && _SoundAnim==CSoundAnimationNoId)
222 // If some sound anim bound
223 if(!_SoundAnimName.empty())
225 std::string animNameNotConst = _SoundAnimName;
226 // if already exist, take
227 _SoundAnim = sndMngr->getAnimationFromName(animNameNotConst);
228 // else create
229 if(_SoundAnim==CSoundAnimationNoId)
230 _SoundAnim = sndMngr->loadAnimation(animNameNotConst);
235 //-----------------------------------------------
236 // getNextAnimList
237 //-----------------------------------------------
238 const std::vector<sint8> &CAnimation::getNextAnimList() const
240 static std::vector<sint8> emptyList;
241 if(_Sheet)
242 return _Sheet->Next;
243 else
244 return emptyList;