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:
parent
4a99054425
commit
6f4ad8eef3
|
@ -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
|
||||
|
|
17
main/fvi.c
17
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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 = (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) {
|
||||
|
|
Loading…
Reference in a new issue