/**********************************************************************
This file is part of Crack dot Com's free source code release of
Golgotha.
for
information about compiling & licensing issues visit this URL
If that doesn't help, contact Jonathan Clark at
golgotha_source@usa.net (Subject should have "GOLG" in it)
***********************************************************************/
#include "max_object.hh"
#include "file/file.hh"
#include "loaders/dir_save.hh"
#include "saver_id.hh"
#include "debug.hh"
#define G3DF_VERSION 3
w32 current_anim=0, current_frame=0; // these reference model1
m1_poly_object_class *current_model_1=0, *current_model_2=0;
i4_grow_heap_class *m1_object_heap=0;
i4_bool m1_quad_class::set(w16 a, w16 b, w16 c, w16 d)
{
// check for degenerate cases
if (c==d || b==d || a==d ) { d=0xffff; }
else if (b==c || a==c) { c=d; d=0xffff; }
else if (a==b) { b=c; c=d; d=0xffff; }
g1_quad_class::set(a,b,c,d);
return (c!=0xffff);
}
void m1_quad_class::calc_texture(int reverse,
i4_array &verts, w16 vert_off,
char *tname)
{
i4_float
tmp_u[4], tmp_v[4],
max_val, min_val,
scale, translate;
int p;
strcpy(texture_name, tname);
// determine quadgon texture space coordinate system
i4_3d_point_class i,j,k;
i = verts[vertex_ref[1]+vert_off].v;
i -= verts[vertex_ref[0]+vert_off].v;
i.normalize();
j = verts[vertex_ref[num_verts()-1]+vert_off].v;
j -= verts[vertex_ref[0]+vert_off].v;
k.cross(i,j);
k.normalize();
j.cross(k,i);
// find quadgon vertex coordinates in texture space
for (p=0; p max_val) ? tmp_u[p] : max_val;
min_val = (tmp_u[p] < min_val) ? tmp_u[p] : min_val;
}
texture_scale = max_val - min_val;
scale = 1.0/texture_scale;
translate = -min_val;
if (!reverse)
for (p=0; p max_val) ? tmp_v[p] : max_val;
min_val = (tmp_v[p] < min_val) ? tmp_v[p] : min_val;
}
scale = 1.0/(max_val - min_val);
translate = -min_val;
for (p=0; p &verts, w16 vert_off)
{
i4_float
tmp_u[4], tmp_v[4],
max_val, min_val,
scale, translate;
int p;
// determine quadgon texture space coordinate system
i4_3d_point_class i,j,k;
i = verts[vertex_ref[1]+vert_off].v;
i -= verts[vertex_ref[0]+vert_off].v;
i.normalize();
j = verts[vertex_ref[num_verts()-1]+vert_off].v;
j -= verts[vertex_ref[0]+vert_off].v;
k.cross(i,j);
k.normalize();
j.cross(k,i);
// find quadgon vertex coordinates in texture space
for (p=0; p max_val) ? tmp_u[p] : max_val;
min_val = (tmp_u[p] < min_val) ? tmp_u[p] : min_val;
}
texture_scale = max_val - min_val;
}
void m1_poly_object_class::save_quads(i4_saver_class *fp)
{
int i,j;
fp->mark_section(G1_SECTION_MODEL_QUADS);
fp->write_16(quad_a.size());
for (i=0; iwrite_16(quad_a[i]->vertex_ref[j]);
fp->write_float(quad_a[i]->u[j]);
fp->write_float(quad_a[i]->v[j]);
}
fp->write_float(quad_a[i]->texture_scale);
fp->write_16(quad_a[i]->flags);
fp->write_float(quad_a[i]->normal.x);
fp->write_float(quad_a[i]->normal.y);
fp->write_float(quad_a[i]->normal.z);
}
}
void m1_poly_object_class::save_texture_names(i4_saver_class *fp)
{
fp->mark_section(G1_SECTION_MODEL_TEXTURE_NAMES);
fp->write_16(quad_a.size());
for (int i=0; itexture_name);
fp->write_16(len);
fp->write(quad_a[i]->texture_name, len);
}
}
void m1_poly_object_class::save_vert_animations(i4_saver_class *fp)
{
int i,j;
fp->mark_section(G1_SECTION_MODEL_VERT_ANIMATION);
fp->write_16(num_vertex);
fp->write_16(anim_a.size());
for (i=0; iwrite_counted_str(*anim_a[i]->animation_name);
fp->write_16(anim_a[i]->vertex_a.size() / num_vertex);
for (j=0; jvertex_a.size(); j++)
{
g1_vert_class *v=&anim_a[i]->vertex_a[j];
fp->write_float(v->v.x);
fp->write_float(v->v.y);
fp->write_float(v->v.z);
fp->write_float(v->normal.y);
fp->write_float(v->normal.z);
fp->write_float(v->normal.z);
}
}
}
void m1_poly_object_class::save_mount_points(i4_saver_class *fp)
{
int i,j;
fp->mark_section("GMOD Mounts");
fp->write_16(mount_a.size());
for (i=0; iwrite_counted_str(*mount_a[i]->name);
fp->write_float(mount_a[i]->offset.x);
fp->write_float(mount_a[i]->offset.y);
fp->write_float(mount_a[i]->offset.z);
}
}
void m1_poly_object_class::calc_quad_normal(i4_array &v,
m1_quad_class &q)
{
// find the surface normal used in lighting
i4_3d_point_class p[4];
for (int i=0; inormal2.length())
q.normal = normal1;
else
q.normal = normal2;
}
if (q.normal.x==0 && q.normal.y==0 && q.normal.z==0)
q.normal=i4_3d_vector(0,0,1);
else
q.normal.normalize();
}
void m1_poly_object_class::calc_vert_normals()
{
for (int a=0; avertex_a, *quad_a[i]);
for (w32 v=0; vvertex_ref[0]==v ||
quad_a[j]->vertex_ref[1]==v ||
quad_a[j]->vertex_ref[2]==v ||
quad_a[j]->vertex_ref[3]==v)
{
t++;
sum+=quad_a[j]->normal;
}
}
if (sum.x!=0 || sum.y!=0 || sum.z!=0)
sum.normalize();
else
sum.set(0,0,1);
anim_a[a]->vertex_a[v].normal=sum;
}
}
}
void m1_poly_object_class::save(i4_saver_class *fp)
{
int i,j;
calc_vert_normals();
dbg("saving textures...");
save_texture_names(fp);
dbg("saving quads...");
save_quads(fp);
dbg("saving verts...");
save_vert_animations(fp);
dbg("saving mount points...");
save_mount_points(fp);
dbg("done.\n");
}
void m1_poly_object_class::cleanup()
{
w32 i;
dbg("Zapping quads...");
for (i=0; i