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.3KB

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