start making the rotated bounding box (really dynamic clipping huls) more

generice, and also more in line with the rest of quake's clipping system
(ie, support the entity size selected hulls). I'm not /entirly happy with
what's here, but it's a start, and the force fields in customtf work /much/
better :)
This commit is contained in:
Bill Currie 2001-07-30 04:33:59 +00:00
parent 0219bcb4c8
commit 6cb2cb5bdc
10 changed files with 244 additions and 74 deletions

View file

@ -1,7 +1,7 @@
AUTOMAKE_OPTIONS = foreign
SUBDIRS = plugin
includedir = $(prefix)/include/QF
include_HEADERS = bspfile.h cdaudio.h checksum.h cmd.h \
include_HEADERS = bspfile.h cdaudio.h checksum.h clip_hull.h cmd.h \
console.h crc.h cvar.h draw.h gcc_attr.h gib.h hash.h hl.h info.h \
input.h joystick.h keys.h link.h locs.h mathlib.h mdfour.h model.h \
modelgen.h msg.h pcx.h plugin.h pr_comp.h pr_debug.h progs.h qargs.h \

47
include/QF/clip_hull.h Normal file
View file

@ -0,0 +1,47 @@
/*
clip_hull.h
dynamic bsp clipping hull management
Copyright (C) 2001 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2001/7/28
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifndef __QF_clip_hull_h
#define __QF_clip_hull_h
#include "QF/bspfile.h"
typedef struct clip_hull_s {
vec3_t mins;
vec3_t maxs;
vec3_t axis[3];
struct hull_s *hulls[MAX_MAP_HULLS];
} clip_hull_t;
clip_hull_t *MOD_Alloc_Hull (int nodes, int planes);
void MOD_Free_Hull (clip_hull_t *ch);
#endif//__QF_clip_hull_h

View file

@ -202,7 +202,7 @@ typedef struct mleaf_s
} mleaf_t;
// !!! if this is changed, it must be changed in asm_i386.h too !!!
typedef struct
typedef struct hull_s
{
dclipnode_t *clipnodes;
mplane_t *planes;

View file

@ -143,8 +143,8 @@ pr_type_t *PR_GetGlobalPointer (progs_t *pr, const char *name);
func_t PR_GetFunctionIndex (progs_t *pr, const char *name);
int PR_GetFieldOffset (progs_t *pr, const char *name);
void PR_Error (progs_t *pr, const char *error, ...) __attribute__((format(printf,2,3)));
void PR_RunError (progs_t *pr, const char *error, ...) __attribute__((format(printf,2,3)));
void PR_Error (progs_t *pr, const char *error, ...) __attribute__((format(printf,2,3), noreturn));
void PR_RunError (progs_t *pr, const char *error, ...) __attribute__((format(printf,2,3), noreturn));
void ED_PrintEdicts (progs_t *pr, const char *fieldval);
void ED_PrintNum (progs_t *pr, int ent);

View file

@ -45,7 +45,7 @@ typedef void (*sys_printf_t) (const char *fmt, va_list args);
void Sys_SetPrintf (sys_printf_t func);
void Sys_Printf (const char *fmt, ...) __attribute__((format(printf,1,2)));
void Sys_Error (const char *error, ...) __attribute__((format(printf,1,2)));
void Sys_Error (const char *error, ...) __attribute__((format(printf,1,2), noreturn));
void Sys_Quit (void);
double Sys_DoubleTime (void);

View file

@ -16,19 +16,21 @@ endif
lib_LTLIBRARIES = libQFmodels.la $(MODELS_GL) $(MODELS_SW)
models_SOURCES = clip_hull.c model.c
libQFmodels_la_LDFLAGS = -version-info 1:0:0
libQFmodels_la_LIBADD = brush/libbrush.la
libQFmodels_la_SOURCES = model.c
libQFmodels_la_SOURCES = $(models_SOURCES)
libQFmodels_la_DEPENDENCIES = brush/libbrush.la
libQFmodels_gl_la_LDFLAGS = -version-info 1:0:0
libQFmodels_gl_la_LIBADD = alias/libalias_gl.la brush/libbrush_gl.la sprite/libsprite_gl.la
libQFmodels_gl_la_SOURCES = model.c gl_model_fullbright.c
libQFmodels_gl_la_SOURCES = $(models_SOURCES) gl_model_fullbright.c
libQFmodels_gl_la_DEPENDENCIES = alias/libalias_gl.la brush/libbrush_gl.la sprite/libsprite_gl.la
libQFmodels_sw_la_LDFLAGS = -version-info 1:0:0
libQFmodels_sw_la_LIBADD = alias/libalias_sw.la brush/libbrush_sw.la sprite/libsprite_sw.la
libQFmodels_sw_la_SOURCES = model.c
libQFmodels_sw_la_SOURCES = $(models_SOURCES)
libQFmodels_sw_la_DEPENDENCIES = alias/libalias_sw.la brush/libbrush_sw.la sprite/libsprite_sw.la
LIBLIST = libQFmodels.la libQFmodels_gl.la libQFmodels_sw.la

68
libs/models/clip_hull.c Normal file
View file

@ -0,0 +1,68 @@
/*
clip_hull.c
dynamic bsp clipping hull management
Copyright (C) 2001 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2001/7/28
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include "QF/clip_hull.h"
#include "QF/model.h"
clip_hull_t *MOD_Alloc_Hull (int nodes, int planes)
{
clip_hull_t *ch;
int size;
int i;
size = sizeof (hull_t);
size += sizeof (dclipnode_t) * nodes + sizeof (mplane_t) * planes;
size *= MAX_MAP_HULLS;
size += sizeof (clip_hull_t);
ch = calloc (size, 1);
if (!ch)
return 0;
ch->hulls[0] = (hull_t*)&ch[1];
for (i = 1; i < MAX_MAP_HULLS; i++)
ch->hulls[i] = &ch->hulls[i - 1][1];
ch->hulls[0]->clipnodes = (dclipnode_t*)&ch->hulls[i - 1][1];
ch->hulls[0]->planes = (mplane_t*)&ch->hulls[0]->clipnodes[nodes];
for (i = 1; i < MAX_MAP_HULLS; i++) {
ch->hulls[i]->clipnodes = (dclipnode_t*)&ch->hulls[i - 1]->planes[planes];
ch->hulls[i]->planes = (mplane_t*)&ch->hulls[i]->clipnodes[nodes];
}
return ch;
}
void MOD_Free_Hull (clip_hull_t *ch)
{
free (ch);
}

View file

@ -33,17 +33,18 @@
# include <string.h>
#endif
#include "QF/clip_hull.h"
#include "QF/cmd.h"
#include "compat.h"
#include "QF/cvar.h"
#include "QF/msg.h"
#include "QF/va.h"
#include "compat.h"
#include "crudefile.h"
#include "server.h"
#include "sv_pr_cmds.h"
#include "sv_progs.h"
#include "world.h"
#include "crudefile.h"
#define RETURN_EDICT(p, e) ((p)->pr_globals[OFS_RETURN].integer_var = EDICT_TO_PROG(p, e))
#define RETURN_STRING(p, s) ((p)->pr_globals[OFS_RETURN].integer_var = PR_SetString((p), s))
@ -1815,11 +1816,7 @@ PF_testentitypos (progs_t *pr)
#define MAX_PF_HULLS 64 // FIXME make dynamic?
static int pf_hull_list_inited;
static hull_t *pf_free_hulls;
static dclipnode_t pf_clipnodes[MAX_PF_HULLS][6];
static mplane_t pf_planes[MAX_PF_HULLS][6];
hull_t pf_hull_list[MAX_PF_HULLS];
clip_hull_t *pf_hull_list[MAX_PF_HULLS];
static void
PF_hullpointcontents (progs_t *pr)
@ -1840,40 +1837,37 @@ static void
PF_getboxbounds (progs_t *pr)
{
int h = G_INT (pr, OFS_PARM0) - 1;
hull_t *hull = &pf_hull_list[h];
clip_hull_t *ch;
if (h < 0 || h > MAX_PF_HULLS - 1
|| hull->clipnodes != pf_clipnodes[h]
|| hull->planes != pf_planes[h])
if (h < 0 || h > MAX_PF_HULLS - 1 || !(ch = pf_hull_list[h]))
PR_RunError (pr, "PF_freeboxhull: invalid box hull handle\n");
if (G_INT (pr, OFS_PARM1)) {
VectorCopy (hull->clip_maxs, G_VECTOR (pr, OFS_RETURN));
VectorCopy (ch->maxs, G_VECTOR (pr, OFS_RETURN));
} else {
VectorCopy (hull->clip_mins, G_VECTOR (pr, OFS_RETURN));
VectorCopy (ch->mins, G_VECTOR (pr, OFS_RETURN));
}
}
static void
PF_getboxhull (progs_t *pr)
{
hull_t *hull;
clip_hull_t *ch = 0;
int i;
if (!pf_hull_list_inited) {
int i;
pf_hull_list_inited = 1;
for (i = 0; i < MAX_PF_HULLS - 1; i++)
pf_hull_list[i].clipnodes = (dclipnode_t*)&pf_hull_list[i + 1];
pf_hull_list[i].clipnodes = 0;
pf_free_hulls = pf_hull_list;
for (i = 0; i < MAX_PF_HULLS; i++) {
if (!pf_hull_list[i]) {
ch = MOD_Alloc_Hull (6, 6);
break;
}
}
hull = pf_free_hulls;
if (hull) {
pf_free_hulls = (hull_t*)hull->clipnodes;
SV_InitHull (hull, pf_clipnodes[hull - pf_hull_list],
pf_planes[hull - pf_hull_list]);
G_INT (pr, OFS_RETURN) = (hull - pf_hull_list) + 1;
if (ch) {
pf_hull_list[i] = ch;
G_INT (pr, OFS_RETURN) = i + 1;
for (i = 0; i < MAX_MAP_HULLS; i++)
SV_InitHull (ch->hulls[i], ch->hulls[i]->clipnodes,
ch->hulls[i]->planes);
} else {
G_INT (pr, OFS_RETURN) = 0;
}
@ -1883,15 +1877,12 @@ static void
PF_freeboxhull (progs_t *pr)
{
int h = G_INT (pr, OFS_PARM0) - 1;
hull_t *hull = &pf_hull_list[h];
clip_hull_t *ch;
if (h < 0 || h > MAX_PF_HULLS - 1
|| hull->clipnodes != pf_clipnodes[h]
|| hull->planes != pf_planes[h])
if (h < 0 || h > MAX_PF_HULLS - 1 || !(ch = pf_hull_list[h]))
PR_RunError (pr, "PF_freeboxhull: invalid box hull handle\n");
hull->clipnodes = (dclipnode_t*)pf_free_hulls;
hull->planes = 0;
pf_free_hulls = hull;
pf_hull_list[h] = 0;
MOD_Free_Hull (ch);
}
static void
@ -1905,25 +1896,36 @@ PF_rotate_bbox (progs_t *pr)
};
float *mi = G_VECTOR (pr, OFS_PARM4);
float *ma = G_VECTOR (pr, OFS_PARM5);
vec3_t m[3];
vec3_t mins, maxs;
float *verts[6] = {maxs, mins, maxs, mins, maxs, mins};
hull_t *hull = &pf_hull_list[h];
int i, j;
vec3_t mins_offs = { -16, -16, -32 };
vec3_t maxs_offs = { +16, +16, +32 };
vec3_t v[8], d;
hull_t *hull;
clip_hull_t *ch;
int i, j;
float l;
if (h < 0 || h > MAX_PF_HULLS - 1 || !(ch = pf_hull_list[h]))
PR_RunError (pr, "PF_freeboxhull: invalid box hull handle\n");
// set up the rotation matrix. the three orientation vectors form the
// columns of the rotation matrix
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
m[i][j] = dir[j][i];
ch->axis[i][j] = dir[j][i];
}
}
// rotate the bounding box points
for (i = 0; i < 3; i++) {
mins[i] = DotProduct (m[i], mi);
maxs[i] = DotProduct (m[i], ma);
mins[i] = DotProduct (ch->axis[i], mi);
maxs[i] = DotProduct (ch->axis[i], ma);
//if (mins[i] > maxs[i]) {
// mins_offs[i] *= -1;
// maxs_offs[i] *= -1;
//}
}
// find all 8 corners of the rotated box
VectorCopy (mins, v[0]);
@ -1938,24 +1940,66 @@ PF_rotate_bbox (progs_t *pr)
VectorSubtract (maxs, x, v[3 + i * 2]);
}
// now find the aligned bounding box
VectorCopy (v[0], hull->clip_mins);
VectorCopy (v[0], hull->clip_maxs);
VectorCopy (v[0], ch->mins);
VectorCopy (v[0], ch->maxs);
for (i = 0; i < 8; i++) {
//Con_Printf ("'%0.1f %0.1f %0.1f'\n", v[i][0], v[i][1], v[i][2]);
for (j = 0; j < 3; j++) {
hull->clip_mins[j] = min (hull->clip_mins[j], v[i][j]);
hull->clip_maxs[j] = max (hull->clip_maxs[j], v[i][j]);
ch->mins[j] = min (ch->mins[j], v[i][j]);
ch->maxs[j] = max (ch->maxs[j], v[i][j]);
}
}
//Con_Printf ("---\n");
//Con_Printf ("'%0.1f %0.1f %0.1f'\n", hull->clip_mins[0], hull->clip_mins[1], hull->clip_mins[2]);
//Con_Printf ("'%0.1f %0.1f %0.1f'\n", hull->clip_maxs[0], hull->clip_maxs[1], hull->clip_maxs[2]);
hull = ch->hulls[0];
// now set up the clip planes
for (i = 0; i < 6; i++) {
hull->planes[i].dist = DotProduct (dir[i / 2], verts[i]);
hull->planes[i].type = 4;
VectorCopy (dir[i / 2], hull->planes[i].normal);
//Con_Printf ("%f %f %f %f\n",
// hull->planes[i].dist,
// hull->planes[i].normal[0], hull->planes[i].normal[1],
// hull->planes[i].normal[2]);
}
hull = ch->hulls[1];
hull->clip_mins[0] = -16;
hull->clip_mins[1] = -16;
hull->clip_mins[2] = -24;
hull->clip_maxs[0] = 16;
hull->clip_maxs[1] = 16;
hull->clip_maxs[2] = 32;
VectorAdd (mins_offs, mins, mins);
VectorAdd (maxs_offs, maxs, maxs);
for (i = 0; i < 6; i++) {
hull->planes[i].dist = DotProduct (dir[i / 2], verts[i]);
hull->planes[i].type = 4;
VectorCopy (dir[i / 2], hull->planes[i].normal);
//Con_Printf ("%f %f %f %f\n",
// hull->planes[i].dist,
// hull->planes[i].normal[0], hull->planes[i].normal[1],
// hull->planes[i].normal[2]);
}
hull = ch->hulls[2];
hull->clip_mins[0] = -32;
hull->clip_mins[1] = -32;
hull->clip_mins[2] = -24;
hull->clip_maxs[0] = 32;
hull->clip_maxs[1] = 32;
hull->clip_maxs[2] = 64;
maxs_offs[2] = 0;
VectorAdd (mins_offs, mins, mins);
VectorAdd (maxs_offs, maxs, maxs);
for (i = 0; i < 6; i++) {
hull->planes[i].dist = DotProduct (dir[i / 2], verts[i]);
hull->planes[i].type = 4;
VectorCopy (dir[i / 2], hull->planes[i].normal);
//Con_Printf ("%f %f %f %f\n",
// hull->planes[i].dist,
// hull->planes[i].normal[0], hull->planes[i].normal[1],
// hull->planes[i].normal[2]);
}
}

View file

@ -42,13 +42,15 @@
#include <ctype.h>
#include "QF/checksum.h"
#include "QF/clip_hull.h"
#include "QF/cmd.h"
#include "compat.h"
#include "QF/cvar.h"
#include "QF/msg.h"
#include "QF/sys.h"
#include "QF/va.h"
#include "QF/vfs.h"
#include "compat.h"
#include "bothdefs.h"
#include "msg_ucmd.h"
#include "pmove.h"
@ -1311,9 +1313,9 @@ AddLinksToPmove (areanode_t *node)
if (sv_fields.rotated_bbox != -1
&& SVFIELD (check, rotated_bbox, integer)) {
int h = SVFIELD (check, rotated_bbox, integer);
extern hull_t pf_hull_list[];
pe->hull = &pf_hull_list[h - 1];
int h = SVFIELD (check, rotated_bbox, integer) - 1;
extern clip_hull_t *pf_hull_list[];
pe->hull = pf_hull_list[h]->hulls[1];
} else {
pe->hull = 0;
if (SVFIELD (check, solid, float) == SOLID_BSP) {

View file

@ -38,6 +38,7 @@
#include <stdio.h>
#include "QF/clip_hull.h"
#include "QF/console.h"
#include "QF/crc.h"
@ -152,17 +153,27 @@ SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
model_t *model;
vec3_t size;
vec3_t hullmins, hullmaxs;
hull_t *hull;
hull_t *hull = 0;
int hull_index = 0;
if (sv_fields.rotated_bbox != -1
&& SVFIELD (ent, rotated_bbox, integer)) {
extern hull_t pf_hull_list[];
hull = &pf_hull_list[SVFIELD (ent, rotated_bbox, integer) - 1];
VectorCopy (SVFIELD (ent, origin, vector), offset);
return hull;
if ((sv_fields.rotated_bbox != -1
&& SVFIELD (ent, rotated_bbox, integer))
|| SVFIELD (ent, solid, float) == SOLID_BSP) {
VectorSubtract (maxs, mins, size);
if (size[0] < 3)
hull_index = 0;
else if (size[0] <= 32)
hull_index = 1;
else
hull_index = 2;
}
// decide which clipping hull to use, based on the size
if (SVFIELD (ent, solid, float) == SOLID_BSP) {
if (sv_fields.rotated_bbox != -1
&& SVFIELD (ent, rotated_bbox, integer)) {
extern clip_hull_t *pf_hull_list[];
int h = SVFIELD (ent, rotated_bbox, integer) - 1;
hull = pf_hull_list[h]->hulls[hull_index];
} if (SVFIELD (ent, solid, float) == SOLID_BSP) {
// explicit hulls in the BSP model
if (SVFIELD (ent, movetype, float) != MOVETYPE_PUSH)
SV_Error ("SOLID_BSP without MOVETYPE_PUSH");
@ -172,14 +183,10 @@ SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
if (!model || model->type != mod_brush)
SV_Error ("SOLID_BSP with a non bsp model");
VectorSubtract (maxs, mins, size);
if (size[0] < 3)
hull = &model->hulls[0];
else if (size[0] <= 32)
hull = &model->hulls[1];
else
hull = &model->hulls[2];
hull = &model->hulls[hull_index];
}
if (hull) {
// calculate an offset value to center the origin
VectorSubtract (hull->clip_mins, mins, offset);
VectorAdd (offset, SVFIELD (ent, origin, vector), offset);