mesh.cpp
上传用户:qccn516
上传日期:2013-05-02
资源大小:3382k
文件大小:46k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /* Mesh
  2.  *
  3.  * Copyright (C) 2003-2004, Alexander Zaprjagaev <frustum@frustum.org>
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  */
  19. #include "mesh.h"
  20. Mesh::Mesh() : num_surfaces(0) {
  21. min = vec3(1000000,1000000,1000000);
  22. max = vec3(-1000000,-1000000,-1000000);
  23. center = vec3(0,0,0);
  24. radius = 1000000;
  25. }
  26. Mesh::Mesh(const char *name) : num_surfaces(0) {
  27. load(name);
  28. }
  29. Mesh::Mesh(const Mesh *mesh) : num_surfaces(0) {
  30. min = mesh->min;
  31. max = mesh->max;
  32. center = mesh->center;
  33. radius = mesh->radius;
  34. for(int i = 0; i < mesh->num_surfaces; i++) {
  35. Surface *s = new Surface;
  36. memcpy(s,mesh->surfaces[i],sizeof(Surface));
  37. s->vertex = new Vertex[s->num_vertex];
  38. memcpy(s->vertex,mesh->surfaces[i]->vertex,sizeof(Vertex) * s->num_vertex);
  39. if(mesh->surfaces[i]->edges) {
  40. s->edges = new Edge[s->num_edges];
  41. memcpy(s->edges,mesh->surfaces[i]->edges,sizeof(Edge) * s->num_edges);
  42. }
  43. if(mesh->surfaces[i]->triangles) {
  44. s->triangles = new Triangle[s->num_triangles];
  45. memcpy(s->triangles,mesh->surfaces[i]->triangles,sizeof(Triangle) * s->num_triangles);
  46. }
  47. if(mesh->surfaces[i]->indices) {
  48. s->indices = new int[s->num_indices];
  49. memcpy(s->indices,mesh->surfaces[i]->indices,sizeof(int) * s->num_indices);
  50. }
  51. if(mesh->surfaces[i]->silhouettes[0].vertex) {
  52. for(int j = 0; j < NUM_SILHOUETTES; j++) {
  53. s->silhouettes[j].vertex = new vec4[s->num_edges * 4];
  54. s->silhouettes[j].flags = new char[s->num_triangles];
  55. }
  56. }
  57. if(num_surfaces == NUM_SURFACES) {
  58. fprintf(stderr,"Mesh::Mesh(): many surfacesn");
  59. num_surfaces--;
  60. }
  61. surfaces[num_surfaces++] = s;
  62. }
  63. }
  64. Mesh::~Mesh() {
  65. for(int i = 0; i < num_surfaces; i++) {
  66. Surface *s = surfaces[i];
  67. if(s->vertex) delete s->vertex;
  68. if(s->indices) delete s->indices;
  69. if(s->edges) delete s->edges;
  70. if(s->triangles) delete s->triangles;
  71. if(s->silhouettes[0].vertex) {
  72. for(int j = 0; j < NUM_SILHOUETTES; j++) {
  73. delete s->silhouettes[j].vertex;
  74. delete s->silhouettes[j].flags;
  75. }
  76. }
  77. delete s;
  78. }
  79. num_surfaces = 0;
  80. }
  81. /*****************************************************************************/
  82. /*                                                                           */
  83. /* render                                                                    */
  84. /*                                                                           */
  85. /*****************************************************************************/
  86. /*
  87.  */
  88. int Mesh::render(int,int) {
  89. fprintf(stderr,"Mesh::render()n");
  90. return 0;
  91. }
  92. /*****************************************************************************/
  93. /*                                                                           */
  94. /* stencil shadows                                                           */
  95. /*                                                                           */
  96. /*****************************************************************************/
  97. /*
  98.  */
  99. void Mesh::findSilhouette(const vec4 &light,int s) {
  100. if(s < 0) {
  101. for(int i = 0; i < num_surfaces; i++) {
  102. Surface *s = surfaces[i];
  103. for(int j = 0; j < NUM_SILHOUETTES; j++) {
  104. if(s->silhouettes[j].light == light) {
  105. s->silhouette = &s->silhouettes[j];
  106. continue;
  107. }
  108. }
  109. s->silhouette = &s->silhouettes[s->last_silhouette++];
  110. if(s->last_silhouette == NUM_SILHOUETTES) s->last_silhouette = 0;
  111. for(int j = 0; j < s->num_edges; j++) s->edges[j].flag = -1;
  112. for(int j = 0; j < s->num_triangles; j++) {
  113. if(s->triangles[j].plane * light > 0.0) {
  114. s->silhouette->flags[j] = 1;
  115. Triangle *t = &s->triangles[j];
  116. s->edges[t->e[0]].reverse = t->reverse[0];
  117. s->edges[t->e[1]].reverse = t->reverse[1];
  118. s->edges[t->e[2]].reverse = t->reverse[2];
  119. s->edges[t->e[0]].flag++;
  120. s->edges[t->e[1]].flag++;
  121. s->edges[t->e[2]].flag++;
  122. } else s->silhouette->flags[j] = 0;
  123. }
  124. s->silhouette->light = light;
  125. s->silhouette->num_vertex = 0;
  126. vec4 *vertex = s->silhouette->vertex;
  127. for(int j = 0; j < s->num_edges; j++) {
  128. if(s->edges[j].flag != 0) continue;
  129. Edge *e = &s->edges[j];
  130. if(e->reverse) {
  131. *vertex++ = vec4(e->v[0],1);
  132. *vertex++ = vec4(e->v[1],1);
  133. *vertex++ = vec4(e->v[1],0);
  134. *vertex++ = vec4(e->v[0],0);
  135. } else {
  136. *vertex++ = vec4(e->v[1],1);
  137. *vertex++ = vec4(e->v[0],1);
  138. *vertex++ = vec4(e->v[0],0);
  139. *vertex++ = vec4(e->v[1],0);
  140. }
  141. s->silhouette->num_vertex += 4;
  142. }
  143. }
  144. } else {
  145. Surface *surface = surfaces[s];
  146. Surface *s = surface; // :)
  147. for(int i = 0; i < NUM_SILHOUETTES; i++) {
  148. if(s->silhouettes[i].light == light) {
  149. s->silhouette = &s->silhouettes[i];
  150. return;
  151. }
  152. }
  153. s->silhouette = &s->silhouettes[s->last_silhouette++];
  154. if(s->last_silhouette == NUM_SILHOUETTES) s->last_silhouette = 0;
  155. for(int i = 0; i < s->num_edges; i++) s->edges[i].flag = -1;
  156. for(int i = 0; i < s->num_triangles; i++) {
  157. if(s->triangles[i].plane * light > 0.0) {
  158. s->silhouette->flags[i] = 1;
  159. Triangle *t = &s->triangles[i];
  160. s->edges[t->e[0]].reverse = t->reverse[0];
  161. s->edges[t->e[1]].reverse = t->reverse[1];
  162. s->edges[t->e[2]].reverse = t->reverse[2];
  163. s->edges[t->e[0]].flag++;
  164. s->edges[t->e[1]].flag++;
  165. s->edges[t->e[2]].flag++;
  166. } else s->silhouette->flags[i] = 0;;
  167. }
  168. s->silhouette->light = light;
  169. s->silhouette->num_vertex = 0;
  170. vec4 *vertex = s->silhouette->vertex;
  171. for(int i = 0; i < s->num_edges; i++) {
  172. if(s->edges[i].flag != 0) continue;
  173. Edge *e = &s->edges[i];
  174. if(e->reverse) {
  175. *vertex++ = vec4(e->v[0],1);
  176. *vertex++ = vec4(e->v[1],1);
  177. *vertex++ = vec4(e->v[1],0);
  178. *vertex++ = vec4(e->v[0],0);
  179. } else {
  180. *vertex++ = vec4(e->v[1],1);
  181. *vertex++ = vec4(e->v[0],1);
  182. *vertex++ = vec4(e->v[0],0);
  183. *vertex++ = vec4(e->v[1],0);
  184. }
  185. s->silhouette->num_vertex += 4;
  186. }
  187. }
  188. }
  189. int Mesh::getNumIntersections(const vec3 &line0,const vec3 &line1,int s) {
  190. int num_intersections = 0;
  191. if(s < 0) {
  192. vec3 dir = line1 - line0;
  193. float dot = (dir * center - dir * line0) / (dir * dir);
  194. if(dot < 0.0 && (line0 - center).length() > radius) return 0;
  195. else if(dot > 1.0 && (line1 - center).length() > radius) return 0;
  196. else if((line0 + dir * dot - center).length() > radius) return 0;
  197. for(int i = 0; i < num_surfaces; i++) {
  198. Surface *s = surfaces[i];
  199. float dot = (dir * s->center - dir * line0) / (dir * dir);
  200. if(dot < 0.0 && (line0 - s->center).length() > s->radius) continue;
  201. else if(dot > 1.0 && (line1 - s->center).length() > s->radius) continue;
  202. else if((line0 + dir * dot - s->center).length() > s->radius) continue;
  203. for(int j = 0; j < s->num_triangles; j++) {
  204. if(s->silhouette->flags[j] == 0) continue;
  205. Triangle *t = &s->triangles[j];
  206. float dot = -(t->plane * vec4(line0,1)) / (vec3(t->plane) * dir);
  207. if(dot < 0.0 || dot > 1.0) continue;
  208. vec3 p = line0 + dir * dot;
  209. if(p * t->c[0] > 0.0 && p * t->c[1] > 0.0 && p * t->c[2] > 0.0) num_intersections++;
  210. }
  211. }
  212. return num_intersections;
  213. } else {
  214. Surface *surface = surfaces[s];
  215. Surface *s = surface;
  216. vec3 dir = line1 - line0;
  217. float dot = (dir * s->center - dir * line0) / (dir * dir);
  218. if(dot < 0.0 && (line0 - s->center).length() > s->radius) return 0;
  219. else if(dot > 1.0 && (line1 - s->center).length() > s->radius) return 0;
  220. else if((line0 + dir * dot - s->center).length() > s->radius) return 0;
  221. for(int i = 0; i < s->num_triangles; i++) {
  222. if(s->silhouette->flags[i] == 0) continue;
  223. Triangle *t = &s->triangles[i];
  224. float dot = -(t->plane * vec4(line0,1)) / (vec3(t->plane) * dir);
  225. if(dot < 0.0 || dot > 1.0) continue;
  226. vec3 p = line0 + dir * dot;
  227. if(p * t->c[0] > 0.0 && p * t->c[1] > 0.0 && p * t->c[2] > 0.0) num_intersections++;
  228. }
  229. return num_intersections;
  230. }
  231. }
  232. int Mesh::renderShadowVolume(int) {
  233. fprintf(stderr,"Mesh::renderShadowVolume()n");
  234. return 0;
  235. }
  236. /*****************************************************************************/
  237. /*                                                                           */
  238. /* line inersection                                                          */
  239. /*                                                                           */
  240. /*****************************************************************************/
  241. int Mesh::intersection(const vec3 &line0,const vec3 &line1,vec3 &point,vec3 &normal,int s) {
  242. float nearest = 2.0;
  243. if(s < 0) {
  244. vec3 dir = line1 - line0;
  245. float dot = (dir * center - dir * line0) / (dir * dir);
  246. if(dot < 0.0 && (line0 - center).length() > radius) return 0;
  247. else if(dot > 1.0 && (line1 - center).length() > radius) return 0;
  248. else if((line0 + dir * dot - center).length() > radius) return 0;
  249. for(int i = 0; i < num_surfaces; i++) {
  250. Surface *s = surfaces[i];
  251. float dot = (dir * s->center - dir * line0) / (dir * dir);
  252. if(dot < 0.0 && (line0 - s->center).length() > s->radius) continue;
  253. else if(dot > 1.0 && (line1 - s->center).length() > s->radius) continue;
  254. else if((line0 + dir * dot - s->center).length() > s->radius) continue;
  255. for(int j = 0; j < s->num_triangles; j++) {
  256. Triangle *t = &s->triangles[j];
  257. float dot = -(t->plane * vec4(line0,1)) / (vec3(t->plane) * dir);
  258. if(dot < 0.0 || dot > 1.0) continue;
  259. vec3 p = line0 + dir * dot;
  260. if(nearest > dot && p * t->c[0] > 0.0 && p * t->c[1] > 0.0 && p * t->c[2] > 0.0) {
  261. nearest = dot;
  262. point = p;
  263. normal = t->plane;
  264. }
  265. }
  266. }
  267. return nearest < 2.0 ? 1 : 0;
  268. } else {
  269. Surface *surface = surfaces[s];
  270. Surface *s = surface;
  271. vec3 dir = line1 - line0;
  272. float dot = (dir * s->center - dir * line0) / (dir * dir);
  273. if(dot < 0.0 && (line0 - s->center).length() > s->radius) return 0;
  274. else if(dot > 1.0 && (line1 - s->center).length() > s->radius) return 0;
  275. else if((line0 + dir * dot - s->center).length() > s->radius) return 0;
  276. for(int i = 0; i < s->num_triangles; i++) {
  277. Triangle *t = &s->triangles[i];
  278. float dot = -(t->plane * vec4(line0,1)) / (vec3(t->plane) * dir);
  279. if(dot < 0.0 || dot > 1.0) continue;
  280. vec3 p = line0 + dir * dot;
  281. if(nearest > dot && p * t->c[0] > 0.0 && p * t->c[1] > 0.0 && p * t->c[2] > 0.0) {
  282. nearest = dot;
  283. point = p;
  284. normal = t->plane;
  285. }
  286. }
  287. return nearest < 2.0 ? 1 : 0;
  288. }
  289. }
  290. /*****************************************************************************/
  291. /*                                                                           */
  292. /* transform                                                                 */
  293. /*                                                                           */
  294. /*****************************************************************************/
  295. void Mesh::transform(const mat4 &m,int s) {
  296. mat4 r = m.rotation();
  297. if(s < 0) {
  298. for(int i = 0; i < num_surfaces; i++) {
  299. Surface *s = surfaces[i];
  300. for(int j = 0; j < s->num_vertex; j++) {
  301. Vertex *v = &s->vertex[j];
  302. v->xyz = m * v->xyz;
  303. v->normal = r * v->normal;
  304. v->normal.normalize();
  305. v->tangent = r * v->tangent;
  306. v->tangent.normalize();
  307. v->binormal = r * v->binormal;
  308. v->binormal.normalize();
  309. }
  310. for(int j = 0; j < s->num_edges; j++) {
  311. Edge *e = &s->edges[j];
  312. e->v[0] = m * e->v[0];
  313. e->v[1] = m * e->v[1];
  314. }
  315. for(int j = 0; j < s->num_triangles; j++) {
  316. Triangle *t = &s->triangles[j];
  317. t->v[0] = m * t->v[0];
  318. t->v[1] = m * t->v[1];
  319. t->v[2] = m * t->v[2];
  320. vec3 normal;
  321. normal.cross(t->v[1] - t->v[0],t->v[2] - t->v[0]);
  322. normal.normalize();
  323. t->plane = vec4(normal,-t->v[0] * normal);
  324. normal.cross(t->plane,t->v[0] - t->v[2]); // fast point in traingle
  325. normal.normalize();
  326. t->c[0] = vec4(normal,-t->v[0] * normal);
  327. normal.cross(t->plane,t->v[1] - t->v[0]);
  328. normal.normalize();
  329. t->c[1] = vec4(normal,-t->v[1] * normal);
  330. normal.cross(t->plane,t->v[2] - t->v[1]);
  331. normal.normalize();
  332. t->c[2] = vec4(normal,-t->v[2] * normal);
  333. }
  334. }
  335. } else {
  336. Surface *surface = surfaces[s];
  337. Surface *s = surface;
  338. for(int i = 0; i < s->num_vertex; i++) {
  339. Vertex *v = &s->vertex[i];
  340. v->xyz = m * v->xyz;
  341. v->normal = r * v->normal;
  342. v->normal.normalize();
  343. v->tangent = r * v->tangent;
  344. v->tangent.normalize();
  345. v->binormal = r * v->binormal;
  346. v->binormal.normalize();
  347. }
  348. for(int i = 0; i < s->num_edges; i++) {
  349. Edge *e = &s->edges[i];
  350. e->v[0] = m * e->v[0];
  351. e->v[1] = m * e->v[1];
  352. }
  353. for(int i = 0; i < s->num_triangles; i++) {
  354. Triangle *t = &s->triangles[i];
  355. t->v[0] = m * t->v[0];
  356. t->v[1] = m * t->v[1];
  357. t->v[2] = m * t->v[2];
  358. vec3 normal;
  359. normal.cross(t->v[1] - t->v[0],t->v[2] - t->v[0]);
  360. normal.normalize();
  361. t->plane = vec4(normal,-t->v[0] * normal);
  362. normal.cross(t->plane,t->v[0] - t->v[2]); // fast point in traingle
  363. normal.normalize();
  364. t->c[0] = vec4(normal,-t->v[0] * normal);
  365. normal.cross(t->plane,t->v[1] - t->v[0]);
  366. normal.normalize();
  367. t->c[1] = vec4(normal,-t->v[1] * normal);
  368. normal.cross(t->plane,t->v[2] - t->v[1]);
  369. normal.normalize();
  370. t->c[2] = vec4(normal,-t->v[2] * normal);
  371. }
  372. }
  373. calculate_bounds();
  374. }
  375. /*****************************************************************************/
  376. /*                                                                           */
  377. /* IO functions                                                              */
  378. /*                                                                           */
  379. /*****************************************************************************/
  380. /*
  381.  */
  382. int Mesh::getNumSurfaces() {
  383. return num_surfaces;
  384. }
  385. const char *Mesh::getSurfaceName(int s) {
  386. return surfaces[s]->name;
  387. }
  388. int Mesh::getSurface(const char *name) {
  389. for(int i = 0; i < num_surfaces; i++) if(!strcmp(name,surfaces[i]->name)) return i;
  390. fprintf(stderr,"Mesh::getSurface(): can`t find "%s" surfacen",name);
  391. return -1;
  392. }
  393. /*
  394.  */
  395. int Mesh::getNumVertex(int s) {
  396. return surfaces[s]->num_vertex;
  397. }
  398. Mesh::Vertex *Mesh::getVertex(int s) {
  399. return surfaces[s]->vertex;
  400. }
  401. int Mesh::getNumStrips(int s) {
  402. return surfaces[s]->num_strips;
  403. }
  404. int *Mesh::getIndices(int s) {
  405. return surfaces[s]->indices;
  406. }
  407. int Mesh::getNumEdges(int s) {
  408. return surfaces[s]->num_edges;
  409. }
  410. Mesh::Edge *Mesh::getEdges(int s) {
  411. return surfaces[s]->edges;
  412. }
  413. int Mesh::getNumTriangles(int s) {
  414. return surfaces[s]->num_triangles;
  415. }
  416. Mesh::Triangle *Mesh::getTriangles(int s) {
  417. return surfaces[s]->triangles;
  418. }
  419. /*
  420.  */
  421. const vec3 &Mesh::getMin(int s) {
  422. if(s < 0) return min;
  423. return surfaces[s]->min;
  424. }
  425. const vec3 &Mesh::getMax(int s) {
  426. if(s < 0) return max;
  427. return surfaces[s]->max;
  428. }
  429. const vec3 &Mesh::getCenter(int s) {
  430. if(s < 0) return center;
  431. return surfaces[s]->center;
  432. }
  433. float Mesh::getRadius(int s) {
  434. if(s < 0) return radius;
  435. return surfaces[s]->radius;
  436. }
  437. /* add surface
  438.  */
  439. void Mesh::addSurface(Mesh *mesh,int surface) {
  440. Surface *s = new Surface;
  441. memcpy(s,mesh->surfaces[surface],sizeof(Surface));
  442. s->vertex = new Vertex[s->num_vertex];
  443. memcpy(s->vertex,mesh->surfaces[surface]->vertex,sizeof(Vertex) * s->num_vertex);
  444. if(mesh->surfaces[surface]->edges) {
  445. s->edges = new Edge[s->num_edges];
  446. memcpy(s->edges,mesh->surfaces[surface]->edges,sizeof(Edge) * s->num_edges);
  447. }
  448. if(mesh->surfaces[surface]->triangles) {
  449. s->triangles = new Triangle[s->num_triangles];
  450. memcpy(s->triangles,mesh->surfaces[surface]->triangles,sizeof(Triangle) * s->num_triangles);
  451. }
  452. if(mesh->surfaces[surface]->indices) {
  453. s->indices = new int[s->num_indices];
  454. memcpy(s->indices,mesh->surfaces[surface]->indices,sizeof(int) * s->num_indices);
  455. }
  456. if(mesh->surfaces[surface]->silhouettes[0].vertex) {
  457. for(int j = 0; j < NUM_SILHOUETTES; j++) {
  458. s->silhouettes[j].vertex = new vec4[s->num_edges * 4];
  459. s->silhouettes[j].flags = new char[s->num_triangles];
  460. }
  461. }
  462. if(num_surfaces == NUM_SURFACES) {
  463. fprintf(stderr,"Mesh::addSurface(): many surfacesn");
  464. num_surfaces--;
  465. }
  466. surfaces[num_surfaces++] = s;
  467. calculate_bounds();
  468. }
  469. void Mesh::addSurface(const char *name,Vertex *vertex,int num_vertex) {
  470. Surface *s = new Surface;
  471. memset(s,0,sizeof(Surface));
  472. strcpy(s->name,name);
  473. s->num_vertex = num_vertex;
  474. s->vertex = new Vertex[s->num_vertex];
  475. memcpy(s->vertex,vertex,sizeof(Vertex) * s->num_vertex);
  476. if(num_surfaces == NUM_SURFACES) {
  477. fprintf(stderr,"Mesh::addSurface(): many surfacesn");
  478. num_surfaces--;
  479. }
  480. surfaces[num_surfaces++] = s;
  481. calculate_bounds();
  482. }
  483. /* load
  484.  */
  485. int Mesh::load(const char *name) {
  486. for(int i = 0; i < num_surfaces; i++) {
  487. Surface *s = surfaces[i];
  488. if(s->vertex) delete s->vertex;
  489. if(s->edges) delete s->edges;
  490. if(s->triangles) delete s->triangles;
  491. if(s->indices) delete s->indices;
  492. delete s;
  493. }
  494. if(strstr(name,".mesh")) {
  495. FILE *file = fopen(name,"rb");
  496. if(!file) {
  497. fprintf(stderr,"Mesh::load(): error open "%s" filen",name);
  498. return 0;
  499. }
  500. int magic;
  501. fread(&magic,sizeof(int),1,file);
  502. if(magic == MESH_STRIP_MAGIC) { // load mesh file
  503. load(file);
  504. fclose(file);
  505. return 1;
  506. }
  507. fclose(file);
  508. }
  509. if(strstr(name,".3ds")) load_3ds(name);
  510. else if(strstr(name,".mesh")) load_mesh(name);
  511. if(num_surfaces == 0) {
  512. fprintf(stderr,"Mesh::load(): error open "%s" filen",name);
  513. return 0;
  514. }
  515. calculate_tangent();
  516. create_shadow_volumes();
  517. create_triangle_strips();
  518. calculate_bounds();
  519. return 1;
  520. }
  521. /* save
  522.  */
  523. int Mesh::save(const char *name) {
  524. FILE *file = fopen(name,"wb");
  525. if(!file) {
  526. fprintf(stderr,"Mesh::load(): error create "%s" filen",name);
  527. return 0;
  528. }
  529. int magic = MESH_STRIP_MAGIC;
  530. fwrite(&magic,sizeof(int),1,file);
  531. save(file);
  532. fclose(file);
  533. return 1;
  534. }
  535. /* strip mesh loader
  536.  */
  537. void Mesh::load(FILE *file) {
  538. // number of surfaces
  539. int num_surfaces;
  540. fread(&num_surfaces,sizeof(int),1,file);
  541. for(int i = 0; i < num_surfaces; i++) {
  542. Surface *s = new Surface;
  543. memset(s,0,sizeof(Surface));
  544. // name
  545. fread(s->name,sizeof(s->name),1,file);
  546. // vertexes
  547. fread(&s->num_vertex,sizeof(int),1,file);
  548. s->vertex = new Vertex[s->num_vertex];
  549. fread(s->vertex,sizeof(Vertex),s->num_vertex,file);
  550. // edges
  551. fread(&s->num_edges,sizeof(int),1,file);
  552. s->edges = new Edge[s->num_edges];
  553. for(int j = 0; j < s->num_edges; j++) {
  554. Edge *e = &s->edges[j];
  555. fread(e->v,sizeof(vec3),2,file);
  556. e->reverse = 0;
  557. e->flag = 0;
  558. }
  559. // triangles
  560. fread(&s->num_triangles,sizeof(int),1,file);
  561. s->triangles = new Triangle[s->num_triangles];
  562. for(int j = 0; j < s->num_triangles; j++) {
  563. Triangle *t = &s->triangles[j];
  564. fread(t->v,sizeof(vec3),3,file);
  565. fread(t->e,sizeof(int),3,file);
  566. char reverse;
  567. fread(&reverse,sizeof(char),1,file);
  568. t->reverse[0] = reverse & (1 << 0);
  569. t->reverse[1] = reverse & (1 << 1);
  570. t->reverse[2] = reverse & (1 << 2);
  571. vec3 normal;
  572. normal.cross(t->v[1] - t->v[0],t->v[2] - t->v[0]);
  573. normal.normalize();
  574. t->plane = vec4(normal,-t->v[0] * normal);
  575. normal.cross(t->plane,t->v[0] - t->v[2]);
  576. normal.normalize();
  577. t->c[0] = vec4(normal,-t->v[0] * normal);
  578. normal.cross(t->plane,t->v[1] - t->v[0]);
  579. normal.normalize();
  580. t->c[1] = vec4(normal,-t->v[1] * normal);
  581. normal.cross(t->plane,t->v[2] - t->v[1]);
  582. normal.normalize();
  583. t->c[2] = vec4(normal,-t->v[2] * normal);
  584. }
  585. // indices
  586. fread(&s->num_indices,sizeof(int),1,file);
  587. fread(&s->num_strips,sizeof(int),1,file);
  588. s->indices = new int[s->num_indices];
  589. if(s->num_indices < 65536) {
  590. unsigned short *buf = new unsigned short[s->num_indices];
  591. fread(buf,sizeof(unsigned short),s->num_indices,file);
  592. for(int j = 0; j < s->num_indices; j++) s->indices[j] = buf[j];
  593. delete buf;
  594. } else fread(s->indices,sizeof(int),s->num_indices,file);
  595. // shadow volume vertexes
  596. for(int j = 0; j < NUM_SILHOUETTES; j++) {
  597. s->silhouettes[j].vertex = new vec4[s->num_edges * 4];
  598. s->silhouettes[j].flags = new char[s->num_triangles];
  599. }
  600. if(this->num_surfaces == NUM_SURFACES) {
  601. fprintf(stderr,"Mesh::load(): many surfacesn");
  602. this->num_surfaces--;
  603. }
  604. surfaces[this->num_surfaces++] = s;
  605. }
  606. calculate_bounds();
  607. }
  608. /* strip mesh saver
  609.  */
  610. void Mesh::save(FILE *file) {
  611. fwrite(&num_surfaces,sizeof(int),1,file);
  612. for(int i = 0; i < num_surfaces; i++) {
  613. Surface *s = surfaces[i];
  614. fwrite(s->name,sizeof(s->name),1,file);
  615. // vertexes
  616. fwrite(&s->num_vertex,sizeof(int),1,file);
  617. fwrite(s->vertex,sizeof(Vertex),s->num_vertex,file);
  618. // edges
  619. fwrite(&s->num_edges,sizeof(int),1,file);
  620. for(int j = 0; j < s->num_edges; j++) {
  621. fwrite(s->edges[j].v,sizeof(vec3),2,file);
  622. }
  623. // triangles
  624. fwrite(&s->num_triangles,sizeof(int),1,file);
  625. for(int j = 0; j < s->num_triangles; j++) {
  626. fwrite(s->triangles[j].v,sizeof(vec3),3,file);
  627. fwrite(s->triangles[j].e,sizeof(int),3,file);
  628. char reverse = (s->triangles[j].reverse[2] << 2) | (s->triangles[j].reverse[1] << 1) | (s->triangles[j].reverse[0] << 0);
  629. fwrite(&reverse,sizeof(char),1,file);
  630. }
  631. // indices
  632. fwrite(&s->num_indices,sizeof(int),1,file);
  633. fwrite(&s->num_strips,sizeof(int),1,file);
  634. if(s->num_indices < 65536) {
  635. unsigned short *buf = new unsigned short[s->num_indices];
  636. for(int j = 0; j < s->num_indices; j++) buf[j] = (unsigned int)s->indices[j];
  637. fwrite(buf,sizeof(unsigned short),s->num_indices,file);
  638. delete buf;
  639. } else fwrite(s->indices,sizeof(int),s->num_indices,file);
  640. }
  641. }
  642. /*****************************************************************************/
  643. /*                                                                           */
  644. /* raw mesh loader                                                           */
  645. /*                                                                           */
  646. /*****************************************************************************/
  647. struct load_mesh_Vertex {
  648. vec3 xyz;
  649. vec3 normal;
  650. vec2 texcoord;
  651. };
  652. int Mesh::load_mesh(const char *name) {
  653. FILE *file = fopen(name,"rb");
  654. if(!file) {
  655. fprintf(stderr,"Mesh::load_mesh(): error open "%s" filen",name);
  656. return 0;
  657. }
  658. int magic;
  659. // mesh magic raw
  660. fread(&magic,sizeof(int),1,file);
  661. if(magic != MESH_RAW_MAGIC) {
  662. fprintf(stderr,"Mesh::load_mesh(): wrong magic 0x%04x in "%s" filen",magic,name);
  663. fclose(file);
  664. return 0;
  665. }
  666. // number of surfaces
  667. int num_surfaces;
  668. fread(&num_surfaces,sizeof(int),1,file);
  669. for(int i = 0; i < num_surfaces; i++) {
  670. Surface *s = new Surface;
  671. memset(s,0,sizeof(Surface));
  672. // name
  673. fread(s->name,sizeof(s->name),1,file);
  674. // vertexes
  675. int num_vertex;
  676. fread(&num_vertex,sizeof(int),1,file);
  677. load_mesh_Vertex *vertex = new load_mesh_Vertex[num_vertex];
  678. fread(vertex,sizeof(load_mesh_Vertex),num_vertex,file);
  679. s->vertex = new Vertex[num_vertex];
  680. for(int j = 0; j < num_vertex; j += 3) {
  681. if(vertex[j + 0].xyz == vertex[j + 1].xyz) continue; // skip degenerate triangles
  682. if(vertex[j + 1].xyz == vertex[j + 2].xyz) continue;
  683. if(vertex[j + 2].xyz == vertex[j + 0].xyz) continue;
  684. for(int k = 0; k < 3; k++) {
  685. s->vertex[s->num_vertex + k].xyz = vertex[j + k].xyz;
  686. s->vertex[s->num_vertex + k].normal = vertex[j + k].normal;
  687. s->vertex[s->num_vertex + k].texcoord = vertex[j + k].texcoord;
  688. }
  689. s->num_vertex += 3;
  690. }
  691. delete vertex;
  692. if(this->num_surfaces == NUM_SURFACES) {
  693. fprintf(stderr,"Mesh::load_mesh(): many surfacesn");
  694. this->num_surfaces--;
  695. }
  696. surfaces[this->num_surfaces++] = s;
  697. }
  698. fclose(file);
  699. return 1;
  700. }
  701. /*****************************************************************************/
  702. /*                                                                           */
  703. /* 3ds loader                                                                */
  704. /*                                                                           */
  705. /*****************************************************************************/
  706. enum {
  707. LOAD_3DS_CHUNK_MAIN = 0x4d4d,
  708. LOAD_3DS_CHUNK_OBJMESH = 0x3d3d,
  709. LOAD_3DS_CHUNK_OBJBLOCK = 0x4000,
  710. LOAD_3DS_CHUNK_TRIMESH = 0x4100,
  711. LOAD_3DS_CHUNK_VERTLIST = 0x4110,
  712. LOAD_3DS_CHUNK_FACELIST = 0x4120,
  713. LOAD_3DS_CHUNK_MAPLIST = 0x4140,
  714. LOAD_3DS_CHUNK_SMOOTHLIST = 0x4150
  715. };
  716. struct load_3ds_trimesh {
  717. vec3 *vertex;
  718. int num_vertex;
  719. vec2 *texcoord;
  720. int num_texcoord;
  721. int *face;
  722. int *smoothgroup;
  723. int num_face;
  724. vec3 *normal;
  725. };
  726. struct load_3ds_objblock {
  727. char *name;
  728. load_3ds_trimesh **trimesh;
  729. int num_trimesh;
  730. };
  731. struct load_3ds_mesh {
  732. load_3ds_objblock **objblock;
  733. int num_objblock;
  734. };
  735. typedef int (*load_3ds_process_chunk)(FILE *file,int type,int size,void *data);
  736. static int load_3ds_skeep_bytes(FILE *file,int bytes) {
  737. fseek(file,bytes,SEEK_CUR);
  738. return bytes;
  739. }
  740. static int load_3ds_read_string(FILE *file,char *string) {
  741. int i = 0;
  742. char *s = string;
  743. while((*s++ = fgetc(file)) != '') i++;
  744. return ++i;
  745. }
  746. static int load_3ds_read_ushort(FILE *file) {
  747. unsigned short ret;
  748. fread(&ret,1,sizeof(unsigned short),file);
  749. return ret;
  750. }
  751. static int load_3ds_read_int(FILE *file) {
  752. int ret;
  753. fread(&ret,1,sizeof(int),file);
  754. return ret;
  755. }
  756. static float load_3ds_read_float(FILE *file) {
  757. float ret;
  758. fread(&ret,1,sizeof(float),file);
  759. return ret;
  760. }
  761. static int load_3ds_read_chunk(FILE *file,load_3ds_process_chunk func,void *data) {
  762. int type = load_3ds_read_ushort(file);
  763. int size = load_3ds_read_int(file);
  764. if(func(file,type,size - 6,data) == 0) load_3ds_skeep_bytes(file,size - 6);
  765. return size;
  766. }
  767. static int load_3ds_read_chunks(FILE *file,int bytes,load_3ds_process_chunk func,void *data) {
  768. int bytes_read = 0;
  769. while(bytes_read < bytes) bytes_read += load_3ds_read_chunk(file,func,data);
  770. if(bytes_read != bytes) fprintf(stderr,"Mesh::load_3ds(): expected %d bytes but read %dn",bytes,bytes_read);
  771. return bytes_read;
  772. }
  773. static int load_3ds_process_smoothlist(FILE *file,int type,int size,void *data) {
  774. if(type == LOAD_3DS_CHUNK_SMOOTHLIST) {
  775. load_3ds_trimesh *t = (load_3ds_trimesh*)data;
  776. t->smoothgroup = new int[t->num_face];
  777. for(int i = 0; i < t->num_face; i++) t->smoothgroup[i] = load_3ds_read_int(file);
  778. return 1;
  779. }
  780. return 0;
  781. }
  782. static int load_3ds_process_trimesh(FILE *file,int type,int size,void *data) {
  783. load_3ds_trimesh *t = (load_3ds_trimesh*)data;
  784. if(type == LOAD_3DS_CHUNK_VERTLIST) {
  785. t->num_vertex = load_3ds_read_ushort(file);
  786. t->vertex = new vec3[t->num_vertex];
  787. for(int i = 0; i < t->num_vertex; i++) {
  788. t->vertex[i].x = load_3ds_read_float(file);
  789. t->vertex[i].y = load_3ds_read_float(file);
  790. t->vertex[i].z = load_3ds_read_float(file);
  791. }
  792. return 1;
  793. } else if(type == LOAD_3DS_CHUNK_MAPLIST) {
  794. t->num_texcoord = load_3ds_read_ushort(file);
  795. t->texcoord = new vec2[t->num_texcoord];
  796. for(int i = 0; i < t->num_texcoord; i++) {
  797. t->texcoord[i].x = load_3ds_read_float(file);
  798. t->texcoord[i].y = 1.0f - load_3ds_read_float(file);
  799. }
  800. return 1;
  801. } else if(type == LOAD_3DS_CHUNK_FACELIST) {
  802. int bytes_left;
  803. t->num_face = load_3ds_read_ushort(file);
  804. t->face = new int[t->num_face * 3];
  805. for(int i = 0; i < t->num_face * 3; i += 3) {
  806. t->face[i + 0] = load_3ds_read_ushort(file);
  807. t->face[i + 1] = load_3ds_read_ushort(file);
  808. t->face[i + 2] = load_3ds_read_ushort(file);
  809. load_3ds_read_ushort(file);
  810. }
  811. bytes_left = size - t->num_face * sizeof(unsigned short) * 4 - 2;
  812. if(bytes_left > 0) load_3ds_read_chunks(file,bytes_left,load_3ds_process_smoothlist,t);
  813. return 1;
  814. }
  815. return 0;
  816. }
  817. static int load_3ds_process_objblock(FILE *file,int type,int size,void *data) {
  818. if(type == LOAD_3DS_CHUNK_TRIMESH) {
  819. load_3ds_objblock *o = (load_3ds_objblock*)data;
  820. o->num_trimesh++;
  821. o->trimesh = (load_3ds_trimesh**)realloc(o->trimesh,sizeof(load_3ds_trimesh) * o->num_trimesh);
  822. o->trimesh[o->num_trimesh - 1] = new load_3ds_trimesh;
  823. load_3ds_trimesh *t = o->trimesh[o->num_trimesh - 1];
  824. memset(t,0,sizeof(load_3ds_trimesh));
  825. load_3ds_read_chunks(file,size,load_3ds_process_trimesh,t);
  826. return 1;
  827. }
  828. return 0;
  829. }
  830. static int load_3ds_process_objmesh(FILE *file,int type,int size,void *data) {
  831. if(type == LOAD_3DS_CHUNK_OBJBLOCK) {
  832. char name[256];
  833. size -= load_3ds_read_string(file,name);
  834. load_3ds_mesh *m = (load_3ds_mesh*)data;
  835. m->num_objblock++;
  836. m->objblock = (load_3ds_objblock**)realloc(m->objblock,sizeof(load_3ds_objblock) * m->num_objblock);
  837. m->objblock[m->num_objblock - 1] = new load_3ds_objblock;
  838. load_3ds_objblock *o = m->objblock[m->num_objblock - 1];
  839. memset(o,0,sizeof(load_3ds_objblock));
  840. o->name = strdup(name);
  841. load_3ds_read_chunks(file,size,load_3ds_process_objblock,o);
  842. return 1;
  843. }
  844. return 0;
  845. }
  846. static int load_3ds_process_main(FILE *file,int type,int size,void *data) {
  847. if(type == LOAD_3DS_CHUNK_OBJMESH) {
  848. load_3ds_read_chunks(file,size,load_3ds_process_objmesh,data);
  849. return 1;
  850. }
  851. return 0;
  852. }
  853. static void load_3ds_trimesh_calculate_normals(load_3ds_trimesh *t) {
  854. vec3 *normal_face = new vec3[t->num_face];
  855. int *vertex_count = new int[t->num_vertex];
  856. memset(vertex_count,0,sizeof(int) * t->num_vertex);
  857. int **vertex_face = new int*[t->num_vertex];
  858. t->normal = new vec3[t->num_face * 3];
  859. memset(t->normal,0,sizeof(vec3) * t->num_face * 3);
  860. if(t->texcoord == NULL) {
  861. t->num_texcoord = t->num_vertex;
  862. t->texcoord = new vec2[t->num_vertex];
  863. memset(t->texcoord,0,sizeof(vec2) * t->num_vertex);
  864. }
  865. for(int i = 0, j = 0; i < t->num_face; i++, j += 3) {
  866. int v0 = t->face[j + 0];
  867. int v1 = t->face[j + 1];
  868. int v2 = t->face[j + 2];
  869. vertex_count[v0]++;
  870. vertex_count[v1]++;
  871. vertex_count[v2]++;
  872. normal_face[i].cross(t->vertex[v1] - t->vertex[v0],t->vertex[v2] - t->vertex[v0]);
  873. normal_face[i].normalize();
  874. }
  875. for(int i = 0; i < t->num_vertex; i++) {
  876. vertex_face[i] = new int[vertex_count[i] + 1];
  877. vertex_face[i][0] = vertex_count[i];
  878. }
  879. for(int i = 0, j = 0; i < t->num_face; i++, j += 3) {
  880. int v0 = t->face[j + 0];
  881. int v1 = t->face[j + 1];
  882. int v2 = t->face[j + 2];
  883. vertex_face[v0][vertex_count[v0]--] = i;
  884. vertex_face[v1][vertex_count[v1]--] = i;
  885. vertex_face[v2][vertex_count[v2]--] = i;
  886. }
  887. for(int i = 0, j = 0; i < t->num_face; i++, j += 3) {
  888. int v0 = t->face[j + 0];
  889. int v1 = t->face[j + 1];
  890. int v2 = t->face[j + 2];
  891. for(int k = 1; k <= vertex_face[v0][0]; k++) {
  892. int l = vertex_face[v0][k];
  893. if(l == i || (t->smoothgroup && t->smoothgroup[i] & t->smoothgroup[l])) t->normal[j + 0] += normal_face[l];
  894. }
  895. for(int k = 1; k <= vertex_face[v1][0]; k++) {
  896. int l = vertex_face[v1][k];
  897. if(l == i || (t->smoothgroup && t->smoothgroup[i] & t->smoothgroup[l])) t->normal[j + 1] += normal_face[l];
  898. }
  899. for(int k = 1; k <= vertex_face[v2][0]; k++) {
  900. int l = vertex_face[v2][k];
  901. if(l == i || (t->smoothgroup && t->smoothgroup[i] & t->smoothgroup[l])) t->normal[j + 2] += normal_face[l];
  902. }
  903. }
  904. for(int i = 0; i < t->num_face * 3; i++) t->normal[i].normalize();
  905. for(int i = 0; i < t->num_vertex; i++) delete vertex_face[i];
  906. delete vertex_face;
  907. delete vertex_count;
  908. delete normal_face;
  909. }
  910. /*
  911.  */
  912. int Mesh::load_3ds(const char *name) {
  913. FILE *file;
  914. file = fopen(name,"rb");
  915. if(!file) {
  916. fprintf(stderr,"Mesh::load_3ds(): error open "%s" filen",name);
  917. return 0;
  918. }
  919. int type = load_3ds_read_ushort(file);
  920. int size = load_3ds_read_int(file);
  921. if(type != LOAD_3DS_CHUNK_MAIN) {
  922. fprintf(stderr,"Mesh::load_3ds(): wrong main chunk in "%s" filen",name);
  923. fclose(file);
  924. return 0;
  925. }
  926. load_3ds_mesh *m = new load_3ds_mesh;
  927. memset(m,0,sizeof(load_3ds_mesh));
  928. load_3ds_read_chunks(file,size - 6,load_3ds_process_main,m);
  929. fclose(file);
  930. for(int i = 0; i < m->num_objblock; i++) {
  931. load_3ds_objblock *o = m->objblock[i];
  932. Surface *s = new Surface;
  933. memset(s,0,sizeof(Surface));
  934. // name
  935. strcpy(s->name,m->objblock[i]->name);
  936. free(m->objblock[i]->name);
  937. // calculate number of vertexes
  938. int num_objblock_vertex = 0;
  939. for(int j = 0; j < o->num_trimesh; j++) {
  940. num_objblock_vertex += o->trimesh[j]->num_face * 3;
  941. load_3ds_trimesh_calculate_normals(o->trimesh[j]);
  942. }
  943. s->num_vertex = num_objblock_vertex;
  944. s->vertex = new Vertex[s->num_vertex];
  945. // copy vertexes
  946. num_objblock_vertex = 0;
  947. for(int j = 0; j < o->num_trimesh; j++) {
  948. load_3ds_trimesh *t = o->trimesh[j];
  949. for(int k = 0, l = 0; k < t->num_face; k++, l += 3) {
  950. Vertex *v = s->vertex + num_objblock_vertex + l;
  951. v[0].xyz = t->vertex[t->face[l + 0]];
  952. v[1].xyz = t->vertex[t->face[l + 1]];
  953. v[2].xyz = t->vertex[t->face[l + 2]];
  954. v[0].texcoord = t->texcoord[t->face[l + 0]];
  955. v[1].texcoord = t->texcoord[t->face[l + 1]];
  956. v[2].texcoord = t->texcoord[t->face[l + 2]];
  957. v[0].normal = t->normal[l + 0];
  958. v[1].normal = t->normal[l + 1];
  959. v[2].normal = t->normal[l + 2];
  960. }
  961. num_objblock_vertex += t->num_face * 3;
  962. delete t->vertex;
  963. delete t->texcoord;
  964. delete t->face;
  965. if(t->smoothgroup) delete t->smoothgroup;
  966. delete t->normal;
  967. delete t;
  968. }
  969. free(o->trimesh);
  970. delete o;
  971. if(num_surfaces == NUM_SURFACES) {
  972. fprintf(stderr,"Mesh::load_3ds(): many surfacesn");
  973. num_surfaces--;
  974. }
  975. surfaces[num_surfaces++] = s;
  976. }
  977. free(m->objblock);
  978. delete m;
  979. return 1;
  980. }
  981. /*****************************************************************************/
  982. /*                                                                           */
  983. /* calculate tangent                                                         */
  984. /*                                                                           */
  985. /*****************************************************************************/
  986. void Mesh::calculate_tangent() {
  987. for(int i = 0; i < num_surfaces; i++) {
  988. Surface *s = surfaces[i];
  989. for(int j = 0; j < s->num_vertex; j += 3) {
  990. Vertex *v0 = &s->vertex[j + 0];
  991. Vertex *v1 = &s->vertex[j + 1];
  992. Vertex *v2 = &s->vertex[j + 2];
  993. vec3 normal,tangent,binormal;
  994. vec3 e0 = vec3(0,v1->texcoord.x - v0->texcoord.x,v1->texcoord.y - v0->texcoord.y);
  995. vec3 e1 = vec3(0,v2->texcoord.x - v0->texcoord.x,v2->texcoord.y - v0->texcoord.y);
  996. for(int k = 0; k < 3; k++) {
  997. e0.x = v1->xyz[k] - v0->xyz[k];
  998. e1.x = v2->xyz[k] - v0->xyz[k];
  999. vec3 v;
  1000. v.cross(e0,e1);
  1001. if(fabs(v[0]) > EPSILON) {
  1002. tangent[k] = -v[1] / v[0];
  1003. binormal[k] = -v[2] / v[0];
  1004. } else {
  1005. tangent[k] = 0;
  1006. binormal[k] = 0;
  1007. }
  1008. }
  1009. tangent.normalize();
  1010. binormal.normalize();
  1011. normal.cross(tangent,binormal);
  1012. normal.normalize();
  1013. v0->binormal.cross(v0->normal,tangent);
  1014. v0->binormal.normalize();
  1015. v0->tangent.cross(v0->binormal,v0->normal);
  1016. if(normal * v0->normal < 0) v0->binormal = -v0->binormal;
  1017. v1->binormal.cross(v1->normal,tangent);
  1018. v1->binormal.normalize();
  1019. v1->tangent.cross(v1->binormal,v1->normal);
  1020. if(normal * v1->normal < 0) v1->binormal = -v1->binormal;
  1021. v2->binormal.cross(v2->normal,tangent);
  1022. v2->binormal.normalize();
  1023. v2->tangent.cross(v2->binormal,v2->normal);
  1024. if(normal * v2->normal < 0) v2->binormal = -v2->binormal;
  1025. }
  1026. }
  1027. }
  1028. /*****************************************************************************/
  1029. /*                                                                           */
  1030. /* calculate bounds                                                          */
  1031. /*                                                                           */
  1032. /*****************************************************************************/
  1033. void Mesh::calculate_bounds() {
  1034. min = vec3(1000000,1000000,1000000);
  1035. max = vec3(-1000000,-1000000,-1000000);
  1036. for(int i = 0; i < num_surfaces; i++) {
  1037. Surface *s = surfaces[i];
  1038. s->min = vec3(1000000,1000000,1000000);
  1039. s->max = vec3(-1000000,-1000000,-1000000);
  1040. for(int j = 0; j < s->num_vertex; j++) {
  1041. if(s->max.x < s->vertex[j].xyz.x) s->max.x = s->vertex[j].xyz.x;
  1042. if(s->min.x > s->vertex[j].xyz.x) s->min.x = s->vertex[j].xyz.x;
  1043. if(s->max.y < s->vertex[j].xyz.y) s->max.y = s->vertex[j].xyz.y;
  1044. if(s->min.y > s->vertex[j].xyz.y) s->min.y = s->vertex[j].xyz.y;
  1045. if(s->max.z < s->vertex[j].xyz.z) s->max.z = s->vertex[j].xyz.z;
  1046. if(s->min.z > s->vertex[j].xyz.z) s->min.z = s->vertex[j].xyz.z;
  1047. }
  1048. s->center = (s->min + s->max) / 2.0f;
  1049. s->radius = 0;
  1050. if(max.x < s->max.x) max.x = s->max.x;
  1051. if(min.x > s->min.x) min.x = s->min.x;
  1052. if(max.y < s->max.y) max.y = s->max.y;
  1053. if(min.y > s->min.y) min.y = s->min.y;
  1054. if(max.z < s->max.z) max.z = s->max.z;
  1055. if(min.z > s->min.z) min.z = s->min.z;
  1056. }
  1057. center = (min + max) / 2.0f;
  1058. radius = 0;
  1059. for(int i = 0; i < num_surfaces; i++) {
  1060. Surface *s = surfaces[i];
  1061. for(int j = 0; j < s->num_vertex; j++) {
  1062. float r = (s->center - s->vertex[j].xyz).length();
  1063. if(r > s->radius) s->radius = r;
  1064. r = (center - s->vertex[j].xyz).length();
  1065. if(r > radius) radius = r;
  1066. }
  1067. }
  1068. }
  1069. /*****************************************************************************/
  1070. /*                                                                           */
  1071. /* create shadow volume                                                      */
  1072. /*                                                                           */
  1073. /*****************************************************************************/
  1074. struct csv_Vertex {
  1075. vec3 xyz;
  1076. int id;
  1077. };
  1078. struct csv_Edge {
  1079. int v[2];
  1080. int id;
  1081. };
  1082. static int csv_vertex_cmp(const void *a,const void *b) {
  1083. csv_Vertex *v0 = (csv_Vertex*)a;
  1084. csv_Vertex *v1 = (csv_Vertex*)b;
  1085. float d;
  1086. d = v0->xyz[0] - v1->xyz[0];
  1087. if(d > EPSILON) return 1;
  1088. if(d < -EPSILON) return -1;
  1089. d = v0->xyz[1] - v1->xyz[1];
  1090. if(d > EPSILON) return 1;
  1091. if(d < -EPSILON) return -1;
  1092. d = v0->xyz[2] - v1->xyz[2];
  1093. if(d > EPSILON) return 1;
  1094. if(d < -EPSILON) return -1;
  1095. return 0;
  1096. }
  1097. static int csv_edge_cmp(const void *a,const void *b) {
  1098. csv_Edge *e0 = (csv_Edge*)a;
  1099. csv_Edge *e1 = (csv_Edge*)b;
  1100. int v[2][2];
  1101. if(e0->v[0] < e0->v[1]) { v[0][0] = e0->v[0]; v[0][1] = e0->v[1]; }
  1102. else { v[0][0] = e0->v[1]; v[0][1] = e0->v[0]; }
  1103. if(e1->v[0] < e1->v[1]) { v[1][0] = e1->v[0]; v[1][1] = e1->v[1]; }
  1104. else { v[1][0] = e1->v[1]; v[1][1] = e1->v[0]; }
  1105. if(v[0][0] > v[1][0]) return 1;
  1106. if(v[0][0] < v[1][0]) return -1;
  1107. if(v[0][1] > v[1][1]) return 1;
  1108. if(v[0][1] < v[1][1]) return -1;
  1109. return 0;
  1110. }
  1111. void Mesh::create_shadow_volumes() {
  1112. for(int i = 0; i < num_surfaces; i++) {
  1113. Surface *s = surfaces[i];
  1114. s->num_edges = s->num_vertex;
  1115. s->num_triangles = s->num_vertex / 3;
  1116. // cerate vertexes
  1117. csv_Vertex *v = new csv_Vertex[s->num_vertex];
  1118. for(int j = 0; j < s->num_vertex; j++) {
  1119. v[j].xyz = s->vertex[j].xyz;
  1120. v[j].id = j;
  1121. }
  1122. qsort(v,s->num_vertex,sizeof(csv_Vertex),csv_vertex_cmp);
  1123. int num_optimized_vertex = 0;
  1124. int *vbuf = new int[s->num_vertex];
  1125. for(int j = 0; j < s->num_vertex; j++) {
  1126. if(j == 0 || csv_vertex_cmp(&v[num_optimized_vertex - 1],&v[j])) v[num_optimized_vertex++] = v[j];
  1127. vbuf[v[j].id] = num_optimized_vertex - 1;
  1128. }
  1129. // create edges
  1130. csv_Edge *e = new csv_Edge[s->num_edges];
  1131. for(int j = 0; j < s->num_edges; j += 3) {
  1132. e[j + 0].v[0] = vbuf[j + 0];
  1133. e[j + 0].v[1] = vbuf[j + 1];
  1134. e[j + 1].v[0] = vbuf[j + 1];
  1135. e[j + 1].v[1] = vbuf[j + 2];
  1136. e[j + 2].v[0] = vbuf[j + 2];
  1137. e[j + 2].v[1] = vbuf[j + 0];
  1138. e[j + 0].id = j + 0;
  1139. e[j + 1].id = j + 1;
  1140. e[j + 2].id = j + 2;
  1141. }
  1142. qsort(e,s->num_edges,sizeof(csv_Edge),csv_edge_cmp);
  1143. int num_optimized_edges = 0;
  1144. int *ebuf = new int[s->num_edges];
  1145. int *rbuf = new int[s->num_edges];
  1146. for(int j = 0; j < s->num_edges; j++) {
  1147. if(j == 0 || csv_edge_cmp(&e[num_optimized_edges - 1],&e[j])) e[num_optimized_edges++] = e[j];
  1148. ebuf[e[j].id] = num_optimized_edges - 1;
  1149. rbuf[e[j].id] = e[num_optimized_edges - 1].v[0] != e[j].v[0];
  1150. }
  1151. // final
  1152. s->num_edges = num_optimized_edges;
  1153. s->edges = new Edge[s->num_edges];
  1154. for(int j = 0; j < s->num_edges; j++) {
  1155. s->edges[j].v[0] = v[e[j].v[0]].xyz;
  1156. s->edges[j].v[1] = v[e[j].v[1]].xyz;
  1157. s->edges[j].reverse = 0;
  1158. s->edges[j].flag = 0;
  1159. }
  1160. // triangles
  1161. s->triangles = new Triangle[s->num_triangles];
  1162. for(int j = 0, k = 0; j < s->num_triangles; j++, k += 3) {
  1163. Triangle *t = &s->triangles[j];
  1164. t->v[0] = v[vbuf[k + 0]].xyz;
  1165. t->v[1] = v[vbuf[k + 1]].xyz;
  1166. t->v[2] = v[vbuf[k + 2]].xyz;
  1167. t->e[0] = ebuf[k + 0];
  1168. t->e[1] = ebuf[k + 1];
  1169. t->e[2] = ebuf[k + 2];
  1170. t->reverse[0] = rbuf[k + 0];
  1171. t->reverse[1] = rbuf[k + 1];
  1172. t->reverse[2] = rbuf[k + 2];
  1173. vec3 normal;
  1174. normal.cross(t->v[1] - t->v[0],t->v[2] - t->v[0]);
  1175. normal.normalize();
  1176. t->plane = vec4(normal,-t->v[0] * normal);
  1177. normal.cross(t->plane,t->v[0] - t->v[2]); // fast point in traingle
  1178. normal.normalize();
  1179. t->c[0] = vec4(normal,-t->v[0] * normal);
  1180. normal.cross(t->plane,t->v[1] - t->v[0]);
  1181. normal.normalize();
  1182. t->c[1] = vec4(normal,-t->v[1] * normal);
  1183. normal.cross(t->plane,t->v[2] - t->v[1]);
  1184. normal.normalize();
  1185. t->c[2] = vec4(normal,-t->v[2] * normal);
  1186. }
  1187. // shadow volume vertexes
  1188. for(int j = 0; j < NUM_SILHOUETTES; j++) {
  1189. s->silhouettes[j].vertex = new vec4[s->num_edges * 4];
  1190. s->silhouettes[j].flags = new char[s->num_triangles];
  1191. }
  1192. delete rbuf;
  1193. delete ebuf;
  1194. delete e;
  1195. delete v;
  1196. }
  1197. }
  1198. /*****************************************************************************/
  1199. /*                                                                           */
  1200. /* create triangle strips                                                    */
  1201. /*                                                                           */
  1202. /*****************************************************************************/
  1203. struct cts_Vertex {
  1204. Mesh::Vertex v;
  1205. int face;
  1206. int num;
  1207. int id;
  1208. };
  1209. struct cts_Edge {
  1210. int v[2];
  1211. int face;
  1212. int num;
  1213. };
  1214. struct cts_Triangle {
  1215. int v[3];
  1216. int env[3];
  1217. int flag;
  1218. };
  1219. static int cts_vertex_cmp(const void *a,const void *b) {
  1220. cts_Vertex *ctsv0 = (cts_Vertex*)a;
  1221. cts_Vertex *ctsv1 = (cts_Vertex*)b;
  1222. Mesh::Vertex *v0 = &ctsv0->v;
  1223. Mesh::Vertex *v1 = &ctsv1->v;
  1224. float d;
  1225. #define CMP(a,b,e) { 
  1226. d = (a)[0] - (b)[0]; 
  1227. if(d > e) return 1; 
  1228. if(d < -e) return -1; 
  1229. d = (a)[1] - (b)[1]; 
  1230. if(d > e) return 1; 
  1231. if(d < -e) return -1; 
  1232. d = (a)[2] - (b)[2]; 
  1233. if(d > e) return 1; 
  1234. if(d < -e) return -1; 
  1235. }
  1236. CMP(v0->xyz,v1->xyz,EPSILON)
  1237. CMP(v0->normal,v1->normal,EPSILON)
  1238. //CMP(v0->tangent,v1->tangent,0.1)
  1239. //CMP(v0->binormal,v1->binormal,0.1)
  1240. #undef CMP
  1241. d = v0->texcoord[0] - v1->texcoord[0];
  1242. if(d > EPSILON) return 1;
  1243. if(d < -EPSILON) return -1;
  1244. d = v0->texcoord[1] - v1->texcoord[1];
  1245. if(d > EPSILON) return 1;
  1246. if(d < -EPSILON) return -1;
  1247. return 0;
  1248. }
  1249. static int cts_edge_cmp(const void *a,const void *b) {
  1250. cts_Edge *e0 = (cts_Edge*)a;
  1251. cts_Edge *e1 = (cts_Edge*)b;
  1252. int v[2][2];
  1253. if(e0->v[0] < e0->v[1]) { v[0][0] = e0->v[0]; v[0][1] = e0->v[1]; }
  1254. else { v[0][0] = e0->v[1]; v[0][1] = e0->v[0]; }
  1255. if(e1->v[0] < e1->v[1]) { v[1][0] = e1->v[0]; v[1][1] = e1->v[1]; }
  1256. else { v[1][0] = e1->v[1]; v[1][1] = e1->v[0]; }
  1257. if(v[0][0] > v[1][0]) return 1;
  1258. if(v[0][0] < v[1][0]) return -1;
  1259. if(v[0][1] > v[1][1]) return 1;
  1260. if(v[0][1] < v[1][1]) return -1;
  1261. return 0;
  1262. }
  1263. void Mesh::create_triangle_strips() {
  1264. for(int i = 0; i < num_surfaces; i++) {
  1265. Surface *s = surfaces[i];
  1266. s->num_indices = 0; // already is zero
  1267. s->num_strips = 0;
  1268. s->indices = new int[s->num_vertex * 4 / 3];
  1269. cts_Vertex *v = new cts_Vertex[s->num_vertex];
  1270. cts_Edge *e = new cts_Edge[s->num_vertex];
  1271. cts_Triangle *t = new cts_Triangle[s->num_vertex / 3];
  1272. // create vertexes
  1273. for(int j = 0; j < s->num_vertex; j++) {
  1274. v[j].v = s->vertex[j];
  1275. v[j].face = j / 3;
  1276. v[j].num = j % 3;
  1277. v[j].id = j;
  1278. }
  1279. qsort(v,s->num_vertex,sizeof(cts_Vertex),cts_vertex_cmp);
  1280. int num_optimized_vertex = 0;
  1281. int *vbuf = new int[s->num_vertex];
  1282. for(int j = 0; j < s->num_vertex; j++) {
  1283. if(j == 0 || cts_vertex_cmp(&v[num_optimized_vertex - 1],&v[j])) v[num_optimized_vertex++] = v[j];
  1284. t[v[j].face].v[v[j].num] = num_optimized_vertex - 1;
  1285. vbuf[v[j].id] = num_optimized_vertex - 1;
  1286. }
  1287. // create edges
  1288. for(int j = 0; j < s->num_vertex; j += 3) {
  1289. e[j + 0].v[0] = vbuf[j + 1];
  1290. e[j + 0].v[1] = vbuf[j + 2];
  1291. e[j + 1].v[0] = vbuf[j + 0];
  1292. e[j + 1].v[1] = vbuf[j + 2];
  1293. e[j + 2].v[0] = vbuf[j + 0];
  1294. e[j + 2].v[1] = vbuf[j + 1];
  1295. e[j + 0].face = e[j + 1].face = e[j + 2].face = j / 3;
  1296. e[j + 0].num = 0;
  1297. e[j + 1].num = 1;
  1298. e[j + 2].num = 2;
  1299. }
  1300. delete vbuf;
  1301. qsort(e,s->num_vertex,sizeof(cts_Edge),cts_edge_cmp);
  1302. // create triangles
  1303. for(int j = 0; j < s->num_vertex / 3; j++) {
  1304. t[j].env[0] = t[j].env[1] = t[j].env[2] = -1;
  1305. t[j].flag = 0;
  1306. }
  1307. // find triangle environment
  1308. for(int j = 0, k = 0; j < s->num_vertex; j++) {
  1309. if(j == 0 || cts_edge_cmp(&e[k],&e[j])) k = j;
  1310. if(j != k) {
  1311. t[e[j].face].env[e[j].num] = e[k].face;
  1312. t[e[k].face].env[e[k].num] = e[j].face;
  1313. }
  1314. }
  1315. delete e;
  1316. // create triangle strips
  1317. for(int j = 0; j < s->num_vertex / 3; j++) {
  1318. if(t[j].v[0] == t[j].v[1] || t[j].v[1] == t[j].v[2] || t[j].v[2] == t[j].v[0]) t[j].flag = 1;
  1319. }
  1320. int *indices = s->indices;
  1321. for(int j = 0; j < s->num_vertex / 3; j++) {
  1322. if(!t[j].flag) {
  1323. s->num_strips++;
  1324. int env;
  1325. for(env = 0; env < 3; env++) if(t[j].env[env] != -1 && t[t[j].env[env]].flag == 0) break;
  1326. int *strip_length = indices++;
  1327. *strip_length = 3;
  1328. *indices++ = t[j].v[(0 + env) % 3];
  1329. *indices++ = t[j].v[(1 + env) % 3];
  1330. *indices++ = t[j].v[(2 + env) % 3];
  1331. t[j].flag = 1;
  1332. int k = j;
  1333. while(1) {
  1334. for(env = 0; env < 3; env++) {
  1335. if(t[k].env[env] != -1 && t[t[k].env[env]].flag == 0) {
  1336. int *v = t[t[k].env[env]].v;
  1337. if(*(indices - 3) != v[0] && ((*(indices - 2) == v[2] && *(indices - 1) == v[1]) || (*(indices - 2) == v[1] && *(indices - 1) == v[2]))) {
  1338. *indices++ = v[0];
  1339. break;
  1340. }
  1341. if(*(indices - 3) != v[2] && ((*(indices - 2) == v[1] && *(indices - 1) == v[0]) || (*(indices - 2) == v[0] && *(indices - 1) == v[1]))) {
  1342. *indices++ = v[2];
  1343. break;
  1344. }
  1345. if(*(indices - 3) != v[1] && ((*(indices - 2) == v[0] && *(indices - 1) == v[2]) || (*(indices - 2) == v[2] && *(indices - 1) == v[0]))) {
  1346. *indices++ = v[1];
  1347. break;
  1348. }
  1349. }
  1350. }
  1351. if(env == 3) break;
  1352. vec3 normal;
  1353. normal.cross(v[*(indices - 3)].v.xyz - v[*(indices - 2)].v.xyz,v[*(indices - 4)].v.xyz - v[*(indices - 2)].v.xyz);
  1354. normal.cross(normal,v[*(indices - 3)].v.xyz - v[*(indices - 2)].v.xyz);
  1355. vec4 plane(normal,-(v[*(indices - 2)].v.xyz * normal));
  1356. if((plane * v[*(indices - 4)].v.xyz) * (plane * v[*(indices - 1)].v.xyz) > 0.0) {
  1357. indices--;
  1358. break;
  1359. };
  1360. k = t[k].env[env];
  1361. t[k].flag = 1;
  1362. (*strip_length)++;
  1363. }
  1364. s->num_indices += (*strip_length) + 1;
  1365. }
  1366. }
  1367. delete t;
  1368. delete s->vertex;
  1369. s->num_vertex = num_optimized_vertex;
  1370. s->vertex = new Vertex[s->num_vertex];
  1371. for(int j = 0; j < s->num_vertex; j++) s->vertex[j] = v[j].v;
  1372. delete v;
  1373. indices = new int[s->num_indices];
  1374. for(int j = 0; j < s->num_indices; j++) indices[j] = s->indices[j];
  1375. delete s->indices;
  1376. s->indices = indices;
  1377. }
  1378. }