1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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.
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/>.
26 #include "nel/misc/debug.h"
28 #include "nel/georges/u_form_elm.h"
29 #include "nel/georges/u_form.h"
30 #include "nel/georges/u_form_loader.h"
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 ?).
46 using namespace NLGEORGES
;
47 using namespace NLSOUND
;
54 std::set
<std::string
> CAnimation::MissingAnim
;
56 //-----------------------------------------------
59 //-----------------------------------------------
60 CAnimation::CAnimation()
63 _Animation
= UnknownAnim
;
69 //-----------------------------------------------
71 //-----------------------------------------------
72 CAnimation::~CAnimation()
77 //-----------------------------------------------
79 //-----------------------------------------------
80 void CAnimation::init(CAnimationSheet
*sheet
, NL3D::UAnimationSet
*animationSet
)
84 _FXSet
.init(&sheet
->FXSet
, animationSet
);
87 string animName
= _Sheet
->AnimNames
.get(_Sheet
->IdAnim
);
88 computeAnimation(animationSet
, animName
);
91 //-----------------------------------------------
93 //-----------------------------------------------
94 void CAnimation::computeAnimation(NL3D::UAnimationSet
*animationSet
, const std::string
&animName
)
96 // Check animationSet.
99 nlwarning("CAnimation:computeAnimation: Animation Set is NULL.");
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
);
114 nlwarning("CAnimation::computeAnimation: Animation '%s' NOT FOUND.", animName
.c_str());
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
;
124 CSoundAnimManager
*sndMngr
= CSoundAnimManager::instance();
127 std::string animNameNotConst
= animName
;
128 _SoundAnim
= sndMngr
->loadAnimation(animNameNotConst
);
135 // Must store name for reload (or if the sound is not currently enabled)
136 _SoundAnimName
= animName
;
138 CSoundAnimManager
*sndMngr
= CSoundAnimManager::instance();
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
156 if(_Sheet
->Next
.empty())
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;
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
];
175 filteredNextAnim
.push_back(nextAnim
);
176 filteredNextWeight
.push_back(nw
);
180 // if no filter match, abort
181 if(filteredNextAnim
.empty())
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
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());
205 //-----------------------------------------------
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
);
229 if(_SoundAnim
==CSoundAnimationNoId
)
230 _SoundAnim
= sndMngr
->loadAnimation(animNameNotConst
);
235 //-----------------------------------------------
237 //-----------------------------------------------
238 const std::vector
<sint8
> &CAnimation::getNextAnimList() const
240 static std::vector
<sint8
> emptyList
;