diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 80b3ad8fa..2b550c0d9 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,9 @@ D1X-Rebirth Changelog +20110314 +-------- +main/fvi.c, main/physics.c: Again reworked new bump hack to only apply when fate == HIT_WALL (to not break level SKYBOX) and made bumping by distance between object position and wall hit point; Removed/handled some safety checks in find_plane_line_intersection() to make sliding along joining edges smoother again while bad values *should* be handled in pyhsics.c and not make object warp-crashing tru the whole level or stuck in walls (fvi code should still be rewritten tho) + 20110310 -------- main/kconfig.c: Due to lazy copy&paste sliding up/down speed was divided by 2 - fixed diff --git a/main/fvi.c b/main/fvi.c index 4e19012c6..39474633d 100644 --- a/main/fvi.c +++ b/main/fvi.c @@ -35,31 +35,6 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED. #define face_type_num(nfaces,face_num,tri_edge) ((nfaces==1)?0:(tri_edge*2 + face_num)) -// keep the original ASM code here in case we need it again one day... -// static inline int oflow_check(fix a,fix b) { -// register int __ret; -// int dummy; -// __asm__ ( -// " cdq;" -// " xorl %%edx,%%eax;" -// " subl %%edx,%%eax;" -// " xchgl %%ebx,%%eax;" -// " cdq;" -// " xorl %%edx,%%eax;" -// " subl %%edx,%%eax;" -// " imull %%ebx;" -// " sarl $15,%%edx;" -// " orw %%dx,%%dx;" -// " setnz %%al;" -// " movzbl %%al,%%eax" -// : "=a" (__ret), "=b" (dummy) : "a" (a), "1" (b) : "%edx"); -// return __ret; -// } - -static int oflow_check(fix a,fix b) { - return 0; /* hoping the floating point fix-math is used */ -} - //find the point on the specified plane where the line intersects //returns true if point found, false if line parallel to plane //new_pnt is the found point on the plane @@ -76,42 +51,22 @@ int find_plane_line_intersection(vms_vector *new_pnt,vms_vector *plane_pnt,vms_v num = vm_vec_dot(plane_norm,&w); den = -vm_vec_dot(plane_norm,&d); -//Why does this assert hit so often -// Assert(num > -rad); + num -= rad; //move point out by rad - num -= rad; //move point out by rad - - //check for various bad values - - if ( (den==0) || //moving parallel to wall, so can't hit it - ((den>0) && - ( (num>den) || //frac greater than one - ((-num>>15)>=den))) || //will overflow (large negative) - (den<0 && num= labs(den)) {Int3(); return 0;} - k = fixdiv(num,den); - - Assert(k<=f1_0); //should be trapped above - -// Assert(k>=0); - if (oflow_check(d.x,k) || oflow_check(d.y,k) || oflow_check(d.z,k)) return 0; - //Note: it is ok for k to be greater than 1, since this might mean - //that an object with a non-zero radius that moved from p0 to p1 - //actually hit the wall on the "other side" of p0. - } + //check for various bad values + if (den > 0 && (-num>>15) >= den) //will overflow (large negative) + num = (f1_0-f0_5)*den; + // FIXME: need to handle those or catch somewhere else? +// if (den > 0 && num > den) //frac greater than one +// return 0; +// if (den < 0 && num < den) //frac greater than one +// return 0; vm_vec_scale2(&d,num,den); - vm_vec_add(new_pnt,p0,&d); - //we should have vm_vec_scale2_add2() - return 1; } @@ -356,17 +311,11 @@ int check_line_to_line(fix *t1,fix *t2,vms_vector *p1,vms_vector *v1,vms_vector det.uvec = *v2; d = calc_det_value(&det); - if (oflow_check(d,cross_mag2)) - return 0; - else - *t1 = fixdiv(d,cross_mag2); + *t1 = fixdiv(d,cross_mag2); det.uvec = *v1; d = calc_det_value(&det); - if (oflow_check(d,cross_mag2)) - return 0; - else - *t2 = fixdiv(d,cross_mag2); + *t2 = fixdiv(d,cross_mag2); return 1; //found point } diff --git a/main/physics.c b/main/physics.c index f8c87c1a3..70a52bb0b 100644 --- a/main/physics.c +++ b/main/physics.c @@ -297,7 +297,7 @@ void do_physics_sim(object *obj) int fate=0; vms_vector frame_vec; //movement in this frame vms_vector new_pos,ipos; //position after this frame - int count=0,bumpcount=0; + int count=0; int objnum; int WallHitSeg, WallHitSide; fvi_info hit_info; @@ -495,21 +495,6 @@ void do_physics_sim(object *obj) if ( iseg != obj->segnum ) obj_relink(objnum, iseg ); - /* - * 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. Two things to improve: - * 1) object_intersects_wall() does not say how far we went inside the wall which is why we use while to move out until we do not intersect anymore. This should be improved so we only move one time. - * 2) we move the object towards segment center. Depending on the level architecture this is safe. However this will heavily influence velocity and reduce sliding speed near joining edges. Also depending on velocity it's still possible we might not pass an endge leading into another segment since we are pulled back to the old one. - */ - if (obj->type == OBJ_PLAYER || obj->type == OBJ_ROBOT) - while (object_intersects_wall(obj) && bumpcount++ < 64) - { - vms_vector center,bump_vec; - //bump player a little towards center of segment to unstick - compute_segment_center(¢er,&Segments[iseg]); - vm_vec_normalized_dir_quick(&bump_vec,¢er,&obj->pos); - vm_vec_scale_add2(&obj->pos,&bump_vec,F0_1); - } - //if start point not in segment, move object to center of segment if (get_seg_masks(&obj->pos,obj->segnum,0,__FILE__,__LINE__).centermask!=0) { int n; @@ -619,6 +604,18 @@ void do_physics_sim(object *obj) try_again = 1; } } + + /* + * 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(¢er,&Segments[obj->segnum]); + vm_vec_normalized_dir_quick(&bump_vec,¢er,&obj->pos); + vm_vec_scale_add2(&obj->pos,&bump_vec,vm_vec_dist(&hit_info.hit_pnt, &obj->pos)); + } + break; }