Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "md3-model.h"
00035
00036 #include "animation-state/animation-state.h"
00037 #include "perf/perf.h"
00038 #include "Md3Player.h"
00039
00040
00041 namespace md3 {
00042
00043
00044
00045 struct anim_entry_t {
00046 Md3PlayerAnimType index1;
00047 Md3PlayerAnimType index2;
00048 };
00049
00050
00051
00052 typedef std::map<std::string, anim_entry_t> animation_map_t;
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 static void
00063 addAnimation
00064 (
00065 IN animation_map_t * map,
00066 IN const char * verb,
00067 IN Md3PlayerAnimType index1,
00068 IN Md3PlayerAnimType index2
00069 )
00070 {
00071 ASSERT(map, "null");
00072 ASSERT(verb, "null");
00073
00074 anim_entry_t ae;
00075 ae.index1 = index1;
00076 ae.index2 = index2;
00077
00078 map->operator[](verb) = ae;
00079 }
00080
00081
00082
00083 static animation_map_t *
00084 getAnimationMap
00085 (
00086 void
00087 )
00088 {
00089 static smart_ptr<animation_map_t> s_map;
00090 if (!s_map) {
00091
00092 smart_ptr<animation_map_t> map = new animation_map_t;
00093 ASSERT(map, "null");
00094
00095
00096 addAnimation(map, "idle", kLegsIdle, kTorsoStand);
00097 addAnimation(map, "walk", kLegsWalk, kTorsoStand2);
00098 addAnimation(map, "run", kLegsRun, kTorsoStand2);
00099
00100
00101 s_map = map;
00102 }
00103
00104 return s_map;
00105 }
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 class PlayerTask : public glut::Task {
00120 public:
00121 PlayerTask(IN const char * dir) {
00122 m_dir = dir;
00123 }
00124 ~PlayerTask(void) throw() { }
00125
00126
00127 smart_ptr<Md3Player> getPlayer(void) { return m_player; }
00128
00129
00130 void doTask(void) {
00131 m_player = new Md3Player(m_dir.c_str());
00132 ASSERT(m_player, "null");
00133
00134 m_player->setAnimation(kTorsoStand);
00135 m_player->setAnimation(kLegsIdle);
00136 }
00137
00138 private:
00139 std::string m_dir;
00140 smart_ptr<Md3Player> m_player;
00141 };
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 class Player : public glut::Renderable {
00153 public:
00154 ~Player(void) throw() { }
00155
00156
00157 void initialize(IN const char * model_path);
00158
00159
00160 void render(IN const glut::render_context_t& rc,
00161 IN glut::RenderQueue * rq);
00162 rect3d_t getBoundingBox(void) const throw() { m_boundingBox.dump("MD3 DEBUG"); return m_boundingBox; }
00163 bool isAnimateable(void) const throw();
00164 void getAnimationState(OUT std::string& state);
00165 bool setAnimationState(IN const char * state);
00166 bool setAnimation(IN const char * verb);
00167
00168 private:
00169
00170
00171
00172 void addState(IO glut::AnimationState& as,
00173 IN eAnimationArea area);
00174 void setState(IN const glut::anim_channel_state_t& acs,
00175 IN eAnimationArea area);
00176
00177
00178 smart_ptr<Md3Player> m_md3Player;
00179 rect3d_t m_boundingBox;
00180 };
00181
00182
00183
00184 void
00185 Player::initialize
00186 (
00187 IN const char * model_path
00188 )
00189 {
00190 ASSERT(model_path, "null");
00191
00192
00193 PlayerTask task(model_path);
00194
00195
00196 glut::requestTask(&task);
00197
00198
00199 m_md3Player = task.getPlayer();
00200 ASSERT(m_md3Player, "failed to load player?");
00201
00202
00203
00204
00205 m_boundingBox.clear();
00206 m_boundingBox.inflate(1.5);
00207 }
00208
00209
00210
00211 void
00212 Player::render
00213 (
00214 IN const glut::render_context_t& rc,
00215 IN glut::RenderQueue * rq
00216 )
00217 {
00218 ASSERT(rq, "null");
00219
00220 glMatrixMode(GL_TEXTURE);
00221 glPushMatrix();
00222
00223
00224 m_md3Player->animate(0.01);
00225
00226 glEnable(GL_TEXTURE_2D);
00227 m_md3Player->draw();
00228 glDisable(GL_TEXTURE_2D);
00229
00230 glMatrixMode(GL_TEXTURE);
00231 glPopMatrix();
00232 }
00233
00234
00235
00236 bool
00237 Player::isAnimateable
00238 (
00239 void
00240 )
00241 const
00242 throw()
00243 {
00244 return true;
00245 }
00246
00247
00248
00249 void
00250 Player::getAnimationState
00251 (
00252 OUT std::string& state
00253 )
00254 {
00255 glut::AnimationState as;
00256
00257 addState(as, eAnimationArea_Upper);
00258 addState(as, eAnimationArea_Lower);
00259 as.serialize(state);
00260
00261
00262 }
00263
00264
00265
00266 bool
00267 Player::setAnimationState
00268 (
00269 IN const char * state
00270 )
00271 {
00272 ASSERT(state, "null");
00273
00274 glut::AnimationState as;
00275 if (!as.deserialize(state)) {
00276 DPRINTF("Unable to deserialize animation state?");
00277 DPRINTF(" state='%s'", state);
00278 return false;
00279 }
00280
00281
00282 if (2 != as.size()) {
00283 DPRINTF("Only support 2-channel animation state");
00284 return false;
00285 }
00286
00287 setState(as[0], eAnimationArea_Upper);
00288 setState(as[1], eAnimationArea_Lower);
00289
00290 return true;
00291 }
00292
00293
00294
00295 bool
00296 Player::setAnimation
00297 (
00298 IN const char * verb
00299 )
00300 {
00301 ASSERT(verb, "null");
00302 ASSERT(m_md3Player, "null");
00303
00304 animation_map_t * map = getAnimationMap();
00305 ASSERT(map, "failed to acquire animation map?");
00306
00307 animation_map_t::const_iterator i = map->find(verb);
00308 if (map->end() == i) {
00309 DPRINTF("No such verb for md3 models: '%s'", verb);
00310 return false;
00311 }
00312
00313
00314 const anim_entry_t& ae = i->second;
00315 m_md3Player->setAnimation(ae.index1);
00316 m_md3Player->setAnimation(ae.index2);
00317
00318 return true;
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 void
00330 Player::addState
00331 (
00332 IO glut::AnimationState& as,
00333 IN eAnimationArea area
00334 )
00335 {
00336 ASSERT(m_md3Player, "null");
00337
00338
00339 Md3AnimState_t mas;
00340 m_md3Player->getAnimationState(area, mas);
00341
00342
00343 glut::anim_channel_state_t acs;
00344 acs.animIndex = (int16_t) mas.animationIndex;
00345 acs.msElapsed = (int32_t) ((mas.time * 1000) + 0.5);
00346
00347
00348 as.push_back(acs);
00349 }
00350
00351
00352
00353 void
00354 Player::setState
00355 (
00356 IN const glut::anim_channel_state_t& acs,
00357 IN eAnimationArea area
00358 )
00359 {
00360 ASSERT(m_md3Player, "null");
00361
00362 Md3AnimState_t mas;
00363
00364 mas.animationIndex = acs.animIndex;
00365 mas.time = 0.001 * acs.msElapsed;
00366
00367 m_md3Player->setAnimationState(area, mas);
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378 smart_ptr<glut::Renderable>
00379 loadMd3Player
00380 (
00381 IN const char * model_path
00382 )
00383 {
00384 perf::Timer timer("loadMd3Model");
00385 ASSERT(model_path, "null");
00386
00387 smart_ptr<Player> local = new Player;
00388 ASSERT(local, "null");
00389
00390 local->initialize(model_path);
00391
00392 return local;
00393 }
00394
00395
00396
00397 };
00398