MDLModel.cpp
Upload User: xuczgm
Upload Date: 2022-04-25
Package Size: 8601k
Code Size: 23k
Category:

Special Effects

Development Platform:

Visual C++

  1. #include "stdafx.h"
  2. #include "MdlModel.h"
  3. DWORD CurrentTexture = 1;
  4. vec3_t TransformVertices[MAXVERTICES]; // Transformed vertices
  5. vec3_t LightValues[MAXVERTICES]; // Light surface normals
  6. vec3_t *TransformVertPtr;
  7. vec3_t *LightValuesPtr;
  8. vec3_t LightVector; // Light vector in model reference frame
  9. vec3_t BoneLightVector[MAXBONES]; // Light vectors in bone reference frames
  10. long AmbientLightColor; // Ambient world light
  11. float ShadeLight; // Direct world light
  12. vec3_t LightColor;
  13. float BoneTransforms[MAXBONES][3][4]; // Bone transformation matrix
  14. void TMDLModel::Init(char *Filename)
  15. { char TextureName[256];
  16. char SeqGroupName[256];
  17. Header = LoadModel(Filename);
  18. if (0 == Header->NumTextures)
  19. { strcpy(TextureName, Filename);
  20. // strcpy(&TextureName[strlen(TextureName) - 4], "T.mdl");
  21. TextureHeader = LoadModel(TextureName);
  22. }
  23. else
  24. { TextureHeader = Header;
  25. }
  26. if (Header->NumSeqGroups > 1)
  27. { for (long Loop = 1; Loop < Header->NumSeqGroups; Loop++)
  28. { strcpy(SeqGroupName, Filename);
  29. sprintf(&SeqGroupName[strlen(SeqGroupName) - 4], "%02d.mdl", Loop);
  30. AnimationHeader[Loop] = LoadDemandSequences(SeqGroupName);
  31. }
  32. }
  33. }
  34. void TMDLModel::AdvanceFrame(float Time)
  35. {
  36. tagMDLSeqDescription *SeqDescription = (tagMDLSeqDescription *)((BYTE *)Header + 
  37. Header->SequenceOffset) + CurrentSequence;
  38. if (Time > 0.1f)
  39. {
  40. Time = 0.1f;
  41. }
  42. CurrentFrame += Time * SeqDescription->Timing;
  43. if (SeqDescription->NumFrames <= 1)
  44. {
  45. CurrentFrame = 0;
  46. }
  47. else
  48. {
  49. CurrentFrame -= (long)(CurrentFrame / (SeqDescription->NumFrames - 1)) * 
  50. (SeqDescription->NumFrames - 1);
  51. }
  52. }
  53. void TMDLModel::ExtractBoundBox(float *Minimums, float *Maximums)
  54. {
  55. tagMDLSeqDescription *SeqDescription = (tagMDLSeqDescription *)((BYTE *)Header + 
  56. Header->SequenceOffset);
  57. Minimums[0] = SeqDescription[CurrentSequence].BoundingBoxMinimum[0];
  58. Minimums[1] = SeqDescription[CurrentSequence].BoundingBoxMinimum[1];
  59. Minimums[2] = SeqDescription[CurrentSequence].BoundingBoxMinimum[2];
  60. Maximums[0] = SeqDescription[CurrentSequence].BoundingBoxMaximum[0];
  61. Maximums[1] = SeqDescription[CurrentSequence].BoundingBoxMaximum[1];
  62. Maximums[2] = SeqDescription[CurrentSequence].BoundingBoxMaximum[2];
  63. }
  64. long TMDLModel::SetSequence(long Sequence)
  65. {
  66. if (Sequence > Header->NumSequences)
  67. {
  68. Sequence = 0;
  69. }
  70. else if (Sequence < 0)
  71. {
  72. Sequence = Header->NumSequences - 1;
  73. }
  74. CurrentSequence = Sequence;
  75. CurrentFrame = 0;
  76. return CurrentSequence;
  77. }
  78. long TMDLModel::GetSequence()
  79. {
  80. return CurrentSequence;
  81. }
  82. void TMDLModel::GetSequenceInfo(float *FrameRate, float *GroundSpeed)
  83. {
  84. tagMDLSeqDescription *SeqDescription = (tagMDLSeqDescription *)((BYTE *)Header + 
  85. Header->SequenceOffset) + CurrentSequence;
  86. if (SeqDescription->NumFrames > 1)
  87. {
  88. *FrameRate = 256 * SeqDescription->Timing / (SeqDescription->NumFrames - 1);
  89. *GroundSpeed = (float)sqrt(SeqDescription->LinearMovement[0] * 
  90. SeqDescription->LinearMovement[0] + SeqDescription->LinearMovement[1] * 
  91. SeqDescription->LinearMovement[1] + SeqDescription->LinearMovement[2] * 
  92. SeqDescription->LinearMovement[2]);
  93. *GroundSpeed = *GroundSpeed * SeqDescription->Timing / (SeqDescription->NumFrames - 1);
  94. }
  95. else
  96. {
  97. *FrameRate = 256.0f;
  98. *GroundSpeed = 0.0f;
  99. }
  100. }
  101. float TMDLModel::SetController(long ControllerIndex, float Value)
  102. {
  103. tagMDLBoneController *BoneController = 
  104. (tagMDLBoneController *)((BYTE *)Header + Header->BoneControllerOffset);
  105. for (long Loop = 0; Loop < Header->NumBoneControllers; Loop++, BoneController++)
  106. {
  107. if (BoneController->Index == ControllerIndex)
  108. {
  109. break;
  110. }
  111. }
  112. if (Loop >= Header->NumBoneControllers)
  113. {
  114. return Value;
  115. }
  116. if (BoneController->Type & (TRANSITION_XR | TRANSITION_YR | TRANSITION_ZR))
  117. {
  118. if (BoneController->End < BoneController->Start)
  119. {
  120. Value = -Value;
  121. }
  122. if (BoneController->Start + 359.0f >= BoneController->End)
  123. {
  124. if (Value > ((BoneController->Start + BoneController->End) / 2.0f) + 180)
  125. {
  126. Value = Value - 360.0f;
  127. }
  128. if (Value < ((BoneController->Start + BoneController->End) / 2.0f) - 180)
  129. {
  130. Value = Value + 360.0f;
  131. }
  132. }
  133. else
  134. {
  135. if (Value > 360.0f)
  136. {
  137. Value = Value - (long)(Value / 360.0f) * 360.0f;
  138. }
  139. else if (Value < 0.0f)
  140. {
  141. Value = Value + (long)((Value / -360.0f) + 1.0f) * 360.0f;
  142. }
  143. }
  144. }
  145. long Setting = (long)(255.0f * (Value - BoneController->Start) / (BoneController->End - 
  146. BoneController->Start));
  147. if (Setting < 0)
  148. {
  149. Setting = 0;
  150. }
  151. else if (Setting > 255)
  152. {
  153. Setting = 255;
  154. }
  155. Controller[ControllerIndex] = (BYTE)Setting;
  156. return Setting * (1.0f / 255.0f) * (BoneController->End - BoneController->Start) + 
  157. BoneController->Start;
  158. }
  159. float TMDLModel::SetMouth(float Value)
  160. {
  161. tagMDLBoneController *BoneController = 
  162. (tagMDLBoneController *)((BYTE *)Header + Header->BoneControllerOffset);
  163. for (long Loop = 0; Loop < Header->NumBoneControllers; Loop++, BoneController++)
  164. {
  165. if (4 == BoneController->Index)
  166. {
  167. break;
  168. }
  169. }
  170. if (BoneController->Type & (TRANSITION_XR | TRANSITION_YR | TRANSITION_ZR))
  171. {
  172. if (BoneController->End < BoneController->Start)
  173. {
  174. Value = -Value;
  175. }
  176. if (BoneController->Start + 359.0f >= BoneController->End)
  177. {
  178. if (Value > ((BoneController->Start + BoneController->End) / 2.0f) + 180.0f)
  179. {
  180. Value = Value - 360.0f;
  181. }
  182. if (Value < ((BoneController->Start + BoneController->End) / 2.0f) - 180.0f)
  183. {
  184. Value = Value + 360.0f;
  185. }
  186. }
  187. else
  188. {
  189. if (Value > 360.0f)
  190. {
  191. Value = Value - (long)(Value / 360.0f) * 360.0f;
  192. }
  193. else if (Value < 0.0f)
  194. {
  195. Value = Value + (long)((Value / -360.0f) + 1.0f) * 360.0f;
  196. }
  197. }
  198. }
  199. long Setting = (long)(64.0f * (Value - BoneController->Start) / (BoneController->End - 
  200. BoneController->Start));
  201. if (Setting < 0)
  202. {
  203. Setting = 0;
  204. }
  205. if (Setting > 64)
  206. {
  207. Setting = 64;
  208. }
  209. MouthPosition = (BYTE)Setting;
  210. return Setting * (1.0f / 64.0f) * (BoneController->End - BoneController->Start) + 
  211. BoneController->Start;
  212. }
  213. float TMDLModel::SetBlending(long Blender, float Value)
  214. {
  215. tagMDLSeqDescription *SeqDescription = 
  216. (tagMDLSeqDescription *)((BYTE *)Header + Header->SequenceOffset) + CurrentSequence;
  217. if (0 == SeqDescription->BlendType[Blender])
  218. {
  219. return Value;
  220. }
  221. if (SeqDescription->BlendType[Blender] & (TRANSITION_XR | TRANSITION_YR | TRANSITION_ZR))
  222. {
  223. if (SeqDescription->BlendEnd[Blender] < SeqDescription->BlendStart[Blender])
  224. {
  225. Value = -Value;
  226. }
  227. if (SeqDescription->BlendStart[Blender] + 359.0f >= SeqDescription->BlendEnd[Blender])
  228. {
  229. if (Value > ((SeqDescription->BlendStart[Blender] + 
  230. SeqDescription->BlendEnd[Blender]) / 2.0f) + 180.0f)
  231. {
  232. Value = Value - 360.0f;
  233. }
  234. if (Value < ((SeqDescription->BlendStart[Blender] + 
  235. SeqDescription->BlendEnd[Blender]) / 2.0f) - 180.0f)
  236. {
  237. Value = Value + 360.0f;
  238. }
  239. }
  240. }
  241. long Setting = (long)(255.0f * (Value - SeqDescription->BlendStart[Blender]) / 
  242. (SeqDescription->BlendEnd[Blender] - SeqDescription->BlendStart[Blender]));
  243. if (Setting < 0)
  244. {
  245. Setting = 0;
  246. }
  247. if (Setting > 255)
  248. {
  249. Setting = 255;
  250. }
  251. Blending[Blender] = (BYTE)Setting;
  252. return Setting * (1.0f / 255.0f) * (SeqDescription->BlendEnd[Blender] - 
  253. SeqDescription->BlendStart[Blender]) + SeqDescription->BlendStart[Blender];
  254. }
  255. long TMDLModel::SetBodyGroup(long Group, long Value)
  256. {
  257. if (Group > Header->NumBodyParts)
  258. {
  259. return -1;
  260. }
  261. tagMDLBodyPart *BodyPart = 
  262. (tagMDLBodyPart *)((BYTE *)Header + Header->BodyPartOffset) + Group;
  263. long Current = (CurrentBodyPart / BodyPart->Base) % BodyPart->NumModels;
  264. if (Value >= BodyPart->NumModels)
  265. {
  266. return Current;
  267. }
  268. CurrentBodyPart = (CurrentBodyPart - (Current * BodyPart->Base) + (Value * BodyPart->Base));
  269. return Value;
  270. }
  271. long TMDLModel::SetSkin(long Value)
  272. {
  273. if (Value < Header->NumSkinFamilies)
  274. {
  275. return CurrentSkin;
  276. }
  277. CurrentSkin = Value;
  278. return Value;
  279. }
  280. tagMDLHeader *TMDLModel::LoadModel(char *Filename)
  281. {
  282. FILE *Handle;
  283. long Size;
  284. BYTE *Buffer;
  285. Handle = fopen(Filename, "rb");
  286. if (NULL == Handle)
  287. {
  288. printf("Unable to open %sn", Filename);
  289. exit(1);
  290. }
  291. fseek(Handle, 0, SEEK_END);
  292. Size = ftell(Handle);
  293. rewind(Handle);
  294. Buffer = new BYTE[Size];
  295. if (NULL == Buffer)
  296. {
  297. printf("Unable to allocate memoryn");
  298. exit(1);
  299. }
  300. fread(Buffer, Size, 1, Handle);
  301. fclose(Handle);
  302. tagMDLHeader *MDLHeader = (tagMDLHeader *)Buffer;
  303. tagMDLTexture *Texture = (tagMDLTexture *)(Buffer + MDLHeader->TextureOffset);
  304. if (MDLHeader->TextureOffset != 0)
  305. {
  306. for (long Loop = 0; Loop < MDLHeader->NumTextures; Loop++)
  307. {
  308. UploadTexture(&Texture[Loop], Buffer + Texture[Loop].Index, Buffer + 
  309. Texture[Loop].Width * Texture[Loop].Height + Texture[Loop].Index);
  310. }
  311. }
  312. return (tagMDLHeader *)Buffer;
  313. }
  314. tagMDLSeqHeader *TMDLModel::LoadDemandSequences(char *Filename)
  315. {
  316. FILE *Handle;
  317. long Size;
  318. BYTE *Buffer;
  319. Handle = fopen(Filename, "rb");
  320. if (NULL == Handle)
  321. {
  322. printf("Unable to open %sn", Filename);
  323. exit(1);
  324. }
  325. fseek(Handle, 0, SEEK_END);
  326. Size = ftell(Handle);
  327. rewind(Handle);
  328. Buffer = new BYTE[Size];
  329. if (NULL == Buffer)
  330. {
  331. printf("Unable to allocate memoryn");
  332. exit(1);
  333. }
  334. fread(Buffer, Size, 1, Handle);
  335. fclose(Handle);
  336. return (tagMDLSeqHeader *)Buffer;
  337. }
  338. void TMDLModel::CalcBoneQuaternion(long Frame, float Value, tagMDLBone *Bone, tagAnimation *Anim, 
  339. float *Q)
  340. {
  341. vec3_t Angle1;
  342. vec3_t Angle2;
  343. tagMDLAnimFrame *AnimValue;
  344. for (long Loop = 0; Loop < 3; Loop++)
  345. {
  346. if (0 == Anim->Offset[Loop + 3])
  347. {
  348. Angle2[Loop] = Angle1[Loop] = Bone->Value[Loop + 3];
  349. }
  350. else
  351. {
  352. AnimValue = (tagMDLAnimFrame *)((BYTE *)Anim + Anim->Offset[Loop + 3]);
  353. long Index = Frame;
  354. while (AnimValue->Total <= Index)
  355. {
  356. Index -= AnimValue->Total;
  357. AnimValue += AnimValue->Valid + 1;
  358. }
  359. if (AnimValue->Valid > Index)
  360. {
  361. Angle1[Loop] = AnimValue[Index + 1].Value;
  362. if (AnimValue->Valid > Index + 1)
  363. {
  364. Angle2[Loop] = AnimValue[Index + 2].Value;
  365. }
  366. else
  367. {
  368. if (AnimValue->Total > Index + 1)
  369. {
  370. Angle2[Loop] = Angle1[Loop];
  371. }
  372. else
  373. {
  374. Angle2[Loop] = AnimValue[AnimValue->Valid + 2].Value;
  375. }
  376. }
  377. }
  378. else
  379. {
  380. Angle1[Loop] = AnimValue[AnimValue->Valid].Value;
  381. if (AnimValue->Total > Index + 1)
  382. {
  383. Angle2[Loop] = Angle1[Loop];
  384. }
  385. else
  386. {
  387. Angle2[Loop] = AnimValue[AnimValue->Valid + 2].Value;
  388. }
  389. }
  390. Angle1[Loop] = Bone->Value[Loop + 3] + Angle1[Loop] * Bone->Scale[Loop + 3];
  391. Angle2[Loop] = Bone->Value[Loop + 3] + Angle2[Loop] * Bone->Scale[Loop + 3];
  392. }
  393. }
  394. if (!VectorCompare(Angle1, Angle2))
  395. {
  396. vec4_t Q1;
  397. vec4_t Q2;
  398. AngleQuaternion(Angle1, Q1);
  399. AngleQuaternion(Angle2, Q2);
  400. QuaternionSlerp(Q1, Q2, Value, Q);
  401. }
  402. else
  403. {
  404. AngleQuaternion(Angle1, Q);
  405. }
  406. }
  407. void TMDLModel::CalcBonePosition(long Frame, float Value, tagMDLBone *Bone, tagAnimation *Anim, 
  408. float *Pos)
  409. {
  410. tagMDLAnimFrame *AnimValue;
  411. for (long Loop = 0; Loop < 3; Loop++)
  412. {
  413. Pos[Loop] = Bone->Value[Loop];
  414. if (Anim->Offset[Loop] != 0)
  415. {
  416. AnimValue = (tagMDLAnimFrame *)((BYTE *)Anim + Anim->Offset[Loop]);
  417. long Index = Frame;
  418. while (AnimValue->Total <= Index)
  419. {
  420. Index -= AnimValue->Total;
  421. AnimValue += AnimValue->Valid + 1;
  422. }
  423. if (AnimValue->Valid > Index)
  424. {
  425. if (AnimValue->Valid > Index + 1)
  426. {
  427. Pos[Loop] += (AnimValue[Index + 1].Value * (1.0f - Value) + Value * 
  428. AnimValue[Index + 2].Value) * Bone->Scale[Loop];
  429. }
  430. else
  431. {
  432. Pos[Loop] += AnimValue[Index + 1].Value * Bone->Scale[Loop];
  433. }
  434. }
  435. else
  436. {
  437. if (AnimValue->Total <= Index + 1)
  438. {
  439. Pos[Loop] += (AnimValue[AnimValue->Valid].Value * (1.0f - Value) + Value * 
  440. AnimValue[AnimValue->Valid + 2].Value) * Bone->Scale[Loop];
  441. }
  442. else
  443. {
  444. Pos[Loop] += AnimValue[AnimValue->Valid].Value * Bone->Scale[Loop];
  445. }
  446. }
  447. }
  448. }
  449. }
  450. void TMDLModel::CalcRotations(vec3_t *Pos, vec4_t *Q, tagMDLSeqDescription *SeqDescription, 
  451. tagAnimation *Anim, float FrameValue)
  452. {
  453. long Frame;
  454. float Fractional;
  455. Frame = (long)FrameValue;
  456. Fractional = (FrameValue - Frame);
  457. tagMDLBone *Bone = (tagMDLBone *)((BYTE *)Header + Header->BoneOffset);
  458. for (long Loop = 0; Loop < Header->NumBones; Loop++, Bone++, Anim++) 
  459. {
  460. CalcBoneQuaternion(Frame, Fractional, Bone, Anim, Q[Loop]);
  461. CalcBonePosition(Frame, Fractional, Bone, Anim, Pos[Loop]);
  462. }
  463. if (SeqDescription->MotionType & TRANSITION_X)
  464. {
  465. Pos[SeqDescription->MotionBone][0] = 0.0f;
  466. }
  467. if (SeqDescription->MotionType & TRANSITION_Y)
  468. {
  469. Pos[SeqDescription->MotionBone][1] = 0.0f;
  470. }
  471. if (SeqDescription->MotionType & TRANSITION_Z)
  472. {
  473. Pos[SeqDescription->MotionBone][2] = 0.0f;
  474. }
  475. }
  476. tagAnimation *TMDLModel::GetAnim(tagMDLSeqDescription *SeqDescription)
  477. {
  478. tagMDLSeqGroup *pseqgroup = (tagMDLSeqGroup *)((BYTE *)Header + 
  479. Header->SeqGroupOffset) + SeqDescription->SeqGroup;
  480. if (SeqDescription->SeqGroup == 0)
  481. {
  482. return (tagAnimation *)((BYTE *)Header + pseqgroup->Data + 
  483. SeqDescription->AnimOffset);
  484. }
  485. return (tagAnimation *)((BYTE *)AnimationHeader[SeqDescription->SeqGroup] + 
  486. SeqDescription->AnimOffset);
  487. }
  488. void TMDLModel::SlerpBones(vec4_t Q1[], vec3_t Pos1[], vec4_t Q2[], vec3_t Pos2[], float Value)
  489. {
  490. vec4_t Q3;
  491. float Inverse;
  492. if (Value < 0.0f)
  493. {
  494. Value = 0.0f;
  495. }
  496. else if (Value > 1.0f)
  497. {
  498. Value = 1.0f;
  499. }
  500. Inverse = 1.0f - Value;
  501. for (long Loop = 0; Loop < Header->NumBones; Loop++)
  502. {
  503. QuaternionSlerp(Q1[Loop], Q2[Loop], Value, Q3);
  504. Q1[Loop][0] = Q3[0];
  505. Q1[Loop][1] = Q3[1];
  506. Q1[Loop][2] = Q3[2];
  507. Q1[Loop][3] = Q3[3];
  508. Pos1[Loop][0] = Pos1[Loop][0] * Inverse + Pos2[Loop][0] * Value;
  509. Pos1[Loop][1] = Pos1[Loop][1] * Inverse + Pos2[Loop][1] * Value;
  510. Pos1[Loop][2] = Pos1[Loop][2] * Inverse + Pos2[Loop][2] * Value;
  511. }
  512. }
  513. void TMDLModel::SetUpBones()
  514. {
  515. float BoneMatrix[3][4];
  516. static vec3_t Pos1[MAXBONES];
  517. static vec4_t Q1[MAXBONES];
  518. static vec3_t Pos2[MAXBONES];
  519. static vec4_t Q2[MAXBONES];
  520. static vec3_t Pos3[MAXBONES];
  521. static vec4_t Q3[MAXBONES];
  522. static vec3_t Pos4[MAXBONES];
  523. static vec4_t Q4[MAXBONES];
  524. if (CurrentSequence >= Header->NumSequences)
  525. {
  526. CurrentSequence = 0;
  527. }
  528. tagMDLSeqDescription *SeqDescription = (tagMDLSeqDescription *)((BYTE *)Header + 
  529. Header->SequenceOffset) + CurrentSequence;
  530. tagAnimation *Anim = GetAnim(SeqDescription);
  531. CalcRotations(Pos1, Q1, SeqDescription, Anim, CurrentFrame);
  532. if (SeqDescription->NumBlends > 1)
  533. {
  534. float Value;
  535. Anim += Header->NumBones;
  536. CalcRotations(Pos2, Q2, SeqDescription, Anim, CurrentFrame);
  537. Value = Blending[0] / 255.0f;
  538. SlerpBones(Q1, Pos1, Q2, Pos2, Value);
  539. if (4 == SeqDescription->NumBlends)
  540. {
  541. Anim += Header->NumBones;
  542. CalcRotations(Pos3, Q3, SeqDescription, Anim, CurrentFrame);
  543. Anim += Header->NumBones;
  544. CalcRotations(Pos4, Q4, SeqDescription, Anim, CurrentFrame);
  545. Value = Blending[0] / 255.0f;
  546. SlerpBones(Q3, Pos3, Q4, Pos4, Value);
  547. Value = Blending[1] / 255.0f;
  548. SlerpBones(Q1, Pos1, Q3, Pos3, Value);
  549. }
  550. }
  551. tagMDLBone *Bones = (tagMDLBone *)((BYTE *)Header + Header->BoneOffset);
  552. for (long Loop = 0; Loop < Header->NumBones; Loop++)
  553. {
  554. QuaternionMatrix(Q1[Loop], BoneMatrix);
  555. BoneMatrix[0][3] = Pos1[Loop][0];
  556. BoneMatrix[1][3] = Pos1[Loop][1];
  557. BoneMatrix[2][3] = Pos1[Loop][2];
  558. if (-1 == Bones[Loop].Parent)
  559. {
  560. memcpy(BoneTransforms[Loop], BoneMatrix, sizeof(float) * 12);
  561. else
  562. {
  563. R_ConcatTransforms(BoneTransforms[Bones[Loop].Parent], BoneMatrix, 
  564. BoneTransforms[Loop]);
  565. }
  566. }
  567. }
  568. void TMDLModel::Lighting(float *lv, long Bone, long Flags, vec3_t Normal)
  569. {
  570. float  Illumination;
  571. float LightCosine;
  572. Illumination = (float)AmbientLightColor;
  573. if (Flags & LIGHT_FLATSHADE)
  574. {
  575. Illumination += ShadeLight * 0.8f;
  576. else 
  577. {
  578. float Value;
  579. LightCosine = DotProduct (Normal, BoneLightVector[Bone]);
  580. if (LightCosine > 1.0f)
  581. {
  582. LightCosine = 1.0f;
  583. }
  584. Illumination += ShadeLight;
  585. Value = 1.5f;
  586. if (Value <= 1.0f)
  587. {
  588. Value = 1.0f;
  589. }
  590. LightCosine = (LightCosine + (Value - 1.0f)) / Value; 
  591. if (LightCosine > 0.0f) 
  592. {
  593. Illumination -= ShadeLight * LightCosine; 
  594. }
  595. if (Illumination <= 0)
  596. {
  597. Illumination = 0;
  598. }
  599. }
  600. if (Illumination > 255) 
  601. {
  602. Illumination = 255;
  603. }
  604. *lv = Illumination / 255.0f;
  605. }
  606. void TMDLModel::SetupLighting()
  607. {
  608. AmbientLightColor = 32;
  609. ShadeLight = 192;
  610. LightVector[0] = 0.0f;
  611. LightVector[1] = 0.0f;
  612. LightVector[2] = -1.0f;
  613. LightColor[0] = 1.0f;
  614. LightColor[1] = 1.0f;
  615. LightColor[2] = 1.0f;
  616. for (long Loop = 0; Loop < Header->NumBones; Loop++)
  617. {
  618. VectorIRotate(LightVector, BoneTransforms[Loop], BoneLightVector[Loop]);
  619. }
  620. }
  621. void TMDLModel::SetupModel(long BodyPart)
  622. {
  623. if (BodyPart > Header->NumBodyParts)
  624. {
  625. BodyPart = 0;
  626. }
  627. tagMDLBodyPart   *BodyPartPtr = (tagMDLBodyPart *)((BYTE *)Header + Header->BodyPartOffset) + 
  628. BodyPart;
  629. long Index = CurrentBodyPart / BodyPartPtr->Base;
  630. Index = Index % BodyPartPtr->NumModels;
  631. Model = (tagMDLModel *)((BYTE *)Header + BodyPartPtr->ModelOffset) + Index;
  632. }
  633. void TMDLModel::DrawModel()
  634. { TransformVertPtr = &TransformVertices[0];
  635. LightValuesPtr = &LightValues[0];
  636. if (0 == Header->NumBodyParts) return;
  637. /* glPushMatrix();
  638.     glTranslatef(Origin[0], Origin[1], Origin[2]);
  639.     glRotatef(Rotation[1], 0, 0, 1);
  640.     glRotatef(Rotation[0], 0, 1, 0);
  641.     glRotatef(Rotation[2], 1, 0, 0);
  642. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);*/
  643. SetUpBones();
  644. SetupLighting();
  645. for (long Loop = 0; Loop < Header->NumBodyParts; Loop++) 
  646. { SetupModel(Loop);
  647. DrawPoints();
  648. }
  649. // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  650. // glPopMatrix();
  651. }
  652. /////////////////////////////////////////////////////////////
  653. void TMDLModel::DrawPoints()//显示0
  654. { float *LightValue;
  655. BYTE *BoneVertexPtr = ((BYTE *)Header + Model->VertexInfoOffset);
  656. BYTE *BoneNormalPtr = ((BYTE *)Header + Model->NormalInfoOffset);
  657. tagMDLTexture *Texture = (tagMDLTexture *)((BYTE *)TextureHeader + 
  658. TextureHeader->TextureOffset);
  659. tagMDLMesh *MeshPtr = (tagMDLMesh *)((BYTE *)Header + Model->MeshOffset);
  660. vec3_t *Vertices = (vec3_t *)((BYTE *)Header + Model->VertexOffset);
  661. vec3_t *Normals = (vec3_t *)((BYTE *)Header + Model->NormalOffset);
  662. short *SkinReference = (short *)((BYTE *)TextureHeader + TextureHeader->SkinOffset);
  663. if (CurrentSkin != 0 && CurrentSkin < TextureHeader->NumSkinFamilies)
  664. SkinReference += (CurrentSkin * TextureHeader->NumSkinReferences);
  665. for (long Loop = 0; Loop < Model->NumVertices; Loop++)
  666. { VectorTransform(Vertices[Loop], BoneTransforms[BoneVertexPtr[Loop]], 
  667. TransformVertPtr[Loop]);
  668. }
  669. LightValue = (float *)LightValuesPtr;
  670. for (long OuterLoop = 0; OuterLoop < Model->NumMesh; OuterLoop++) 
  671. { long Flags = Texture[SkinReference[MeshPtr[OuterLoop].SkinReference]].Flags;
  672. for (long InnerLoop = 0; InnerLoop < MeshPtr[OuterLoop].NumNormals; InnerLoop++, 
  673. LightValue += 3, Normals++, BoneNormalPtr++)
  674. { float Temp;
  675. Lighting(&Temp, *BoneNormalPtr, Flags, (float *)Normals);
  676. LightValue[0] = Temp * LightColor[0];
  677. LightValue[1] = Temp * LightColor[1];
  678. LightValue[2] = Temp * LightColor[2];
  679. }
  680. }
  681. // glCullFace(GL_FRONT);
  682. for (Loop = 0; Loop < Model->NumMesh; Loop++) 
  683. { MeshPtr = (tagMDLMesh *)((BYTE *)Header + Model->MeshOffset) + Loop;
  684. short *Triangles = (short *)((BYTE *)Header + MeshPtr->TriangleOffset);
  685. float U = 1.0f / (float)Texture[SkinReference[MeshPtr->SkinReference]].Width;
  686. float V = 1.0f / (float)Texture[SkinReference[MeshPtr->SkinReference]].Height;
  687. glBindTexture(GL_TEXTURE_2D, Texture[SkinReference[MeshPtr->SkinReference]].Index);
  688. long NumTriangles;
  689. while (NumTriangles = *(Triangles++))
  690. { if (NumTriangles < 0)
  691. { glBegin(GL_TRIANGLE_FAN);
  692. NumTriangles = -NumTriangles;
  693. }
  694. else glBegin(GL_TRIANGLE_STRIP);
  695. for (; NumTriangles > 0; NumTriangles--, Triangles += 4)
  696. { glTexCoord2f(Triangles[2] * U, Triangles[3] * V);
  697. LightValue = LightValuesPtr[Triangles[1]];
  698. glColor4f(LightValue[0], LightValue[1], LightValue[2], 1.0f);
  699. float *Vertex = TransformVertPtr[Triangles[0]];
  700. glVertex3f(Vertex[0], Vertex[1], Vertex[2]);
  701. }
  702. glEnd();
  703. }
  704. }
  705. }
  706. void TMDLModel::UploadTexture(tagMDLTexture *Texture, BYTE *Data, BYTE *Palette)
  707. { long Row1[256];
  708. long Row2[256];
  709. long Column1[256];
  710. long Column2[256];
  711. BYTE *TextureBuffer;
  712. BYTE *BufferPtr;
  713. for (long OutWidth = 1; OutWidth < Texture->Width; OutWidth <<= 1);
  714. if (OutWidth > 256) OutWidth = 256;
  715. for (long OutHeight = 1; OutHeight < Texture->Height; OutHeight <<= 1);
  716. if (OutHeight > 256) OutHeight = 256;
  717. TextureBuffer = new BYTE[OutWidth * OutHeight * 4];
  718. if (NULL == TextureBuffer)
  719. { printf("Unable to allocate memory.n");
  720. exit(1);
  721. }
  722. BufferPtr = TextureBuffer;
  723. for (long Loop = 0; Loop < OutWidth; Loop++)
  724. {
  725. Column1[Loop] = (long)((Loop + 0.25f) * (Texture->Width / (float)OutWidth));
  726. Column2[Loop] = (long)((Loop + 0.75f) * (Texture->Width / (float)OutWidth));
  727. }
  728. for (Loop = 0; Loop < OutHeight; Loop++)
  729. {
  730. Row1[Loop] = (long)((Loop + 0.25f) * (Texture->Height / (float)OutHeight)) * 
  731. Texture->Width;
  732. Row2[Loop] = (long)((Loop + 0.75f) * (Texture->Height / (float)OutHeight)) * 
  733. Texture->Width;
  734. }
  735. for (long OuterLoop = 0;  OuterLoop < OutHeight; OuterLoop++)
  736. {
  737. for (long InnerLoop = 0; InnerLoop < OutWidth; InnerLoop++, BufferPtr += 4)
  738. {
  739. BYTE *Pixel1 = &Palette[Data[Row1[OuterLoop] + Column1[InnerLoop]] * 3];
  740. BYTE *Pixel2 = &Palette[Data[Row1[OuterLoop] + Column2[InnerLoop]] * 3];
  741. BYTE *Pixel3 = &Palette[Data[Row2[OuterLoop] + Column1[InnerLoop]] * 3];
  742. BYTE *Pixel4 = &Palette[Data[Row2[OuterLoop] + Column2[InnerLoop]] * 3];
  743. BufferPtr[0] = (Pixel1[0] + Pixel2[0] + Pixel3[0] + Pixel4[0]) >> 2;
  744. BufferPtr[1] = (Pixel1[1] + Pixel2[1] + Pixel3[1] + Pixel4[1]) >> 2;
  745. BufferPtr[2] = (Pixel1[2] + Pixel2[2] + Pixel3[2] + Pixel4[2]) >> 2;
  746. BufferPtr[3] = 0xFF;
  747. }
  748. }
  749. glBindTexture(GL_TEXTURE_2D, CurrentTexture);
  750. glTexImage2D(GL_TEXTURE_2D, 0, 3, OutWidth, OutHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 
  751. TextureBuffer);
  752. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  753. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  754. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  755. Texture->Index = CurrentTexture;
  756. CurrentTexture++;
  757. delete [] TextureBuffer;
  758. }