void object_thrust(obj_type *obj) { float xmove,ymove,zmove,ztemp, xmax,ymax,zmax,drag; if (obj->input_mode!=im_thrust) return; // contacts cancel thrust if ((obj->contact.hit_poly.mesh_idx!=-1) || (obj->contact.obj_uid!=-1)) { obj->thrust.vct.x=0; obj->thrust.vct.y=0; obj->thrust.vct.z=0; } // run thrust if (!obj->forward_move.moving) return; if (obj->thrust.max_speed==0.0f) return; angle_get_movement_float(obj->ang.y,obj->thrust.speed,&xmove,&zmove); angle_get_movement_float(obj->view_ang.x,obj->thrust.speed,&ymove,&ztemp); obj->thrust.vct.x+=xmove; obj->thrust.vct.y+=ymove; obj->thrust.vct.z+=zmove; // drag option if (obj->thrust.drag) { drag=1.0f-(obj->thrust.speed/obj->thrust.max_speed); angle_get_movement_float(obj->ang.y,obj->thrust.max_speed,&xmax,&zmax); xmax=(float)fabs(xmax); zmax=(float)fabs(zmax); angle_get_movement_float(obj->view_ang.x,obj->thrust.max_speed,&ymax,&ztemp); ymax=(float)fabs(ymax); if ((obj->thrust.vct.x>xmax) || (obj->thrust.vct.x<-xmax)) obj->thrust.vct.x*=drag; if ((obj->thrust.vct.y>ymax) || (obj->thrust.vct.y<-ymax)) obj->thrust.vct.y*=drag; if ((obj->thrust.vct.z>zmax) || (obj->thrust.vct.z<-zmax)) obj->thrust.vct.z*=drag; return; } // regular thrust locked by max if (obj->thrust.vct.x>obj->thrust.max_speed) obj->thrust.vct.x=obj->thrust.max_speed; if (obj->thrust.vct.x<-obj->thrust.max_speed) obj->thrust.vct.x=-obj->thrust.max_speed; if (obj->thrust.vct.y>obj->thrust.max_speed) obj->thrust.vct.y=obj->thrust.max_speed; if (obj->thrust.vct.y<-obj->thrust.max_speed) obj->thrust.vct.y=-obj->thrust.max_speed; if (obj->thrust.vct.z>obj->thrust.max_speed) obj->thrust.vct.z=obj->thrust.max_speed; if (obj->thrust.vct.z<-obj->thrust.max_speed) obj->thrust.vct.z=-obj->thrust.max_speed; }
void get_motion_movement(float ang,obj_movement *move,float *xmove,float *zmove) { angle_get_movement_float(ang,move->speed,xmove,zmove); if (move->reverse) { *xmove=-(*xmove); *zmove=-(*zmove); } }
void map_prepare_mesh_poly(map_type *map,map_mesh_type *mesh,map_mesh_poly_type *poly) { int n,ptsz,y,lx,rx,lz,rz,dist; float ang; bool flat; d3pnt min,max,mid; d3pnt *pt; d3vct map_up; // find enclosing square // and middle and if polygon is flat pt=&mesh->vertexes[poly->v[0]]; min.x=max.x=mid.x=pt->x; min.y=max.y=mid.y=y=pt->y; min.z=max.z=mid.z=pt->z; flat=TRUE; ptsz=poly->ptsz; for (n=1;n<ptsz;n++) { pt=&mesh->vertexes[poly->v[n]]; // get min and max if (pt->x<min.x) min.x=pt->x; if (pt->x>max.x) max.x=pt->x; if (pt->y<min.y) min.y=pt->y; if (pt->y>max.y) max.y=pt->y; if (pt->z<min.z) min.z=pt->z; if (pt->z>max.z) max.z=pt->z; // add for middle mid.x+=pt->x; mid.y+=pt->y; mid.z+=pt->z; // check for flat y if (pt->y!=y) flat=FALSE; } memmove(&poly->box.min,&min,sizeof(d3pnt)); memmove(&poly->box.max,&max,sizeof(d3pnt)); poly->box.mid.x=mid.x/ptsz; poly->box.mid.y=mid.y/ptsz; poly->box.mid.z=mid.z/ptsz; poly->box.flat=flat; // get dot product of normal and up // vector to determine the slope of surface // and if it's wall like if (flat) { poly->slope.y=0.0f; poly->slope.ang_y=0.0f; poly->slope.move_x=0.0f; poly->slope.move_z=0.0f; poly->box.wall_like=FALSE; } else { map_up.x=0.0f; map_up.y=-1.0f; map_up.z=0.0f; ang=fabsf(vector_dot_product(&map_up,&poly->tangent_space.normal)); // use dot product to tell if wall like // and the y slope poly->box.wall_like=(ang<=0.4f); poly->slope.y=1.0f-ang; // find the slope angle map_prepare_mesh_poly_slope_ang(mesh,poly); angle_get_movement_float(poly->slope.ang_y,(map->physics.slope_max_speed*poly->slope.y),&poly->slope.move_x,&poly->slope.move_z); } // create wall "line" for wall like polygons if (poly->box.wall_like) { // get the lx,lz to rx,rz lx=poly->box.min.x; rx=poly->box.max.x; lz=poly->box.min.z; rz=poly->box.max.z; for (n=0;n!=poly->ptsz;n++) { pt=&mesh->vertexes[poly->v[n]]; if ((rx-lx)>(rz-lz)) { if (pt->x==lx) lz=pt->z; if (pt->x==rx) rz=pt->z; } else { if (pt->z==lz) lx=pt->x; if (pt->z==rz) rx=pt->x; } } poly->line.lx=lx; poly->line.rx=rx; poly->line.lz=lz; poly->line.rz=rz; // find ty,by for each point // we need to catch polygons that have higher or lower // points slightly offset from lx,lz or rx,rz, so we use // a distance calculation here (within 20% of end point) dist=distance_2D_get(lx,lz,rx,rz); dist=(dist*20)/100; poly->line.l_ty=poly->line.r_ty=poly->line.l_by=poly->line.r_by=-1; for (n=0;n!=poly->ptsz;n++) { pt=&mesh->vertexes[poly->v[n]]; if (distance_2D_get(pt->x,pt->z,lx,lz)<dist) { if ((pt->y<poly->line.l_ty) || (poly->line.l_ty==-1)) poly->line.l_ty=pt->y; if ((pt->y>poly->line.l_by) || (poly->line.l_by==-1)) poly->line.l_by=pt->y; } if (distance_2D_get(pt->x,pt->z,rx,rz)<dist) { if ((pt->y<poly->line.r_ty) || (poly->line.r_ty==-1)) poly->line.r_ty=pt->y; if ((pt->y>poly->line.r_by) || (poly->line.r_by==-1)) poly->line.r_by=pt->y; } } if (poly->line.l_ty==-1) poly->line.l_ty=poly->box.min.y; if (poly->line.r_ty==-1) poly->line.r_ty=poly->box.min.y; if (poly->line.l_by==-1) poly->line.l_by=poly->box.max.y; if (poly->line.r_by==-1) poly->line.r_by=poly->box.max.y; } // get the plane equation for ray-plane intersections map_prepare_mesh_poly_plane(mesh,poly); // determine if shadows can project on this polygon map_prepare_mesh_poly_shadow(map,mesh,poly); }
void object_motion_setup(obj_type *obj,float *xmove,float *ymove,float *zmove) { float ang,xadd,zadd; // if thrust input type, then use thrust if (obj->input_mode==im_thrust) { *xmove=obj->thrust.vct.x+obj->force.vct.x; *ymove=obj->thrust.vct.y+obj->force.vct.y; *zmove=obj->thrust.vct.z+obj->force.vct.z; return; } // forward motion ang=obj->motion.ang.y; get_motion_movement(ang,&obj->forward_move,xmove,zmove); // side motion if (obj->side_step) { get_motion_movement(angle_add(ang,270),&obj->side_move,&xadd,&zadd); *xmove=(*xmove)+xadd; *zmove=(*zmove)+zadd; } // vertical motion *ymove=0; // flying or swiming if ((obj->fly) || (obj->liquid_mode==lm_under)) { // in auto-walk? if (obj->auto_walk.mode!=aw_none) { if (obj->forward_move.moving) { angle_get_movement_float(obj->vert_move.seek_ang,obj->vert_move.max_walk_speed,&xadd,&zadd); *ymove=xadd; } } // regular seeking else { *ymove=obj->vert_move.speed; if (obj->vert_move.reverse) *ymove=-(*ymove); } } // climbing ladders else { if (obj->on_ladder) { *ymove=obj->vert_move.speed; if (obj->vert_move.reverse) *ymove=-(*ymove); } } // add in outside forces *xmove=(*xmove)+obj->force.vct.x; *ymove=(*ymove)+obj->force.vct.y; *zmove=(*zmove)+obj->force.vct.z; }