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
00042 #include "omicron/internal.h"
00043 #include "omicron/file.h"
00044 #include "omicron/render.h"
00045 #include "omicron/model.h"
00046
00047
00048
00049
00050
00051
00052
00053 kmf_c::kmf_c()
00054 {
00055 memset(&header, 0, sizeof(header));
00056 verts = NULL;
00057 tris = NULL;
00058 mods = NULL;
00059 normals = NULL;
00060 tmpdrawvertices = NULL;
00061 drawvertices = NULL;
00062 shader = NULL;
00063 }
00064
00065 kmf_c::~kmf_c()
00066 {
00067 AssertThis;
00068
00069 unload();
00070 }
00071
00072 void kmf_c::unload()
00073 {
00074 AssertThis;
00075
00076 SafeArrayDelete(verts);
00077 SafeArrayDelete(tris);
00078 SafeArrayDelete(mods);
00079 SafeArrayDelete(normals);
00080 SafeArrayDelete(tmpdrawvertices);
00081 SafeArrayDelete(drawvertices);
00082 }
00083
00084 bool kmf_c::load(const char *filename)
00085 {
00086 AssertThisV;
00087 AssertReturnValue1(filename, 0);
00088
00089 unload();
00090
00091 file_t *file = gv.fileman->load((char*)filename, false);
00092
00093 AssertReturnValue1(file, 0);
00094
00095 gv.fileman->read(&header, sizeof(header), 1, file);
00096
00097 if (header.version != 3 ||
00098 memcmp(header.magic, KMF_MAGIC, 4) ||
00099 !header.framecount)
00100 {
00101 gv.fileman->close(file);
00102 return false;
00103 }
00104
00105 shader = shader_load(header.texturename);
00106
00107 mods = new kmf_vertmodifier_t[header.framecount];
00108 gv.fileman->read(mods, sizeof(kmf_vertmodifier_t),
00109 header.framecount, file);
00110
00111 tris = new ulong[header.triangles*3];
00112 gv.fileman->read(tris, sizeof(ulong),
00113 header.triangles*3, file);
00114
00115 verts = new kmf_vertex_t[header.vertices*header.framecount];
00116 gv.fileman->read(verts, sizeof(kmf_vertex_t),
00117 header.vertices*header.framecount, file);
00118
00119 normals = new uchar[header.framecount*header.triangles*3*3];
00120 gv.fileman->read(normals, sizeof(char),
00121 header.framecount*header.triangles*3*3, file);
00122
00123 tmpdrawvertices = new vertex_t[header.vertices];
00124
00125 drawvertices = new vertex_t[header.triangles*3];
00126 drawvertcount = header.triangles*3;
00127
00128 gv.fileman->close(file);
00129
00130 set_frame(0);
00131
00132 return true;
00133 }
00134
00135 void kmf_c::set_frame(float frame)
00136 {
00137 AssertThis;
00138
00139 ulong frameidx = (ulong)(floor(frame));
00140 ulong nextframeidx = (frameidx+1)%header.framecount;
00141 float framefrac = frame-frameidx;
00142
00143 ulong index = 0;
00144 ulong i = 0;
00145 ulong tri = 0;
00146
00147 vec3_t pos1, pos2;
00148 vec2_t uv1, uv2;
00149 vec3_t norm1, norm2;
00150 vec3_c tmp;
00151
00152 AssertReturn1(verts);
00153
00154 for (index=0; index<header.vertices; index++)
00155 {
00156 ulong vertindex1 = index+frameidx*header.vertices;
00157 ulong vertindex2 = index+nextframeidx*header.vertices;
00158
00159
00160 for (i=0; i<3; i++)
00161 {
00162 pos1[i] = ((float)((uchar)verts[vertindex1].pos[i]))/255.0f*
00163 mods[frameidx].scale[i]+mods[frameidx].offset[i];
00164
00165 pos2[i] = ((float)((uchar)verts[vertindex2].pos[i]))/255.0f*
00166 mods[nextframeidx].scale[i]+mods[nextframeidx].offset[i];
00167 }
00168
00169 float t;
00170
00171 t = pos1[2]; pos1[2] = pos1[1]; pos1[1] = -t;
00172 t = pos2[2]; pos2[2] = pos2[1]; pos2[1] = -t;
00173
00174 uv1[0] = verts[vertindex1].uv[0]/255.0f;
00175 uv1[1] = verts[vertindex1].uv[1]/255.0f;
00176 uv2[0] = verts[vertindex2].uv[0]/255.0f;
00177 uv2[1] = verts[vertindex2].uv[1]/255.0f;
00178
00179 tmp.linear(pos1, pos2, framefrac);
00180 tmp.copy(tmpdrawvertices[index].xyz);
00181
00182 vec2_c::linear(uv1, uv2, framefrac).copy(tmpdrawvertices[index].uv[0]);
00183 tmpdrawvertices[index].diffuse = -1;
00184
00185 tmp.unpack_normal(verts[vertindex1].normal); tmp.copy(norm1);
00186 tmp.unpack_normal(verts[vertindex2].normal); tmp.copy(norm2);
00187
00188 tmp.linear(norm1, norm2, framefrac);
00189 tmp.normalize().copy(tmpdrawvertices[index].normal);
00190 }
00191
00192 for (tri = 0; tri<header.triangles; tri++)
00193 {
00194
00195
00196
00197 for (ulong vert = 0; vert<3; vert++)
00198 {
00199 drawvertices[tri*3+vert] = tmpdrawvertices[tris[tri*3+vert]];
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 }
00213 }
00214 }
00215
00216 ulong kmf_c::get_frame_count()
00217 {
00218 AssertThisV;
00219
00220 return header.framecount;
00221 }
00222
00223 void kmf_c::draw()
00224 {
00225 AssertThis;
00226
00227 gv.renderer->use_shader(shader);
00228 gv.renderer->render_verts(drawvertices, drawvertcount, PT_TRIANGLES);
00229 }