xoreos  0.0.5
model.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include <cassert>
26 #include <cstdlib>
27 
28 #include "src/common/fallthrough.h"
30 #include <SDL_timer.h>
32 
33 #include "glm/gtc/type_ptr.hpp"
34 #include "glm/gtc/matrix_transform.hpp"
35 #include "glm/gtx/matrix_interpolation.hpp"
36 
37 #include "src/common/readstream.h"
38 #include "src/common/debug.h"
39 
40 #include "src/graphics/camera.h"
41 
48 
52 
54 
56 
57 namespace Graphics {
58 
59 namespace Aurora {
60 
62  : Renderable((RenderableType) type),
63  _type(type),
64  _superModel(0),
65  _currentState(0),
66  _skinned(false),
67  _positionRelative(false),
68  _drawBound(false),
69  _drawSkeleton(false),
70  _drawSkeletonInvisible(false) {
71 
72  _scale [0] = 1.0f; _scale [1] = 1.0f; _scale [2] = 1.0f;
73  _position[0] = 0.0f; _position[1] = 0.0f; _position[2] = 0.0f;
74 
75  _orientation[0] = 0.0f;
76  _orientation[1] = 0.0f;
77  _orientation[2] = 0.0f;
78  _orientation[3] = 0.0f;
79 
80  _center[0] = 0.0f; _center[1] = 0.0f; _center[2] = 0.0f;
81 
82  // TODO: Is this the same as modelScale for non-UI?
83  _animationScale = 1.0f;
84 
86 
87  _boundRenderable.setSurface(SurfaceMan.getSurface("defaultSurface"));
88  _boundRenderable.setMaterial(MaterialMan.getMaterial("defaultWhite"));
89  _boundRenderable.setMesh(MeshMan.getMesh("defaultWireBox"));
90 }
91 
93  hide();
94 
95  for (AnimationChannelMap::iterator c = _animationChannels.begin();
96  c != _animationChannels.end(); ++c) {
97  delete c->second;
98  }
99 
100  for (AnimationMap::iterator a = _animationMap.begin(); a != _animationMap.end(); ++a)
101  delete a->second;
102 
103  for (StateList::iterator s = _stateList.begin(); s != _stateList.end(); ++s) {
104  for (NodeList::iterator n = (*s)->nodeList.begin(); n != (*s)->nodeList.end(); ++n)
105  delete *n;
106 
107  delete *s;
108  }
109 }
110 
111 void Model::show() {
113  GfxMan.registerAnimatedModel(this);
114 }
115 
116 void Model::hide() {
117  GfxMan.unregisterAnimatedModel(this);
119 }
120 
122  return _type;
123 }
124 
126  return _name;
127 }
128 
129 bool Model::isIn(float x, float y) const {
130  if (_type == kModelTypeGUIFront) {
131  const float minX = _position[0];
132  const float minY = _position[1];
133  const float maxX = minX + (_boundBox.getWidth() * _scale[0]);
134  const float maxY = minY + (_boundBox.getHeight() * _scale[1]);
135 
136  if ((x < minX) || (x > maxX))
137  return false;
138  if ((y < minY) || (y > maxY))
139  return false;
140 
141  return true;
142  }
143 
144 
145  return _absoluteBoundBox.isIn(x, y);
146 }
147 
148 bool Model::isIn(float x, float y, float z) const {
149  if (_type == kModelTypeGUIFront)
150  return isIn(x, y);
151 
152  return _absoluteBoundBox.isIn(x, y, z);
153 }
154 
155 bool Model::isIn(float x1, float y1, float z1, float x2, float y2, float z2) const {
156  if (_type == kModelTypeGUIFront)
157  return false;
158 
159  return _absoluteBoundBox.isIn(x1, y1, z1, x2, y2, z2);
160 }
161 
162 float Model::getWidth() const {
163  return _boundBox.getWidth() * _scale[0];
164 }
165 
166 float Model::getHeight() const {
167  return _boundBox.getHeight() * _scale[1];
168 }
169 
170 float Model::getDepth() const {
171  return _boundBox.getDepth() * _scale[2];
172 }
173 
174 void Model::drawBound(bool enabled) {
175  _drawBound = enabled;
176 }
177 
178 void Model::drawSkeleton(bool enabled, bool showInvisible) {
179  _drawSkeleton = enabled;
180  _drawSkeletonInvisible = showInvisible;
181 }
182 
183 void Model::setEnvironmentMap(const Common::UString &environmentMap) {
185 
186  for (StateList::iterator s = _stateList.begin(); s != _stateList.end(); ++s)
187  for (NodeList::iterator n = (*s)->nodeList.begin(); n != (*s)->nodeList.end(); ++n)
188  (*n)->setEnvironmentMap(environmentMap);
189 
191 }
192 
193 void Model::getScale(float &x, float &y, float &z) const {
194  x = _scale[0];
195  y = _scale[1];
196  z = _scale[2];
197 }
198 
199 void Model::getOrientation(float &x, float &y, float &z, float &angle) const {
200  x = _orientation[0];
201  y = _orientation[1];
202  z = _orientation[2];
203 
204  angle = _orientation[3];
205 }
206 
207 void Model::getPosition(float &x, float &y, float &z) const {
208  x = _position[0];
209  y = _position[1];
210  z = _position[2];
211 }
212 
213 void Model::getAbsolutePosition(float &x, float &y, float &z) const {
214  x = _absolutePosition[3][0];
215  y = _absolutePosition[3][1];
216  z = _absolutePosition[3][2];
217 }
218 
219 void Model::setScale(float x, float y, float z) {
221 
222  _scale[0] = x;
223  _scale[1] = y;
224  _scale[2] = z;
225 
228 
229  resort();
230 
232 }
233 
234 void Model::setOrientation(float x, float y, float z, float angle) {
236 
237  _orientation[0] = x;
238  _orientation[1] = y;
239  _orientation[2] = z;
240  _orientation[3] = angle;
241 
244 
245  resort();
246 
248 }
249 
250 void Model::setPosition(float x, float y, float z) {
252 
253  _position[0] = x;
254  _position[1] = y;
255  _position[2] = z;
256 
259 
260  resort();
261 
263 }
264 
265 void Model::scale(float x, float y, float z) {
266  setScale(_scale[0] * x, _scale[1] * y, _scale[2] * z);
267 }
268 
269 void Model::rotate(float x, float y, float z, float angle) {
270  glm::mat4 orientation;
271 
272  if (_orientation[0] != 0 || _orientation[1] != 0 || _orientation[2] != 0)
273  orientation = glm::rotate(orientation,
275  glm::vec3(_orientation[0], _orientation[1], _orientation[2]));
276 
277  if (x != 0 || y != 0 || z != 0)
278  orientation = glm::rotate(orientation,
279  Common::deg2rad(angle),
280  glm::vec3(x, y, z));
281 
282  glm::vec3 axis;
283  glm::axisAngle(orientation, axis, angle);
284  angle = Common::rad2deg(angle);
285 
286  setOrientation(axis.x, axis.y, axis.z, angle);
287 }
288 
289 void Model::move(float x, float y, float z) {
290  setPosition(_position[0] + x, _position[1] + y, _position[2] + z);
291 }
292 
293 void Model::getTooltipAnchor(float &x, float &y, float &z) const {
294  glm::mat4 pos = _absolutePosition;
295 
296  pos = glm::translate(pos, glm::vec3(0.0f, 0.0f, _absoluteBoundBox.getDepth()));
297 
298  x = pos[3][0];
299  y = pos[3][1];
300  z = pos[3][2];
301 }
302 
304  _absolutePosition = glm::mat4();
305 
306  _absolutePosition = glm::translate(_absolutePosition, glm::vec3(_position[0], _position[1], _position[2]));
307 
308  if (_orientation[0] != 0 || _orientation[1] != 0 || _orientation[2] != 0)
309  _absolutePosition = glm::rotate(_absolutePosition,
311  glm::vec3(_orientation[0], _orientation[1], _orientation[2]));
312 
313  _absolutePosition = glm::scale(_absolutePosition, glm::vec3(_scale[0], _scale[1], _scale[2]));
314 
318 }
319 
320 const std::list<Common::UString> &Model::getStates() const {
321  return _stateNames;
322 }
323 
324 void Model::setState(const Common::UString &name) {
325  if (_stateList.empty())
326  return;
327 
328  State *state = 0;
329 
330  StateMap::iterator s = _stateMap.find(name);
331  if (s == _stateMap.end())
332  s = _stateMap.find("");
333 
334  if (s != _stateMap.end())
335  state = s->second;
336  else
337  state = _stateList.front();
338 
339  assert(state);
340 
341  if (state == _currentState)
342  return;
343 
344  bool visible = isVisible();
345  if (visible) {
346  lockFrame();
347  hide();
348  }
349 
350  _currentState = state;
351 
352  createBound();
353 
354  if (visible) {
355  show();
356  unlockFrame();
357  }
358 }
359 
362  if (!_currentState)
363  return kNoState;
364 
365  return _currentState->name;
366 }
367 
368 bool Model::hasNode(const Common::UString &node) const {
369  if (!_currentState)
370  return false;
371 
372  NodeMap::iterator n = _currentState->nodeMap.find(node);
373  if (n == _currentState->nodeMap.end())
374  return false;
375 
376  return true;
377 }
378 
380  if (!_currentState)
381  return 0;
382 
383  NodeMap::iterator n = _currentState->nodeMap.find(node);
384  if (n == _currentState->nodeMap.end()) {
385  if (_superModel)
386  return _superModel->getNode(node);
387 
388  return 0;
389  }
390 
391  return n->second;
392 }
393 
394 const ModelNode *Model::getNode(const Common::UString &node) const {
395  if (!_currentState)
396  return 0;
397 
398  NodeMap::const_iterator n = _currentState->nodeMap.find(node);
399  if (n == _currentState->nodeMap.end()) {
400  if (_superModel)
401  return _superModel->getNode(node);
402 
403  return 0;
404  }
405 
406  return n->second;
407 }
408 
409 ModelNode *Model::getNode(const Common::UString &stateName, const Common::UString &node) {
410  StateMap::const_iterator s = _stateMap.find(stateName);
411  if (s == _stateMap.end())
412  return 0;
413 
414  State *state = s->second;
415 
416  NodeMap::iterator n = state->nodeMap.find(node);
417  if (n == state->nodeMap.end()) {
418  if (_superModel)
419  return _superModel->getNode(stateName, node);
420 
421  return 0;
422  }
423 
424  return n->second;
425 }
426 
427 const ModelNode *Model::getNode(const Common::UString &stateName, const Common::UString &node) const {
428  StateMap::const_iterator s = _stateMap.find(stateName);
429  if (s == _stateMap.end())
430  return 0;
431 
432  State *state = s->second;
433 
434  NodeMap::const_iterator n = state->nodeMap.find(node);
435  if (n == state->nodeMap.end()) {
436  if (_superModel)
437  return _superModel->getNode(stateName, node);
438 
439  return 0;
440  }
441 
442  return n->second;
443 }
444 
446  if (_currentState) {
447  const std::list<ModelNode *> &nodes = _currentState->nodeList;
448  for (NodeList::const_iterator it = nodes.begin(); it != nodes.end(); ++it) {
449  ModelNode *node = *it;
450  if (node->getNodeNumber() == nodeNumber) {
451  return node;
452  }
453  }
454  }
455  return 0;
456 }
457 
458 const ModelNode *Model::getNode(uint16 nodeNumber) const {
459  if (_currentState) {
460  const std::list<ModelNode *> &nodes = _currentState->nodeList;
461  for (NodeList::const_iterator it = nodes.begin(); it != nodes.end(); ++it) {
462  ModelNode *node = *it;
463  if (node->getNodeNumber() == nodeNumber) {
464  return node;
465  }
466  }
467  }
468  return 0;
469 }
470 
471 static std::list<ModelNode *> kEmptyNodeList;
472 const std::list<ModelNode *> &Model::getNodes() {
473  if (!_currentState)
474  return kEmptyNodeList;
475 
476  return _currentState->nodeList;
477 }
478 
479 void Model::attachModel(const Common::UString &nodeName, Model *model) {
480  ModelNode *node = getNode(nodeName);
481  if (node) {
482  std::map<Common::UString, Model *>::iterator m = _attachedModels.find(nodeName);
483  if (m != _attachedModels.end()) {
484  _attachedModels.erase(m);
485  }
486 
487  node->_attachedModel = model;
488 
489  if (model)
490  _attachedModels.insert(std::pair<Common::UString, Model *>(nodeName, model));
491 
492  createBound();
493  }
494 }
495 
497 
498  AnimationMap::iterator n = _animationMap.find(anim);
499  if (n == _animationMap.end()) {
500  if (_superModel)
501  return _superModel->getAnimation(anim);
502 
503  return 0;
504  }
505 
506  return n->second;
507 }
508 
509 bool Model::hasAnimation(const Common::UString &anim) const {
510  return _animationMap.find(anim) != _animationMap.end();
511 }
512 
514  // TODO: We can cache this for performance
515  AnimationMap::iterator n = _animationMap.find(anim);
516  if (n == _animationMap.end()) {
517  // Animation scaling only applies to inherited animations
518  if (_superModel)
520  // Can't find it, return sensible default
521  return 1.0f;
522  }
523  // We found it, don't scale further
524  return 1.0f;
525 }
526 
528  AnimationChannelMap::iterator c = _animationChannels.find(name);
529  if (c != _animationChannels.end())
530  return;
531 
532  _animationChannels.insert(std::pair<AnimationChannelName,
533  AnimationChannel *>(name,
534  new AnimationChannel(this)));
535 }
536 
538  AnimationChannelMap::iterator c = _animationChannels.find(name);
539  if (c == _animationChannels.end())
540  return 0;
541 
542  return c->second;
543 }
544 
546  AnimationChannel *channel = _animationChannels.begin()->second;
547  channel->clearDefaultAnimations();
548 }
549 
550 void Model::addDefaultAnimation(const Common::UString &anim, uint8 probability) {
551  AnimationChannel *channel = _animationChannels.begin()->second;
552  channel->addDefaultAnimation(anim, probability);
553 }
554 
556  AnimationChannel *channel = _animationChannels.begin()->second;
557  channel->playDefaultAnimation();
558 }
559 
560 void Model::playAnimation(const Common::UString &anim, bool restart, float length, float speed) {
561  AnimationChannel *channel = _animationChannels.begin()->second;
562  channel->playAnimation(anim, restart, length, speed);
563 }
564 
566  if (_type == kModelTypeGUIFront) {
567  _distance = _position[2];
568  return;
569  }
570 
571 
572  glm::mat4 center = _absolutePosition;
573 
574  center = glm::translate(center, glm::vec3(_center[0], _center[1], _center[2]));
575 
576 
577  const float cameraX = -CameraMan.getPosition()[0];
578  const float cameraY = -CameraMan.getPosition()[1];
579  const float cameraZ = -CameraMan.getPosition()[2];
580 
581  const float x = ABS(center[3][0] - cameraX);
582  const float y = ABS(center[3][1] - cameraY);
583  const float z = ABS(center[3][2] - cameraZ);
584 
585 
586  _distance = x + y + z;
587 }
588 
589 void Model::advanceTime(float dt) {
590  manageAnimations(dt);
592 }
593 
595  for (std::map<Common::UString, Model *>::iterator m = _attachedModels.begin();
596  m != _attachedModels.end(); ++m) {
597  m->second->flushNodeBuffers();
598  }
599 
600  if (!_currentState)
601  return;
602 
603  NodeList &nodes = _currentState->nodeList;
604  for (NodeList::iterator n = nodes.begin();
605  n != nodes.end();
606  ++n) {
607  (*n)->flushBuffers();
608  }
609 }
610 
612  std::map<Common::UString, Model *>::iterator m = _attachedModels.find(node);
613  return m == _attachedModels.end() ? 0 : m->second;
614 }
615 
616 void Model::setSkinned(bool skinned) {
617  _skinned = skinned;
618 }
619 
620 void Model::manageAnimations(float dt) {
621  for (AnimationChannelMap::iterator c = _animationChannels.begin();
622  c != _animationChannels.end(); ++c) {
623  c->second->manageAnimations(dt);
624  }
625 
626  for (std::map<Common::UString, Model *>::iterator m = _attachedModels.begin();
627  m != _attachedModels.end(); ++m) {
628  m->second->manageAnimations(dt);
629  }
630 }
631 
633  if (!_currentState || (pass > kRenderPassAll))
634  return;
635 
636  if (pass == kRenderPassAll) {
639  return;
640  }
641 
642  // Apply our global model transformation
643  glTranslatef(_position[0], _position[1], _position[2]);
644  glRotatef(_orientation[3], _orientation[0], _orientation[1], _orientation[2]);
645  glScalef(_scale[0], _scale[1], _scale[2]);
646 
647  // Draw the bounding box, if requested
648  doDrawBound();
649 
650  // Draw the nodes
651  for (NodeList::iterator n = _currentState->rootNodes.begin();
652  n != _currentState->rootNodes.end(); ++n) {
653 
654  glPushMatrix();
655  (*n)->render(pass);
656  glPopMatrix();
657  }
658 
659  // Reset the first texture units
660  TextureMan.reset();
661 
662  // Draw the skeleton, if requested
663  doDrawSkeleton();
664 }
665 
666 void Model::renderImmediate(const glm::mat4 &parentTransform) {
667  if (!_currentState) {
668  return;
669  }
670 
671  glm::mat4 transform = parentTransform * _absolutePosition;
672  queueDrawBound();
673 
674  // Queue the nodes
675  for (NodeList::iterator n = _currentState->rootNodes.begin();
676  n != _currentState->rootNodes.end(); ++n) {
677  (*n)->renderImmediate(transform);
678  }
679 }
680 
681 void Model::queueRender(const glm::mat4 &parentTransform) {
682  if (!_currentState) {
683  return;
684  }
685 
686  glm::mat4 transform = parentTransform * _absolutePosition;
687  queueDrawBound();
688 
689  // Queue the nodes
690  for (NodeList::iterator n = _currentState->rootNodes.begin();
691  n != _currentState->rootNodes.end(); ++n) {
692  (*n)->queueRender(transform);
693  }
694 }
695 
697  if (!_drawBound)
698  return;
699 
700  glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
701  glLineWidth(1.0f);
702 
704 
705  float minX, minY, minZ, maxX, maxY, maxZ;
706  object.getMin(minX, minY, minZ);
707  object.getMax(maxX, maxY, maxZ);
708 
710  _boundTransform *= glm::translate(glm::mat4(), glm::vec3((maxX + minX) * 0.5f, (maxY + minY) * 0.5f, (maxZ + minZ) * 0.5f));
711  _boundTransform *= glm::scale(glm::mat4(), glm::vec3((maxX - minX) * 0.5f, (maxY - minY) * 0.5f, (maxZ - minZ) * 0.5f));
712 
713  RenderMan.queueRenderable(&_boundRenderable, &_boundTransform, 1.0f);
714 }
715 
717  if (!_drawBound)
718  return;
719 
720  glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
721  glLineWidth(1.0f);
722 
724 
725  float minX, minY, minZ, maxX, maxY, maxZ;
726  object.getMin(minX, minY, minZ);
727  object.getMax(maxX, maxY, maxZ);
728 
729  /*
730  glBegin(GL_LINE_LOOP);
731  glVertex3f(minX, minY, minZ);
732  glVertex3f(maxX, minY, minZ);
733  glVertex3f(maxX, maxY, minZ);
734  glVertex3f(minX, maxY, minZ);
735  glEnd();
736 
737  glBegin(GL_LINE_LOOP);
738  glVertex3f(minX, minY, maxZ);
739  glVertex3f(maxX, minY, maxZ);
740  glVertex3f(maxX, maxY, maxZ);
741  glVertex3f(minX, maxY, maxZ);
742  glEnd();
743 
744  glBegin(GL_LINE_LOOP);
745  glVertex3f(minX, minY, minZ);
746  glVertex3f(minX, maxY, minZ);
747  glVertex3f(minX, maxY, maxZ);
748  glVertex3f(minX, minY, maxZ);
749  glEnd();
750 
751  glBegin(GL_LINE_LOOP);
752  glVertex3f(maxX, minY, minZ);
753  glVertex3f(maxX, maxY, minZ);
754  glVertex3f(maxX, maxY, maxZ);
755  glVertex3f(maxX, minY, maxZ);
756  glEnd();
757 
758  glBegin(GL_LINE_LOOP);
759  glVertex3f(minX, minY, minZ);
760  glVertex3f(maxX, minY, minZ);
761  glVertex3f(maxX, minY, maxZ);
762  glVertex3f(minX, minY, maxZ);
763  glEnd();
764 
765  glBegin(GL_LINE_LOOP);
766  glVertex3f(minX, maxY, minZ);
767  glVertex3f(maxX, maxY, minZ);
768  glVertex3f(maxX, maxY, maxZ);
769  glVertex3f(minX, maxY, maxZ);
770  glEnd();
771  */
772 
773  glm::mat4 tform = _absolutePosition;
774  tform = glm::translate(tform, glm::vec3((maxX + minX) * 0.5f, (maxY + minY) * 0.5f, (maxZ + minZ) * 0.5f));
775  tform = glm::scale(tform, glm::vec3((maxX - minX) * 0.5f, (maxY - minY) * 0.5f, (maxZ - minZ) * 0.5f));
777 }
778 
780  if (!_drawSkeleton)
781  return;
782 
783  glm::mat4 tform;
784 
785  if (_type == kModelTypeObject)
786  glDisable(GL_DEPTH_TEST);
787 
788  for (NodeList::iterator n = _currentState->rootNodes.begin(); n != _currentState->rootNodes.end(); ++n)
789  (*n)->drawSkeleton(tform, _drawSkeletonInvisible);
790 
791  if (_type == kModelTypeObject)
792  glEnable(GL_DEPTH_TEST);
793 
794  glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
795  glLineWidth(1.0f);
796  glPointSize(1.0f);
797 }
798 
800  // TODO: remove this and all references to it.
801 }
802 
804  // TODO: remove this and all references to it.
805 }
806 
808  _currentState = 0;
809 
811  setState();
812 
813  createBound();
814 
815  // Order all node children lists
816  for (StateList::iterator s = _stateList.begin(); s != _stateList.end(); ++s)
817  for (NodeList::iterator n = (*s)->rootNodes.begin(); n != (*s)->rootNodes.end(); ++n)
818  (*n)->orderChildren();
819 
820  AnimationChannelMap::iterator c = _animationChannels.begin();
821  c->second->playDefaultAnimation();
822 
824 }
825 
826 void Model::createStateNamesList(std::list<Common::UString> *stateNames) {
827  bool isRoot = false;
828 
829  if (!stateNames) {
830  _stateNames.clear();
831 
832  stateNames = &_stateNames;
833  isRoot = true;
834  }
835 
836  for (StateList::const_iterator s = _stateList.begin(); s != _stateList.end(); ++s)
837  stateNames->push_back((*s)->name);
838 
839  if (_superModel)
840  _superModel->createStateNamesList(stateNames);
841 
842  if (isRoot) {
843  stateNames->sort();
844  stateNames->unique();
845  }
846 }
847 
849  _boundBox.clear();
850 
851  if (!_currentState)
852  return;
853 
854  for (NodeList::iterator n = _currentState->rootNodes.begin();
855  n != _currentState->rootNodes.end(); ++n) {
856 
857  Common::BoundingBox position;
858 
859  (*n)->createAbsoluteBound(position);
860 
861  _boundBox.add((*n)->getAbsoluteBound());
862  }
863 
864  float minX, minY, minZ, maxX, maxY, maxZ;
865  _boundBox.getMin(minX, minY, minZ);
866  _boundBox.getMax(maxX, maxY, maxZ);
867 
868  _center[0] = minX + ((maxX - minX) / 2.0f);
869  _center[1] = minY + ((maxY - minY) / 2.0f);
870  _center[2] = minZ + ((maxZ - minZ) / 2.0f);
871 
872 
876 }
877 
879  value = stream.readUint32LE();
880 }
881 
882 void Model::readValue(Common::SeekableReadStream &stream, float &value) {
883  value = stream.readIEEEFloatLE();
884 }
885 
887  uint32 &offset, uint32 &count) {
888 
889  offset = stream.readUint32LE();
890 
891  uint32 usedCount = stream.readUint32LE();
892  uint32 allocatedCount = stream.readUint32LE();
893 
894  if (usedCount != allocatedCount)
895  warning("Model::readArrayDef(): usedCount != allocatedCount (%d, %d)",
896  usedCount, allocatedCount);
897 
898  count = usedCount;
899 }
900 
901 template<typename T>
903  uint32 offset, uint32 count, std::vector<T> &values) {
904 
905  const size_t pos = stream.seek(offset);
906 
907  values.resize(count);
908  for (uint32 i = 0; i < count; i++)
909  readValue(stream, values[i]);
910 
911  stream.seek(pos);
912 }
913 
914 template
915 void Model::readArray<uint32>(Common::SeekableReadStream &stream,
916  uint32 offset, uint32 count, std::vector<uint32> &values);
917 template
918 void Model::readArray<float>(Common::SeekableReadStream &stream,
919  uint32 offset, uint32 count, std::vector<float> &values);
920 
921 } // End of namespace Aurora
922 
923 } // End of namespace Graphics
static void readValue(Common::SeekableReadStream &stream, uint32 &value)
Definition: model.cpp:878
Shader::ShaderRenderable _boundRenderable
Definition: model.h:274
const Common::UString & getState() const
Return the name of the current state.
Definition: model.cpp:361
A node within an animation.
T ABS(T x)
Definition: util.h:69
virtual void show()
Show the object.
Definition: renderable.cpp:114
NodeMap nodeMap
The nodes within the state, indexed by name.
Definition: model.h:207
void getPosition(float &x, float &y, float &z) const
Get the current position of the model.
Definition: model.cpp:207
float getHeight() const
Get the height of the model&#39;s bounding box.
Definition: model.cpp:166
bool isIn(float x, float y) const
void playAnimation(const Common::UString &anim, bool restart=true, float length=0.0f, float speed=1.0f)
Play a named animation.
Only render transparent parts.
Definition: types.h:99
Model * getAttachedModel(const Common::UString &node)
Definition: model.cpp:611
Common::BoundingBox _absoluteBoundBox
The model&#39;s box after translate/rotate.
Definition: model.h:248
uint32 readUint32LE()
Read an unsigned 32-bit word stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:133
virtual void hide()
Hide the object.
Definition: renderable.cpp:123
An element of the front GUI.
Definition: types.h:53
RenderableType
Definition: types.h:89
#define START_IGNORE_IMPLICIT_FALLTHROUGH
Definition: fallthrough.h:79
void scale(float x, float y, float z)
Scale the model, relative to its current scale.
Definition: model.cpp:265
A class holding an UTF-8 string.
Definition: ustring.h:48
#define TextureMan
Shortcut for accessing the texture manager.
Definition: textureman.h:127
virtual size_t seek(ptrdiff_t offset, Origin whence=kOriginBegin)=0
Sets the stream position indicator for the stream.
An animation to be applied to a model.
void advanceTime(float dt)
Advance time (used by renderables with animations).
Definition: model.cpp:589
double _distance
The distance of the object from the viewer.
Definition: renderable.h:101
Utility functions for debug output.
#define SurfaceMan
Shortcut for accessing the shader manager.
Definition: surfaceman.h:74
float getDepth() const
Get the depth of the bounding box.
float getWidth() const
Get the width of the model&#39;s bounding box.
Definition: model.cpp:162
uint8_t uint8
Definition: types.h:200
std::map< Common::UString, Model * > _attachedModels
Definition: model.h:282
The Aurora texture manager.
Common::UString name
The state&#39;s name.
Definition: model.h:204
A real object in the game world.
Definition: types.h:52
Camera management.
float getAnimationScale(const Common::UString &anim)
Determine what animation scaling applies.
Definition: model.cpp:513
NodeList rootNodes
The nodes in the state without a parent.
Definition: model.h:209
void hide()
Hide the object.
Definition: model.cpp:116
static std::list< ModelNode * > kEmptyNodeList
Definition: model.cpp:471
static const Common::UString kNoState
Definition: model.cpp:360
State * _currentState
The current state.
Definition: model.h:227
void move(float x, float y, float z)
Move the model, relative to its current position.
Definition: model.cpp:289
std::list< Common::UString > _stateNames
All state names.
Definition: model.h:229
void setSurface(Shader::ShaderSurface *surface, bool rebuildProgram=true)
const Common::UString & getName() const
Get the model&#39;s name.
Definition: model.cpp:125
void addDefaultAnimation(const Common::UString &name, uint8 probability)
A bounding box around 3D points.
Definition: boundingbox.h:33
void clearDefaultAnimations()
Definition: model.cpp:545
void addAnimationChannel(AnimationChannelName name)
Definition: model.cpp:527
Common::UString _name
The model&#39;s name.
Definition: model.h:220
float getHeight() const
Get the height of the bounding box.
void setState(const Common::UString &name="")
Set the current animation state.
Definition: model.cpp:324
void createAbsolutePosition()
Definition: model.cpp:303
Common::BoundingBox _boundBox
The model&#39;s bounding box.
Definition: model.h:246
void getMin(float &x, float &y, float &z) const
Definition: boundingbox.cpp:68
void setOrientation(float x, float y, float z, float angle)
Set the current orientation of the model.
Definition: model.cpp:234
void drawBound(bool enabled)
Should a bounding box be drawn around this model?
Definition: model.cpp:174
RenderPass
Definition: types.h:97
Render all parts.
Definition: types.h:100
float _position[3]
Model&#39;s position.
Definition: model.h:239
AnimationMap _animationMap
Map of all animations in this model.
Definition: model.h:231
ModelType
The display type of a model.
Definition: types.h:51
ModelType _type
The model&#39;s type.
Definition: model.h:216
uint16_t uint16
Definition: types.h:202
bool _drawSkeletonInvisible
Definition: model.h:280
void getMax(float &x, float &y, float &z) const
Definition: boundingbox.cpp:87
float getWidth() const
Get the width of the bounding box.
void getScale(float &x, float &y, float &z) const
Get the current scale of the model.
Definition: model.cpp:193
"GGraphics", global, non-engine graphics.
Definition: debugman.h:42
static void readArray(Common::SeekableReadStream &stream, uint32 offset, uint32 count, std::vector< T > &values)
Definition: model.cpp:902
Model(ModelType type=kModelTypeObject)
Definition: model.cpp:61
A node within a 3D model.
A 3D model of an object.
void createStateNamesList(std::list< Common::UString > *stateNames=0)
Create the list of all state names.
Definition: model.cpp:826
void rotate(float x, float y, float z, float angle)
Rotate the model, relative to its current orientation.
Definition: model.cpp:269
void transform(const glm::mat4 &m)
bool hasNode(const Common::UString &node) const
Does the specified node exist in the current state?
Definition: model.cpp:368
bool isIn(float x, float y) const
Is that point within the model&#39;s bounding box?
Definition: model.cpp:129
The global shader material manager.
The global shader surface manager.
const std::list< ModelNode * > & getNodes()
Get all nodes in the current state.
Definition: model.cpp:472
The global mesh manager.
#define MaterialMan
Shortcut for accessing the shader material manager.
Definition: materialman.h:74
void absolutize()
Apply the origin transformations directly to the coordinates.
NodeList nodeList
The nodes within the state.
Definition: model.h:206
void getAbsolutePosition(float &x, float &y, float &z) const
Get the position of the node after translate/rotate.
Definition: model.cpp:213
void warning(const char *s,...)
Definition: util.cpp:33
void setPosition(float x, float y, float z)
Set the current position of the model.
Definition: model.cpp:250
void playDefaultAnimation()
Definition: model.cpp:555
StateMap _stateMap
All states within this model, index by name.
Definition: model.h:226
AnimationChannel * getAnimationChannel(AnimationChannelName name)
Definition: model.cpp:537
Basic reading stream interfaces.
std::list< ModelNode * > NodeList
Definition: model.h:197
float _scale[3]
Model&#39;s scale.
Definition: model.h:237
AnimationChannelName
Definition: model.h:58
#define STOP_IGNORE_IMPLICIT_FALLTHROUGH
Definition: fallthrough.h:80
void render(RenderPass pass)
Render the object.
Definition: model.cpp:632
Render queue manager.
FORCEINLINE float readIEEEFloatLE()
Read a 32-bit IEEE float stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:230
#define MeshMan
Shortcut for accessing the shader manager.
Definition: meshman.h:74
void add(float x, float y, float z)
An object that can be displayed by the graphics manager.
Definition: renderable.h:42
AnimationChannelMap _animationChannels
Definition: model.h:233
float _orientation[4]
Model&#39;s orientation.
Definition: model.h:238
void createBound()
Create the model&#39;s bounding box.
Definition: model.cpp:848
float getDepth() const
Get the depth of the model&#39;s bounding box.
Definition: model.cpp:170
void getTooltipAnchor(float &x, float &y, float &z) const
Get the point where the feedback tooltip is anchored.
Definition: model.cpp:293
void show()
Show the object.
Definition: model.cpp:111
void playAnimation(const Common::UString &anim, bool restart=true, float length=0.0f, float speed=1.0f)
Definition: model.cpp:560
bool isVisible() const
Is the object visible?
Definition: renderable.cpp:106
const std::list< Common::UString > & getStates() const
Return a list of all animation state names.
Definition: model.cpp:320
uint32_t uint32
Definition: types.h:204
static void readArrayDef(Common::SeekableReadStream &stream, uint32 &offset, uint32 &count)
Definition: model.cpp:886
void setEnvironmentMap(const Common::UString &environmentMap="")
Change the environment map on this model.
Definition: model.cpp:183
float _center[3]
Model&#39;s center.
Definition: model.h:241
void getOrientation(float &x, float &y, float &z, float &angle) const
Get the current orientation of the model.
Definition: model.cpp:199
Model * _superModel
The actual super model.
Definition: model.h:223
glm::mat4 _absolutePosition
Definition: model.h:243
void manageAnimations(float dt)
Definition: model.cpp:620
#define CameraMan
Shortcut for accessing the camera manager.
Definition: camera.h:83
Compiler-specific defines to mark an implicit switch-case fallthrough.
static float rad2deg(float rad)
Definition: maths.h:93
bool hasAnimation(const Common::UString &anim) const
Does this model have this named animation?
Definition: model.cpp:509
void finalize()
Finalize the loading procedure.
Definition: model.cpp:807
void addDefaultAnimation(const Common::UString &anim, uint8 probability)
Definition: model.cpp:550
ModelType getType() const
Return the model&#39;s type.
Definition: model.cpp:121
uint16 getNodeNumber() const
Definition: modelnode.cpp:213
#define pass
Definition: fft.cpp:257
Animation * getAnimation(const Common::UString &anim)
Get the animation from its name.
Definition: model.cpp:496
friend class AnimationChannel
Definition: model.h:309
Animation channel.
void flushNodeBuffers()
Apply buffered changes to model nodes position and geometry.
Definition: model.cpp:594
void calculateDistance()
Calculate the object&#39;s distance.
Definition: model.cpp:565
void queueRender(const glm::mat4 &parentTransform)
Queue the object for later rendering.
Definition: model.cpp:681
Model * _attachedModel
The model that is attached to this node.
Definition: modelnode.h:212
ModelNode * getNode(const Common::UString &node)
Get the specified node, from the current state.
Definition: model.cpp:379
StateList _stateList
All states within this model.
Definition: model.h:225
void renderImmediate(const glm::mat4 &tform, float alpha=1.0f)
float _animationScale
The scale of the animation.
Definition: model.h:235
static float deg2rad(float deg)
Definition: maths.h:97
Interface for a seekable & readable data stream.
Definition: readstream.h:265
void setScale(float x, float y, float z)
Set the current scale of the model.
Definition: model.cpp:219
#define GfxMan
Shortcut for accessing the graphics manager.
Definition: graphics.h:299
void drawSkeleton(bool enabled, bool showInvisible)
Should a skeleton showing the nodes and their relation be drawn inside the model? ...
Definition: model.cpp:178
void attachModel(const Common::UString &nodeName, Model *model)
Add another model as a child to the named node.
Definition: model.cpp:479
Only render opaque parts.
Definition: types.h:98
void renderImmediate(const glm::mat4 &parentTransform)
For shader based systems, don&#39;t sort anything, render this right_now.
Definition: model.cpp:666
void setSkinned(bool skinned)
Set the flag if the model has skinned animations.
Definition: model.cpp:616
glm::mat4 _boundTransform
Definition: model.h:275
void setMaterial(Shader::ShaderMaterial *material, bool rebuildProgram=true)
#define RenderMan
Shortcut for accessing the render manager.
Definition: renderman.h:84