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

游戏引擎

开发平台:

Visual C++

  1. /* SkinnedMesh
  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 <stdio.h>
  20. #include <string.h>
  21. #ifdef _WIN32
  22. #include <windows.h>
  23. #endif
  24. #include <GL/gl.h>
  25. #include <GL/glext.h>
  26. #include "engine.h"
  27. #include "skinnedmesh.h"
  28. SkinnedMesh::SkinnedMesh(const char *name) : num_bones(0), bones(NULL), num_frames(0), frames(NULL), num_surfaces(0) {
  29. min = vec3(0,0,0);
  30. max = vec3(0,0,0);
  31. center = vec3(0,0,0);
  32. radius = 0;
  33. load(name);
  34. }
  35. SkinnedMesh::~SkinnedMesh() {
  36. if(bones) delete bones;
  37. if(frames) {
  38. for(int i = 0; i < num_frames; i++) delete frames[i];
  39. delete frames;
  40. }
  41. for(int i = 0; i < num_surfaces; i++) {
  42. Surface *s = surfaces[i];
  43. for(int j = 0; j < s->num_vertex; j++) delete s->vertex[j].weights;
  44. if(s->vertex) delete s->vertex;
  45. if(s->edges) delete s->edges;
  46. if(s->triangles) delete s->triangles;
  47. if(s->shadow_volume_vertex) delete s->shadow_volume_vertex;
  48. delete s;
  49. }
  50. num_surfaces = 0;
  51. }
  52. /*****************************************************************************/
  53. /*                                                                           */
  54. /* animation                                                                 */
  55. /*                                                                           */
  56. /*****************************************************************************/
  57. void SkinnedMesh::setFrame(float frame,int from,int to) {
  58. if(num_frames == 0) return;
  59. if(from < 0) from = 0;
  60. if(to < 0) to = num_frames;
  61. int frame0 = (int)frame;
  62. frame -= frame0;
  63. frame0 += from;
  64. if(frame0 >= to) frame0 = (frame0 - from) % (to - from) + from;
  65. int frame1 = frame0 + 1;
  66. if(frame1 >= to) frame1 = from;
  67. for(int i = 0; i < num_bones; i++) { // calculate matrixes
  68. mat4 translate;
  69. translate.translate(frames[frame0][i].xyz * (1.0f - frame) + frames[frame1][i].xyz * frame);
  70. quat rot;
  71. rot.slerp(frames[frame0][i].rot,frames[frame1][i].rot,frame);
  72. bones[i].rotation = rot.to_matrix();
  73. bones[i].transform = translate * bones[i].rotation;
  74. }
  75. }
  76. /*
  77.  */
  78. void SkinnedMesh::calculateSkin() {
  79. min = vec3(1000000,1000000,1000000); // bound box
  80. max = vec3(-1000000,-1000000,-1000000);
  81. for(int i = 0; i < num_surfaces; i++) { // calculate vertexes
  82. Surface *s = surfaces[i];
  83. s->min = vec3(1000000,1000000,1000000);
  84. s->max = vec3(-1000000,-1000000,-1000000);
  85. for(int j = 0; j < s->num_vertex; j++) {
  86. Vertex *v = &s->vertex[j];
  87. v->xyz = vec3(0,0,0);
  88. v->normal = vec3(0,0,0);
  89. v->tangent = vec3(0,0,0);
  90. v->binormal = vec3(0,0,0);
  91. for(int k = 0; k < v->num_weights; k++) {
  92. Weight *w = &v->weights[k];
  93. v->xyz += bones[w->bone].transform * w->xyz * w->weight;
  94. v->normal += bones[w->bone].rotation * w->normal * w->weight;
  95. v->tangent += bones[w->bone].rotation * w->tangent * w->weight;
  96. v->binormal += bones[w->bone].rotation * w->binormal * w->weight;
  97. }
  98. if(s->max.x < v->xyz.x) s->max.x = v->xyz.x;
  99. if(s->min.x > v->xyz.x) s->min.x = v->xyz.x;
  100. if(s->max.y < v->xyz.y) s->max.y = v->xyz.y;
  101. if(s->min.y > v->xyz.y) s->min.y = v->xyz.y;
  102. if(s->max.z < v->xyz.z) s->max.z = v->xyz.z;
  103. if(s->min.z > v->xyz.z) s->min.z = v->xyz.z;
  104. }
  105. for(int j = 0; j < s->num_triangles; j++) {
  106. Triangle *t = &s->triangles[j];
  107. vec3 normal;
  108. normal.cross(s->vertex[t->v[1]].xyz - s->vertex[t->v[0]].xyz,s->vertex[t->v[2]].xyz - s->vertex[t->v[0]].xyz);
  109. normal.normalize();
  110. t->plane = vec4(normal,-s->vertex[t->v[0]].xyz * normal);
  111. normal.cross(t->plane,s->vertex[t->v[0]].xyz - s->vertex[t->v[2]].xyz); // fast point in triangle
  112. normal.normalize();
  113. t->c[0] = vec4(normal,-s->vertex[t->v[0]].xyz * normal);
  114. normal.cross(t->plane,s->vertex[t->v[1]].xyz - s->vertex[t->v[0]].xyz);
  115. normal.normalize();
  116. t->c[1] = vec4(normal,-s->vertex[t->v[1]].xyz * normal);
  117. normal.cross(t->plane,s->vertex[t->v[2]].xyz - s->vertex[t->v[1]].xyz);
  118. normal.normalize();
  119. t->c[2] = vec4(normal,-s->vertex[t->v[2]].xyz * normal);
  120. t->flag = 0;
  121. }
  122. s->center = (s->min + s->max) / 2.0f;
  123. s->radius = (s->max - s->center).length();
  124. if(max.x < s->max.x) max.x = s->max.x;
  125. if(min.x > s->min.x) min.x = s->min.x;
  126. if(max.y < s->max.y) max.y = s->max.y;
  127. if(min.y > s->min.y) min.y = s->min.y;
  128. if(max.z < s->max.z) max.z = s->max.z;
  129. if(min.z > s->min.z) min.z = s->min.z;
  130. }
  131. center = (min + max) / 2.0f;
  132. radius = (max - center).length();
  133. }
  134. /*****************************************************************************/
  135. /*                                                                           */
  136. /* render                                                                    */
  137. /*                                                                           */
  138. /*****************************************************************************/
  139. int SkinnedMesh::render(int ppl,int s) {
  140. int num_triangles = 0;
  141. if(ppl) {
  142. glEnableVertexAttribArrayARB(0);
  143. glEnableVertexAttribArrayARB(1);
  144. glEnableVertexAttribArrayARB(2);
  145. glEnableVertexAttribArrayARB(3);
  146. glEnableVertexAttribArrayARB(4);
  147. if(s < 0) {
  148. for(int i = 0; i < num_surfaces; i++) {
  149. Surface *s = surfaces[i];
  150. glVertexAttribPointerARB(0,3,GL_FLOAT,0,sizeof(Vertex),s->vertex->xyz);
  151. glVertexAttribPointerARB(1,3,GL_FLOAT,0,sizeof(Vertex),s->vertex->normal);
  152. glVertexAttribPointerARB(2,3,GL_FLOAT,0,sizeof(Vertex),s->vertex->tangent);
  153. glVertexAttribPointerARB(3,3,GL_FLOAT,0,sizeof(Vertex),s->vertex->binormal);
  154. glVertexAttribPointerARB(4,2,GL_FLOAT,0,sizeof(Vertex),s->vertex->texcoord);
  155. glDrawElements(GL_TRIANGLES,s->num_indices,GL_UNSIGNED_INT,s->indeices);
  156. num_triangles += s->num_triangles;
  157. }
  158. } else {
  159. Surface *surface = surfaces[s];
  160. Surface *s = surface;
  161. glVertexAttribPointerARB(0,3,GL_FLOAT,0,sizeof(Vertex),s->vertex->xyz);
  162. glVertexAttribPointerARB(1,3,GL_FLOAT,0,sizeof(Vertex),s->vertex->normal);
  163. glVertexAttribPointerARB(2,3,GL_FLOAT,0,sizeof(Vertex),s->vertex->tangent);
  164. glVertexAttribPointerARB(3,3,GL_FLOAT,0,sizeof(Vertex),s->vertex->binormal);
  165. glVertexAttribPointerARB(4,2,GL_FLOAT,0,sizeof(Vertex),s->vertex->texcoord);
  166. glDrawElements(GL_TRIANGLES,s->num_indices,GL_UNSIGNED_INT,s->indeices);
  167. num_triangles += s->num_triangles;
  168. }
  169. glDisableVertexAttribArrayARB(4);
  170. glDisableVertexAttribArrayARB(3);
  171. glDisableVertexAttribArrayARB(2);
  172. glDisableVertexAttribArrayARB(1);
  173. glDisableVertexAttribArrayARB(0);
  174. } else {
  175. glEnableClientState(GL_VERTEX_ARRAY);
  176. glEnableClientState(GL_NORMAL_ARRAY);
  177. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  178. if(s < 0) {
  179. for(int i = 0; i < num_surfaces; i++) {
  180. Surface *s = surfaces[i];
  181. glVertexPointer(3,GL_FLOAT,sizeof(Vertex),s->vertex->xyz);
  182. glNormalPointer(GL_FLOAT,sizeof(Vertex),s->vertex->normal);
  183. glTexCoordPointer(2,GL_FLOAT,sizeof(Vertex),s->vertex->texcoord);
  184. glDrawElements(GL_TRIANGLES,s->num_indices,GL_UNSIGNED_INT,s->indeices);
  185. num_triangles += s->num_triangles;
  186. }
  187. } else {
  188. Surface *surface = surfaces[s];
  189. Surface *s = surface;
  190. glVertexPointer(3,GL_FLOAT,sizeof(Vertex),s->vertex->xyz);
  191. glNormalPointer(GL_FLOAT,sizeof(Vertex),s->vertex->normal);
  192. glTexCoordPointer(2,GL_FLOAT,sizeof(Vertex),s->vertex->texcoord);
  193. glDrawElements(GL_TRIANGLES,s->num_indices,GL_UNSIGNED_INT,s->indeices);
  194. num_triangles += s->num_triangles;
  195. }
  196. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  197. glDisableClientState(GL_NORMAL_ARRAY);
  198. glDisableClientState(GL_VERTEX_ARRAY);
  199. }
  200. return num_triangles;
  201. }
  202. /*****************************************************************************/
  203. /*                                                                           */
  204. /* stencil shadows                                                           */
  205. /*                                                                           */
  206. /*****************************************************************************/
  207. void SkinnedMesh::findSilhouette(const vec4 &light,int s) {
  208. if(s < 0) {
  209. for(int i = 0; i < num_surfaces; i++) {
  210. Surface *s = surfaces[i];
  211. for(int j = 0; j < s->num_edges; j++) s->edges[j].flag = -1;
  212. for(int j = 0; j < s->num_triangles; j++) {
  213. Triangle *t = &s->triangles[j];
  214. if(t->plane * light > 0.0) {
  215. t->flag = 1;
  216. s->edges[t->e[0]].reverse = t->reverse[0];
  217. s->edges[t->e[1]].reverse = t->reverse[1];
  218. s->edges[t->e[2]].reverse = t->reverse[2];
  219. s->edges[t->e[0]].flag++;
  220. s->edges[t->e[1]].flag++;
  221. s->edges[t->e[2]].flag++;
  222. } else t->flag = 0;
  223. }
  224. s->num_shadow_volume_vertex = 0;
  225. vec4 *shadow_volume_vertex = s->shadow_volume_vertex;
  226. for(int j = 0; j < s->num_edges; j++) {
  227. if(s->edges[j].flag != 0) continue;
  228. Edge *e = &s->edges[j];
  229. if(e->reverse) {
  230. *shadow_volume_vertex++ = vec4(s->vertex[e->v[0]].xyz,1);
  231. *shadow_volume_vertex++ = vec4(s->vertex[e->v[1]].xyz,1);
  232. *shadow_volume_vertex++ = vec4(s->vertex[e->v[1]].xyz,0);
  233. *shadow_volume_vertex++ = vec4(s->vertex[e->v[0]].xyz,0);
  234. } else {
  235. *shadow_volume_vertex++ = vec4(s->vertex[e->v[1]].xyz,1);
  236. *shadow_volume_vertex++ = vec4(s->vertex[e->v[0]].xyz,1);
  237. *shadow_volume_vertex++ = vec4(s->vertex[e->v[0]].xyz,0);
  238. *shadow_volume_vertex++ = vec4(s->vertex[e->v[1]].xyz,0);
  239. }
  240. s->num_shadow_volume_vertex += 4;
  241. }
  242. }
  243. } else {
  244. Surface *surface = surfaces[s];
  245. Surface *s = surface; // :)
  246. for(int i = 0; i < s->num_edges; i++) s->edges[i].flag = -1;
  247. for(int i = 0; i < s->num_triangles; i++) {
  248. Triangle *t = &s->triangles[i];
  249. if(t->plane * light > 0.0) {
  250. t->flag = 1;
  251. s->edges[t->e[0]].reverse = t->reverse[0];
  252. s->edges[t->e[1]].reverse = t->reverse[1];
  253. s->edges[t->e[2]].reverse = t->reverse[2];
  254. s->edges[t->e[0]].flag++;
  255. s->edges[t->e[1]].flag++;
  256. s->edges[t->e[2]].flag++;
  257. } else t->flag = 0;
  258. }
  259. s->num_shadow_volume_vertex = 0;
  260. vec4 *shadow_volume_vertex = s->shadow_volume_vertex;
  261. for(int i = 0; i < s->num_edges; i++) {
  262. if(s->edges[i].flag != 0) continue;
  263. Edge *e = &s->edges[i];
  264. if(e->reverse) {
  265. *shadow_volume_vertex++ = vec4(s->vertex[e->v[0]].xyz,1);
  266. *shadow_volume_vertex++ = vec4(s->vertex[e->v[1]].xyz,1);
  267. *shadow_volume_vertex++ = vec4(s->vertex[e->v[1]].xyz,0);
  268. *shadow_volume_vertex++ = vec4(s->vertex[e->v[0]].xyz,0);
  269. } else {
  270. *shadow_volume_vertex++ = vec4(s->vertex[e->v[1]].xyz,1);
  271. *shadow_volume_vertex++ = vec4(s->vertex[e->v[0]].xyz,1);
  272. *shadow_volume_vertex++ = vec4(s->vertex[e->v[0]].xyz,0);
  273. *shadow_volume_vertex++ = vec4(s->vertex[e->v[1]].xyz,0);
  274. }
  275. s->num_shadow_volume_vertex += 4;
  276. }
  277. }
  278. }
  279. /*
  280.  */
  281. int SkinnedMesh::getNumIntersections(const vec3 &line0,const vec3 &line1,int s) {
  282. int num_intersections = 0;
  283. if(s < 0) {
  284. vec3 dir = line1 - line0;
  285. float dot = (dir * center - dir * line0) / (dir * dir);
  286. if(dot < 0.0 && (line0 - center).length() > radius) return 0;
  287. else if(dot > 1.0 && (line1 - center).length() > radius) return 0;
  288. else if((line0 + dir * dot - center).length() > radius) return 0;
  289. for(int i = 0; i < num_surfaces; i++) {
  290. Surface *s = surfaces[i];
  291. float dot = (dir * s->center - dir * line0) / (dir * dir);
  292. if(dot < 0.0 && (line0 - s->center).length() > s->radius) continue;
  293. else if(dot > 1.0 && (line1 - s->center).length() > s->radius) continue;
  294. else if((line0 + dir * dot - s->center).length() > s->radius) continue;
  295. for(int j = 0; j < s->num_triangles; j++) {
  296. Triangle *t = &s->triangles[j];
  297. if(t->flag == 0) continue;
  298. float dot = -(t->plane * vec4(line0,1)) / (vec3(t->plane) * dir);
  299. if(dot < 0.0 || dot > 1.0) continue;
  300. vec3 p = line0 + dir * dot;
  301. if(p * t->c[0] > 0.0 && p * t->c[1] > 0.0 && p * t->c[2] > 0.0) num_intersections++;
  302. }
  303. }
  304. return num_intersections;
  305. } else {
  306. Surface *surface = surfaces[s];
  307. Surface *s = surface;
  308. vec3 dir = line1 - line0;
  309. float dot = (dir * s->center - dir * line0) / (dir * dir);
  310. if(dot < 0.0 && (line0 - s->center).length() > s->radius) return 0;
  311. else if(dot > 1.0 && (line1 - s->center).length() > s->radius) return 0;
  312. else if((line0 + dir * dot - s->center).length() > s->radius) return 0;
  313. for(int i = 0; i < s->num_triangles; i++) {
  314. Triangle *t = &s->triangles[i];
  315. if(t->flag == 0) continue;
  316. float dot = -(t->plane * vec4(line0,1)) / (vec3(t->plane) * dir);
  317. if(dot < 0.0 || dot > 1.0) continue;
  318. vec3 p = line0 + dir * dot;
  319. if(p * t->c[0] > 0.0 && p * t->c[1] > 0.0 && p * t->c[2] > 0.0) num_intersections++;
  320. }
  321. return num_intersections;
  322. }
  323. }
  324. /*
  325.  */
  326. int SkinnedMesh::renderShadowVolume(int s) {
  327. int num_triangles = 0;
  328. glEnableVertexAttribArrayARB(0);
  329. if(s < 0) {
  330. for(int i = 0; i < num_surfaces; i++) {
  331. Surface *s = surfaces[i];
  332. glVertexAttribPointerARB(0,4,GL_FLOAT,0,sizeof(vec4),s->shadow_volume_vertex);
  333. glDrawArrays(GL_QUADS,0,s->num_shadow_volume_vertex);
  334. num_triangles += s->num_shadow_volume_vertex / 2;
  335. }
  336. } else {
  337. Surface *surface = surfaces[s];
  338. Surface *s = surface;
  339. glVertexAttribPointerARB(0,4,GL_FLOAT,0,sizeof(vec4),s->shadow_volume_vertex);
  340. glDrawArrays(GL_QUADS,0,s->num_shadow_volume_vertex);
  341. num_triangles += s->num_shadow_volume_vertex / 2;
  342. }
  343. glDisableVertexAttribArrayARB(0);
  344. return num_triangles;
  345. }
  346. /*****************************************************************************/
  347. /*                                                                           */
  348. /* line inersection                                                          */
  349. /*                                                                           */
  350. /*****************************************************************************/
  351. int SkinnedMesh::intersection(const vec3 &line0,const vec3 &line1,vec3 &point,vec3 &normal,int s) {
  352. float nearest = 2.0;
  353. if(s < 0) {
  354. vec3 dir = line1 - line0;
  355. float dot = (dir * center - dir * line0) / (dir * dir);
  356. if(dot < 0.0 && (line0 - center).length() > radius) return 0;
  357. else if(dot > 1.0 && (line1 - center).length() > radius) return 0;
  358. else if((line0 + dir * dot - center).length() > radius) return 0;
  359. for(int i = 0; i < num_surfaces; i++) {
  360. Surface *s = surfaces[i];
  361. float dot = (dir * s->center - dir * line0) / (dir * dir);
  362. if(dot < 0.0 && (line0 - s->center).length() > s->radius) continue;
  363. else if(dot > 1.0 && (line1 - s->center).length() > s->radius) continue;
  364. else if((line0 + dir * dot - s->center).length() > s->radius) continue;
  365. for(int j = 0; j < s->num_triangles; j++) {
  366. Triangle *t = &s->triangles[j];
  367. float dot = -(t->plane * vec4(line0,1)) / (vec3(t->plane) * dir);
  368. if(dot < 0.0 || dot > 1.0) continue;
  369. vec3 p = line0 + dir * dot;
  370. if(nearest > dot && p * t->c[0] > 0.0 && p * t->c[1] > 0.0 && p * t->c[2] > 0.0) {
  371. nearest = dot;
  372. point = p;
  373. normal = t->plane;
  374. }
  375. }
  376. }
  377. return nearest < 2.0 ? 1 : 0;
  378. } else {
  379. Surface *surface = surfaces[s];
  380. Surface *s = surface;
  381. vec3 dir = line1 - line0;
  382. float dot = (dir * s->center - dir * line0) / (dir * dir);
  383. if(dot < 0.0 && (line0 - s->center).length() > s->radius) return 0;
  384. else if(dot > 1.0 && (line1 - s->center).length() > s->radius) return 0;
  385. else if((line0 + dir * dot - s->center).length() > s->radius) return 0;
  386. for(int i = 0; i < s->num_triangles; i++) {
  387. Triangle *t = &s->triangles[i];
  388. float dot = -(t->plane * vec4(line0,1)) / (vec3(t->plane) * dir);
  389. if(dot < 0.0 || dot > 1.0) continue;
  390. vec3 p = line0 + dir * dot;
  391. if(nearest > dot && p * t->c[0] > 0.0 && p * t->c[1] > 0.0 && p * t->c[2] > 0.0) {
  392. nearest = dot;
  393. point = p;
  394. normal = t->plane;
  395. }
  396. }
  397. return nearest < 2.0 ? 1 : 0;
  398. }
  399. }
  400. /*****************************************************************************/
  401. /*                                                                           */
  402. /* transform                                                                 */
  403. /*                                                                           */
  404. /*****************************************************************************/
  405. void SkinnedMesh::transform(const mat4 &m) {
  406. mat4 r = m.rotation();
  407. for(int i = 0; i < num_surfaces; i++) {
  408. Surface *s = surfaces[i];
  409. for(int j = 0; j < s->num_vertex; j++) {
  410. Vertex *v = &s->vertex[j];
  411. for(int k = 0; k < v->num_weights; k++) {
  412. Weight *w = &v->weights[k];
  413. w->xyz = m * w->xyz;
  414. w->normal = r * w->normal;
  415. w->normal.normalize();
  416. }
  417. }
  418. }
  419. for(int i = 0; i < num_frames; i++) {
  420. for(int j = 0; j < num_bones; j++) {
  421. frames[i][j].xyz = m * frames[i][j].xyz;
  422. }
  423. }
  424. calculate_tangent();
  425. setFrame(0);
  426. calculateSkin();
  427. }
  428. /*****************************************************************************/
  429. /*                                                                           */
  430. /* IO functions                                                              */
  431. /*                                                                           */
  432. /*****************************************************************************/
  433. /*
  434.  */
  435. int SkinnedMesh::getNumSurfaces() {
  436. return num_surfaces;
  437. }
  438. const char *SkinnedMesh::getSurfaceName(int s) {
  439. return surfaces[s]->name;
  440. }
  441. int SkinnedMesh::getSurface(const char *name) {
  442. for(int i = 0; i < num_surfaces; i++) if(!strcmp(name,surfaces[i]->name)) return i;
  443. fprintf(stderr,"SkinnedMesh::getSurface(): can`t find "%s" surfacen",name);
  444. return -1;
  445. }
  446. /*
  447.  */
  448. int SkinnedMesh::getNumBones() {
  449. return num_bones;
  450. }
  451. SkinnedMesh::Bone *SkinnedMesh::getBones() {
  452. return bones;
  453. }
  454. const char *SkinnedMesh::getBoneName(int b) {
  455. return bones[b].name;
  456. }
  457. int SkinnedMesh::getBone(const char *name) {
  458. for(int i = 0; i < num_bones; i++) if(!strcmp(name,bones[i].name)) return i;
  459. fprintf(stderr,"SkinnedMesh::getBone(): can`t find "%s" bonen",name);
  460. return -1;
  461. }
  462. const mat4 &SkinnedMesh::getBoneTransform(int b) {
  463. if(b < 0) {
  464. static mat4 dummy;
  465. return dummy;
  466. }
  467. return bones[b].transform;
  468. }
  469. /*
  470.  */
  471. int SkinnedMesh::getNumVertex(int s) {
  472. return surfaces[s]->num_vertex;
  473. }
  474. SkinnedMesh::Vertex *SkinnedMesh::getVertex(int s) {
  475. return surfaces[s]->vertex;
  476. }
  477. int SkinnedMesh::getNumEdges(int s) {
  478. return surfaces[s]->num_edges;
  479. }
  480. SkinnedMesh::Edge *SkinnedMesh::getEdges(int s) {
  481. return surfaces[s]->edges;
  482. }
  483. int SkinnedMesh::getNumTriangles(int s) {
  484. return surfaces[s]->num_triangles;
  485. }
  486. SkinnedMesh::Triangle *SkinnedMesh::getTriangles(int s) {
  487. return surfaces[s]->triangles;
  488. }
  489. /*
  490.  */
  491. const vec3 &SkinnedMesh::getMin(int s) {
  492. if(s < 0) return min;
  493. return surfaces[s]->min;
  494. }
  495. const vec3 &SkinnedMesh::getMax(int s) {
  496. if(s < 0) return max;
  497. return surfaces[s]->max;
  498. }
  499. const vec3 &SkinnedMesh::getCenter(int s) {
  500. if(s < 0) return center;
  501. return surfaces[s]->center;
  502. }
  503. float SkinnedMesh::getRadius(int s) {
  504. if(s < 0) return radius;
  505. return surfaces[s]->radius;
  506. }
  507. /* load
  508.  */
  509. int SkinnedMesh::load(const char *name) {
  510. FILE *file = fopen(name,"rb");
  511. if(!file) {
  512. fprintf(stderr,"SkinnedMesh::load(): error open "%s" filen",name);
  513. return 0;
  514. }
  515. int magic = 0;
  516. fread(&magic,sizeof(int),1,file);
  517. fclose(file);
  518. int ret = 0;
  519. if(magic == SKINNED_MESH_MAGIC) ret = load_binary(name);
  520. else ret = load_ascii(name);
  521. calculate_tangent();
  522. create_shadow_volumes();
  523. setFrame(0);
  524. calculateSkin();
  525. return ret;
  526. }
  527. /* save
  528.  */
  529. int SkinnedMesh::save(const char *name) {
  530. FILE *file = fopen(name,"wb");
  531. if(!file) {
  532. fprintf(stderr,"SkinnedMesh::save(): error create "%s" filen",name);
  533. return 0;
  534. }
  535. int magic = SKINNED_MESH_MAGIC;
  536. fwrite(&magic,sizeof(int),1,file);
  537. fwrite(&num_bones,sizeof(int),1,file); // bones
  538. for(int i = 0; i < num_bones; i++) {
  539. fwrite(bones[i].name,sizeof(bones[i].name),1,file);
  540. fwrite(&bones[i].parent,sizeof(int),1,file);
  541. }
  542. fwrite(&num_surfaces,sizeof(int),1,file); // surfaces
  543. for(int i = 0; i < num_surfaces; i++) {
  544. Surface *s = surfaces[i];
  545. fwrite(s->name,sizeof(s->name),1,file); // name
  546. fwrite(&s->num_vertex,sizeof(int),1,file); // vertexes
  547. for(int j = 0; j < s->num_vertex; j++) {
  548. Vertex *v = &s->vertex[j];
  549. fwrite(&v->texcoord,sizeof(vec2),1,file);
  550. fwrite(&v->num_weights,sizeof(int),1,file); // weights
  551. for(int k = 0; k < v->num_weights; k++) {
  552. Weight *w = &v->weights[k];
  553. fwrite(&w->bone,sizeof(int),1,file);
  554. fwrite(&w->weight,sizeof(float),1,file);
  555. fwrite(&w->xyz,sizeof(vec3),1,file);
  556. fwrite(&w->normal,sizeof(vec3),1,file);
  557. }
  558. }
  559. fwrite(&s->num_triangles,sizeof(int),1,file); // triangles
  560. for(int j = 0; j < s->num_triangles; j++) fwrite(s->triangles[j].v,sizeof(int),3,file);
  561. }
  562. fwrite(&num_frames,sizeof(int),1,file); // frames
  563. for(int i = 0; i < num_frames; i++) fwrite(frames[i],sizeof(Frame),num_bones,file);
  564. fclose(file);
  565. return 1;
  566. }
  567. /*****************************************************************************/
  568. /*                                                                           */
  569. /* binary skinned mesh loader                                                */
  570. /*                                                                           */
  571. /*****************************************************************************/
  572. int SkinnedMesh::load_binary(const char *name) {
  573. FILE *file = fopen(name,"rb");
  574. if(!file) {
  575. fprintf(stderr,"SkinnedMesh::load_binary(): error open "%s" filen",name);
  576. return 0;
  577. }
  578. int magic; // magic
  579. fread(&magic,sizeof(int),1,file);
  580. if(magic != SKINNED_MESH_MAGIC) {
  581. fprintf(stderr,"SkinnedMesh::load_binary(): wrong magic 0x%04x in "%s" file",magic,name);
  582. fclose(file);
  583. return 0;
  584. }
  585. fread(&num_bones,sizeof(int),1,file); // bones
  586. bones = new Bone[num_bones];
  587. for(int i = 0; i < num_bones; i++) {
  588. fread(bones[i].name,sizeof(bones[i].name),1,file);
  589. fread(&bones[i].parent,sizeof(int),1,file);
  590. }
  591. int num_surfaces; // surfaces
  592. fread(&num_surfaces,sizeof(int),1,file);
  593. for(int i = 0; i < num_surfaces; i++) {
  594. Surface *s = new Surface;
  595. memset(s,0,sizeof(Surface));
  596. fread(s->name,sizeof(s->name),1,file); // name
  597. fread(&s->num_vertex,sizeof(int),1,file); // vertexes
  598. s->vertex = new Vertex[s->num_vertex];
  599. for(int j = 0; j < s->num_vertex; j++) {
  600. Vertex *v = &s->vertex[j];
  601. fread(&v->texcoord,sizeof(vec2),1,file);
  602. fread(&v->num_weights,sizeof(int),1,file); // weights
  603. v->weights = new Weight[v->num_weights];
  604. for(int k = 0; k < v->num_weights; k++) {
  605. Weight *w = &v->weights[k];
  606. fread(&w->bone,sizeof(int),1,file);
  607. fread(&w->weight,sizeof(float),1,file);
  608. fread(&w->xyz,sizeof(vec3),1,file);
  609. fread(&w->normal,sizeof(vec3),1,file);
  610. }
  611. }
  612. fread(&s->num_triangles,sizeof(int),1,file); // triangles
  613. s->triangles = new Triangle[s->num_triangles];
  614. s->num_indices = s->num_triangles * 3;
  615. s->indeices = new int[s->num_indices];
  616. for(int j = 0; j < s->num_triangles; j++) {
  617. Triangle *t = &s->triangles[j];
  618. fread(t->v,sizeof(int),3,file);
  619. s->indeices[j * 3 + 0] = t->v[0];
  620. s->indeices[j * 3 + 1] = t->v[1];
  621. s->indeices[j * 3 + 2] = t->v[2];
  622. }
  623. if(this->num_surfaces == NUM_SURFACES) {
  624. fprintf(stderr,"SkinnedMesh::load_binary(): many surfacesn");
  625. this->num_surfaces--;
  626. }
  627. surfaces[this->num_surfaces++] = s;
  628. }
  629. fread(&num_frames,sizeof(int),1,file); // frames
  630. frames = new Frame*[num_frames];
  631. for(int i = 0; i < num_frames; i++) {
  632. frames[i] = new Frame[num_bones];
  633. fread(frames[i],sizeof(Frame),num_bones,file);
  634. }
  635. fclose(file);
  636. return 1;
  637. }
  638. /*****************************************************************************/
  639. /*                                                                           */
  640. /* ascii skinned mesh loader                                                 */
  641. /*                                                                           */
  642. /*****************************************************************************/
  643. void SkinnedMesh::read_string(FILE *file,char *string) {
  644. char c;
  645. char *s = string;
  646. int quoted = -1;
  647. while(fread(&c,sizeof(char),1,file) == 1) {
  648. if(quoted == -1) {
  649. if(c == '"') quoted = 1;
  650. else if(!strchr(" tnr",c)) {
  651. *s++ = c;
  652. quoted = 0;
  653. }
  654. continue;
  655. }
  656. if(quoted == 1 && c == '"') break;
  657. if(quoted == 0 && strchr(" tnr",c)) break;
  658. *s++ = c;
  659. }
  660. *s = '';
  661. }
  662. /*
  663.  */
  664. int SkinnedMesh::load_ascii(const char *name) {
  665. FILE *file = fopen(name,"r");
  666. if(!file) {
  667. fprintf(stderr,"SkinnedMesh::load_ascii(): error open "%s" filen",name);
  668. return 0;
  669. }
  670. char buf[1024];
  671. while(fscanf(file,"%s",buf) != EOF) {
  672. if(!strcmp(buf,"bones")) {
  673. fscanf(file,"%d %s",&num_bones,buf);
  674. bones = new Bone[num_bones];
  675. for(int i = 0; i < num_bones; i++) {
  676. memset(bones[i].name,0,sizeof(bones[i].name));
  677. read_string(file,bones[i].name);
  678. fscanf(file,"%d",&bones[i].parent);
  679. }
  680. fscanf(file,"%s",buf);
  681. }
  682. else if(!strcmp(buf,"surface")) {
  683. Surface *s = new Surface;
  684. memset(s,0,sizeof(Surface));
  685. memset(s->name,0,sizeof(s->name));
  686. read_string(file,s->name);
  687. fscanf(file,"%s",buf);
  688. while(fscanf(file,"%s",buf) != EOF) {
  689. if(!strcmp(buf,"vertex")) {
  690. fscanf(file,"%d %s",&s->num_vertex,buf);
  691. s->vertex = new Vertex[s->num_vertex];
  692. for(int i = 0; i < s->num_vertex; i++) {
  693. Vertex *v = &s->vertex[i];
  694. fscanf(file,"%f %f",&v->texcoord.x,&v->texcoord.y);
  695. fscanf(file,"%s %d",buf,&v->num_weights);
  696. fscanf(file,"%s",buf);
  697. v->weights = new Weight[v->num_weights];
  698. for(int j = 0; j < v->num_weights; j++) {
  699. Weight *w = &v->weights[j];
  700. fscanf(file,"%d %f",&w->bone,&w->weight);
  701. fscanf(file,"%f %f %f",&w->xyz.x,&w->xyz.y,&w->xyz.z);
  702. fscanf(file,"%f %f %f",&w->normal.x,&w->normal.y,&w->normal.z);
  703. }
  704. fscanf(file,"%s",buf);
  705. }
  706. fscanf(file,"%s",buf);
  707. }
  708. else if(!strcmp(buf,"triangles")) {
  709. fscanf(file,"%d %s",&s->num_triangles,buf);
  710. s->triangles = new Triangle[s->num_triangles];
  711. s->num_indices = s->num_triangles * 3;
  712. s->indeices = new int[s->num_indices];
  713. for(int i = 0; i < s->num_triangles; i++) {
  714. Triangle *t = &s->triangles[i];
  715. fscanf(file,"%d %d %d",&t->v[0],&t->v[1],&t->v[2]);
  716. s->indeices[i * 3 + 0] = t->v[0];
  717. s->indeices[i * 3 + 1] = t->v[1];
  718. s->indeices[i * 3 + 2] = t->v[2];
  719. }
  720. fscanf(file,"%s",buf);
  721. }
  722. else if(!strcmp(buf,"}")) {
  723. break;
  724. }
  725. else {
  726. fprintf(stderr,"SkinnedMesh::load_ascii(): unknown token "%s"n",buf);
  727. fclose(file);
  728. return 0;
  729. }
  730. }
  731. if(num_surfaces == NUM_SURFACES) {
  732. fprintf(stderr,"SkinnedMesh::load_ascii(): many surfacesn");
  733. num_surfaces--;
  734. }
  735. surfaces[num_surfaces++] = s;
  736. }
  737. else if(!strcmp(buf,"animation")) {
  738. fscanf(file,"%d %s",&num_frames,buf);
  739. frames = new Frame*[num_frames];
  740. for(int i = 0; i < num_frames; i++) {
  741. frames[i] = new Frame[num_bones];
  742. for(int j = 0; j < num_bones; j++) {
  743. Frame *f = &frames[i][j];
  744. fscanf(file,"%f %f %f",&f->xyz.x,&f->xyz.y,&f->xyz.z);
  745. fscanf(file,"%f %f %f %f",&f->rot.x,&f->rot.y,&f->rot.z,&f->rot.w);
  746. }
  747. }
  748. fscanf(file,"%s",buf);
  749. }
  750. else {
  751. fprintf(stderr,"SkinnedMesh::load_ascii(): unknown token "%s"n",buf);
  752. fclose(file);
  753. return 0;
  754. }
  755. }
  756. fclose(file);
  757. return 1;
  758. }
  759. /*****************************************************************************/
  760. /*                                                                           */
  761. /* calculate tangent                                                         */
  762. /*                                                                           */
  763. /*****************************************************************************/
  764. void SkinnedMesh::calculate_tangent() {
  765. setFrame(0.0);
  766. calculateSkin();
  767. for(int i = 0; i < num_surfaces; i++) {
  768. Surface *s = surfaces[i];
  769. for(int j = 0; j < s->num_vertex; j++) { // set tangents and binormals to zero
  770. Vertex *v = &s->vertex[j];
  771. for(int k = 0; k < v->num_weights; k++) {
  772. Weight *w = &v->weights[k];
  773. w->tangent = vec3(0,0,0);
  774. w->binormal = vec3(0,0,0);
  775. }
  776. }
  777. for(int j = 0; j < s->num_triangles; j++) {
  778. Triangle *t = &s->triangles[j];
  779. Vertex *v0 = &s->vertex[t->v[0]];
  780. Vertex *v1 = &s->vertex[t->v[1]];
  781. Vertex *v2 = &s->vertex[t->v[2]];
  782. vec3 normal,tangent,binormal; // calculate tangent and bonormal for triangle
  783. vec3 e0 = vec3(0,v1->texcoord.x - v0->texcoord.x,v1->texcoord.y - v0->texcoord.y);
  784. vec3 e1 = vec3(0,v2->texcoord.x - v0->texcoord.x,v2->texcoord.y - v0->texcoord.y);
  785. for(int k = 0; k < 3; k++) {
  786. e0.x = v1->xyz[k] - v0->xyz[k];
  787. e1.x = v2->xyz[k] - v0->xyz[k];
  788. vec3 v;
  789. v.cross(e0,e1);
  790. if(fabs(v[0]) > EPSILON) {
  791. tangent[k] = -v[1] / v[0];
  792. binormal[k] = -v[2] / v[0];
  793. } else {
  794. tangent[k] = 0;
  795. binormal[k] = 0;
  796. }
  797. }
  798. tangent.normalize();
  799. binormal.normalize();
  800. normal.cross(tangent,binormal);
  801. normal.normalize();
  802. v0->binormal.cross(v0->normal,tangent);
  803. v0->binormal.normalize();
  804. v0->tangent.cross(v0->binormal,v0->normal);
  805. if(normal * v0->normal < 0) v0->binormal = -v0->binormal;
  806. for(int k = 0; k < v0->num_weights; k++) { // add it in to vertex weights
  807. Weight *w = &v0->weights[k];
  808. mat4 transform = bones[w->bone].rotation.inverse();
  809. w->tangent += transform * v0->tangent;
  810. w->binormal += transform * v0->binormal;
  811. }
  812. v1->binormal.cross(v1->normal,tangent);
  813. v1->binormal.normalize();
  814. v1->tangent.cross(v1->binormal,v1->normal);
  815. if(normal * v1->normal < 0) v1->binormal = -v1->binormal;
  816. for(int k = 0; k < v1->num_weights; k++) {
  817. Weight *w = &v1->weights[k];
  818. mat4 transform = bones[w->bone].rotation.inverse();
  819. w->tangent += transform * v1->tangent;
  820. w->binormal += transform * v1->binormal;
  821. }
  822. v2->binormal.cross(v2->normal,tangent);
  823. v2->binormal.normalize();
  824. v2->tangent.cross(v2->binormal,v2->normal);
  825. if(normal * v2->normal < 0) v2->binormal = -v2->binormal;
  826. for(int k = 0; k < v2->num_weights; k++) {
  827. Weight *w = &v2->weights[k];
  828. mat4 transform = bones[w->bone].rotation.inverse();
  829. w->tangent += transform * v2->tangent;
  830. w->binormal += transform * v2->binormal;
  831. }
  832. }
  833. for(int j = 0; j < s->num_vertex; j++) { // normalize tangents and binormals
  834. Vertex *v = &s->vertex[j];
  835. for(int k = 0; k < v->num_weights; k++) {
  836. Weight *w = &v->weights[k];
  837. w->tangent.normalize();
  838. w->binormal.normalize();
  839. }
  840. }
  841. }
  842. }
  843. /*****************************************************************************/
  844. /*                                                                           */
  845. /* create shadow volume                                                      */
  846. /*                                                                           */
  847. /*****************************************************************************/
  848. struct csv_Edge {
  849. int v[2];
  850. int id;
  851. };
  852. static int csv_edge_cmp(const void *a,const void *b) {
  853. csv_Edge *e0 = (csv_Edge*)a;
  854. csv_Edge *e1 = (csv_Edge*)b;
  855. int v[2][2];
  856. if(e0->v[0] < e0->v[1]) { v[0][0] = e0->v[0]; v[0][1] = e0->v[1]; }
  857. else { v[0][0] = e0->v[1]; v[0][1] = e0->v[0]; }
  858. if(e1->v[0] < e1->v[1]) { v[1][0] = e1->v[0]; v[1][1] = e1->v[1]; }
  859. else { v[1][0] = e1->v[1]; v[1][1] = e1->v[0]; }
  860. if(v[0][0] > v[1][0]) return 1;
  861. if(v[0][0] < v[1][0]) return -1;
  862. if(v[0][1] > v[1][1]) return 1;
  863. if(v[0][1] < v[1][1]) return -1;
  864. return 0;
  865. }
  866. void SkinnedMesh::create_shadow_volumes() {
  867. for(int i = 0; i < num_surfaces; i++) {
  868. Surface *s = surfaces[i];
  869. s->num_edges = s->num_triangles * 3;
  870. csv_Edge *e = new csv_Edge[s->num_edges]; // create temporary edges
  871. for(int j = 0, k = 0; j < s->num_edges; j += 3, k++) {
  872. e[j + 0].v[0] = s->triangles[k].v[0];
  873. e[j + 0].v[1] = s->triangles[k].v[1];
  874. e[j + 1].v[0] = s->triangles[k].v[1];
  875. e[j + 1].v[1] = s->triangles[k].v[2];
  876. e[j + 2].v[0] = s->triangles[k].v[2];
  877. e[j + 2].v[1] = s->triangles[k].v[0];
  878. e[j + 0].id = j + 0;
  879. e[j + 1].id = j + 1;
  880. e[j + 2].id = j + 2;
  881. }
  882. qsort(e,s->num_edges,sizeof(csv_Edge),csv_edge_cmp); // optimize it
  883. int num_optimized_edges = 0;
  884. int *ebuf = new int[s->num_edges];
  885. int *rbuf = new int[s->num_edges];
  886. for(int j = 0; j < s->num_edges; j++) {
  887. if(j == 0 || csv_edge_cmp(&e[num_optimized_edges - 1],&e[j])) e[num_optimized_edges++] = e[j];
  888. ebuf[e[j].id] = num_optimized_edges - 1;
  889. rbuf[e[j].id] = e[num_optimized_edges - 1].v[0] != e[j].v[0];
  890. }
  891. s->num_edges = num_optimized_edges;
  892. s->edges = new Edge[s->num_edges];
  893. for(int j = 0; j < s->num_edges; j++) {
  894. s->edges[j].v[0] = e[j].v[0];
  895. s->edges[j].v[1] = e[j].v[1];
  896. s->edges[j].reverse = 0;
  897. s->edges[j].flag = 0;
  898. }
  899. for(int j = 0, k = 0; j < s->num_triangles; j++, k += 3) {
  900. Triangle *t = &s->triangles[j];
  901. t->e[0] = ebuf[k + 0];
  902. t->e[1] = ebuf[k + 1];
  903. t->e[2] = ebuf[k + 2];
  904. t->reverse[0] = rbuf[k + 0];
  905. t->reverse[1] = rbuf[k + 1];
  906. t->reverse[2] = rbuf[k + 2];
  907. }
  908. s->shadow_volume_vertex = new vec4[s->num_edges * 4];
  909. delete rbuf;
  910. delete ebuf;
  911. delete e;
  912. }
  913. }