Since current approach to improve wall collisions prevented the player to enter segments which basically are too small for the player ship, added simple bumping function via object_intersects_wall(); Also when validating segments check for segment degeneration outside the editor build, too and set flag in segment structure for all different purposes but right now helps us to disable bumping when encountering degenerated segments and not break such levels

This commit is contained in:
zicodxx 2011-05-04 02:15:07 +02:00
parent 4efbd0d9c4
commit 609bd15fd1
6 changed files with 113 additions and 100 deletions

View file

@ -1,5 +1,9 @@
D1X-Rebirth Changelog
20110504
--------
editor/segment.c, main/fvi.c, main/gameseg.c, main/physics.c, main/segment.h: Since current approach to improve wall collisions prevented the player to enter segments which basically are too small for the player ship, added simple bumping function via object_intersects_wall(); Also when validating segments check for segment degeneration outside the editor build, too and set flag in segment structure for all different purposes but right now helps us to disable bumping when encountering degenerated segments and not break such levels
20110424
--------
d1x-rebirth.xcodeproj/project.pbxproj, main/newmenu.c: Check if a menu closed in a subfunction before setting it's return value, fixing crash when levels are mismatched in multiplayer; Small tidy up for Xcode project

View file

@ -475,50 +475,6 @@ int med_set_vertex(int vnum,vms_vector *vp)
return vnum;
}
// ----
// A side is determined to be degenerate if the cross products of 3 consecutive points does not point outward.
int check_for_degenerate_side(segment *sp, int sidenum)
{
sbyte *vp = Side_to_verts[sidenum];
vms_vector vec1, vec2, cross, vec_to_center;
vms_vector segc, sidec;
fix dot;
int degeneracy_flag = 0;
compute_segment_center(&segc, sp);
compute_center_point_on_side(&sidec, sp, sidenum);
vm_vec_sub(&vec_to_center, &segc, &sidec);
//vm_vec_sub(&vec1, &Vertices[sp->verts[vp[1]]], &Vertices[sp->verts[vp[0]]]);
//vm_vec_sub(&vec2, &Vertices[sp->verts[vp[2]]], &Vertices[sp->verts[vp[1]]]);
//vm_vec_normalize(&vec1);
//vm_vec_normalize(&vec2);
vm_vec_normalized_dir(&vec1, &Vertices[sp->verts[(int) vp[1]]], &Vertices[sp->verts[(int) vp[0]]]);
vm_vec_normalized_dir(&vec2, &Vertices[sp->verts[(int) vp[2]]], &Vertices[sp->verts[(int) vp[1]]]);
vm_vec_cross(&cross, &vec1, &vec2);
dot = vm_vec_dot(&vec_to_center, &cross);
if (dot <= 0)
degeneracy_flag |= 1;
//vm_vec_sub(&vec1, &Vertices[sp->verts[vp[2]]], &Vertices[sp->verts[vp[1]]]);
//vm_vec_sub(&vec2, &Vertices[sp->verts[vp[3]]], &Vertices[sp->verts[vp[2]]]);
//vm_vec_normalize(&vec1);
//vm_vec_normalize(&vec2);
vm_vec_normalized_dir(&vec1, &Vertices[sp->verts[(int) vp[2]]], &Vertices[sp->verts[(int) vp[1]]]);
vm_vec_normalized_dir(&vec2, &Vertices[sp->verts[(int) vp[3]]], &Vertices[sp->verts[(int) vp[2]]]);
vm_vec_cross(&cross, &vec1, &vec2);
dot = vm_vec_dot(&vec_to_center, &cross);
if (dot <= 0)
degeneracy_flag |= 1;
return degeneracy_flag;
}
// -------------------------------------------------------------------------------
void create_removable_wall(segment *sp, int sidenum, int tmap_num)
{
@ -530,42 +486,6 @@ void create_removable_wall(segment *sp, int sidenum, int tmap_num)
assign_light_to_side(sp, sidenum);
}
// ----
// See if a segment has gotten turned inside out, or something.
// If so, set global Degenerate_segment_found and return 1, else return 0.
int check_for_degenerate_segment(segment *sp)
{
vms_vector fvec, rvec, uvec, cross;
fix dot;
int i, degeneracy_flag = 0; // degeneracy flag for current segment
extract_forward_vector_from_segment(sp, &fvec);
extract_right_vector_from_segment(sp, &rvec);
extract_up_vector_from_segment(sp, &uvec);
vm_vec_normalize(&fvec);
vm_vec_normalize(&rvec);
vm_vec_normalize(&uvec);
vm_vec_cross(&cross, &fvec, &rvec);
dot = vm_vec_dot(&cross, &uvec);
if (dot > 0)
degeneracy_flag = 0;
else {
degeneracy_flag = 1;
}
// Now, see if degenerate because of any side.
for (i=0; i<MAX_SIDES_PER_SEGMENT; i++)
degeneracy_flag |= check_for_degenerate_side(sp, i);
Degenerate_segment_found |= degeneracy_flag;
return degeneracy_flag;
}
#if 0
// ---------------------------------------------------------------------------------------------

View file

@ -58,11 +58,10 @@ int find_plane_line_intersection(vms_vector *new_pnt,vms_vector *plane_pnt,vms_v
//check for various bad values
if (den > 0 && (-num>>15) >= den) //will overflow (large negative)
num = (f1_0-f0_5)*den;
// FIXME: Handle those better!
if (den > 0 && num > den) //frac greater than one
num = den; //return 0;
return 0;
if (den < 0 && num < den) //frac greater than one
num = den; //return 0;
return 0;
if (labs (num) / (f1_0 / 2) >= labs (den))
return 0;

View file

@ -1178,7 +1178,6 @@ void extract_orient_from_segment(vms_matrix *m,segment *seg)
vm_vector_2_matrix(m,&fvec,&uvec,NULL);
}
#ifdef EDITOR
// ------------------------------------------------------------------------------------------
// Extract the forward vector from segment *sp, return in *vp.
// The forward vector is defined to be the vector from the the center of the front face of the segment
@ -1205,8 +1204,87 @@ void extract_up_vector_from_segment(segment *sp,vms_vector *vp)
{
extract_vector_from_segment(sp,vp,WBOTTOM,WTOP);
}
// ----
// A side is determined to be degenerate if the cross products of 3 consecutive points does not point outward.
int check_for_degenerate_side(segment *sp, int sidenum)
{
sbyte *vp = Side_to_verts[sidenum];
vms_vector vec1, vec2, cross, vec_to_center;
vms_vector segc, sidec;
fix dot;
int degeneracy_flag = 0;
compute_segment_center(&segc, sp);
compute_center_point_on_side(&sidec, sp, sidenum);
vm_vec_sub(&vec_to_center, &segc, &sidec);
//vm_vec_sub(&vec1, &Vertices[sp->verts[vp[1]]], &Vertices[sp->verts[vp[0]]]);
//vm_vec_sub(&vec2, &Vertices[sp->verts[vp[2]]], &Vertices[sp->verts[vp[1]]]);
//vm_vec_normalize(&vec1);
//vm_vec_normalize(&vec2);
vm_vec_normalized_dir(&vec1, &Vertices[sp->verts[(int) vp[1]]], &Vertices[sp->verts[(int) vp[0]]]);
vm_vec_normalized_dir(&vec2, &Vertices[sp->verts[(int) vp[2]]], &Vertices[sp->verts[(int) vp[1]]]);
vm_vec_cross(&cross, &vec1, &vec2);
dot = vm_vec_dot(&vec_to_center, &cross);
if (dot <= 0)
degeneracy_flag |= 1;
//vm_vec_sub(&vec1, &Vertices[sp->verts[vp[2]]], &Vertices[sp->verts[vp[1]]]);
//vm_vec_sub(&vec2, &Vertices[sp->verts[vp[3]]], &Vertices[sp->verts[vp[2]]]);
//vm_vec_normalize(&vec1);
//vm_vec_normalize(&vec2);
vm_vec_normalized_dir(&vec1, &Vertices[sp->verts[(int) vp[2]]], &Vertices[sp->verts[(int) vp[1]]]);
vm_vec_normalized_dir(&vec2, &Vertices[sp->verts[(int) vp[3]]], &Vertices[sp->verts[(int) vp[2]]]);
vm_vec_cross(&cross, &vec1, &vec2);
dot = vm_vec_dot(&vec_to_center, &cross);
if (dot <= 0)
degeneracy_flag |= 1;
return degeneracy_flag;
}
// ----
// See if a segment has gotten turned inside out, or something.
// If so, set global Degenerate_segment_found and return 1, else return 0.
int check_for_degenerate_segment(segment *sp)
{
vms_vector fvec, rvec, uvec, cross;
fix dot;
int i, degeneracy_flag = 0; // degeneracy flag for current segment
extract_forward_vector_from_segment(sp, &fvec);
extract_right_vector_from_segment(sp, &rvec);
extract_up_vector_from_segment(sp, &uvec);
vm_vec_normalize(&fvec);
vm_vec_normalize(&rvec);
vm_vec_normalize(&uvec);
vm_vec_cross(&cross, &fvec, &rvec);
dot = vm_vec_dot(&cross, &uvec);
if (dot > 0)
degeneracy_flag = 0;
else {
degeneracy_flag = 1;
}
// Now, see if degenerate because of any side.
for (i=0; i<MAX_SIDES_PER_SEGMENT; i++)
degeneracy_flag |= check_for_degenerate_side(sp, i);
#ifdef EDITOR
Degenerate_segment_found |= degeneracy_flag;
#endif
return degeneracy_flag;
}
void add_side_as_quad(segment *sp, int sidenum, vms_vector *normal)
{
side *sidep = &sp->sides[sidenum];
@ -1642,8 +1720,6 @@ void validate_segment_side(segment *sp, int sidenum)
// sp->sides[sidenum].render_flag = 0;
}
extern int check_for_degenerate_segment(segment *sp);
// -------------------------------------------------------------------------------
// Make a just-modified segment valid.
// check all sides to see how many faces they each should have (0,1,2)
@ -1652,9 +1728,7 @@ void validate_segment(segment *sp)
{
int side;
#ifdef EDITOR
check_for_degenerate_segment(sp);
#endif
sp->degenerated = check_for_degenerate_segment(sp);
for (side = 0; side < MAX_SIDES_PER_SEGMENT; side++)
validate_segment_side(sp, side);

View file

@ -287,6 +287,30 @@ void do_physics_sim_rot(object *obj)
check_and_fix_matrix(&obj->orient);
}
// On joining edges fvi tends to get inaccurate as hell due to object size. And I have no means to fix that - shame on me (that whole code should be rewritten). Approach is to check if the object interects with the wall and if so, move it out towards segment center.
void fix_illegal_wall_intersection(object *obj)
{
int i = 0;
vms_vector center,bump_vec;
if ( !(obj->type == OBJ_PLAYER || obj->type == OBJ_ROBOT) )
return;
if ( !object_intersects_wall(obj) )
return;
// HACK: check if the segment the object is located in and all it's children are valid. Otherwise we will break some levels where some segments are only passable since they are degenerated...
if ( Segments[obj->segnum].degenerated )
return;
for (i = 0; i < MAX_SIDES_PER_SEGMENT; i++)
if ( Segments[obj->segnum].children[i] > -1 && Segments[obj->segnum].children[i] <= Highest_segment_index )
if ( Segments[Segments[obj->segnum].children[i]].degenerated )
return;
compute_segment_center(&center,&Segments[obj->segnum]);
vm_vec_normalized_dir_quick(&bump_vec,&center,&obj->pos);
vm_vec_scale_add2(&obj->pos,&bump_vec,F0_1);
}
// -----------------------------------------------------------------------------------------------------------
//Simulate a physics object for this frame
void do_physics_sim(object *obj)
@ -562,17 +586,6 @@ void do_physics_sim(object *obj)
vms_vector moved_v;
fix hit_speed=0, wall_part=0;
/*
* On joining edges fvi tends to get inaccurate as hell due to object size. And I have no means to fix that - shame on me (that whole code should be rewritten). Approach is to check if the object interects with the wall and if so, move it out towards segment center. (also see FIXME in find_plane_line_intersection)
*/
if ( object_intersects_wall(obj) && (obj->type == OBJ_PLAYER || obj->type == OBJ_ROBOT) )
{
vms_vector center,bump_vec;
compute_segment_center(&center,&Segments[obj->segnum]);
vm_vec_normalized_dir_quick(&bump_vec,&center,&obj->pos);
vm_vec_scale_add2(&obj->pos,&bump_vec,F0_1);
}
// Find hit speed
vm_vec_sub(&moved_v,&obj->pos,&save_pos);
@ -716,6 +729,8 @@ void do_physics_sim(object *obj)
vm_vec_copy_scale(&obj->mtype.phys_info.velocity,&moved_vec,fixdiv(f1_0,FrameTime));
}
fix_illegal_wall_intersection(obj);
//Assert(check_point_in_seg(&obj->pos,obj->segnum,0).centermask==0);
//if (obj->control_type == CT_FLYING)

View file

@ -108,6 +108,7 @@ typedef struct segment {
sbyte matcen_num; // which center segment is associated with.
short value;
fix static_light; //average static light in segment
int degenerated; // true if this segment has gotten turned inside out, or something.
#ifndef EDITOR
short pad; //make structure longword aligned
#endif