DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
model_dpmodel.h
Go to the documentation of this file.
1
2#ifndef MODEL_DPMODEL_H
3#define MODEL_DPMODEL_H
4
5/*
6type 2 model (hierarchical skeletal pose)
7within this specification, int is assumed to be 32bit, float is assumed to be 32bit, char is assumed to be 8bit, text is assumed to be an array of chars with NULL termination
8all values are big endian (also known as network byte ordering), NOT x86 little endian
9general notes:
10a pose is a 3x4 matrix (rotation matrix, and translate vector)
11parent bones must always be lower in number than their children, models will be rejected if this is not obeyed (can be fixed by modelling utilities)
12utility notes:
13if a hard edge is desired (faceted lighting, or a jump to another set of skin coordinates), vertices must be duplicated
14ability to visually edit groupids of triangles is highly recommended
15bones should be markable as 'attach' somehow (up to the utility) and thus protected from culling of unused resources
16frame 0 is always the base pose (the one the skeleton was built for)
17game notes:
18the loader should be very thorough about error checking, all vertex and bone indices should be validated, etc
19the gamecode can look up bone numbers by name using a builtin function, for use in attachment situations (the client should have the same model as the host of the gamecode in question - that is to say if the server gamecode is setting the bone number, the client and server must have vaguely compatible models so the client understands, and if the client gamecode is setting the bone number, the server could have a completely different model with no harm done)
20the triangle groupid values are up to the gamecode, it is recommended that gamecode process this in an object-oriented fashion (I.E. bullet hits entity, call that entity's function for getting properties of that groupid)
21frame 0 should be usable, not skipped
22speed optimizations for the saver to do:
23remove all unused data (unused bones, vertices, etc, be sure to check if bones are used for attachments however)
24sort triangles into strips
25sort vertices according to first use in a triangle (caching benefits) after sorting triangles
26speed optimizations for the loader to do:
27if the model only has one frame, process it at load time to create a simple static vertex mesh to render (this is a hassle, but it is rewarding to optimize all such models)
28rendering process:
291*. one or two poses are looked up by number
302*. boneposes (matrices) are interpolated, building bone matrix array
313. bones are parsed sequentially, each bone's matrix is transformed by it's parent bone (which can be -1; the model to world matrix)
324. meshs are parsed sequentially, as follows:
33 1. vertices are parsed sequentially and may be influenced by more than one bone (the results of the 3x4 matrix transform will be added together - weighting is already built into these)
34 2. shader is looked up and called, passing vertex buffer (temporary) and triangle indices (which are stored in the mesh)
355. rendering is complete
36* - these stages can be replaced with completely dynamic animation instead of pose animations.
37*/
38// header for the entire file
39typedef struct dpmheader_s
40{
41 char id[16]; // "DARKPLACESMODEL\0", length 16
42 unsigned int type; // 2 (hierarchical skeletal pose)
43 unsigned int filesize; // size of entire model file
44 float mins[3], maxs[3], yawradius, allradius; // for clipping uses
45 // these offsets are relative to the file
46 unsigned int num_bones;
47 unsigned int num_meshs;
48 unsigned int num_frames;
49 unsigned int ofs_bones; // dpmbone_t bone[num_bones];
50 unsigned int ofs_meshs; // dpmmesh_t mesh[num_meshs];
51 unsigned int ofs_frames; // dpmframe_t frame[num_frames];
52}
54// there may be more than one of these
55typedef struct dpmmesh_s
56{
57 // these offsets are relative to the file
58 char shadername[32]; // name of the shader to use
59 unsigned int num_verts;
60 unsigned int num_tris;
61 unsigned int ofs_verts; // dpmvertex_t vert[numvertices]; // see vertex struct
62 unsigned int ofs_texcoords; // float texcoords[numvertices][2];
63 unsigned int ofs_indices; // unsigned int indices[numtris*3]; // designed for glDrawElements (each triangle is 3 unsigned int indices)
64 unsigned int ofs_groupids; // unsigned int groupids[numtris]; // the meaning of these values is entirely up to the gamecode and modeler
65}
67// if set on a bone, it must be protected from removal
68#define DPMBONEFLAG_ATTACHMENT 1
69// one per bone
70typedef struct dpmbone_s
71{
72 // name examples: upperleftarm leftfinger1 leftfinger2 hand, etc
73 char name[32];
74 // parent bone number
75 signed int parent;
76 // flags for the bone
77 unsigned int flags;
78}
80// a bonepose matrix is intended to be used like this:
81// (n = output vertex, v = input vertex, m = matrix, f = influence)
82// n[0] = v[0] * m[0][0] + v[1] * m[0][1] + v[2] * m[0][2] + f * m[0][3];
83// n[1] = v[0] * m[1][0] + v[1] * m[1][1] + v[2] * m[1][2] + f * m[1][3];
84// n[2] = v[0] * m[2][0] + v[1] * m[2][1] + v[2] * m[2][2] + f * m[2][3];
85typedef struct dpmbonepose_s
86{
87 float matrix[3][4];
88}
90// immediately followed by bone positions for the frame
91typedef struct dpmframe_s
92{
93 // name examples: idle_1 idle_2 idle_3 shoot_1 shoot_2 shoot_3, etc
94 char name[32];
95 float mins[3], maxs[3], yawradius, allradius;
96 int ofs_bonepositions; // dpmbonepose_t bonepositions[bones];
97}
99// one or more of these per vertex
100typedef struct dpmbonevert_s
101{
102 // this pairing of origin and influence is intentional
103 // (in SSE or 3DNow! assembly it can be done as a quad vector op
104 // (or two dual vector ops) very easily)
105 float origin[3]; // vertex location (these blend)
106 float influence; // influence fraction (these must add up to 1)
107 // this pairing of normal and bonenum is intentional
108 // (in SSE or 3DNow! assembly it can be done as a quad vector op
109 // (or two dual vector ops) very easily, the bonenum is ignored)
110 float normal[3]; // surface normal (these blend)
111 unsigned int bonenum; // number of the bone
112}
114// variable size, parsed sequentially
115typedef struct dpmvertex_s
116{
117 unsigned int numbones;
118 // immediately followed by 1 or more dpmbonevert_t structures
119}
121
122#endif
123
vector mins
vector maxs
vector origin
const GLchar * name
Definition glquake.h:601
vec3 normal
unsigned int flags
signed int parent
unsigned int bonenum
float allradius
int ofs_bonepositions
unsigned int num_meshs
unsigned int ofs_frames
unsigned int ofs_bones
unsigned int type
unsigned int filesize
unsigned int ofs_meshs
unsigned int num_bones
unsigned int num_frames
unsigned int ofs_indices
unsigned int ofs_groupids
unsigned int ofs_verts
unsigned int num_verts
unsigned int num_tris
unsigned int ofs_texcoords
unsigned int numbones