#include "solid.h"
#include "base_image.h"
#include "base_config.h"
+#include "fs.h"
+#include "common.h"
#define MAXSTR 256
#define MAXKEY 16
/*---------------------------------------------------------------------------*/
-static int debug_output = 0;
+static const char *input_file;
+static int debug_output = 0;
/*---------------------------------------------------------------------------*/
#define MAXV 65536
#define MAXE 65536
#define MAXS 65536
-#define MAXT 65536
+#define MAXT 131072
#define MAXG 65536
-#define MAXL 2048
+#define MAXL 4096
#define MAXN 2048
-#define MAXP 1024
+#define MAXP 2048
#define MAXB 1024
#define MAXH 2048
#define MAXZ 1024
#define MAXW 1024
#define MAXD 1024
#define MAXA 16384
-#define MAXI 131072
+#define MAXI 262144
static int overflow(const char *s)
{
* and fills waiting ints with the proper values.
*/
-#define MAXSYM 1024
+#define MAXSYM 2048
static char symv[MAXSYM][MAXSTR];
static int valv[MAXSYM];
strcpy(jpg, name); strcat(jpg, ".jpg");
strcpy(png, name); strcat(png, ".png");
- if (size_load(config_data(png), w, h) ||
- size_load(config_data(jpg), w, h))
+ if (size_load(png, w, h) ||
+ size_load(jpg, w, h))
{
if (image_n + 1 >= image_alloc)
/* Read the given material file, adding a new material to the solid. */
+#define scan_vec4(f, s, v) \
+ if (fs_gets((s), sizeof (s), (f))) \
+ sscanf((s), "%f %f %f %f", (v), (v) + 1, (v) + 2, (v) + 3)
+
static int read_mtrl(struct s_file *fp, const char *name)
{
+ static char line[MAXSTR];
struct s_mtrl *mp;
- FILE *fin;
+ fs_file fin;
int mi;
for (mi = 0; mi < fp->mc; mi++)
mp->fl = 0;
mp->angle = 45.0f;
- if ((fin = fopen(config_data(name), "r")))
+ if ((fin = fs_open(name, "r")))
{
- fscanf(fin,
- "%f %f %f %f "
- "%f %f %f %f "
- "%f %f %f %f "
- "%f %f %f %f "
- "%f %d %f",
- mp->d, mp->d + 1, mp->d + 2, mp->d + 3,
- mp->a, mp->a + 1, mp->a + 2, mp->a + 3,
- mp->s, mp->s + 1, mp->s + 2, mp->s + 3,
- mp->e, mp->e + 1, mp->e + 2, mp->e + 3,
- mp->h, &mp->fl, &mp->angle);
- fclose(fin);
+ scan_vec4(fin, line, mp->d);
+ scan_vec4(fin, line, mp->a);
+ scan_vec4(fin, line, mp->s);
+ scan_vec4(fin, line, mp->e);
+
+ if (fs_gets(line, sizeof (line), fin))
+ mp->h[0] = strtod(line, NULL);
+
+ if (fs_gets(line, sizeof (line), fin))
+ mp->fl = strtol(line, NULL, 10);
+
+ if (fs_gets(line, sizeof (line), fin))
+ mp->angle = strtod(line, NULL);
+
+ fs_close(fin);
}
+ else
+ fprintf(stderr, "%s: unknown material \"%s\"\n", input_file, name);
return mi;
}
+#undef scan_vec4
+
/*---------------------------------------------------------------------------*/
/*
{
char line[MAXSTR];
char mtrl[MAXSTR];
- FILE *fin;
+ fs_file fin;
int v0 = fp->vc;
int t0 = fp->tc;
int s0 = fp->sc;
- if ((fin = fopen(config_data(name), "r")))
+ if ((fin = fs_open(name, "r")))
{
- while (fgets(line, MAXSTR, fin))
+ while (fs_gets(line, MAXSTR, fin))
{
if (strncmp(line, "usemtl", 6) == 0)
{
else if (strncmp(line, "vn", 2) == 0) read_vn(fp, line + 2);
else if (strncmp(line, "v", 1) == 0) read_v (fp, line + 1);
}
- fclose(fin);
+ fs_close(fin);
}
}
static int plane_f[MAXS];
static int plane_m[MAXS];
-static void make_plane(int pi, int x0, int y0, int z0,
- int x1, int y1, int z1,
- int x2, int y2, int z2,
- int tu, int tv, int r,
- float su, float sv, int fl, const char *s)
+static void make_plane(int pi, float x0, float y0, float z0,
+ float x1, float y1, float z1,
+ float x2, float y2, float z2,
+ float tu, float tv, float r,
+ float su, float sv, int fl, const char *s)
{
static const float base[6][3][3] = {
- {{ 0, 0, 1 }, { 1, 0, 0 }, { 0, -1, 0 }},
- {{ 0, 0, -1 }, { 1, 0, 0 }, { 0, -1, 0 }},
- {{ 1, 0, 0 }, { 0, 0, -1 }, { 0, -1, 0 }},
- {{ -1, 0, 0 }, { 0, 0, -1 }, { 0, -1, 0 }},
- {{ 0, 1, 0 }, { 1, 0, 0 }, { 0, 0, 1 }},
- {{ 0, -1, 0 }, { 1, 0, 0 }, { 0, 0, 1 }},
+ {{ 0, 0, 1 }, { 1, 0, 0 }, { 0, 1, 0 }},
+ {{ 0, 0, -1 }, { 1, 0, 0 }, { 0, 1, 0 }},
+ {{ 1, 0, 0 }, { 0, 0, -1 }, { 0, 1, 0 }},
+ {{ -1, 0, 0 }, { 0, 0, -1 }, { 0, 1, 0 }},
+ {{ 0, 1, 0 }, { 1, 0, 0 }, { 0, 0, -1 }},
+ {{ 0, -1, 0 }, { 1, 0, 0 }, { 0, 0, -1 }},
};
float R[16];
plane_f[pi] = fl ? L_DETAIL : 0;
- p0[0] = +(float) x0 / SCALE;
- p0[1] = +(float) z0 / SCALE;
- p0[2] = -(float) y0 / SCALE;
+ p0[0] = +x0 / SCALE;
+ p0[1] = +z0 / SCALE;
+ p0[2] = -y0 / SCALE;
- p1[0] = +(float) x1 / SCALE;
- p1[1] = +(float) z1 / SCALE;
- p1[2] = -(float) y1 / SCALE;
+ p1[0] = +x1 / SCALE;
+ p1[1] = +z1 / SCALE;
+ p1[2] = -y1 / SCALE;
- p2[0] = +(float) x2 / SCALE;
- p2[1] = +(float) z2 / SCALE;
- p2[2] = -(float) y2 / SCALE;
+ p2[0] = +x2 / SCALE;
+ p2[1] = +z2 / SCALE;
+ p2[2] = -y2 / SCALE;
v_sub(u, p0, p1);
v_sub(v, p2, p1);
p[1] = 0.f;
p[2] = 0.f;
- m_rot(R, base[n][0], V_RAD(r));
+ /* Always rotate around the positive axis */
+
+ m_rot(R, base[n - (n % 2)][0], V_RAD(r));
- v_mad(p, p, base[n][1], su * tu / SCALE);
- v_mad(p, p, base[n][2], sv * tv / SCALE);
+ v_mad(p, p, base[n][1], +su * tu / SCALE);
+ v_mad(p, p, base[n][2], -sv * tv / SCALE);
m_vxfm(plane_u[pi], R, base[n][1]);
m_vxfm(plane_v[pi], R, base[n][2]);
#define T_END 4
#define T_NOP 5
-static int map_token(FILE *fin, int pi, char key[MAXSTR], char val[MAXSTR])
+static int map_token(fs_file fin, int pi, char key[MAXSTR], char val[MAXSTR])
{
char buf[MAXSTR];
- if (fgets(buf, MAXSTR, fin))
+ if (fs_gets(buf, MAXSTR, fin))
{
char c;
- int x0, y0, z0;
- int x1, y1, z1;
- int x2, y2, z2;
- int tu, tv, r;
+ float x0, y0, z0;
+ float x1, y1, z1;
+ float x2, y2, z2;
+ float tu, tv, r;
float su, sv;
int fl;
/* Scan a plane. */
if (sscanf(buf,
- "%c %d %d %d %c "
- "%c %d %d %d %c "
- "%c %d %d %d %c "
- "%s %d %d %d %f %f %d",
+ "%c %f %f %f %c "
+ "%c %f %f %f %c "
+ "%c %f %f %f %c "
+ "%s %f %f %f %f %f %d",
&c, &x0, &y0, &z0, &c,
&c, &x1, &y1, &z1, &c,
&c, &x2, &y2, &z2, &c,
/* Parse a lump from the given file and add it to the solid. */
-static void read_lump(struct s_file *fp, FILE *fin)
+static void read_lump(struct s_file *fp, fs_file fin)
{
char k[MAXSTR];
char v[MAXSTR];
if (strcmp(k[i], "origin") == 0)
{
- int x = 0, y = 0, z = 0;
+ float x = 0.f, y = 0.f, z = 0.f;
- sscanf(v[i], "%d %d %d", &x, &y, &z);
+ sscanf(v[i], "%f %f %f", &x, &y, &z);
- pp->p[0] = +(float) x / SCALE;
- pp->p[1] = +(float) z / SCALE;
- pp->p[2] = -(float) y / SCALE;
+ pp->p[0] = +x / SCALE;
+ pp->p[1] = +z / SCALE;
+ pp->p[2] = -y / SCALE;
}
}
}
float p[3];
- int x = 0;
- int y = 0;
- int z = 0;
+ float x = 0.f;
+ float y = 0.f;
+ float z = 0.f;
struct s_body *bp = fp->bv + bi;
read_obj(fp, v[i], mi);
else if (strcmp(k[i], "origin") == 0)
- sscanf(v[i], "%d %d %d", &x, &y, &z);
+ sscanf(v[i], "%f %f %f", &x, &y, &z);
else if (read_dict_entries && strcmp(k[i], "classname") != 0)
make_dict(fp, k[i], v[i]);
for (i = 0; i < bp->gc; i++)
fp->iv[inci(fp)] = g0++;
- p[0] = +(float) x / SCALE;
- p[1] = +(float) z / SCALE;
- p[2] = -(float) y / SCALE;
+ p[0] = +x / SCALE;
+ p[1] = +z / SCALE;
+ p[2] = -y / SCALE;
for (i = v0; i < fp->vc; i++)
v_add(fp->vv[i].p, fp->vv[i].p, p);
if (strcmp(k[i], "origin") == 0)
{
- int x = 0, y = 0, z = 0;
+ float x = 0.f, y = 0.f, z = 0.f;
- sscanf(v[i], "%d %d %d", &x, &y, &z);
+ sscanf(v[i], "%f %f %f", &x, &y, &z);
- hp->p[0] = +(float) x / SCALE;
- hp->p[1] = +(float) z / SCALE;
- hp->p[2] = -(float) y / SCALE;
+ hp->p[0] = +x / SCALE;
+ hp->p[1] = +z / SCALE;
+ hp->p[2] = -y / SCALE;
}
}
}
if (strcmp(k[i], "origin") == 0)
{
- int x = 0, y = 0, z = 0;
+ float x = 0.f, y = 0.f, z = 0.f;
- sscanf(v[i], "%d %d %d", &x, &y, &z);
+ sscanf(v[i], "%f %f %f", &x, &y, &z);
- rp->p[0] = +(float) x / SCALE;
- rp->p[1] = +(float) z / SCALE;
- rp->p[2] = -(float) y / SCALE;
+ rp->p[0] = +x / SCALE;
+ rp->p[1] = +z / SCALE;
+ rp->p[2] = -y / SCALE;
}
}
if (strcmp(k[i], "origin") == 0)
{
- int x = 0, y = 0, z = 0;
+ float x = 0.f, y = 0.f, z = 0.f;
- sscanf(v[i], "%d %d %d", &x, &y, &z);
+ sscanf(v[i], "%f %f %f", &x, &y, &z);
- zp->p[0] = +(float) (x) / SCALE;
- zp->p[1] = +(float) (z - 24) / SCALE;
- zp->p[2] = -(float) (y) / SCALE;
+ zp->p[0] = +(x) / SCALE;
+ zp->p[1] = +(z - 24) / SCALE;
+ zp->p[2] = -(y) / SCALE;
}
}
}
if (strcmp(k[i], "origin") == 0)
{
- int x = 0, y = 0, z = 0;
+ float x = 0.f, y = 0.f, z = 0.f;
- sscanf(v[i], "%d %d %d", &x, &y, &z);
+ sscanf(v[i], "%f %f %f", &x, &y, &z);
- wp->p[0] = +(float) x / SCALE;
- wp->p[1] = +(float) z / SCALE;
- wp->p[2] = -(float) y / SCALE;
+ wp->p[0] = +x / SCALE;
+ wp->p[1] = +z / SCALE;
+ wp->p[2] = -y / SCALE;
}
}
}
if (strcmp(k[i], "origin") == 0)
{
- int x = 0, y = 0, z = 0;
+ float x = 0.f, y = 0.f, z = 0.f;
- sscanf(v[i], "%d %d %d", &x, &y, &z);
+ sscanf(v[i], "%f %f %f", &x, &y, &z);
- jp->p[0] = +(float) x / SCALE;
- jp->p[1] = +(float) z / SCALE;
- jp->p[2] = -(float) y / SCALE;
+ jp->p[0] = +x / SCALE;
+ jp->p[1] = +z / SCALE;
+ jp->p[2] = -y / SCALE;
}
}
}
make_ref(v[i], &xp->pi);
if (strcmp(k[i], "timer") == 0)
+ {
sscanf(v[i], "%f", &xp->t0);
+ xp->t = xp->t0;
+ }
if (strcmp(k[i], "state") == 0)
{
if (strcmp(k[i], "origin") == 0)
{
- int x = 0, y = 0, z = 0;
+ float x = 0.f, y = 0.f, z = 0.f;
- sscanf(v[i], "%d %d %d", &x, &y, &z);
+ sscanf(v[i], "%f %f %f", &x, &y, &z);
- xp->p[0] = +(float) x / SCALE;
- xp->p[1] = +(float) z / SCALE;
- xp->p[2] = -(float) y / SCALE;
+ xp->p[0] = +x / SCALE;
+ xp->p[1] = +z / SCALE;
+ xp->p[2] = -y / SCALE;
}
}
}
if (strcmp(k[i], "origin") == 0)
{
- int x = 0, y = 0, z = 0;
+ float x = 0.f, y = 0.f, z = 0.f;
- sscanf(v[i], "%d %d %d", &x, &y, &z);
+ sscanf(v[i], "%f %f %f", &x, &y, &z);
- targ_p[targ_n][0] = +(float) x / SCALE;
- targ_p[targ_n][1] = +(float) z / SCALE;
- targ_p[targ_n][2] = -(float) y / SCALE;
+ targ_p[targ_n][0] = +x / SCALE;
+ targ_p[targ_n][1] = +z / SCALE;
+ targ_p[targ_n][2] = -y / SCALE;
}
}
if (strcmp(k[i], "origin") == 0)
{
- int x = 0, y = 0, z = 0;
+ float x = 0.f, y = 0.f, z = 0.f;
- sscanf(v[i], "%d %d %d", &x, &y, &z);
+ sscanf(v[i], "%f %f %f", &x, &y, &z);
- up->p[0] = +(float) (x) / SCALE;
- up->p[1] = +(float) (z - 24) / SCALE;
- up->p[2] = -(float) (y) / SCALE;
+ up->p[0] = +(x) / SCALE;
+ up->p[1] = +(z - 24) / SCALE;
+ up->p[2] = -(y) / SCALE;
}
}
/*---------------------------------------------------------------------------*/
-static void read_ent(struct s_file *fp, FILE *fin)
+static void read_ent(struct s_file *fp, fs_file fin)
{
char k[MAXKEY][MAXSTR];
char v[MAXKEY][MAXSTR];
if (!strcmp(v[i], "misc_model")) make_body(fp, k, v, c, l0);
}
-static void read_map(struct s_file *fp, FILE *fin)
+static void read_map(struct s_file *fp, fs_file fin)
{
char k[MAXSTR];
char v[MAXSTR];
int i, j;
for (i = 1; i < lp->vc; i++)
+ {
+ int vi = fp->iv[lp->v0 + i];
+
+ if (!on_side(fp->vv[vi].p, fp->sv + si) ||
+ !on_side(fp->vv[vi].p, fp->sv + sj))
+ continue;
+
for (j = 0; j < i; j++)
{
- int vi = fp->iv[lp->v0 + i];
int vj = fp->iv[lp->v0 + j];
- if (on_side(fp->vv[vi].p, fp->sv + si) &&
- on_side(fp->vv[vj].p, fp->sv + si) &&
- on_side(fp->vv[vi].p, fp->sv + sj) &&
+ if (on_side(fp->vv[vj].p, fp->sv + si) &&
on_side(fp->vv[vj].p, fp->sv + sj))
{
fp->ev[fp->ec].vi = vi;
lp->ec++;
}
}
+ }
}
/*
if (fp->rv[i].mi == mi) fp->rv[i].mi = mj;
}
+static int vert_swaps[MAXV];
+
+static void apply_vert_swaps(struct s_file *fp)
+{
+ int i, j;
+
+ for (i = 0; i < fp->ec; i++)
+ {
+ fp->ev[i].vi = vert_swaps[fp->ev[i].vi];
+ fp->ev[i].vj = vert_swaps[fp->ev[i].vj];
+ }
+
+ for (i = 0; i < fp->gc; i++)
+ {
+ fp->gv[i].vi = vert_swaps[fp->gv[i].vi];
+ fp->gv[i].vj = vert_swaps[fp->gv[i].vj];
+ fp->gv[i].vk = vert_swaps[fp->gv[i].vk];
+ }
+
+ for (i = 0; i < fp->lc; i++)
+ for (j = 0; j < fp->lv[i].vc; j++)
+ fp->iv[fp->lv[i].v0 + j] = vert_swaps[fp->iv[fp->lv[i].v0 + j]];
+}
+
static void swap_vert(struct s_file *fp, int vi, int vj)
{
int i, j;
fp->iv[fp->lv[i].v0 + j] = vj;
}
-static void swap_edge(struct s_file *fp, int ei, int ej)
+static int edge_swaps[MAXE];
+
+static void apply_edge_swaps(struct s_file *fp)
{
int i, j;
for (i = 0; i < fp->lc; i++)
for (j = 0; j < fp->lv[i].ec; j++)
- if (fp->iv[fp->lv[i].e0 + j] == ei)
- fp->iv[fp->lv[i].e0 + j] = ej;
+ fp->iv[fp->lv[i].e0 + j] = edge_swaps[fp->iv[fp->lv[i].e0 + j]];
}
-static void swap_side(struct s_file *fp, int si, int sj)
+static int side_swaps[MAXS];
+
+static void apply_side_swaps(struct s_file *fp)
{
int i, j;
for (i = 0; i < fp->gc; i++)
{
- if (fp->gv[i].si == si) fp->gv[i].si = sj;
- if (fp->gv[i].sj == si) fp->gv[i].sj = sj;
- if (fp->gv[i].sk == si) fp->gv[i].sk = sj;
+ fp->gv[i].si = side_swaps[fp->gv[i].si];
+ fp->gv[i].sj = side_swaps[fp->gv[i].sj];
+ fp->gv[i].sk = side_swaps[fp->gv[i].sk];
}
for (i = 0; i < fp->nc; i++)
- if (fp->nv[i].si == si) fp->nv[i].si = sj;
+ fp->nv[i].si = side_swaps[fp->nv[i].si];
for (i = 0; i < fp->lc; i++)
for (j = 0; j < fp->lv[i].sc; j++)
- if (fp->iv[fp->lv[i].s0 + j] == si)
- fp->iv[fp->lv[i].s0 + j] = sj;
+ fp->iv[fp->lv[i].s0 + j] = side_swaps[fp->iv[fp->lv[i].s0 + j]];
}
-static void swap_texc(struct s_file *fp, int ti, int tj)
+static int texc_swaps[MAXT];
+
+static void apply_texc_swaps(struct s_file *fp)
{
int i;
for (i = 0; i < fp->gc; i++)
{
- if (fp->gv[i].ti == ti) fp->gv[i].ti = tj;
- if (fp->gv[i].tj == ti) fp->gv[i].tj = tj;
- if (fp->gv[i].tk == ti) fp->gv[i].tk = tj;
+ fp->gv[i].ti = texc_swaps[fp->gv[i].ti];
+ fp->gv[i].tj = texc_swaps[fp->gv[i].tj];
+ fp->gv[i].tk = texc_swaps[fp->gv[i].tk];
}
}
+static int geom_swaps[MAXG];
-static void swap_geom(struct s_file *fp, int gi, int gj)
+static void apply_geom_swaps(struct s_file *fp)
{
int i, j;
for (i = 0; i < fp->lc; i++)
for (j = 0; j < fp->lv[i].gc; j++)
- if (fp->iv[fp->lv[i].g0 + j] == gi)
- fp->iv[fp->lv[i].g0 + j] = gj;
+ fp->iv[fp->lv[i].g0 + j] = geom_swaps[fp->iv[fp->lv[i].g0 + j]];
for (i = 0; i < fp->bc; i++)
for (j = 0; j < fp->bv[i].gc; j++)
- if (fp->iv[fp->bv[i].g0 + j] == gi)
- fp->iv[fp->bv[i].g0 + j] = gj;
+ fp->iv[fp->bv[i].g0 + j] = geom_swaps[fp->iv[fp->bv[i].g0 + j]];
}
/*---------------------------------------------------------------------------*/
{
for (j = 0; j < k; j++)
if (comp_vert(fp->vv + i, fp->vv + j))
- {
- swap_vert(fp, i, j);
break;
- }
+
+ vert_swaps[i] = j;
if (j == k)
{
if (i != k)
- {
fp->vv[k] = fp->vv[i];
- swap_vert(fp, i, k);
- }
k++;
}
}
+ apply_vert_swaps(fp);
+
fp->vc = k;
}
{
for (j = 0; j < k; j++)
if (comp_edge(fp->ev + i, fp->ev + j))
- {
- swap_edge(fp, i, j);
break;
- }
+
+ edge_swaps[i] = j;
if (j == k)
{
if (i != k)
- {
fp->ev[k] = fp->ev[i];
- swap_edge(fp, i, k);
- }
k++;
}
}
+ apply_edge_swaps(fp);
+
fp->ec = k;
}
+static int geomlist[MAXV];
+static int nextgeom[MAXG];
+
static void uniq_geom(struct s_file *fp)
{
int i, j, k = 0;
+ for (i = 0; i < MAXV; i++)
+ geomlist[i] = -1;
+
for (i = 0; i < fp->gc; i++)
{
- for (j = 0; j < k; j++)
+ int key = fp->gv[i].vj;
+
+ for (j = geomlist[key]; j != -1; j = nextgeom[j])
if (comp_geom(fp->gv + i, fp->gv + j))
- {
- swap_geom(fp, i, j);
- break;
- }
+ goto found;
- if (j == k)
- {
- if (i != k)
- {
- fp->gv[k] = fp->gv[i];
- swap_geom(fp, i, k);
- }
- k++;
- }
+ fp->gv[k] = fp->gv[i];
+
+ nextgeom[k] = geomlist[key];
+ geomlist[key] = k;
+
+ j = k;
+ k++;
+
+found:
+ geom_swaps[i] = j;
}
+ apply_geom_swaps(fp);
+
fp->gc = k;
}
{
for (j = 0; j < k; j++)
if (comp_texc(fp->tv + i, fp->tv + j))
- {
- swap_texc(fp, i, j);
break;
- }
+
+ texc_swaps[i] = j;
if (j == k)
{
if (i != k)
- {
fp->tv[k] = fp->tv[i];
- swap_texc(fp, i, k);
- }
k++;
}
}
+ apply_texc_swaps(fp);
+
fp->tc = k;
}
{
for (j = 0; j < k; j++)
if (comp_side(fp->sv + i, fp->sv + j))
- {
- swap_side(fp, i, j);
break;
- }
+
+ side_swaps[i] = j;
if (j == k)
{
if (i != k)
- {
fp->sv[k] = fp->sv[i];
- swap_side(fp, i, k);
- }
k++;
}
}
+ apply_side_swaps(fp);
+
fp->sc = k;
}
static int test_lump_side(const struct s_file *fp,
const struct s_lump *lp,
- const struct s_side *sp)
+ const struct s_side *sp,
+ float bsphere[4])
{
int si;
int vi;
int f = 0;
int b = 0;
+ float d;
+
+ if (!lp->vc)
+ return 0;
+
+ /* Check if the bounding sphere of the lump is completely on one side. */
+
+ d = v_dot(bsphere, sp->n) - sp->d;
+
+ if (fabs(d) > bsphere[3])
+ return d > 0 ? 1 : -1;
+
/* If the given side is part of the given lump, then the lump is behind. */
for (si = 0; si < lp->sc; si++)
return 0;
}
-static int node_node(struct s_file *fp, int l0, int lc)
+static int node_node(struct s_file *fp, int l0, int lc, float bsphere[][4])
{
if (lc < 8)
{
int k = 0;
for (li = 0; li < lc; li++)
- if ((k = test_lump_side(fp, fp->lv + l0 + li, fp->sv + si)))
+ if ((k = test_lump_side(fp,
+ fp->lv + l0 + li,
+ fp->sv + si,
+ bsphere[l0 + li])))
d += k;
else
o++;
}
else
{
- switch (test_lump_side(fp, fp->lv + l0 + li, fp->sv + sj))
+ switch (test_lump_side(fp,
+ fp->lv + l0 + li,
+ fp->sv + sj,
+ bsphere[l0 + li]))
{
case +1:
fp->lv[l0+li].fl = (fp->lv[l0+li].fl & 1) | 0x10;
if (fp->lv[l0 + li].fl < fp->lv[l0 + lj].fl)
{
struct s_lump l;
+ float f;
+ int i;
+
+ for (i = 0; i < 4; i++)
+ {
+ f = bsphere[l0 + li][i];
+ bsphere[l0 + li][i] = bsphere[l0 + lj][i];
+ bsphere[l0 + lj][i] = f;
+ }
l = fp->lv[l0 + li];
fp->lv[l0 + li] = fp->lv[l0 + lj];
i = incn(fp);
fp->nv[i].si = sj;
- fp->nv[i].ni = node_node(fp, li, lic);
+ fp->nv[i].ni = node_node(fp, li, lic, bsphere);
- fp->nv[i].nj = node_node(fp, lk, lkc);
+ fp->nv[i].nj = node_node(fp, lk, lkc, bsphere);
fp->nv[i].l0 = lj;
fp->nv[i].lc = ljc;
}
}
+/*
+ * Compute a bounding sphere for a lump (not optimal)
+ */
+static void lump_bounding_sphere(struct s_file *fp,
+ struct s_lump *lp,
+ float bsphere[4])
+{
+ float bbox[6];
+ float r;
+ int i;
+
+ if (!lp->vc)
+ return;
+
+ bbox[0] = bbox[3] = fp->vv[fp->iv[lp->v0]].p[0];
+ bbox[1] = bbox[4] = fp->vv[fp->iv[lp->v0]].p[1];
+ bbox[2] = bbox[5] = fp->vv[fp->iv[lp->v0]].p[2];
+
+ for (i = 1; i < lp->vc; i++)
+ {
+ struct s_vert *vp = fp->vv + fp->iv[lp->v0 + i];
+ int j;
+
+ for (j = 0; j < 3; j++)
+ if (vp->p[j] < bbox[j])
+ bbox[j] = vp->p[j];
+
+ for (j = 0; j < 3; j++)
+ if (vp->p[j] > bbox[j + 3])
+ bbox[j + 3] = vp->p[j];
+ }
+
+ r = 0;
+
+ for (i = 0; i < 3; i++)
+ {
+ bsphere[i] = (bbox[i] + bbox[i + 3]) / 2;
+ r += (bsphere[i] - bbox[i]) * (bsphere[i] - bbox[i]);
+ }
+
+ bsphere[3] = fsqrtf(r);
+}
+
static void node_file(struct s_file *fp)
{
- int bi;
+ float bsphere[MAXL][4];
+ int i;
+
+ /* Compute a bounding sphere for each lump. */
+
+ for (i = 0; i < fp->lc; i++)
+ lump_bounding_sphere(fp, fp->lv + i, bsphere[i]);
/* Sort the lumps of each body into BSP nodes. */
- for (bi = 0; bi < fp->bc; bi++)
- fp->bv[bi].ni = node_node(fp, fp->bv[bi].l0, fp->bv[bi].lc);
+ for (i = 0; i < fp->bc; i++)
+ fp->bv[i].ni = node_node(fp, fp->bv[i].l0, fp->bv[i].lc, bsphere);
}
/*---------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
- char src[MAXSTR];
- char dst[MAXSTR];
+ char src[MAXSTR] = "";
+ char dst[MAXSTR] = "";
struct s_file f;
- FILE *fin;
+ fs_file fin;
+
+ if (!fs_init(argv[0]))
+ {
+ fprintf(stderr, "Failure to initialize virtual file system: %s\n",
+ fs_error());
+ return 1;
+ }
if (argc > 2)
{
+ input_file = argv[1];
+
if (argc > 3 && strcmp(argv[3], "--debug") == 0)
debug_output = 1;
- if (config_data_path(argv[2], NULL))
- {
- strncpy(src, argv[1], MAXSTR);
- strncpy(dst, argv[1], MAXSTR);
+ strncpy(src, argv[1], MAXSTR - 1);
+ strncpy(dst, argv[1], MAXSTR - 1);
- if (strcmp(dst + strlen(dst) - 4, ".map") == 0)
- strcpy(dst + strlen(dst) - 4, ".sol");
- else
- strcat(dst, ".sol");
+ if (strcmp(dst + strlen(dst) - 4, ".map") == 0)
+ strcpy(dst + strlen(dst) - 4, ".sol");
+ else
+ strcat(dst, ".sol");
- if ((fin = fopen(src, "r")))
+ fs_add_path (dir_name(src));
+ fs_set_write_dir(dir_name(dst));
+
+ if ((fin = fs_open(base_name(src, NULL), "r")))
+ {
+ if (!fs_add_path_with_archives(argv[2]))
{
- init_file(&f);
- read_map(&f, fin);
+ fprintf(stderr, "Failure to establish data directory\n");
+ fs_close(fin);
+ fs_quit();
+ return 1;
+ }
- resolve();
- targets(&f);
+ init_file(&f);
+ read_map(&f, fin);
- clip_file(&f);
- move_file(&f);
- uniq_file(&f);
- smth_file(&f);
- sort_file(&f);
- node_file(&f);
- dump_file(&f, dst);
+ resolve();
+ targets(&f);
- sol_stor(&f, dst);
+ clip_file(&f);
+ move_file(&f);
+ uniq_file(&f);
+ smth_file(&f);
+ sort_file(&f);
+ node_file(&f);
+ dump_file(&f, dst);
- fclose(fin);
+ sol_stor(&f, base_name(dst, NULL));
- free_imagedata();
- }
+ fs_close(fin);
+
+ free_imagedata();
}
- else fprintf(stderr, "Failure to establish data directory\n");
}
else fprintf(stderr, "Usage: %s <map> <data> [--debug]\n", argv[0]);