Improvement for fix_illegal_wall_interesection(): Move away from wall in right angle - not towards center. This improves the bumping in many situations and prevents ship getting stuck in small segments. Simplified and optimized code as well and removed check for degenerated Segments as not needed with this approach; Fixed some compiler warnings regarding set but unused variables

This commit is contained in:
zicodxx 2011-05-19 01:25:36 +02:00
parent 4a99054425
commit 6f4ad8eef3
4 changed files with 26 additions and 31 deletions

View file

@ -1,5 +1,9 @@
D1X-Rebirth Changelog
20110519
--------
main/fvi.c, main/fvi.h, main/physics.c: Improvement for fix_illegal_wall_interesection(): Move away from wall in right angle - not towards center. This improves the bumping in many situations and prevents ship getting stuck in small segments. Simplified and optimized code as well and removed check for degenerated Segments as not needed with this approach; Fixed some compiler warnings regarding set but unused variables
20110516
--------
main/menu.c: for debug build ignore player Highest_level_index when starting a mission, making *Load Level* entry in main menu obsolete; Fixed two compiler warnings regarding set but unused variables

View file

@ -1190,7 +1190,7 @@ int check_trans_wall(vms_vector *pnt,segment *seg,int sidenum,int facenum)
//new function for Mike
//note: n_segs_visited must be set to zero before this is called
int sphere_intersects_wall(vms_vector *pnt,int segnum,fix rad)
int sphere_intersects_wall(vms_vector *pnt,int segnum,fix rad,int *hseg,int *hside,int *hface)
{
int facemask;
segment *seg;
@ -1234,10 +1234,15 @@ int sphere_intersects_wall(vms_vector *pnt,int segnum,fix rad)
if (i==n_segs_visited) { //haven't visited here yet
if (!IS_CHILD(child))
{
if (hseg) *hseg = segnum;
if (hside) *hside = side;
if (hface) *hface = face;
return 1;
}
else {
if (sphere_intersects_wall(pnt,child,rad))
if (sphere_intersects_wall(pnt,child,rad,hseg,hside,hface))
return 1;
}
}
@ -1255,6 +1260,12 @@ int object_intersects_wall(object *objp)
{
n_segs_visited = 0;
return sphere_intersects_wall(&objp->pos,objp->segnum,objp->size);
return sphere_intersects_wall(&objp->pos,objp->segnum,objp->size,NULL,NULL,NULL);
}
int object_intersects_wall_d(object *objp,int *hseg,int *hside,int *hface)
{
n_segs_visited = 0;
return sphere_intersects_wall(&objp->pos,objp->segnum,objp->size,hseg,hside,hface);
}

View file

@ -135,6 +135,7 @@ void find_hitpoint_uv(fix *u,fix *v,vms_vector *pnt,segment *seg,int sidenum,int
//Returns true if the object is through any walls
int object_intersects_wall(object *objp);
int object_intersects_wall_d(object *objp,int *hseg,int *hside,int *hface); // same as above but more detailed
#endif

View file

@ -115,12 +115,11 @@ void do_physics_align_object( object * obj )
#endif
if (labs(vm_vec_dot(&desired_upvec,&obj->orient.fvec)) < f1_0/2) {
fixang save_delta_ang;
vms_angvec tangles;
vm_vector_2_matrix(&temp_matrix,&obj->orient.fvec,&desired_upvec,NULL);
save_delta_ang = delta_ang = vm_vec_delta_ang(&obj->orient.uvec,&temp_matrix.uvec,&obj->orient.fvec);
delta_ang = vm_vec_delta_ang(&obj->orient.uvec,&temp_matrix.uvec,&obj->orient.fvec);
delta_ang += obj->mtype.phys_info.turnroll;
@ -287,33 +286,18 @@ 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.
// On joining edges fvi tends to get inaccurate as hell. Approach is to check if the object interects with the wall and if so, move away from it.
void fix_illegal_wall_intersection(object *obj)
{
int i = 0, bocount = 1;
vms_vector center,bump_vec;
int hseg = -1, hside = -1, hface = -1;
if ( !(obj->type == OBJ_PLAYER || obj->type == OBJ_ROBOT) )
return;
if ( !object_intersects_wall(obj) )
if (obj->type == OBJ_PLAYER || obj->type == OBJ_ROBOT)
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;
if (obj->size/2 >= F0_1) // at size bigger than bumping distance use multiple runs so we can move at least half the size of the object we want to bump (rounding covered by >= in while below)
bocount = (obj->size/2/F0_1);
compute_segment_center(&center,&Segments[obj->segnum]);
while ( object_intersects_wall(obj) && bocount-- >= 0 )
if ( object_intersects_wall_d(obj,&hseg,&hside,&hface) )
{
vm_vec_normalized_dir_quick(&bump_vec,&center,&obj->pos);
vm_vec_scale_add2(&obj->pos,&bump_vec,F0_1);
vm_vec_scale_add2(&obj->pos,&Segments[hseg].sides[hside].normals[0],FrameTime*10);
update_object_seg(obj);
}
}
@ -339,7 +323,6 @@ void do_physics_sim(object *obj)
vms_vector start_pos;
int obj_stopped=0;
fix moved_time; //how long objected moved before hit something
vms_vector save_p0,save_p1;
physics_info *pi;
int orig_segnum = obj->segnum;
fix PhysTime = (FrameTime<F1_0/30?F1_0/30:FrameTime);
@ -471,10 +454,6 @@ void do_physics_sim(object *obj)
if (obj->type == OBJ_PLAYER)
fq.flags |= FQ_GET_SEGLIST;
save_p0 = *fq.p0;
save_p1 = *fq.p1;
fate = find_vector_intersection(&fq,&hit_info);
// Matt: Mike's hack.
if (fate == HIT_OBJECT) {