00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00040 #include <string.h>
00041 #include "omicron/internal.h"
00042 #include "omicron/file.h"
00043 #include "omicron/render.h"
00044 #include "omicron/model.h"
00045 #include "omicron/md2.h"
00046
00047 static vec3_t normals[162] =
00048 {
00049 #include "omicron/anorms.h"
00050 };
00051
00052
00053
00054
00055
00056
00057
00058 #pragma pack(1)
00059
00060 md2_c::md2_c()
00061 {
00062 texData = NULL;
00063 triData = NULL;
00064 vertData = NULL;
00065 frameData = NULL;
00066 vertices = NULL;
00067 drawvertices = NULL;
00068 glIndicesData = NULL;
00069 vertcount = 0;
00070 drawvertcount = 0;
00071 }
00072
00073 md2_c::~md2_c()
00074 {
00075 AssertThis;
00076
00077 unload();
00078 }
00079
00080 void md2_c::unload()
00081 {
00082 AssertThis;
00083
00084 SafeArrayDelete(texData );
00085 SafeArrayDelete(triData );
00086 SafeArrayDelete(vertData );
00087 SafeArrayDelete(vertices );
00088 SafeArrayDelete(drawvertices );
00089 SafeArrayDelete(glIndicesData );
00090
00091 if (frameData)
00092 for (ulong index=0;index<header.numFrames;index++)
00093 SafeArrayDelete(frameData[index].pvertices);
00094
00095 SafeArrayDelete(frameData);
00096 }
00097
00098
00099
00100
00101
00102 bool md2_c::load(const char* fileName)
00103 {
00104 AssertThisV;
00105
00106 unload();
00107
00108 file_t *file = gv.fileman->load(fileName, false);
00109
00110 gv.fileman->read(&header, sizeof header, 1, file);
00111
00112
00113 gv.fileman->seek(file, header.offsetSkins, SEEK_SET);
00114 gv.fileman->read(skinName, MAX_SKIN_NAME, header.numSkins, file);
00115
00116
00117 texData = new texture_coord_s[header.numTexCoords];
00118 gv.fileman->seek(file, header.offsetTexCoord, SEEK_SET);
00119 gv.fileman->read(texData, sizeof(texture_coord_s), header.numTexCoords, file);
00120
00121
00122 triData = new triangle_s[header.numTriangles];
00123 gv.fileman->seek(file, header.offsetTriangles, SEEK_SET);
00124 gv.fileman->read(triData, sizeof(triangle_s), header.numTriangles, file);
00125
00126
00127 ulong index;
00128 ulong frameVertSize = header.numVertices * sizeof(triangle_vertex_s);
00129
00130 frameData = new frame_s[header.numFrames];
00131
00132 memset(frameData, 0, sizeof(frameData));
00133
00134 gv.fileman->seek(file, header.offsetFrames, SEEK_SET);
00135
00136 for (index = 0; index<header.numFrames; index++)
00137 {
00138 gv.fileman->read(&frameData[index], FRAME_HEADER_SIZE, 1, file);
00139
00140 frameData[index].pvertices = new triangle_vertex_s[header.numVertices];
00141
00142 gv.fileman->read(frameData[index].pvertices, frameVertSize, 1, file);
00143 }
00144
00145
00146
00147 gv.fileman->close(file);
00148
00149 SafeArrayDelete(vertices);
00150 SafeArrayDelete(drawvertices);
00151
00152 vertcount = header.numVertices;
00153 drawvertcount = header.numTriangles*3;
00154 vertices = new vertex_t[vertcount];
00155 drawvertices = new vertex_t[drawvertcount];
00156
00157 set_frame(0);
00158
00159 return true;
00160 }
00161
00162 void md2_c::set_frame(float frame)
00163 {
00164 AssertThis;
00165
00166 ulong frameidx = (ulong)(floor(frame));
00167 ulong nextframeidx = (frameidx+1)%header.numFrames;
00168 float framefrac = frame-frameidx;
00169
00170 ulong index = 0;
00171 ulong tri = 0;
00172
00173 AssertReturn1(vertices);
00174
00175 vec3_c scale1 = frameData[frameidx].scale;
00176 vec3_c scale2 = frameData[nextframeidx].scale;
00177 vec3_c offset1 = frameData[frameidx].translate;
00178 vec3_c offset2 = frameData[nextframeidx].translate;
00179
00180 for (index=0;index<header.numVertices;index++)
00181 {
00182 vec3_c tmp, tmp2, tmp3;
00183 vec3_c vnorm1, vnorm2;
00184
00185 tmp.set( (float)frameData[frameidx].pvertices[index].vertex[0],
00186 (float)frameData[frameidx].pvertices[index].vertex[1],
00187 (float)frameData[frameidx].pvertices[index].vertex[2]);
00188
00189 tmp = tmp * scale1 + offset1;
00190
00191 tmp2.set( (float)frameData[nextframeidx].pvertices[index].vertex[0],
00192 (float)frameData[nextframeidx].pvertices[index].vertex[1],
00193 (float)frameData[nextframeidx].pvertices[index].vertex[2]);
00194
00195 tmp2 = tmp2 * scale2 + offset2;
00196
00197 (vec3_c::linear(tmp, tmp2, framefrac)).copy(vertices[index].xyz);
00198
00199 vertices[index].uv[0][0] = (float)texData[index].s/(float)header.skinWidth;
00200 vertices[index].uv[0][1] = (float)texData[index].t/(float)header.skinHeight;
00201
00202 vnorm1 = normals[frameData[frameidx ].pvertices[index].lnormal_idx];
00203 vnorm2 = normals[frameData[nextframeidx ].pvertices[index].lnormal_idx];
00204
00205 (vec3_c::linear(vnorm1, vnorm2, framefrac).normalize()).copy(vertices[index].normal);
00206 }
00207
00208 memset(drawvertices, 0, sizeof(vertex_t)*drawvertcount);
00209
00210 for (tri = 0; tri<header.numTriangles; tri++)
00211 {
00212 for (ulong vert = 0; vert<3; vert++)
00213 {
00214 ulong v = tri*3+vert;
00215 ulong thevert = triData[tri].vert_idx[vert];
00216 ulong texvert = triData[tri].tex_idx[vert];
00217
00218 (vec3_c(vertices[thevert].xyz)).copy(drawvertices[v].xyz);
00219 (vec2_c(vertices[texvert].uv[0])).copy(drawvertices[v].uv[0]);
00220 (vec3_c(vertices[thevert].normal)).copy(drawvertices[v].normal);
00221 drawvertices[v].diffuse = 0xFFFFFFFF;
00222 }
00223 }
00224 for (index=0;index<header.numVertices;index++)
00225 {
00226 ((vec3_c(drawvertices[index].normal)).normalize()).copy(drawvertices[index].normal);
00227 }
00228 }
00229
00230 ulong md2_c::get_frame_count()
00231 {
00232 AssertThisV;
00233
00234 return header.numFrames;
00235 }
00236
00237 #pragma pack(8)