Shape3D.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. /***************************************************************************
  2. Shape3D.cpp - description
  3. -------------------
  4. begin : Wed Jan 26 2000
  5. copyright : (C) 2000 by Henrik Enqvist
  6. email : henqvist@excite.com
  7. ***************************************************************************/
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #include "Private.h"
  12. #include "Shape3D.h"
  13. #include "Polygon.h"
  14. Shape3D::Shape3D(int v, int p) {
  15. m_iProperties = 0;
  16. p_Parent = NULL;
  17. m_vPolygon.reserve(p);
  18. m_vVtxSrc.reserve(v);
  19. m_vVtxTrans.reserve(v);
  20. m_vVtxAlign.reserve(v);
  21. m_vNmlSrc.reserve(v);
  22. m_vNmlTrans.reserve(v);
  23. m_vNmlAlign.reserve(v);
  24. m_vLight.reserve(v);
  25. m_vSpecular.reserve(v);
  26. m_vColor.reserve(v);
  27. m_vLitColor.reserve(v);
  28. m_vTexCoord.reserve(v);
  29. m_Texture = NULL;
  30. }
  31. Shape3D::~Shape3D() {
  32. vector<Polygon3D*>::iterator iter = m_vPolygon.begin();
  33. vector<Polygon3D*>::iterator end = m_vPolygon.end();
  34. for ( ; iter != end; iter++) {
  35. delete (*iter);
  36. }
  37. m_vPolygon.clear();
  38. }
  39. void Shape3D::setPolygonProperty(int p) {
  40. vector<Polygon3D*>::iterator iter = m_vPolygon.begin();
  41. vector<Polygon3D*>::iterator end = m_vPolygon.end();
  42. for ( ; iter != end; iter++) {
  43. (*iter)->setProperty(p);
  44. }
  45. }
  46. void Shape3D::unsetPolygonProperty(int p) {
  47. vector<Polygon3D*>::iterator iter = m_vPolygon.begin();
  48. vector<Polygon3D*>::iterator end = m_vPolygon.end();
  49. for ( ; iter != end; iter++) {
  50. (*iter)->unsetProperty(p);
  51. }
  52. }
  53. void Shape3D::setProperty(int p) {
  54. m_iProperties |= p;
  55. }
  56. void Shape3D::unsetProperty(int p) {
  57. m_iProperties -= (m_iProperties & p);
  58. }
  59. void Shape3D::setParent(Group* p) {
  60. p_Parent = p;
  61. }
  62. void Shape3D::setTexture(EmTexture* tex) {
  63. m_Texture = tex;
  64. }
  65. /*
  66. * Adds a vertex to this shape. The index of the vertices will be the
  67. * same as the order they are added.
  68. */
  69. int Shape3D::add(float x, float y, float z) {
  70. this->add(x, y, z, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f);
  71. return m_vVtxSrc.size() - 1;
  72. }
  73. int Shape3D::add(float x, float y, float z, float r, float g, float b, float a, float u, float v) {
  74. EM_COUT("Shape3D::add() "<< x <<" "<< y <<" "<< z, 0);
  75. Vertex3D vtx;
  76. vtx.x = x;
  77. vtx.y = y;
  78. vtx.z = z;
  79. m_vVtxSrc.push_back(vtx);
  80. // Add dummy values to trans and align, i.e. allocate space
  81. m_vVtxTrans.push_back(vtx);
  82. m_vVtxAlign.push_back(vtx);
  83. // Add dummy values to normals, i.e. allocate space
  84. m_vNmlSrc.push_back(vtx);
  85. m_vNmlTrans.push_back(vtx);
  86. m_vNmlAlign.push_back(vtx);
  87. Color color = {1.0f, 1.0f, 1.0f, 1.0f};
  88. m_vLight.push_back(color);
  89. m_vSpecular.push_back(color);
  90. color.r = r;
  91. color.g = g;
  92. color.b = b;
  93. color.a = a;
  94. m_vColor.push_back(color);
  95. m_vLitColor.push_back(color);
  96. TexCoord texcoord;
  97. texcoord.u = u;
  98. texcoord.v = v;
  99. m_vTexCoord.push_back(texcoord);
  100. return m_vVtxSrc.size() - 1;
  101. }
  102. int Shape3D::addAt(int index, float x, float y, float z,
  103. float r, float g, float b, float a, float u, float v) {
  104. if (index < 0 || index >= (signed)m_vVtxSrc.size()) {
  105. return this->add(x, y, z, r, g, b, a, u, v);
  106. }
  107. Vertex3D vtx;
  108. vtx.x = x;
  109. vtx.y = y;
  110. vtx.z = z;
  111. m_vVtxSrc.insert(m_vVtxSrc.begin()+index, vtx);
  112. // Add dummy values to trans and align, i.e. allocate space
  113. m_vVtxTrans.insert(m_vVtxTrans.begin()+index, vtx);
  114. m_vVtxAlign.insert(m_vVtxAlign.begin()+index, vtx);
  115. // Add dummy values to normals, i.e. allocate space
  116. m_vNmlSrc.insert(m_vNmlSrc.begin()+index, vtx);
  117. m_vNmlTrans.insert(m_vNmlTrans.begin()+index, vtx);
  118. m_vNmlAlign.insert(m_vNmlAlign.begin()+index, vtx);
  119. Color color = {1.0f, 1.0f, 1.0f, 1.0f};
  120. m_vLight.insert(m_vLight.begin()+index, color);
  121. m_vSpecular.insert(m_vSpecular.begin()+index, color);
  122. color.r = r;
  123. color.g = g;
  124. color.b = b;
  125. color.a = a;
  126. m_vColor.insert(m_vColor.begin()+index, color);
  127. m_vLitColor.insert(m_vLitColor.begin()+index, color);
  128. TexCoord texcoord;
  129. texcoord.u = u;
  130. texcoord.v = v;
  131. m_vTexCoord.insert(m_vTexCoord.begin()+index, texcoord);
  132. return index;
  133. }
  134. Vertex3D * Shape3D::getVertex3D(int index) {
  135. if ( index < 0 || index >= (signed)m_vVtxSrc.size() ) {
  136. return NULL;
  137. }
  138. return &(m_vVtxSrc[index]);
  139. }
  140. int Shape3D::getVertex3DSize() {
  141. return m_vVtxSrc.size();
  142. }
  143. int Shape3D::getVertex3DIndex(Vertex3D * vtx) {
  144. if (vtx == NULL) return -1;
  145. vector<Vertex3D>::iterator iter = m_vVtxSrc.begin();
  146. vector<Vertex3D>::iterator end = m_vVtxSrc.end();
  147. for (int a=0; iter != end; iter++, a++) {
  148. if (&(*iter) == vtx) return a;
  149. }
  150. return -1;
  151. }
  152. int Shape3D::getVertex3DIndex(TexCoord * tex) {
  153. if (tex == NULL) return -1;
  154. vector<TexCoord>::iterator iter = m_vTexCoord.begin();
  155. vector<TexCoord>::iterator end = m_vTexCoord.end();
  156. for (int a=0; iter != end; iter++, a++) {
  157. if (&(*iter) == tex) return a;
  158. }
  159. return -1;
  160. }
  161. Color * Shape3D::getColor(int index) {
  162. if (index < 0 || index >= (signed)m_vColor.size()) {
  163. return NULL;
  164. }
  165. return &(m_vColor[index]);
  166. }
  167. void Shape3D::setColor(int index, float r, float g, float b, float a) {
  168. if (index < 0 || index >= (signed)m_vColor.size()) {
  169. return;
  170. }
  171. m_vColor[index].r = EM_MAX(EM_MIN(r, 1.0f), 0.0f);
  172. m_vColor[index].g = EM_MAX(EM_MIN(g, 1.0f), 0.0f);
  173. m_vColor[index].b = EM_MAX(EM_MIN(b, 1.0f), 0.0f);
  174. m_vColor[index].a = EM_MAX(EM_MIN(a, 1.0f), 0.0f);
  175. }
  176. TexCoord * Shape3D::getTexCoord(int index) {
  177. if (index < 0 || index >= (signed)m_vTexCoord.size()) {
  178. return NULL;
  179. }
  180. return &(m_vTexCoord[index]);
  181. }
  182. void Shape3D::setTexCoord(int index, float u, float v) {
  183. if (index < 0 || index >= (signed)m_vTexCoord.size()) {
  184. return;
  185. }
  186. m_vTexCoord[index].u = u;
  187. m_vTexCoord[index].v = v;
  188. }
  189. bool Shape3D::removeLooseVertex3D(int vtxindex) {
  190. if (vtxindex < 0 || vtxindex >= (signed)m_vVtxSrc.size()) return false;
  191. // check that the vertex is not included in any polygon
  192. vector<Polygon3D*>::iterator polyiter = m_vPolygon.begin();
  193. vector<Polygon3D*>::iterator polyend = m_vPolygon.end();
  194. for (; polyiter != polyend; ++polyiter) {
  195. if ((*polyiter)->includes(vtxindex) >= 0) return false;
  196. }
  197. m_vVtxSrc.erase(m_vVtxSrc.begin()+vtxindex);
  198. m_vVtxTrans.erase(m_vVtxTrans.begin()+vtxindex);
  199. m_vVtxAlign.erase(m_vVtxAlign.begin()+vtxindex);
  200. m_vNmlSrc.erase(m_vNmlSrc.begin()+vtxindex);
  201. m_vNmlTrans.erase(m_vNmlTrans.begin()+vtxindex);
  202. m_vNmlAlign.erase(m_vNmlAlign.begin()+vtxindex);
  203. // decrement each index above vtxindex
  204. polyiter = m_vPolygon.begin();
  205. polyend = m_vPolygon.end();
  206. for (; polyiter != polyend; ++polyiter) {
  207. (*polyiter)->decrement(vtxindex);
  208. }
  209. return true;
  210. }
  211. Polygon3D * Shape3D::getPolygon(int index) {
  212. if ( index < 0 || index >= (signed)m_vPolygon.size() ) {
  213. return NULL;
  214. }
  215. return m_vPolygon[index];
  216. }
  217. int Shape3D::getPolygonSize() {
  218. return m_vPolygon.size();
  219. }
  220. int Shape3D::getPolygonIndex(Polygon3D * poly) {
  221. if (poly == NULL) return -1;
  222. vector<Polygon3D*>::iterator iter = m_vPolygon.begin();
  223. vector<Polygon3D*>::iterator end = m_vPolygon.end();
  224. for (int a=0; iter != end; iter++, a++) {
  225. if ((*iter) == poly) return a;
  226. }
  227. return -1;
  228. }
  229. void Shape3D::removePolygon(Polygon3D * poly) {
  230. if (poly == NULL) return;
  231. vector<Polygon3D*>::iterator iter = m_vPolygon.begin();
  232. vector<Polygon3D*>::iterator end = m_vPolygon.end();
  233. for (; iter != end; iter++) {
  234. if ((*iter) == poly) {
  235. m_vPolygon.erase(iter);
  236. return;
  237. }
  238. }
  239. }
  240. int Shape3D::find(float x, float y, float z, float diff) {
  241. vector<Vertex3D>::iterator iter = m_vVtxSrc.begin();
  242. vector<Vertex3D>::iterator end = m_vVtxSrc.end();
  243. for (int a=0; iter != end; iter++, a++) {
  244. if ((*iter).x < x+diff && (*iter).x > x-diff &&
  245. (*iter).y < y+diff && (*iter).y > y-diff &&
  246. (*iter).z < z+diff && (*iter).z > z-diff)
  247. return a;
  248. }
  249. return -1;
  250. }
  251. void Shape3D::add(Polygon3D* p) {
  252. if (p == NULL) return;
  253. m_vPolygon.push_back(p);
  254. }
  255. /* Sets all polygons to color c. */
  256. void Shape3D::setColor(float r, float g, float b, float a) {
  257. vector<Polygon3D*>::iterator iter = m_vPolygon.begin();
  258. vector<Polygon3D*>::iterator end = m_vPolygon.end();
  259. for ( ; iter != end; iter++) {
  260. (*iter)->setColor(r,g,b,a);
  261. }
  262. }
  263. /* Counts normals for all vertices in Shape3D. */
  264. void Shape3D::countNormals() {
  265. vector<Vertex3D>::iterator nmlIter = m_vNmlSrc.begin();
  266. vector<Vertex3D>::iterator nmlEnd = m_vNmlSrc.end();
  267. for (int a=0; nmlIter != nmlEnd; nmlIter++, a++) {
  268. (*nmlIter).x = 0;
  269. (*nmlIter).y = 0;
  270. (*nmlIter).z = 0;
  271. // Get the avrage of all normals in which the vertex resides.
  272. vector<Polygon3D*>::iterator polyIter = m_vPolygon.begin();
  273. vector<Polygon3D*>::iterator polyEnd = m_vPolygon.end();
  274. for (; polyIter != polyEnd; polyIter++) {
  275. if ((*polyIter)->includes(a) >= 0) {
  276. (*nmlIter).x += (*polyIter)->m_nmlSrc.x;
  277. (*nmlIter).y += (*polyIter)->m_nmlSrc.y;
  278. (*nmlIter).z += (*polyIter)->m_nmlSrc.z;
  279. }
  280. }
  281. if ( EM_ZERO((*nmlIter).x) &&
  282. EM_ZERO((*nmlIter).y) &&
  283. EM_ZERO((*nmlIter).z) ) {
  284. (*nmlIter).y = 1;
  285. }
  286. EMath::normalizeVector((*nmlIter));
  287. }
  288. }
  289. float Shape3D::getCollisionSize() {
  290. float size = 0;
  291. vector<Vertex3D>::iterator iter = m_vVtxSrc.begin();
  292. vector<Vertex3D>::iterator end = m_vVtxSrc.end();
  293. for ( ; iter != end; iter++) {
  294. if (EM_ABS((*iter).x) > size) size = EM_ABS((*iter).x);
  295. if (EM_ABS((*iter).y) > size) size = EM_ABS((*iter).y);
  296. if (EM_ABS((*iter).z) > size) size = EM_ABS((*iter).z);
  297. }
  298. return size;
  299. }