37 |
* Types declaration corresponding to the format used to store the md3 model. |
* Types declaration corresponding to the format used to store the md3 model. |
38 |
*/ |
*/ |
39 |
|
|
40 |
|
#define MAX_QPATH 64 |
41 |
|
|
42 |
/* |
/* |
43 |
* This holds the header information that is read in |
* This holds the header information that is read in |
44 |
* at the beginning of the file |
* at the beginning of the file |
47 |
{ |
{ |
48 |
char id[4]; /* the file ID - must be "IDP3" */ |
char id[4]; /* the file ID - must be "IDP3" */ |
49 |
int32_t version; /* the file version - must be 15 */ |
int32_t version; /* the file version - must be 15 */ |
50 |
char modelName[68]; /* the name of the model */ |
char modelName[MAX_QPATH]; /* the name of the model */ |
51 |
int16_t numBoneFrames; /* the number of animation frames */ |
int32_t flags; /* ? */ |
52 |
|
int32_t numBoneFrames; /* the number of animation frames */ |
53 |
int32_t numTags; /* the number of tags */ |
int32_t numTags; /* the number of tags */ |
54 |
int32_t numMeshes; /* the number of sub-objets */ |
int32_t numMeshes; /* the number of sub-objets */ |
55 |
int32_t maxTexNum; /* the max number of textures (always 0,i believe) */ |
int32_t maxTexNum; /* the max number of textures (always 0,i believe) */ |
78 |
*/ |
*/ |
79 |
struct MD3Tag_t |
struct MD3Tag_t |
80 |
{ |
{ |
81 |
char tagName[64]; /* the name of the tag */ |
char tagName[MAX_QPATH]; /* the name of the tag */ |
82 |
float pos[3]; /* the position, relative to the model */ |
float pos[3]; /* the position, relative to the model */ |
83 |
float matrix[9]; /* the orientation matrix (rotation) for this frame*/ |
float matrix[9]; /* the orientation matrix (rotation) for this frame*/ |
84 |
}; |
}; |
88 |
*/ |
*/ |
89 |
struct MD3MeshHeader_t |
struct MD3MeshHeader_t |
90 |
{ |
{ |
91 |
char id[4]; /* the mesh ID - must be "IDP3" */ |
char id[4]; /* the mesh ID - must be "IDP3" */ |
92 |
char meshName[68]; /* the name of the mesh */ |
char meshName[MAX_QPATH];/* the name of the mesh */ |
93 |
int32_t numFrames; /* the number of frames |
int32_t flags; /* ? */ |
94 |
* = MD3Header_t::numBoneFrames */ |
int32_t numFrames; /* the number of frames |
95 |
int32_t numTextures; /* the number of textures */ |
* = MD3Header_t::numBoneFrames */ |
96 |
int32_t numVertice; /* the number of vertice */ |
int32_t numTextures; /* the number of textures */ |
97 |
int32_t numTriangles; /* the number of triangles */ |
int32_t numVertice; /* the number of vertice */ |
98 |
int32_t triangleStart; /* the offset for the triangles, |
int32_t numTriangles; /* the number of triangles */ |
99 |
* relative to the mesh */ |
int32_t triangleStart; /* the offset for the triangles, |
100 |
int32_t headerSize; /* the size of the mesh header */ |
* relative to the mesh */ |
101 |
int32_t textureCoordStart; /* the offset for the coordinates of the textures |
int32_t headerSize; /* the size of the mesh header */ |
102 |
* (relative) */ |
int32_t textureCoordStart; /* the offset for the coordinates of the textures |
103 |
int32_t vertexStart; /* the offset for the vertice indices (relative)*/ |
* (relative) */ |
104 |
int32_t meshSize; /* the total size of the mesh */ |
int32_t vertexStart; /* the offset for the vertice indices(relative)*/ |
105 |
|
int32_t meshSize; /* the total size of the mesh */ |
106 |
}; |
}; |
107 |
|
|
108 |
/* |
/* |
110 |
*/ |
*/ |
111 |
struct MD3MeshTexture_t |
struct MD3MeshTexture_t |
112 |
{ |
{ |
113 |
char texName[68]; /* the name of the texture */ |
char texName[MAX_QPATH]; /* the name of the texture */ |
114 |
|
int32_t texIndex; /* texture index */ |
115 |
}; |
}; |
116 |
|
|
117 |
/* |
/* |
136 |
*/ |
*/ |
137 |
struct MD3MeshVertex_t |
struct MD3MeshVertex_t |
138 |
{ |
{ |
139 |
u_int16_t coords[3]; /* vertex coordinates (x, y, z), |
int16_t coords[3]; /* vertex coordinates (x, y, z), |
140 |
* relative to the model */ |
* relative to the model */ |
141 |
u_int8_t texEnv[2]; /* texture coordinates for mapping */ |
u_int8_t texEnv[2]; /* texture coordinates for mapping */ |
142 |
}; |
}; |
158 |
- (struct MD3MeshVertex_t*) _meshVertex: (int32_t)noMesh |
- (struct MD3MeshVertex_t*) _meshVertex: (int32_t)noMesh |
159 |
withNumber: (int32_t)noVertex |
withNumber: (int32_t)noVertex |
160 |
inFrame: (int32_t)noFrame; |
inFrame: (int32_t)noFrame; |
161 |
|
- (const u_int8_t*) _meshTexEnvVertex: (int32_t)noMesh |
162 |
|
withNumber: (int32_t)noVertex |
163 |
|
inFrame: (int32_t)noFrame; |
164 |
- (BOOL) _checkHeader; |
- (BOOL) _checkHeader; |
165 |
- (BOOL) _meshIsValid: (struct MD3MeshHeader_t *)mesh; |
- (BOOL) _meshIsValid: (struct MD3MeshHeader_t *)mesh; |
166 |
- (BOOL) _checkTail; |
- (BOOL) _checkTail; |
213 |
NSParameterAssert (_data); |
NSParameterAssert (_data); |
214 |
|
|
215 |
munmap (_data, _size); |
munmap (_data, _size); |
|
_size = 0; |
|
216 |
|
|
217 |
[super dealloc]; |
[super dealloc]; |
218 |
} |
} |
323 |
/** |
/** |
324 |
* Returns the position of the bone frame located by the number noBoneFrame. |
* Returns the position of the bone frame located by the number noBoneFrame. |
325 |
*/ |
*/ |
326 |
- (const float*) boneFramePosition: (int32_t)noBoneFrame |
- (coord_t) boneFramePosition: (int32_t)noBoneFrame |
327 |
{ |
{ |
328 |
NSParameterAssert (_data); |
NSParameterAssert (_data); |
329 |
NSParameterAssert (noBoneFrame >= 0); |
NSParameterAssert (noBoneFrame >= 0); |
330 |
NSParameterAssert (noBoneFrame < [self nbFrames]); |
NSParameterAssert (noBoneFrame < [self nbFrames]); |
331 |
|
|
332 |
struct MD3BoneFrame_t *boneFrame = [self _boneFrame: noBoneFrame]; |
struct MD3BoneFrame_t *boneFrame = [self _boneFrame: noBoneFrame]; |
333 |
return boneFrame->pos; |
return |
334 |
|
MakeCoord (boneFrame->pos[0], boneFrame->pos[1], boneFrame->pos[2]); |
335 |
} |
} |
336 |
|
|
337 |
|
|
338 |
/** |
/** |
339 |
* Returns the min (x,y,z) value of the bone located by the number noBoneFrame. |
* Returns the min (x,y,z) value of the bone located by the number noBoneFrame. |
340 |
*/ |
*/ |
341 |
- (const float*) boneFrameMins: (int32_t)noBoneFrame |
- (coord_t) boneFrameMins: (int32_t)noBoneFrame |
342 |
{ |
{ |
343 |
NSParameterAssert (_data); |
NSParameterAssert (_data); |
344 |
NSParameterAssert (noBoneFrame >= 0); |
NSParameterAssert (noBoneFrame >= 0); |
345 |
NSParameterAssert (noBoneFrame < [self nbFrames]); |
NSParameterAssert (noBoneFrame < [self nbFrames]); |
346 |
|
|
347 |
struct MD3BoneFrame_t *boneFrame = [self _boneFrame: noBoneFrame]; |
struct MD3BoneFrame_t *boneFrame = [self _boneFrame: noBoneFrame]; |
348 |
return boneFrame->mins; |
return |
349 |
|
MakeCoord (boneFrame->mins[0], boneFrame->mins[1], boneFrame->mins[2]); |
350 |
} |
} |
351 |
|
|
352 |
|
|
353 |
/** |
/** |
354 |
* Returns the max (x,y,z) value of the bone located by the number noBoneFrame. |
* Returns the max (x,y,z) value of the bone located by the number noBoneFrame. |
355 |
*/ |
*/ |
356 |
- (const float*) boneFrameMaxs: (int32_t)noBoneFrame |
- (coord_t) boneFrameMaxs: (int32_t)noBoneFrame |
357 |
{ |
{ |
358 |
NSParameterAssert (_data); |
NSParameterAssert (_data); |
359 |
NSParameterAssert (noBoneFrame >= 0); |
NSParameterAssert (noBoneFrame >= 0); |
360 |
NSParameterAssert (noBoneFrame < [self nbFrames]); |
NSParameterAssert (noBoneFrame < [self nbFrames]); |
361 |
|
|
362 |
struct MD3BoneFrame_t *boneFrame = [self _boneFrame: noBoneFrame]; |
struct MD3BoneFrame_t *boneFrame = [self _boneFrame: noBoneFrame]; |
363 |
return boneFrame->maxs; |
return |
364 |
|
MakeCoord (boneFrame->maxs[0], boneFrame->maxs[1], boneFrame->maxs[2]); |
365 |
} |
} |
366 |
|
|
367 |
|
|
414 |
|
|
415 |
char* tags = ((char*) _data) + [self _tagOffset]; |
char* tags = ((char*) _data) + [self _tagOffset]; |
416 |
|
|
417 |
return |
return |
418 |
((struct MD3Tag_t *) tags) + (noFrame * [self nbTags] + noTag); |
((struct MD3Tag_t *) tags) + (noFrame * [self nbTags] + noTag); |
419 |
} |
} |
420 |
|
|
443 |
* This position is relative to the model, so it gives the translation |
* This position is relative to the model, so it gives the translation |
444 |
* that should be performed. |
* that should be performed. |
445 |
*/ |
*/ |
446 |
- (const float*) tagPosition: (int32_t)noTag |
- (coord_t) tagPosition: (int32_t)noTag |
447 |
inFrame: (int32_t)noFrame |
inFrame: (int32_t)noFrame |
448 |
{ |
{ |
449 |
NSParameterAssert (_data); |
NSParameterAssert (_data); |
454 |
|
|
455 |
struct MD3Tag_t *tag = [self _tag: noTag |
struct MD3Tag_t *tag = [self _tag: noTag |
456 |
inFrame: noFrame]; |
inFrame: noFrame]; |
457 |
return tag->pos; |
return MakeCoord (tag->pos[0],tag->pos[1], tag->pos[2]); |
458 |
} |
} |
459 |
|
|
460 |
/** |
/** |
562 |
|
|
563 |
|
|
564 |
/** |
/** |
565 |
|
|
566 |
* Returns the starting offset of the triangles section of the mesh located |
* Returns the starting offset of the triangles section of the mesh located |
567 |
* by the mesh number. |
* by the mesh number. |
568 |
* This offset is relative to the mesh. |
* This offset is relative to the mesh. |
619 |
NSParameterAssert (noMesh >= 0); |
NSParameterAssert (noMesh >= 0); |
620 |
NSParameterAssert (noMesh < [self nbMeshes]); |
NSParameterAssert (noMesh < [self nbMeshes]); |
621 |
NSParameterAssert (noTexture >= 0); |
NSParameterAssert (noTexture >= 0); |
|
NSParameterAssert (noTexture < [self meshNbTextures: noMesh]); |
|
622 |
|
|
623 |
|
if([self meshNbTextures: noMesh] == 0) |
624 |
|
return ""; |
625 |
|
|
626 |
|
NSParameterAssert (noTexture < [self meshNbTextures: noMesh]); |
627 |
|
|
628 |
struct MD3MeshTexture_t *textures = |
struct MD3MeshTexture_t *textures = |
629 |
(struct MD3MeshTexture_t *) ([self _mesh: noMesh] + 1); |
(struct MD3MeshTexture_t *) ([self _mesh: noMesh] + 1); |
630 |
|
|
636 |
* Returns the triangle located by the triangle number and |
* Returns the triangle located by the triangle number and |
637 |
* contained in the mesh of number noMesh. |
* contained in the mesh of number noMesh. |
638 |
* A triangle is an array of three integer which are the indices |
* A triangle is an array of three integer which are the indices |
639 |
* into the vertice and textures coordinates arrays. |
* into the vertices and textures coordinates arrays. |
640 |
*/ |
*/ |
641 |
- (const int32_t*) meshTriangle: (int32_t)noMesh |
- (triangle_t) meshTriangle: (int32_t)noMesh |
642 |
withNumber: (int32_t)noTriangle |
withNumber: (int32_t)noTriangle |
643 |
{ |
{ |
644 |
NSParameterAssert (_data); |
NSParameterAssert (_data); |
651 |
(struct MD3MeshTriangle_t *) |
(struct MD3MeshTriangle_t *) |
652 |
((char *) [self _mesh: noMesh] + [self _meshTriangleOffset: noMesh]); |
((char *) [self _mesh: noMesh] + [self _meshTriangleOffset: noMesh]); |
653 |
|
|
654 |
return (triangles + noTriangle)->indices; |
triangle_t triangle; |
655 |
|
triangle.vertex1 = (triangles + noTriangle)->indices[0]; |
656 |
|
triangle.vertex2 = (triangles + noTriangle)->indices[1]; |
657 |
|
triangle.vertex3 = (triangles + noTriangle)->indices[2]; |
658 |
|
return triangle; |
659 |
} |
} |
660 |
|
|
661 |
|
|
665 |
* It returns the UV coordinates. |
* It returns the UV coordinates. |
666 |
* There are self::meshNbVertice textures coordinates for each mesh. |
* There are self::meshNbVertice textures coordinates for each mesh. |
667 |
*/ |
*/ |
668 |
- (const float*) meshTexCoord: (int32_t)noMesh |
- (tex_coord_t) meshTexCoord: (int32_t)noMesh |
669 |
withNumber: (int32_t)noVertex |
withNumber: (int32_t)noVertex |
670 |
{ |
{ |
671 |
NSParameterAssert (_data); |
NSParameterAssert (_data); |
672 |
NSParameterAssert (noMesh >= 0); |
NSParameterAssert (noMesh >= 0); |
677 |
struct MD3MeshTexCoord_t *texCoord = |
struct MD3MeshTexCoord_t *texCoord = |
678 |
(struct MD3MeshTexCoord_t *) |
(struct MD3MeshTexCoord_t *) |
679 |
((char *) [self _mesh: noMesh] + |
((char *) [self _mesh: noMesh] + |
680 |
[self _meshTexCoordOffset: noMesh]); |
[self _meshTexCoordOffset: noMesh]); |
681 |
|
|
682 |
return (texCoord + noVertex)->coord; |
return MakeTexCoord ((texCoord + noVertex)->coord[0], |
683 |
|
(texCoord + noVertex)->coord[1]); |
684 |
} |
} |
685 |
|
|
686 |
/** |
/** |
702 |
NSParameterAssert (noVertex < [self meshNbVertice: noMesh]); |
NSParameterAssert (noVertex < [self meshNbVertice: noMesh]); |
703 |
|
|
704 |
char* vertice = |
char* vertice = |
705 |
((char *) [self _mesh: noMesh]) + [self _meshVertexOffset: noMesh]; |
(char *)[self _mesh: noMesh] + [self _meshVertexOffset: noMesh]; |
706 |
|
|
707 |
return ((struct MD3MeshVertex_t *) vertice) + |
return ((struct MD3MeshVertex_t *) vertice) + |
708 |
(noFrame * [self meshNbVertice: noMesh] + noVertex); |
(noFrame * [self meshNbVertice: noMesh] + noVertex); |
714 |
* The coordinates x, y, z are given by three short integer, relative to the |
* The coordinates x, y, z are given by three short integer, relative to the |
715 |
* center of the model. |
* center of the model. |
716 |
*/ |
*/ |
717 |
- (const u_int16_t*) meshCoordVertex: (int32_t)noMesh |
- (coord_t) meshCoordVertex: (int32_t)noMesh |
718 |
withNumber: (int32_t)noVertex |
withNumber: (int32_t)noVertex |
719 |
inFrame: (int32_t)noFrame; |
inFrame: (int32_t)noFrame; |
720 |
{ |
{ |
727 |
NSParameterAssert (noVertex < [self meshNbVertice: noMesh]); |
NSParameterAssert (noVertex < [self meshNbVertice: noMesh]); |
728 |
|
|
729 |
struct MD3MeshVertex_t *vertice = [self _meshVertex: noMesh |
struct MD3MeshVertex_t *vertice = [self _meshVertex: noMesh |
730 |
withNumber: noVertex |
withNumber: noVertex |
731 |
inFrame: noFrame]; |
inFrame: noFrame]; |
732 |
|
|
733 |
return vertice->coords; |
return MakeCoord ((double)vertice->coords[0] / 64.0, |
734 |
|
(double)vertice->coords[1] / 64.0, |
735 |
|
(double)vertice->coords[2] / 64.0); |
736 |
} |
} |
737 |
|
|
738 |
/** |
/** |
741 |
* while the frame noFrame. |
* while the frame noFrame. |
742 |
* The coordinates are given by two char. |
* The coordinates are given by two char. |
743 |
*/ |
*/ |
744 |
- (const u_int8_t*) meshTexEnvVertex: (int32_t)noMesh |
- (const u_int8_t*) _meshTexEnvVertex: (int32_t)noMesh |
745 |
withNumber: (int32_t)noVertex |
withNumber: (int32_t)noVertex |
746 |
inFrame: (int32_t)noFrame; |
inFrame: (int32_t)noFrame; |
747 |
{ |
{ |
748 |
NSParameterAssert (_data); |
NSParameterAssert (_data); |
749 |
NSParameterAssert (noMesh >= 0); |
NSParameterAssert (noMesh >= 0); |
754 |
NSParameterAssert (noVertex < [self meshNbVertice: noMesh]); |
NSParameterAssert (noVertex < [self meshNbVertice: noMesh]); |
755 |
|
|
756 |
struct MD3MeshVertex_t *vertice = [self _meshVertex: noMesh |
struct MD3MeshVertex_t *vertice = [self _meshVertex: noMesh |
757 |
withNumber: noVertex |
withNumber: noVertex |
758 |
inFrame: noFrame]; |
inFrame: noFrame]; |
759 |
return vertice->texEnv; |
return vertice->texEnv; |
760 |
} |
} |
761 |
|
|
762 |
|
/** |
763 |
|
* Returns the normal to the vertex located by the vertex number and contained |
764 |
|
* in the mesh of number noMesh, while the frame noFrame. |
765 |
|
*/ |
766 |
|
- (coord_t) meshNormalVertex: (int32_t)noMesh |
767 |
|
withNumber: (int32_t)noVertex |
768 |
|
inFrame: (int32_t)noFrame; |
769 |
|
{ |
770 |
|
NSParameterAssert (_data); |
771 |
|
NSParameterAssert (noMesh >= 0); |
772 |
|
NSParameterAssert (noMesh < [self nbMeshes]); |
773 |
|
NSParameterAssert (noFrame >= 0); |
774 |
|
NSParameterAssert (noFrame < [self nbFrames]); |
775 |
|
NSParameterAssert (noVertex >= 0 ); |
776 |
|
NSParameterAssert (noVertex < [self meshNbVertice: noMesh]); |
777 |
|
|
778 |
|
coord_t resultNormal = {0.0, 0.0, 0.0}; |
779 |
|
|
780 |
|
const u_int8_t * normal = [self _meshTexEnvVertex: noMesh |
781 |
|
withNumber: noVertex |
782 |
|
inFrame: noFrame]; |
783 |
|
|
784 |
|
double clat = (normal[0] & 255) * (2.0 * M_PI) / 255.0; |
785 |
|
double clng = (normal[1] & 255) * (2.0 * M_PI) / 255.0; |
786 |
|
|
787 |
|
resultNormal.x = cos (clat) * sin (clng); |
788 |
|
resultNormal.y = sin (clat) * sin (clng); |
789 |
|
resultNormal.z = cos (clng); |
790 |
|
|
791 |
|
return resultNormal; |
792 |
|
} |
793 |
|
|
794 |
/* |
/* |
795 |
* Functions used to read and store md3 file |
* Functions used to read and store md3 file |
906 |
|
|
907 |
return SUCCESS; |
return SUCCESS; |
908 |
} |
} |
909 |
|
|
910 |
|
@end |