Tighten processing of WALL_IS_DOORWAY flags

This commit is contained in:
Kp 2014-09-06 22:26:11 +00:00
parent 3573d680ef
commit 02e2e77ee6
10 changed files with 99 additions and 39 deletions

View file

@ -112,7 +112,8 @@ int check_lsegments_validity(void);
// set to WID_FLY_FLAG to see if a robot could fly from one to the other.
// Search up to a maximum depth of max_depth.
// Return the distance.
fix find_connected_distance(const vms_vector *p0, int seg0, const vms_vector *p1, segnum_t seg1, int max_depth, int wid_flag);
struct WALL_IS_DOORWAY_mask_t;
fix find_connected_distance(const vms_vector *p0, int seg0, const vms_vector *p1, segnum_t seg1, int max_depth, WALL_IS_DOORWAY_mask_t wid_flag);
//create a matrix that describes the orientation of the given segment
extern void extract_orient_from_segment(vms_matrix *m,segment *seg);

View file

@ -100,22 +100,93 @@ struct vobjptridx_t;
#define MAX_CLIP_FRAMES 50
#endif
template <unsigned value>
struct WALL_IS_DOORWAY_FLAG
{
constexpr operator unsigned() const { return value; }
template <unsigned F2>
constexpr WALL_IS_DOORWAY_FLAG<value | F2> operator|(WALL_IS_DOORWAY_FLAG<F2>)
{
return {};
}
};
template <unsigned F>
struct WALL_IS_DOORWAY_sresult_t
{
};
template <unsigned F>
static inline constexpr WALL_IS_DOORWAY_sresult_t<F> WALL_IS_DOORWAY_sresult(WALL_IS_DOORWAY_FLAG<F>)
{
return {};
}
struct WALL_IS_DOORWAY_mask_t
{
unsigned value;
template <unsigned F>
constexpr WALL_IS_DOORWAY_mask_t(WALL_IS_DOORWAY_FLAG<F>) :
value(F)
{
}
};
struct WALL_IS_DOORWAY_result_t
{
unsigned value;
template <unsigned F>
constexpr WALL_IS_DOORWAY_result_t(WALL_IS_DOORWAY_sresult_t<F>) :
value(F)
{
}
template <unsigned F>
unsigned operator&(WALL_IS_DOORWAY_FLAG<F>) const
{
return value & F;
}
template <unsigned F>
WALL_IS_DOORWAY_result_t operator|=(WALL_IS_DOORWAY_FLAG<F>)
{
value |= F;
return *this;
}
template <unsigned F>
bool operator==(WALL_IS_DOORWAY_sresult_t<F>) const
{
return value == F;
}
bool operator&(WALL_IS_DOORWAY_mask_t m) const
{
return value & m.value;
}
bool operator==(WALL_IS_DOORWAY_result_t) const = delete;
template <typename T>
bool operator!=(const T &t) const
{
return !(*this == t);
}
};
// WALL_IS_DOORWAY flags.
static const unsigned WID_FLY_FLAG = 1;
static const unsigned WID_RENDER_FLAG = 2;
static const unsigned WID_RENDPAST_FLAG = 4;
static const unsigned WID_EXTERNAL_FLAG = 8;
static const WALL_IS_DOORWAY_FLAG<1> WID_FLY_FLAG;
static const WALL_IS_DOORWAY_FLAG<2> WID_RENDER_FLAG;
static const WALL_IS_DOORWAY_FLAG<4> WID_RENDPAST_FLAG;
static const WALL_IS_DOORWAY_FLAG<8> WID_EXTERNAL_FLAG;
#if defined(DXX_BUILD_DESCENT_II)
static const unsigned WID_CLOAKED_FLAG = 16;
static const WALL_IS_DOORWAY_FLAG<16> WID_CLOAKED_FLAG;
#endif
// WALL_IS_DOORWAY return values F/R/RP
static const unsigned WID_WALL = WID_RENDER_FLAG; // 0/1/0 wall
static const unsigned WID_TRANSPARENT_WALL = WID_RENDER_FLAG | WID_RENDPAST_FLAG; // 0/1/1 transparent wall
static const unsigned WID_ILLUSORY_WALL = WID_FLY_FLAG | WID_RENDPAST_FLAG; // 1/1/0 illusory wall
static const unsigned WID_TRANSILLUSORY_WALL = WID_FLY_FLAG | WID_RENDER_FLAG | WID_RENDPAST_FLAG; // 1/1/1 transparent illusory wall
static const unsigned WID_NO_WALL = WID_FLY_FLAG | WID_RENDPAST_FLAG; // 1/0/1 no wall, can fly through
static const unsigned WID_EXTERNAL = WID_EXTERNAL_FLAG; // 0/0/0/1 don't see it, dont fly through it
static const auto WID_WALL = WALL_IS_DOORWAY_sresult(WID_RENDER_FLAG); // 0/1/0 wall
static const auto WID_TRANSPARENT_WALL = WALL_IS_DOORWAY_sresult(WID_RENDER_FLAG | WID_RENDPAST_FLAG); // 0/1/1 transparent wall
static const auto WID_ILLUSORY_WALL = WALL_IS_DOORWAY_sresult(WID_FLY_FLAG | WID_RENDER_FLAG); // 1/1/0 illusory wall
static const auto WID_TRANSILLUSORY_WALL = WALL_IS_DOORWAY_sresult(WID_FLY_FLAG | WID_RENDER_FLAG | WID_RENDPAST_FLAG); // 1/1/1 transparent illusory wall
static const auto WID_NO_WALL = WALL_IS_DOORWAY_sresult(WID_FLY_FLAG | WID_RENDPAST_FLAG); // 1/0/1 no wall, can fly through
static const auto WID_EXTERNAL = WALL_IS_DOORWAY_sresult(WID_EXTERNAL_FLAG); // 0/0/0/1 don't see it, dont fly through it
#if defined(DXX_BUILD_DESCENT_II)
static const auto WID_CLOAKED_WALL = WALL_IS_DOORWAY_sresult(WID_RENDER_FLAG | WID_RENDPAST_FLAG | WID_CLOAKED_FLAG);
#endif
#define MAX_STUCK_OBJECTS 32
@ -219,8 +290,6 @@ struct wclip : public prohibit_void_ptr<wclip>
extern const char Wall_names[7][10];
//#define WALL_IS_DOORWAY(seg,side) wall_is_doorway(seg, side)
#if defined(DXX_BUILD_DESCENT_II)
#define MAX_CLOAKING_WALLS 10
extern array<cloaking_wall, MAX_CLOAKING_WALLS> CloakingWalls;
@ -251,9 +320,9 @@ struct wclip;
extern void wall_init();
// Automatically checks if a there is a doorway (i.e. can fly through)
extern int wall_is_doorway ( segment *seg, int side );
WALL_IS_DOORWAY_result_t wall_is_doorway (segment *seg, int side);
static inline int WALL_IS_DOORWAY(segment *seg, int side)
static inline WALL_IS_DOORWAY_result_t WALL_IS_DOORWAY(segment *seg, int side)
{
if (seg->children[side] == segment_none)
return WID_WALL;

View file

@ -92,13 +92,11 @@ static void add_light_intensity(segment *segp, int sidenum, int vert, fix intens
// desired, but not entirely invalid. 2 reflects some light back to 0.
static void apply_light_intensity(segment *segp, int sidenum, fix intensity, int depth)
{
int wid_result;
if (intensity == 0)
return;
wid_result = WALL_IS_DOORWAY(segp, sidenum);
if ((wid_result != WID_FLY_FLAG) && (wid_result != WID_NO_WALL)) {
auto wid_result = WALL_IS_DOORWAY(segp, sidenum);
if (!(wid_result & WID_RENDPAST_FLAG)) {
int v;
for (v=0; v<4; v++) // add light to this wall
add_light_intensity(segp, sidenum, v, intensity);

View file

@ -2152,8 +2152,8 @@ static void init_boss_segments(boss_special_segment_array_t &segptr, int size_ch
tail &= QUEUE_SIZE-1;
for (sidenum=0; sidenum<MAX_SIDES_PER_SEGMENT; sidenum++) {
int w;
if (((w = WALL_IS_DOORWAY(segp, sidenum)) & WID_FLY_FLAG) || one_wall_hack)
auto w = WALL_IS_DOORWAY(segp, sidenum);
if ((w & WID_FLY_FLAG) || one_wall_hack)
{
#if defined(DXX_BUILD_DESCENT_II)
// If we get here and w == WID_WALL, then we want to process through this wall, else not.

View file

@ -142,7 +142,7 @@ static void digi_get_sound_loc( const vms_matrix * listener, const vms_vector *
int num_search_segs = f2i(max_distance/20);
if ( num_search_segs < 1 ) num_search_segs = 1;
path_distance = find_connected_distance(listener_pos, listener_seg, sound_pos, sound_seg, num_search_segs, WID_RENDPAST_FLAG+WID_FLY_FLAG );
path_distance = find_connected_distance(listener_pos, listener_seg, sound_pos, sound_seg, num_search_segs, WID_RENDPAST_FLAG|WID_FLY_FLAG );
if ( path_distance > -1 ) {
*volume = max_volume - fixdiv(path_distance,max_distance);
if (*volume > 0 ) {

View file

@ -921,16 +921,13 @@ static int fvi_sub(vms_vector *intp,segnum_t *ints,const vms_vector *p0,segnum_t
if (face_hit_type) { //through this wall/door
int wid_flag;
auto wid_flag = WALL_IS_DOORWAY(seg, side);
//if what we have hit is a door, check the adjoining seg
if ( (thisobjnum == Players[Player_num].objnum) && (cheats.ghostphysics) ) {
wid_flag = WALL_IS_DOORWAY(seg, side);
if (seg->children[side] >= 0 )
wid_flag |= WID_FLY_FLAG;
} else {
wid_flag = WALL_IS_DOORWAY(seg, side);
}
if ((wid_flag & WID_FLY_FLAG) ||

View file

@ -866,7 +866,7 @@ static void add_to_fcd_cache(int seg0, int seg1, int depth, fix dist)
// Determine whether seg0 and seg1 are reachable in a way that allows sound to pass.
// Search up to a maximum depth of max_depth.
// Return the distance.
fix find_connected_distance(const vms_vector *p0, int seg0, const vms_vector *p1, segnum_t seg1, int max_depth, int wid_flag)
fix find_connected_distance(const vms_vector *p0, int seg0, const vms_vector *p1, segnum_t seg1, int max_depth, WALL_IS_DOORWAY_mask_t wid_flag)
{
segnum_t cur_seg;
int sidenum;

View file

@ -160,7 +160,7 @@ static void apply_light(g3s_lrgb obj_light_emission, segnum_t obj_seg, vms_vecto
if (use_fcd_lighting && abs(obji_64) > F1_0*32)
{
dist = find_connected_distance(obj_pos, obj_seg, vertpos, vsegnum, n_render_vertices, WID_RENDPAST_FLAG+WID_FLY_FLAG);
dist = find_connected_distance(obj_pos, obj_seg, vertpos, vsegnum, n_render_vertices, WID_RENDPAST_FLAG|WID_FLY_FLAG);
if (dist >= 0)
apply_light = 1;
}

View file

@ -217,7 +217,7 @@ static inline int is_alphablend_eclip(int eclip_num)
// they are used for our hideously hacked in headlight system.
// vp is a pointer to vertex ids.
// tmap1, tmap2 are texture map ids. tmap2 is the pasty one.
static void render_face(segnum_t segnum, int sidenum, int nv, int *vp, int tmap1, int tmap2, uvl *uvlp, int wid_flags)
static void render_face(segnum_t segnum, int sidenum, int nv, int *vp, int tmap1, int tmap2, uvl *uvlp, WALL_IS_DOORWAY_result_t wid_flags)
{
grs_bitmap *bm;
#ifdef OGL
@ -427,10 +427,7 @@ static void render_side(segment *segp, int sidenum)
uvl temp_uvls[3];
fix min_dot, max_dot;
vms_vector normals[2];
int wid_flags;
wid_flags = WALL_IS_DOORWAY(segp,sidenum);
auto wid_flags = WALL_IS_DOORWAY(segp,sidenum);
if (!(wid_flags & WID_RENDER_FLAG)) //if (WALL_IS_DOORWAY(segp, sidenum) == WID_NO_WALL)
return;
@ -1612,9 +1609,7 @@ static void build_segment_list(render_state_t &rstate, visited_twobit_array_t &v
//tricky code to look at sides in correct order follows
for (c=n_children=0;c<MAX_SIDES_PER_SEGMENT;c++) { //build list of sides
int wid;
wid = WALL_IS_DOORWAY(seg, c);
auto wid = WALL_IS_DOORWAY(seg, c);
if (wid & WID_RENDPAST_FLAG)
{
rotated=1;

View file

@ -100,7 +100,7 @@ static int check_transparency( segment * seg, int side )
// WID_ILLUSORY_WALL 3 // 1/1/0 illusory wall
// WID_TRANSILLUSORY_WALL 7 // 1/1/1 transparent illusory wall
// WID_NO_WALL 5 // 1/0/1 no wall, can fly through
int wall_is_doorway ( segment * seg, int side )
WALL_IS_DOORWAY_result_t wall_is_doorway ( segment * seg, int side )
{
int flags, type;
int state;
@ -150,7 +150,7 @@ int wall_is_doorway ( segment * seg, int side )
#if defined(DXX_BUILD_DESCENT_II)
if (type == WALL_CLOAKED)
return WID_RENDER_FLAG | WID_RENDPAST_FLAG | WID_CLOAKED_FLAG;
return WID_CLOAKED_WALL;
#endif
state = Walls[seg->sides[side].wall_num].state;