PolyEntity.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. /*
  2. * PolyEntity.cpp
  3. * Poly
  4. *
  5. * Created by Ivan Safrin on 1/18/09.
  6. * Copyright 2009 __MyCompanyName__. All rights reserved.
  7. *
  8. */
  9. #include "PolyEntity.h"
  10. using namespace Polycode;
  11. Entity::Entity() {
  12. scale.set(1,1,1);
  13. pitch = 0;
  14. yaw = 0;
  15. roll = 0;
  16. renderer = NULL;
  17. enabled = true;
  18. visible = true;
  19. bBoxRadius = 0;
  20. color.setColor(1.0f,1.0f,1.0f,1.0f);
  21. parentEntity = NULL;
  22. matrixDirty = true;
  23. matrixAdj = 1.0f;
  24. billboardMode = false;
  25. billboardRoll = false;
  26. backfaceCulled = true;
  27. depthOnly = false;
  28. depthWrite = true;
  29. alphaTest = false;
  30. blendingMode = Renderer::BLEND_MODE_NORMAL;
  31. lockMatrix = false;
  32. renderWireframe = false;
  33. colorAffectsChildren = true;
  34. maskEntity = NULL;
  35. isMask = false;
  36. hasMask = false;
  37. }
  38. Entity *Entity::getParentEntity() {
  39. return parentEntity;
  40. }
  41. Color Entity::getCombinedColor() {
  42. if(parentEntity) {
  43. if(parentEntity->colorAffectsChildren)
  44. return color * parentEntity->getCombinedColor();
  45. else
  46. return color;
  47. } else {
  48. return color;
  49. }
  50. }
  51. Matrix4 Entity::getLookAtMatrix(const Vector3 &loc, const Vector3 &upVector) {
  52. rebuildTransformMatrix();
  53. Vector3 D;
  54. if(parentEntity)
  55. D = loc - (parentEntity->getConcatenatedMatrix() *position);
  56. else
  57. D = loc - position;
  58. Vector3 back = D * -1;
  59. back.Normalize();
  60. Vector3 right = back.crossProduct(upVector) ;
  61. right.Normalize();
  62. right = right * -1;
  63. Vector3 up = back.crossProduct(right);
  64. Matrix4 newMatrix(right.x, right.y, right.z, 0,
  65. up.x, up.y, up.z, 0,
  66. back.x, back.y, back.z, 0,
  67. 0, 0 , 0, 1);
  68. return newMatrix;
  69. }
  70. void Entity::lookAt(const Vector3 &loc, const Vector3 &upVector) {
  71. Matrix4 newMatrix = getLookAtMatrix(loc, upVector);
  72. rotationQuat.createFromMatrix(newMatrix);
  73. matrixDirty = true;
  74. }
  75. void Entity::lookAtEntity(Entity *entity, const Vector3 &upVector) {
  76. if(entity->getParentEntity())
  77. lookAt(entity->getParentEntity()->getConcatenatedMatrix() * (*entity->getPosition()), upVector);
  78. else
  79. lookAt(*entity->getPosition(), upVector);
  80. }
  81. void Entity::removeChild(Entity *entityToRemove) {
  82. for(int i=0;i<children.size();i++) {
  83. if(children[i] == entityToRemove) {
  84. children.erase(children.begin()+i);
  85. }
  86. }
  87. }
  88. void Entity::addChild(Entity *newChild) {
  89. addEntity(newChild);
  90. }
  91. void Entity::setColor(Color color) {
  92. this->color.setColor(&color);
  93. }
  94. void Entity::setColorInt(int r, int g, int b, int a) {
  95. color.setColorRGBA(r,g, b, a);
  96. }
  97. void Entity::setColor(float r, float g, float b, float a) {
  98. color.setColor(r,g,b,a);
  99. }
  100. void Entity::recalculateBBox() {
  101. }
  102. void Entity::setBlendingMode(int newBlendingMode) {
  103. blendingMode = newBlendingMode;
  104. }
  105. float Entity::getBBoxRadius() {
  106. float compRad;
  107. float biggest = bBoxRadius;
  108. for(int i=0;i<children.size();i++) {
  109. compRad = children[i]->getCompoundBBoxRadius();
  110. if(compRad > biggest)
  111. biggest = compRad;
  112. }
  113. return biggest;
  114. }
  115. float Entity::getCompoundBBoxRadius() {
  116. float compRad;
  117. float biggest = bBoxRadius + position.distance(Vector3(0,0,0));
  118. for(int i=0;i<children.size();i++) {
  119. compRad = children[i]->getCompoundBBoxRadius();
  120. if(compRad > biggest)
  121. biggest = compRad;
  122. }
  123. return biggest;
  124. }
  125. void Entity::setBBoxRadius(float rad) {
  126. bBoxRadius = rad;
  127. }
  128. Entity::~Entity() {
  129. }
  130. Vector3 Entity::getChildCenter() {
  131. return childCenter;
  132. }
  133. void Entity::setMatrix(Matrix4 matrix) {
  134. transformMatrix = matrix;
  135. matrixDirty = false;
  136. }
  137. Matrix4 Entity::buildPositionMatrix() {
  138. Matrix4 posMatrix;
  139. posMatrix.m[3][0] = position.x*matrixAdj;
  140. posMatrix.m[3][1] = position.y*matrixAdj;
  141. posMatrix.m[3][2] = position.z*matrixAdj;
  142. return posMatrix;
  143. }
  144. void Entity::rebuildTransformMatrix() {
  145. if(lockMatrix)
  146. return;
  147. if(billboardMode){
  148. transformMatrix.identity();
  149. } else {
  150. transformMatrix = rotationQuat.createMatrix();
  151. }
  152. Matrix4 scaleMatrix;
  153. scaleMatrix.m[0][0] *= scale.x;
  154. scaleMatrix.m[1][1] *= scale.y;
  155. scaleMatrix.m[2][2] *= scale.z;
  156. Matrix4 posMatrix = buildPositionMatrix();
  157. transformMatrix = scaleMatrix*transformMatrix*posMatrix;
  158. matrixDirty = false;
  159. }
  160. void Entity::doUpdates() {
  161. Update();
  162. for(int i=0; i < children.size(); i++) {
  163. children[i]->doUpdates();
  164. }
  165. }
  166. void Entity::updateEntityMatrix() {
  167. if(matrixDirty)
  168. rebuildTransformMatrix();
  169. for(int i=0; i < children.size(); i++) {
  170. children[i]->updateEntityMatrix();
  171. }
  172. }
  173. Vector3 Entity::getCompoundScale() {
  174. if(parentEntity != NULL) {
  175. Vector3 parentScale = parentEntity->getCompoundScale();
  176. return Vector3(scale.x * parentScale.x, scale.y * parentScale.y,scale.z * parentScale.z);
  177. }
  178. else
  179. return scale;
  180. }
  181. Matrix4 Entity::getConcatenatedRollMatrix() {
  182. Quaternion q;
  183. q.createFromAxisAngle(0.0f, 0.0f, 1.0f, roll*matrixAdj);
  184. Matrix4 transformMatrix = q.createMatrix();
  185. if(parentEntity != NULL)
  186. return transformMatrix * parentEntity->getConcatenatedRollMatrix();
  187. else
  188. return transformMatrix;
  189. }
  190. void Entity::setMask(Entity *mask) {
  191. mask->setDepthWrite(true);
  192. mask->depthOnly = true;
  193. mask->setPositionZ(0.999);
  194. mask->isMask = true;
  195. mask->enabled = false;
  196. maskEntity = mask;
  197. hasMask = true;
  198. }
  199. void Entity::clearMask() {
  200. maskEntity->setDepthWrite(false);
  201. maskEntity->depthOnly = false;
  202. maskEntity->setPositionZ(0);
  203. maskEntity->enabled = true;
  204. maskEntity = NULL;
  205. hasMask = false;
  206. }
  207. void Entity::setDepthWrite(bool val) {
  208. depthWrite = val;
  209. for(int i=0;i<children.size();i++) {
  210. children[i]->setDepthWrite(val);
  211. }
  212. }
  213. void Entity::transformAndRender() {
  214. if(!renderer || !enabled)
  215. return;
  216. if(depthOnly) {
  217. renderer->drawToColorBuffer(false);
  218. }
  219. if(hasMask) {
  220. renderer->clearBuffer(false, true);
  221. maskEntity->enabled = true;
  222. maskEntity->transformAndRender();
  223. maskEntity->enabled = false;
  224. renderer->setDepthFunction(Renderer::DEPTH_FUNCTION_GREATER);
  225. }
  226. renderer->pushMatrix();
  227. renderer->multModelviewMatrix(transformMatrix);
  228. renderer->setVertexColor(color.r,color.g,color.b,color.a);
  229. if(billboardMode) {
  230. renderer->billboardMatrixWithScale(getCompoundScale());
  231. if(billboardRoll) {
  232. renderer->multModelviewMatrix(getConcatenatedRollMatrix());
  233. }
  234. }
  235. if(!depthWrite)
  236. renderer->enableDepthTest(false);
  237. else
  238. renderer->enableDepthTest(true);
  239. renderer->enableAlphaTest(alphaTest);
  240. Color combined = getCombinedColor();
  241. renderer->setVertexColor(combined.r,combined.g,combined.b,combined.a);
  242. renderer->setBlendingMode(blendingMode);
  243. renderer->enableBackfaceCulling(backfaceCulled);
  244. int mode = renderer->getRenderMode();
  245. if(renderWireframe)
  246. renderer->setRenderMode(Renderer::RENDER_MODE_WIREFRAME);
  247. if(visible) {
  248. Render();
  249. renderer->setRenderMode(mode);
  250. // renderer->pushMatrix();
  251. adjustMatrixForChildren();
  252. renderChildren();
  253. // renderer->popMatrix();
  254. }
  255. renderer->popMatrix();
  256. if(hasMask) {
  257. renderer->clearBuffer(false, true);
  258. }
  259. if(!depthWrite)
  260. renderer->enableDepthTest(true);
  261. if(hasMask) {
  262. renderer->setDepthFunction(Renderer::DEPTH_FUNCTION_LEQUAL);
  263. }
  264. if(depthOnly) {
  265. renderer->drawToColorBuffer(true);
  266. }
  267. }
  268. void Entity::setRenderer(Renderer *renderer) {
  269. this->renderer = renderer;
  270. for(int i=0;i<children.size();i++) {
  271. children[i]->setRenderer(renderer);
  272. }
  273. }
  274. void Entity::addEntity(Entity *newChild) {
  275. newChild->setRenderer(renderer);
  276. newChild->setParentEntity(this);
  277. children.push_back(newChild);
  278. }
  279. void Entity::renderChildren() {
  280. for(int i=0;i<children.size();i++) {
  281. children[i]->transformAndRender();
  282. }
  283. }
  284. void Entity::dirtyMatrix(bool val) {
  285. matrixDirty = val;
  286. }
  287. void Entity::setRotationQuat(float w, float x, float y, float z) {
  288. rotationQuat.w = w;
  289. rotationQuat.x = x;
  290. rotationQuat.y = y;
  291. rotationQuat.z = z;
  292. matrixDirty = true;
  293. }
  294. Quaternion Entity::getRotationQuat() {
  295. return rotationQuat;
  296. }
  297. void Entity::setPitch(float pitch) {
  298. this->pitch = pitch;
  299. rebuildRotation();
  300. matrixDirty = true;
  301. }
  302. void Entity::setYaw(float yaw) {
  303. this->yaw = yaw;
  304. rebuildRotation();
  305. matrixDirty = true;
  306. }
  307. Vector3 Entity::getScale() {
  308. return scale;
  309. }
  310. Matrix4 Entity::getConcatenatedMatrix() {
  311. if(parentEntity != NULL)
  312. return transformMatrix * parentEntity->getConcatenatedMatrix();
  313. else
  314. return transformMatrix;
  315. }
  316. Matrix4 Entity::getTransformMatrix() {
  317. return transformMatrix;
  318. }
  319. void Entity::Pitch(float pitch) {
  320. this->pitch += pitch;
  321. rebuildRotation();
  322. matrixDirty = true;
  323. }
  324. void Entity::Yaw(float yaw) {
  325. this->yaw += yaw;
  326. rebuildRotation();
  327. matrixDirty = true;
  328. }
  329. void Entity::Roll(float roll) {
  330. this->roll += roll;
  331. rebuildRotation();
  332. matrixDirty = true;
  333. }
  334. void Entity::setRoll(float roll) {
  335. this->roll= roll;
  336. rebuildRotation();
  337. matrixDirty = true;
  338. }
  339. void Entity::rebuildRotation() {
  340. rotationQuat.fromAxes(pitch, yaw, roll);
  341. }
  342. String Entity::getEntityProp(String propName) {
  343. for(int i=0; i < entityProps.size(); i++) {
  344. if(entityProps[i].propName == propName) {
  345. return entityProps[i].propValue;
  346. }
  347. }
  348. return "null";
  349. }
  350. Vector3 Entity::getCombinedPosition() {
  351. if(parentEntity != NULL)
  352. return (parentEntity->getCombinedPosition())+position;
  353. else
  354. return position;
  355. }
  356. void Entity::setParentEntity(Entity *entity) {
  357. parentEntity = entity;
  358. }
  359. float Entity::getPitch() {
  360. return pitch;
  361. }
  362. float Entity::getYaw() {
  363. return yaw;
  364. }
  365. float Entity::getRoll() {
  366. return roll;
  367. }
  368. void Entity::setTransformByMatrix(Matrix4 matrix) {
  369. setPosition(matrix.getPosition());
  370. float x,y,z;
  371. matrix.getEulerAngles(&x,&y,&z);
  372. setPitch(x);
  373. setYaw(y);
  374. setRoll(z);
  375. // setYaw(-asin(matrix.m[0][2]) * TODEGREES);
  376. /// setPitch(atan2(-matrix.m[0][1], matrix.m[0][0]) * TODEGREES);
  377. // setRoll(atan2(-matrix.m[1][2], matrix.m[2][2]) * TODEGREES);
  378. matrixDirty = true;
  379. }
  380. void Entity::setPosition(Vector3 posVec) {
  381. position = posVec;
  382. matrixDirty = true;
  383. }
  384. void Entity::setPositionX(float x) {
  385. position.x = x;
  386. matrixDirty = true;
  387. }
  388. void Entity::setPositionY(float y) {
  389. position.y = y;
  390. matrixDirty = true;
  391. }
  392. void Entity::setPositionZ(float z) {
  393. position.z = z;
  394. matrixDirty = true;
  395. }
  396. void Entity::setScaleX(float x) {
  397. scale.x = x;
  398. matrixDirty = true;
  399. }
  400. void Entity::setScaleY(float y) {
  401. scale.y = y;
  402. matrixDirty = true;
  403. }
  404. void Entity::setScaleZ(float z) {
  405. scale.z = z;
  406. matrixDirty = true;
  407. }
  408. void Entity::setPosition(float x, float y, float z) {
  409. position.x = x;
  410. position.y = y;
  411. position.z = z;
  412. matrixDirty = true;
  413. }
  414. void Entity::Translate(Vector3 tVec) {
  415. position += tVec;
  416. matrixDirty = true;
  417. }
  418. void Entity::Translate(float x, float y, float z) {
  419. position.x += x;
  420. position.y += y;
  421. position.z += z;
  422. matrixDirty = true;
  423. }
  424. void Entity::Scale(float x, float y, float z) {
  425. scale.x *= x;
  426. scale.y *= y;
  427. scale.z *= z;
  428. matrixDirty = true;
  429. }
  430. void Entity::setScale(float x, float y, float z) {
  431. scale.x = x;
  432. scale.y = y;
  433. scale.z = z;
  434. matrixDirty = true;
  435. }
  436. Vector3 *Entity::getPosition() {
  437. return &position;
  438. }
  439. float Entity::getCombinedPitch() {
  440. if(parentEntity != NULL)
  441. return parentEntity->getCombinedPitch()+pitch;
  442. else
  443. return pitch;
  444. }
  445. float Entity::getCombinedYaw() {
  446. if(parentEntity != NULL)
  447. return parentEntity->getCombinedYaw()+yaw;
  448. else
  449. return yaw;
  450. }
  451. float Entity::getCombinedRoll() {
  452. if(parentEntity != NULL)
  453. return parentEntity->getCombinedRoll()+roll;
  454. else
  455. return roll;
  456. }