Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

Entity.cpp 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /*!
  2. * \file src/Entity.cpp
  3. * \brief World Entities
  4. *
  5. * \author xythobuz
  6. */
  7. #include <cmath>
  8. #include "global.h"
  9. #include "Log.h"
  10. #include "Render.h"
  11. #include "World.h"
  12. #include "Entity.h"
  13. #include "games/TombRaider1.h"
  14. Entity::Entity(TombRaider &tr, unsigned int index, unsigned int i, unsigned int model) {
  15. tr2_moveable_t *moveable = tr.Moveable();
  16. tr2_item_t *item = tr.Item();
  17. pos[0] = item[i].x;
  18. pos[1] = item[i].y;
  19. pos[2] = item[i].z;
  20. angles[0] = 0;
  21. angles[1] = OR_DEG_TO_RAD(((item[i].angle >> 14) & 0x03) * 90.0f);
  22. angles[2] = 0;
  23. objectId = moveable[index].object_id;
  24. moveType = MoveTypeWalk;
  25. room = getWorld().getRoomByLocation(pos[0], pos[1], pos[2]);
  26. skeletalModel = model;
  27. boneFrame = 0;
  28. animationFrame = 0;
  29. idleAnimation = 0;
  30. state = 0;
  31. }
  32. bool Entity::operator<(Entity &o) {
  33. float distA = getRender().mViewVolume.getDistToSphereFromNear(pos[0], pos[1], pos[2], 1.0f);
  34. float distB = getRender().mViewVolume.getDistToSphereFromNear(o.pos[0], o.pos[1], o.pos[2], 1.0f);
  35. return (distA < distB);
  36. }
  37. bool Entity::compare(Entity *a, Entity *b) {
  38. return (*b) < (*a);
  39. }
  40. void Entity::display() {
  41. glPushMatrix();
  42. glTranslatef(pos[0], pos[1], pos[2]);
  43. glRotatef(OR_RAD_TO_DEG(angles[1]), 0, 1, 0);
  44. glRotatef(OR_RAD_TO_DEG(angles[0]), 1, 0, 0);
  45. //glRotatef(OR_RAD_TO_DEG(angles[2]), 0, 0, 1);
  46. getWorld().getSkeletalModel(skeletalModel).display(animationFrame, boneFrame);
  47. glPopMatrix();
  48. // Cycle frames
  49. if (getRender().getFlags() & Render::fAnimateAllModels) {
  50. if (boneFrame < (getModel().get(animationFrame).size() - 1))
  51. boneFrame++;
  52. else
  53. boneFrame = 0;
  54. }
  55. }
  56. void Entity::move(char movement) {
  57. const float moved = 180.0f;
  58. const float testd = 220.0f;
  59. const float camHeight = 8.0f;
  60. float x, y, z, pitch, h, floor, ceiling;
  61. long roomNew, sector;
  62. bool wall;
  63. unsigned int roomFlags;
  64. switch (moveType) {
  65. case MoveTypeWalkNoSwim:
  66. case MoveTypeWalk:
  67. pitch = 0.0f; // in the future pitch could control jump up blocks here
  68. break;
  69. case MoveTypeNoClipping:
  70. case MoveTypeFly:
  71. case MoveTypeSwim:
  72. pitch = angles[2];
  73. break;
  74. }
  75. switch (movement) {
  76. case 'f':
  77. x = pos[0] + (testd * sinf(angles[1]));
  78. y = pos[1] + (testd * sinf(pitch));
  79. z = pos[2] + (testd * cosf(angles[1]));
  80. break;
  81. case 'b':
  82. x = pos[0] - (testd * sinf(angles[1]));
  83. y = pos[1] - (testd * sinf(pitch));
  84. z = pos[2] - (testd * cosf(angles[1]));
  85. break;
  86. case 'l':
  87. x = pos[0] - (testd * sinf(angles[1] + 90.0f));
  88. y = pos[1];
  89. z = pos[2] - (testd * cosf(angles[1] + 90.0f));
  90. break;
  91. case 'r':
  92. x = pos[0] + (testd * sinf(angles[1] + 90.0f));
  93. y = pos[1];
  94. z = pos[2] + (testd * cosf(angles[1] + 90.0f));
  95. break;
  96. default:
  97. return;
  98. }
  99. roomNew = getWorld().getRoomByLocation(room, x, y, z);
  100. if (roomNew == -1) { // Will we hit a portal?
  101. roomNew = getWorld().getRoom(room).getAdjoiningRoom(pos[0], pos[1], pos[2],
  102. x, y, z);
  103. if (roomNew > -1)
  104. getLog() << "Crossing from room " << room << " to " << roomNew << Log::endl;
  105. else
  106. //! \fixme mRooms, sectors, ... are now std::vector, but often upper bound checks are missing
  107. return;
  108. }
  109. roomFlags = getWorld().getRoom(roomNew).getFlags();
  110. sector = getWorld().getRoom(roomNew).getSector(x, z, &floor, &ceiling);
  111. wall = getWorld().getRoom(roomNew).isWall(sector);
  112. // If you're underwater you may want to swim =)
  113. // ...if you're worldMoveType_walkNoSwim, you better hope it's shallow
  114. if ((roomFlags & RoomFlagUnderWater) && (moveType == MoveTypeWalk))
  115. moveType = MoveTypeSwim;
  116. // Don't swim on land
  117. if (!(roomFlags & RoomFlagUnderWater) && (moveType == MoveTypeSwim))
  118. moveType = MoveTypeWalk;
  119. // Mongoose 2002.09.02, Add check for room -> room transition
  120. // (Only allow by movement between rooms by using portals)
  121. if (((moveType == MoveTypeNoClipping) ||
  122. (moveType == MoveTypeFly) ||
  123. (moveType == MoveTypeSwim)) ||
  124. ((roomNew > -1) && (!wall))) {
  125. room = roomNew;
  126. switch (movement) {
  127. case 'f':
  128. x = pos[0] + (moved * sinf(angles[1]));
  129. y = pos[1] + (moved * sinf(pitch));
  130. z = pos[2] + (moved * cosf(angles[1]));
  131. break;
  132. case 'b':
  133. x = pos[0] - (moved * sinf(angles[1]));
  134. y = pos[1] - (moved * sinf(pitch));
  135. z = pos[2] - (moved * cosf(angles[1]));
  136. break;
  137. case 'l':
  138. x = pos[0] - (moved * sinf(angles[1] + 90.0f));
  139. z = pos[2] - (moved * cosf(angles[1] + 90.0f));
  140. break;
  141. case 'r':
  142. x = pos[0] + (moved * sinf(angles[1] + 90.0f));
  143. z = pos[2] + (moved * cosf(angles[1] + 90.0f));
  144. break;
  145. }
  146. /*! \fixme Test for vector (move vector) / plane (portal) collision here
  147. * to see if we need to switch rooms... man...
  148. */
  149. h = y;
  150. getWorld().getRoom(room).getHeightAtPosition(x, &h, z);
  151. switch (moveType) {
  152. case MoveTypeFly:
  153. case MoveTypeSwim:
  154. // Don't fall out of world, avoid a movement that does
  155. if (h > y - camHeight) {
  156. pos[0] = x;
  157. pos[1] = y;
  158. pos[2] = z;
  159. }
  160. break;
  161. case MoveTypeWalk:
  162. case MoveTypeWalkNoSwim:
  163. y = pos[1]; // Override vector movement walking ( er, not pretty )
  164. // Now fake gravity
  165. // Mongoose 2002.08.14, Remember TR is upside down ( you fall 'up' )
  166. //ddist = h - pos[1];
  167. // This is to force false gravity, by making camera stay on ground
  168. pos[1] = h; //roomFloor->bbox_min[1];
  169. // Check for camera below terrian and correct
  170. if (pos[1] < h - camHeight)
  171. pos[1] = h - camHeight;
  172. pos[0] = x;
  173. pos[2] = z;
  174. break;
  175. case MoveTypeNoClipping:
  176. pos[0] = x;
  177. pos[1] = y;
  178. pos[2] = z;
  179. break;
  180. }
  181. }
  182. }
  183. void Entity::print() {
  184. getLog() << "Entity " << objectId << ":" << Log::endl
  185. << " Room " << room << " (" << getWorld().getRoom(room).getFlags()
  186. << ")" << Log::endl
  187. << " " << pos[0] << "x " << pos[1] << "y " << pos[2] << "z"
  188. << Log::endl
  189. << " " << OR_RAD_TO_DEG(angles[1]) << " Yaw" << Log::endl;
  190. }
  191. SkeletalModel &Entity::getModel() {
  192. return getWorld().getSkeletalModel(skeletalModel);
  193. }
  194. void Entity::setSkeletalModel(unsigned int model) {
  195. skeletalModel = model;
  196. animationFrame = 0;
  197. boneFrame = 0;
  198. idleAnimation = 0;
  199. }
  200. Entity::MoveType Entity::getMoveType() {
  201. return moveType;
  202. }
  203. void Entity::setMoveType(MoveType m) {
  204. moveType = m;
  205. }
  206. int Entity::getObjectId() {
  207. return objectId;
  208. }
  209. void Entity::setAngles(float a[3]) {
  210. for (unsigned int i = 0; i < 3; i++)
  211. angles[i] = a[i];
  212. }
  213. float Entity::getPos(unsigned int i) {
  214. return pos[i];
  215. }
  216. float Entity::getAngle(unsigned int i) {
  217. return angles[i];
  218. }
  219. long Entity::getRoom() {
  220. return room;
  221. }
  222. unsigned long Entity::getAnimation() {
  223. return animationFrame;
  224. }
  225. void Entity::setAnimation(unsigned long index) {
  226. animationFrame = index;
  227. boneFrame = 0;
  228. }
  229. unsigned long Entity::getBoneFrame() {
  230. return boneFrame;
  231. }
  232. void Entity::setBoneFrame(unsigned long index) {
  233. boneFrame = index;
  234. }
  235. unsigned long Entity::getIdleAnimation() {
  236. return idleAnimation;
  237. }
  238. void Entity::setIdleAnimation(unsigned long index) {
  239. idleAnimation = index;
  240. }