diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 87e54f7cf..d6b7b1835 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -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 diff --git a/main/fvi.c b/main/fvi.c index 733efd393..27812388f 100644 --- a/main/fvi.c +++ b/main/fvi.c @@ -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); +} diff --git a/main/fvi.h b/main/fvi.h index 1ad3ef64c..3d3607285 100644 --- a/main/fvi.h +++ b/main/fvi.h @@ -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 diff --git a/main/physics.c b/main/physics.c index 65a090657..211121fc2 100644 --- a/main/physics.c +++ b/main/physics.c @@ -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(¢er,&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,¢er,&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 = (FrameTimetype == 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) {