.[ ČeskéHry.cz ].

Laboratoř ČeskýchHer.cz - PasteBin

Vložit nový kód

ČeskéHry.cz - KOMUNITA HERNÍCH VÝVOJÁŘŮ

  1. 2026110601h04min50sec
    2 min
  2. 2026110600h59min45sec
    7 min
  3. 2026110600h53min25sec
    14 min
  4. 2026110600h47min15sec
    20 min
  5. 2026110600h41min06sec
    26 min
  6. 2026110600h34min48sec
    32 min
  7. 2026110600h27min46sec
    39 min
  8. 2026110600h23min01sec
    44 min
  9. 2026110600h18min17sec
    49 min
  10. 2026110600h12min25sec
    55 min
Link: http://nopaste.ceske-hry.cz/subdom/nopaste480
Zaslal: nou
Popis: Trieda na načítanie a vykreslenie 3D modelu vo formáte MS3D
Jazyk: C++
Vloženo: 12.9.2007, 14:54
Stáhnout jako soubor
  1. ///////////////////////////////////
  2. //MS3D.h
  3. #ifndef _MS3D_H_NOU_
  4. #define _MS3D_H_NOU_
  5.  
  6. #ifndef byte
  7. typedef unsigned char byte;
  8. #endif // byte
  9.  
  10. #ifndef word
  11. typedef unsigned short word;
  12. #endif // word
  13.  
  14. #include "Matrix.h"
  15. // force one byte alignment
  16. #include <pshpack1.h>
  17.  
  18. typedef struct
  19. {
  20. Bod position;
  21. char boneId;
  22. }
  23. ms3d_vertex;
  24.  
  25. typedef struct
  26. {
  27. word vertexIndices[3];
  28. Vector normal[3];
  29. float s[3];
  30. float t[3];
  31. }
  32. ms3d_triangle;
  33.  
  34. typedef struct
  35. {
  36. word numtriangles;
  37. word *triangleIndices;
  38. char materialIndex;
  39. }
  40. ms3d_group;
  41.  
  42. typedef struct
  43. {
  44. float ambient[4];
  45. float diffuse[4];
  46. float specular[4];
  47. float emissive[4];
  48. float shininess;
  49. float transparency;
  50. char texture[128];
  51. char alphamap[128];
  52. unsigned int textura;
  53. }
  54. ms3d_material;
  55.  
  56. typedef struct
  57. {
  58. float time;
  59. float rotation[3];
  60. }
  61. ms3d_keyframe_rot;
  62.  
  63. typedef struct
  64. {
  65. float time;
  66. float position[3];
  67. }
  68. ms3d_keyframe_pos;
  69.  
  70. typedef struct
  71. {
  72. char name[32];
  73. char parentName[32];
  74. float rotation[3];
  75. float position[3];
  76.  
  77. word numKeyFramesRot;
  78. word numKeyFramesTrans;
  79.  
  80. ms3d_keyframe_rot *keyFramesRot;
  81. ms3d_keyframe_pos *keyFramesTrans;
  82.  
  83. int parent;
  84. Matrix relative;
  85. Matrix absolute;
  86. Matrix final;
  87. }
  88. ms3d_joint;
  89.  
  90. #include <poppack.h>
  91.  
  92. class MS3D
  93. {
  94. private:
  95. word poc_vertex;
  96. ms3d_vertex *vertex;
  97. word poc_triangle;
  98. ms3d_triangle *triangle;
  99. word poc_group;
  100. ms3d_group *group;
  101. word poc_material;
  102. ms3d_material *material;
  103. word poc_joint;
  104. ms3d_joint *joint;
  105. float cas;
  106. public:
  107. MS3D()
  108. {//konstruktor nastavi vsetko na nulu
  109. poc_vertex=0;
  110. vertex=NULL;
  111. poc_triangle=0;
  112. triangle=NULL;
  113. poc_group=0;
  114. group=NULL;
  115. poc_material=0;
  116. material=NULL;
  117. poc_joint=0;
  118. joint=NULL;
  119. cas=0;
  120. }
  121. ~MS3D()
  122. {
  123. delete vertex; delete triangle;
  124. delete group; delete material;
  125. delete joint;
  126. }
  127. int LoadData(char *path);//nacitavanie dat modelu
  128. int LoadTexture();//nacita textury vhodne pri strate kontextu okna
  129. void Setup();//nastavime zakladnu kotru
  130. void Animate(float time);//animujeme kosti
  131. void Draw(float time);//vykreslime
  132. };
  133.  
  134. #endif
  135.  
  136. ///////////////////////////////////
  137. //MS3D.cpp
  138. #include "MS3D.h"
  139. #include <stdio.h>
  140. #include <string.h>
  141. #include "resource.h"
  142.  
  143. int MS3D::LoadData(char *path)
  144. {
  145. FILE *fr;
  146. fr = fopen(path,"rb");//otvorime subor
  147. if(fr==NULL)
  148. return 0;//ak neotvorilo vratime 0
  149.  
  150. char hlavicka[11];
  151. int verzia;
  152. fscanf(fr,"%10s",hlavicka);//nacitame hlavicku
  153. fread(&verzia,sizeof(int),1,fr);//aj verziu
  154. if(0!=strcmp(hlavicka,"MS3D000000") || verzia!=4)//ak sa nezhoduju vratime chybu
  155. return 0;
  156.  
  157. int i,o;
  158. fread(&poc_vertex,sizeof(word),1,fr);//nacitame pocet vertexov modelu
  159. vertex = new ms3d_vertex[poc_vertex];
  160. if(vertex==NULL)//testujeme na chybu pridelovania pamete
  161. {
  162. fprintf(stderr,"Nedostatok pamete na vertexy! %d\n",poc_vertex);
  163. return 0;
  164. }
  165. float poloha[3];//premenna na nacitavanie bodov
  166. for(i=0;i<poc_vertex;i++)//nacitavame vertexy
  167. {
  168. fseek(fr,sizeof(byte),SEEK_CUR);//preskocime pre nas nepotrebny udaj
  169. fread(poloha,sizeof(float),3,fr);//nacitame polohu vertexu
  170. fread(&(vertex+i)->boneId,sizeof(byte),1,fr);
  171. fseek(fr,sizeof(byte),SEEK_CUR);//zase preskok
  172. (vertex+i)->position(poloha);//nastavime polohu vertexu
  173. }
  174.  
  175. fread(&poc_triangle,sizeof(word),1,fr);//nacitame pocet trojuholnikov
  176. triangle = new ms3d_triangle[poc_triangle];
  177. if(triangle==NULL)
  178. {
  179. fprintf(stderr,"Nedostatok pamete na trojuholniky!");
  180. return 0;
  181. }
  182. float normaly[3][3];
  183. for(i=0;i<poc_triangle;i++)
  184. {
  185. fseek(fr,sizeof(word),SEEK_CUR);//preskocime pre nas nepotrebny udaj
  186. fread((triangle+i)->vertexIndices,sizeof(word),3,fr);//nacitame index vertexov
  187. fread(normaly,sizeof(float),3*3,fr);//nacitame normaly
  188. ((triangle+i)->normal+0)->Set(normaly[0]);
  189. ((triangle+i)->normal+1)->Set(normaly[1]);
  190. ((triangle+i)->normal+2)->Set(normaly[2]);
  191. fread((triangle+i)->s,sizeof(float),3,fr);//nacitame texturove koordinaty
  192. fread((triangle+i)->t,sizeof(float),3,fr);//nacitame texturove koordinaty
  193. fseek(fr,sizeof(byte)*2,SEEK_CUR);//preskocime pre nas nepotrebny udaj
  194. }
  195.  
  196. fread(&poc_group,sizeof(word),1,fr);//nacitame pocet skupin
  197. group = new ms3d_group[poc_group];
  198. if(group==NULL)
  199. {
  200. fprintf(stderr,"Nedostatok pamete na skupiny!");
  201. return 0;
  202. }
  203. //nacitavanie hodnot skupin
  204. for(i=0;i<poc_group;i++)
  205. {
  206. fseek(fr,sizeof(byte)+sizeof(char)*32,SEEK_CUR);//preskocime flags a meno skupiny
  207. fread(&(group+i)->numtriangles,sizeof(word),1,fr);//nacitame pocet trojuholnikov v skupine
  208. (group+i)->triangleIndices = new word[(group+i)->numtriangles];
  209. if((group+i)->triangleIndices==NULL)
  210. return 0;
  211. fread((group+i)->triangleIndices,sizeof(word),(group+i)->numtriangles,fr);//nacitame indexy
  212. fread(&(group+i)->materialIndex,sizeof(char),1,fr);//nacitanie indexu materialu
  213. }
  214.  
  215. fread(&poc_material,sizeof(word),1,fr);
  216. material = new ms3d_material[poc_material];
  217. if(material==NULL)return 0;
  218. //nacitame materialy
  219. for(i=0;i<poc_material;i++)
  220. {
  221. fseek(fr,sizeof(char)*32,SEEK_CUR);//preskocenie mena materialu
  222. fread((material+i)->ambient,sizeof(float),4,fr);//nacitanie ambient zlozky
  223. fread((material+i)->diffuse,sizeof(float),4,fr);//nacitanie difuse
  224. fread((material+i)->specular,sizeof(float),4,fr);//nacitame specular
  225. fread((material+i)->emissive,sizeof(float),4,fr);//nacitame emisive
  226. fread(&(material+i)->shininess,sizeof(float),1,fr);//nacitame shiness
  227. fread(&(material+i)->transparency,sizeof(float),1,fr);//nacitame priehladnost
  228. fseek(fr,sizeof(char),SEEK_CUR);//preskakujem mode
  229. fread((material+i)->texture,sizeof(char),128,fr);//nacitame texture name
  230. (material+i)->textura=1;
  231. fseek(fr,sizeof(char)*128,SEEK_CUR);//preskocime alpha mapu pretoze ju budem mat v jednej a zakomettujte tento ak odkomentujete dalsi
  232. //fread((materiali+i)->alphamap,sizeof(char),128,fr); //odkomentujte tento riadok ak chcete nacitavat alphamapu
  233. //fprintf(stderr,"%s\n",materiali->texture);
  234. }
  235. //nacitame kosti
  236. float animFPS;
  237. int poc_framov;
  238.  
  239. fread(&animFPS,sizeof(float),1,fr);//nacitame pocet snimkov za sekundu
  240. fseek(fr,sizeof(float),SEEK_CUR);
  241. fread(&poc_framov,sizeof(int),1,fr);//a celkovy pocet snimkov
  242. cas=poc_framov/animFPS;//celkovy cas animacie
  243.  
  244. fread(&poc_joint,sizeof(word),1,fr);
  245. joint = new ms3d_joint[poc_joint];
  246. if(joint==NULL)return 0;
  247. //nacitame hodnoty kosti a animacie
  248. for(i=0;i<poc_joint;i++)
  249. {
  250. fseek(fr,sizeof(byte),SEEK_CUR);
  251. fread((joint+i)->name,sizeof(char),32,fr);//nacitame meno klbu
  252. fread((joint+i)->parentName,sizeof(char),32,fr);//nacitame meno rodicovskeho klbu
  253. fread((joint+i)->rotation,sizeof(float),3,fr);//nacitame zakladnu rotaciu
  254. fread((joint+i)->position,sizeof(float),3,fr);//nacitame zakladne posunutie
  255.  
  256. fread(&(joint+i)->numKeyFramesRot,sizeof(unsigned short),1,fr);//nacitame pocet snimkov rotacie
  257. fread(&(joint+i)->numKeyFramesTrans,sizeof(unsigned short),1,fr);//nacitame pocet snimkov posunutia
  258.  
  259. (joint+i)->keyFramesRot = new ms3d_keyframe_rot[(joint+i)->numKeyFramesTrans];//alokujeme pamet pre snimky
  260. (joint+i)->keyFramesTrans = new ms3d_keyframe_pos[(joint+i)->numKeyFramesTrans];
  261. fread((joint+i)->keyFramesRot,sizeof(ms3d_keyframe_rot),(joint+i)->numKeyFramesRot,fr);//a nacitame ich
  262. fread((joint+i)->keyFramesTrans,sizeof(ms3d_keyframe_pos),(joint+i)->numKeyFramesTrans,fr);
  263.  
  264. (joint+i)->parent=-1;//nastavieme rodica na -1
  265. /*dalej otestujeme pomocou strcmp() kosti ci existuje rodic a nstavime index
  266. nanho do premenej parents*/
  267. if((joint+i)->parentName[0]=='\0')
  268. continue;/*ak je meno rodica przdne tak preskocime porovnanavanie*/
  269. for(o=i-1;o>=0;o--)//ideme odzadu pretoze redicovsky klb moze byt hned predosly
  270. {
  271. if(!strcmp((joint+o)->name,(joint+i)->parentName))//porovnavame meno rodica s menami klbov
  272. {
  273. (joint+i)->parent=o;//ak najdeme zhodu priradime cislo
  274. break;//a vyskocime z cyklu
  275. }
  276. }
  277. }
  278. fclose(fr);//zatvorime model
  279. if(!LoadTexture())return 0;
  280. Setup();
  281. return 1;
  282. }
  283.  
  284. int MS3D::LoadTexture()
  285. {
  286. TextureRes tex;
  287. for(int i=0;i<poc_material;i++)
  288. {//nahrame textury
  289. if((material+i)->texture[0]!='\0')//podmienka proti nacitavaniu nicoho
  290. (material+i)->textura=tex.LoadTex((material+i)->texture);
  291. if((material+i)->textura==NULL)return 0;
  292. }
  293. return 1;
  294. }
  295.  
  296. void MS3D::Setup()
  297. {
  298. int i,o;
  299. Matrix mat;
  300. for(i=0;i<poc_joint;i++)
  301. {
  302. //vykoname tranformaciu podla zakladnych transformcii
  303. mat.Translate((joint+i)->position[0],(joint+i)->position[1],(joint+i)->position[2]);
  304. mat.Rotate((joint+i)->rotation[0],(joint+i)->rotation[1],(joint+i)->rotation[2]);
  305. (joint+i)->relative=mat;//nakopirujem si relativnu maticu
  306. if((joint+i)->parent!=-1)//ak ma kost rodica tak vynasobime tranformaciu rodica potomkovou
  307. mat=mat*(joint+((joint+i)->parent))->absolute;
  308. (joint+i)->absolute=mat;//a vysledok ulozime
  309. mat.Identity();//vyjednotkujeme maticu
  310. }
  311. for(i=0;i<poc_joint;i++)
  312. {
  313. mat=(joint+i)->absolute;
  314. mat.Inverse();//zinvertizujeme absolutnu maticku kosti
  315. for(o=0;o<poc_vertex;o++)
  316. {
  317. /*a nasledne tranformujeme vsetky body prisluchajuce danej kosti
  318. pomocou danej matice*/
  319. if((vertex+o)->boneId==i)
  320. {
  321. (vertex+o)->position=mat*(vertex+o)->position;
  322. }
  323. }
  324. }
  325. }
  326.  
  327. void MS3D::Animate(float time)
  328. {
  329. glPushMatrix();
  330. int nasobky = time/cas;
  331. time=time-cas*nasobky;
  332. Matrix transform;
  333. float tran[3],rot[3];
  334.  
  335. for(int i=0;i<poc_joint;i++)
  336. {
  337. int prev=0,curr=0;//najdeme aktualny snimok
  338. while(((joint+i)->keyFramesTrans+curr)->time < time && curr<(joint+i)->numKeyFramesTrans)curr++;
  339. prev=curr;
  340. if(curr>0)prev--;
  341. float inter=(time-((joint+i)->keyFramesTrans+prev)->time);//zinterpolujeme medzi dvoma snimkami
  342. if(curr!=prev)inter/=((joint+i)->keyFramesTrans+curr)->time-((joint+i)->keyFramesTrans+prev)->time;
  343. tran[0]=((joint+i)->keyFramesTrans+curr)->position[0]-((joint+i)->keyFramesTrans+prev)->position[0];
  344. tran[1]=((joint+i)->keyFramesTrans+curr)->position[1]-((joint+i)->keyFramesTrans+prev)->position[1];
  345. tran[2]=((joint+i)->keyFramesTrans+curr)->position[2]-((joint+i)->keyFramesTrans+prev)->position[2];
  346. if(curr==(joint+i)->numKeyFramesTrans)inter=0;//ak sem za poslednou snimkou
  347. tran[0]*=inter; tran[1]*=inter; tran[2]*=inter;//tak nulou vynulujeme
  348. tran[0]+=((joint+i)->keyFramesTrans+prev)->position[0];//a ostane len posledna snimka
  349. tran[1]+=((joint+i)->keyFramesTrans+prev)->position[1];
  350. tran[2]+=((joint+i)->keyFramesTrans+prev)->position[2];
  351. transform.Translate(tran[0],tran[1],tran[2]);//spravime translaciu podla aktualneho snimka
  352.  
  353. prev=curr=0;//najdeme teraz rotaciu
  354. while(((joint+i)->keyFramesRot+curr)->time < time && curr<(joint+i)->numKeyFramesRot)curr++;
  355. prev=curr;
  356. if(curr>0)prev--;
  357. inter=(time-((joint+i)->keyFramesRot+prev)->time);
  358. if(curr!=prev)inter/=((joint+i)->keyFramesRot+curr)->time-((joint+i)->keyFramesRot+prev)->time;
  359. rot[0]=((joint+i)->keyFramesRot+curr)->rotation[0]-((joint+i)->keyFramesRot+prev)->rotation[0];
  360. rot[1]=((joint+i)->keyFramesRot+curr)->rotation[1]-((joint+i)->keyFramesRot+prev)->rotation[1];
  361. rot[2]=((joint+i)->keyFramesRot+curr)->rotation[2]-((joint+i)->keyFramesRot+prev)->rotation[2];
  362. if(curr==(joint+i)->numKeyFramesRot)inter=0;//ak sem za poslednou snimkou
  363. rot[0]*=inter; rot[1]*=inter; rot[2]*=inter;//tak nulou vynulujeme
  364. rot[0]+=((joint+i)->keyFramesRot+prev)->rotation[0];//a ostane len posledna snimka
  365. rot[1]+=((joint+i)->keyFramesRot+prev)->rotation[1];
  366. rot[2]+=((joint+i)->keyFramesRot+prev)->rotation[2];
  367. transform.Rotate(rot[0],rot[1],rot[2]);//orotujeme
  368.  
  369. (joint+i)->absolute=transform;//ulozime si posunutie oproti zakladu kvoli normalam
  370. transform=transform*(joint+i)->relative;//posuniem relativnu maticu o animaciu
  371. if((joint+i)->parent!=-1)//ak ma rodica tak nasobime finalnou maticou rodica
  372. transform=transform*(joint+((joint+i)->parent))->final;
  373. (joint+i)->final=transform;//ulozime si zanimovanu maticu
  374. transform.Identity();//zjednickujeme si maticu pre dalsie pouzitie
  375. }
  376. }
  377.  
  378. void MS3D::Draw(float time)
  379. {
  380. Animate(time);
  381. int i,o;
  382. Matrix rela;
  383. for(i=0;i<poc_group;i++)//zacneme kreslit
  384. {
  385. glEnable(GL_LIGHTING);
  386. int material_cis = (group+i)->materialIndex;
  387. if((group+i)->materialIndex!=-1)//ak je nastaveny materialovy index tak nastavime material
  388. {
  389. glMaterialfv( GL_FRONT, GL_AMBIENT, (material+material_cis)->ambient); // Nastav ambient material
  390. glMaterialfv( GL_FRONT, GL_DIFFUSE, (material+material_cis)->diffuse); // Nastav diffuse material
  391. glMaterialfv( GL_FRONT, GL_SPECULAR, (material+material_cis)->specular); // Nastav specular material
  392. glMaterialfv( GL_FRONT, GL_EMISSION, (material+material_cis)->emissive); // Nastav emission material
  393. glMaterialf( GL_FRONT, GL_SHININESS, (material+material_cis)->shininess); // Nastav shininess material
  394. }
  395. else//inak nastavim standartne farby
  396. {
  397. float a[4]={0.1f,0.1f,0.1f,1};
  398. float d[4]={1,1,1,1};
  399. float g[4]={0,0,0,0};
  400. glMaterialfv( GL_FRONT, GL_AMBIENT, a); // Nastav ambient material
  401. glMaterialfv( GL_FRONT, GL_DIFFUSE, d); // Nastav diffuse material
  402. glMaterialfv( GL_FRONT, GL_SPECULAR, g); // Nastav specular material
  403. glMaterialfv( GL_FRONT, GL_EMISSION, g); // Nastav emission material
  404. glMaterialf( GL_FRONT, GL_SHININESS, 64);
  405. }
  406. if((material+material_cis)->textura!=0)//ak existuje textura zvol ju
  407. {
  408. glEnable(GL_TEXTURE_2D);//povolime texturovanie
  409. glBindTexture(GL_TEXTURE_2D,(material+material_cis)->textura);// Zvolí texturu
  410. }
  411. else glDisable(GL_TEXTURE_2D);//ak nie je textura nebude texturovanie
  412.  
  413. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  414.  
  415. int w,p[3],bone[3];
  416. for(o=0;o<(group+i)->numtriangles;o++)
  417. {
  418. w = (group+i)->triangleIndices[o]; //priradime index trojholnika do w a ten nasledne vykreslime
  419.  
  420. p[0] = (triangle+w)->vertexIndices[0];//nastavime si indexy vrcholov
  421. p[1] = (triangle+w)->vertexIndices[1];
  422. p[2] = (triangle+w)->vertexIndices[2];
  423. bone[0] = (vertex+p[0])->boneId;//a indexy kosti
  424. bone[1] = (vertex+p[1])->boneId;
  425. bone[2] = (vertex+p[2])->boneId;
  426.  
  427. Bod v1,v2,v3;//transformujeme body podla animacnej kosti
  428. v1=(joint+bone[0])->final*(vertex+p[0])->position;
  429. v2=(joint+bone[1])->final*(vertex+p[1])->position;
  430. v3=(joint+bone[2])->final*(vertex+p[2])->position;
  431. Vector n1,n2,n3;//pretranformujeme normaly na osvetlenie
  432. n1=(joint+bone[0])->absolute**((triangle+w)->normal+0);
  433. n2=(joint+bone[1])->absolute**((triangle+w)->normal+1);
  434. n3=(joint+bone[2])->absolute**((triangle+w)->normal+2);
  435.  
  436. glBegin(GL_TRIANGLES);
  437. glNormal3f(n1[0],n1[1],n1[2]);// Normála
  438. glTexCoord2f((triangle+w)->s[0], (triangle+w)->t[0]);
  439. glVertex3f(v1[0],v1[1],v1[2]);
  440. glNormal3f(n2[0],n2[1],n2[2]);// Normála
  441. glTexCoord2f((triangle+w)->s[1], (triangle+w)->t[1]);
  442. glVertex3f(v2[0],v2[1],v2[2]);
  443. glNormal3f(n3[0],n3[1],n3[2]);// Normála
  444. glTexCoord2f((triangle+w)->s[2], (triangle+w)->t[2]);
  445. glVertex3f(v3[0],v3[1],v3[2]);
  446. glEnd();
  447. }
  448. }
  449. }
  450.