bool object_watch_restrict(obj_type *obj,obj_type *watch_obj) { float ang_y,ang_dif; bool cwise; d3pnt spt,ept; ray_trace_contact_type contact; // within angle ang_y=angle_find(obj->pnt.x,obj->pnt.z,watch_obj->pnt.x,watch_obj->pnt.z); ang_dif=angle_dif(ang_y,angle_add(obj->ang.y,obj->face.ang.y),&cwise); if (ang_dif>(obj->watch.watch_restrict.ang*0.5f)) return(FALSE); // is ray tracing on? if (!obj->watch.watch_restrict.ray_trace) return(TRUE); // can ray trace from eye to middle contact.obj.on=FALSE; contact.proj.on=FALSE; contact.obj.ignore_idx=-1; contact.proj.ignore_idx=-1; contact.origin=poly_ray_trace_origin_object; spt.x=obj->pnt.x; spt.y=obj->pnt.y+obj->size.eye_offset; spt.z=obj->pnt.z; ept.x=watch_obj->pnt.x; ept.y=watch_obj->pnt.y-(watch_obj->size.y>>1); ept.z=watch_obj->pnt.z; return(!ray_trace_map_by_point(&spt,&ept,&contact)); }
void camera_chase_get_position(d3pnt *pnt,d3ang *ang) { int n,xadd,yadd,zadd,radius,div, cx,cz,cy; float fang,fx,fy,fz; d3pnt spt,ept,hpt; ray_trace_contact_type contact; matrix_type mat; obj_type *obj; weapon_type *weap; obj=object_find_uid(camera.obj_uid); // get maximum camera offset fx=0; fy=0; fz=(float)camera.chase_distance; fang=angle_add(camera.cur_chase_ang.x,-obj->view_ang.x); matrix_rotate_zyx(&mat,fang,camera.cur_chase_ang.y,camera.cur_chase_ang.z); matrix_vertex_multiply(&mat,&fx,&fy,&fz); cx=(int)fx+obj->pnt.x; cy=(int)fy+obj->pnt.y; cz=(int)fz+obj->pnt.z; // get camera movement div=camera_chase_get_division(abs(cx-obj->pnt.x),abs(cz-obj->pnt.z),abs(cy-obj->pnt.y)); if (div==0) div=1; xadd=(cx-obj->pnt.x)/div; yadd=(cy-obj->pnt.y)/div; zadd=(cz-obj->pnt.z)/div; // get camera starting position radius=camera.chase_size; fx=0; fy=0; fz=(float)(radius>>2); // always move camera back to protect against hitting walls in front of player fang=angle_add(camera.cur_chase_ang.x,(obj->view_ang.x*2)); matrix_rotate_zyx(&mat,fang,camera.cur_chase_ang.y,camera.cur_chase_ang.z); matrix_vertex_multiply(&mat,&fx,&fy,&fz); cx=(int)fx+obj->pnt.x; cz=(int)fz+obj->pnt.z; cy=(int)fy+(obj->pnt.y-obj->size.y); // setup contacts contact.obj.on=TRUE; contact.obj.ignore_uid=obj->uid; contact.proj.on=FALSE; contact.origin=poly_ray_trace_origin_unknown; // move camera for (n=0;n!=div;n++) { // xz movement spt.x=cx; spt.y=cy; spt.z=cz; ept.x=cx+xadd; ept.y=cy; ept.z=cz+zadd; contact.hit_mode=poly_ray_trace_hit_mode_wall_only; if (!ray_trace_map_by_point(&spt,&ept,&hpt,&contact)) { cx+=xadd; cz+=zadd; } // y movement spt.x=cx; spt.y=cy; spt.z=cz; ept.x=cx; ept.y=cy+yadd; ept.z=cz; contact.hit_mode=poly_ray_trace_hit_mode_floor_only; if (!ray_trace_map_by_point(&spt,&ept,&hpt,&contact)) cy+=yadd; } // new camera position camera.pnt.x=cx; camera.pnt.y=cy; camera.pnt.z=cz; // return values memmove(pnt,&camera.pnt,sizeof(d3pnt)); // looking angles ang->x=(camera.cur_chase_ang.x+camera.ang.x)-obj->view_ang.x; weap=weapon_find_current(obj); if (weap!=NULL) ang->x=object_player_look_constrain(obj,weap,ang->x); ang->y=angle_add(camera.cur_chase_ang.y,camera.ang.y); ang->z=camera.ang.z; }
void remote_draw_names_setup(void) { int n,x,y,z,dist; bool hit,has_tag; d3pnt spt,ept,hpt; obj_type *obj; model_type *mdl; ray_trace_contact_type contact; if (!net_setup.client.joined) return; if (!setup.network.show_names) return; // clear all name draws obj=server.objs; for (n=0;n!=server.count.obj;n++) { obj->draw.remote_name.on=FALSE; obj++; } // remove names behind z or off-screen // ignore console as it won't matter for projection gl_3D_view(); gl_3D_rotate(&view.render->camera.pnt,&view.render->camera.ang); gl_setup_project(); for (n=0;n!=view.render->draw_list.count;n++) { if (view.render->draw_list.items[n].type!=view_render_type_object) continue; obj=&server.objs[view.render->draw_list.items[n].idx]; if (!obj->player) continue; if (obj->hidden) continue; // get name point has_tag=FALSE; mdl=NULL; if ((obj->draw.uid!=-1) && (obj->draw.on)) mdl=model_find_uid(obj->draw.uid); if (mdl!=NULL) { x=obj->pnt.x; y=obj->pnt.y; z=obj->pnt.z; has_tag=model_get_name_position(mdl,&obj->draw.setup,&x,&y,&z); } if (!has_tag) { x=obj->pnt.x; y=(obj->pnt.y-obj->size.y)-map_enlarge; z=obj->pnt.z; } // translate and rotate point dist=distance_get(x,y,z,view.render->camera.pnt.x,view.render->camera.pnt.y,view.render->camera.pnt.z); if (dist>=remote_name_max_distance) continue; obj->draw.remote_name.pnt.x=x; obj->draw.remote_name.pnt.y=y; obj->draw.remote_name.pnt.z=z; // is it behind the z? if (!gl_project_in_view_z(x,y,z)) continue; // project names gl_project_point(&x,&y,&z); obj->draw.remote_name.proj_pnt.x=x; obj->draw.remote_name.proj_pnt.y=y; obj->draw.remote_name.proj_pnt.z=z; // calculate the fade if (dist<remote_name_min_distance) { obj->draw.remote_name.fade=1.0f; } else { obj->draw.remote_name.fade=1.0f-((float)(dist-remote_name_min_distance)/(float)(remote_name_max_distance-remote_name_min_distance)); } obj->draw.remote_name.size=hud.font.text_size_medium-(int)((float)(hud.font.text_size_medium*dist)/(float)(remote_name_max_distance-remote_name_min_distance)); if (obj->draw.remote_name.size<10) obj->draw.remote_name.size=10; obj->draw.remote_name.on=TRUE; } // ray trace remote name to camera's eye level // to check for visibility ept.x=view.render->camera.pnt.x; ept.y=view.render->camera.pnt.y; ept.z=view.render->camera.pnt.z; contact.obj.on=TRUE; contact.proj.on=FALSE; contact.hit_mode=poly_ray_trace_hit_mode_all; contact.origin=poly_ray_trace_origin_object; for (n=0;n!=server.count.obj;n++) { obj=&server.objs[n]; if (!obj->draw.remote_name.on) continue; spt.x=obj->draw.remote_name.pnt.x; spt.y=obj->draw.remote_name.pnt.y; spt.z=obj->draw.remote_name.pnt.z; contact.obj.ignore_uid=obj->uid; hit=ray_trace_map_by_point(&spt,&ept,&hpt,&contact); if (camera.mode==cv_fpp) { if (hit) { if (contact.obj.uid!=server.player_obj_uid) { obj->draw.remote_name.on=FALSE; continue; } } else { obj->draw.remote_name.on=FALSE; continue; } } else { if (hit) { obj->draw.remote_name.on=FALSE; continue; } } } }
bool halo_draw_setup_cull(iface_halo_type *halo,int obj_idx,d3pnt *pnt,int *p_pixel_sz,float *p_alpha) { int pixel_sz,dist,d; float alpha; bool hit; d3pnt ept; ray_trace_contact_type contact; // is ray greater than max distance? dist=distance_get(pnt->x,pnt->y,pnt->z,view.render->camera.pnt.x,view.render->camera.pnt.y,view.render->camera.pnt.z); if (dist>halo->max_dist) return(FALSE); // ray trace for visibily contact.proj.on=FALSE; contact.origin=poly_ray_trace_origin_halo; contact.obj.on=!halo->no_clip_object; if ((halo->no_clip_self) && (obj_idx!=-1)) { contact.obj.ignore_idx=obj_idx; } else { contact.obj.ignore_idx=-1; } ept.x=view.render->camera.pnt.x; ept.y=view.render->camera.pnt.y; ept.z=view.render->camera.pnt.z; hit=ray_trace_map_by_point(pnt,&ept,&contact); // check hit and ignore hitting the projecting // player if (hit) { if ((contact.poly.mesh_idx!=-1) || (map.camera.camera_mode!=cv_fpp)) return(FALSE); if (contact.obj.idx!=server.player_obj_idx) return(FALSE); } // get size if (dist>=halo->max_dist) { pixel_sz=halo->max_size; alpha=halo->max_alpha; } else { if (dist<=halo->min_dist) { pixel_sz=halo->min_size; alpha=halo->min_alpha; } else { dist-=halo->min_dist; d=halo->max_dist-halo->min_dist; pixel_sz=halo->max_size-halo->min_size; alpha=halo->max_alpha-halo->min_alpha; pixel_sz=((pixel_sz*dist)/d)+halo->min_size; alpha=((alpha*(float)dist)/(float)d)+halo->min_alpha; } } *p_pixel_sz=pixel_sz; *p_alpha=alpha; return(TRUE); }
void view_draw_debug_info(d3pnt *pnt,d3pnt *size,int count,char *strs) { int n,x,y,dist; d3col col; d3pnt spt,ept,win_pnt; ray_trace_contact_type contact; // only show closer objects dist=distance_get(pnt->x,pnt->y,pnt->z,view.render->camera.pnt.x,view.render->camera.pnt.y,view.render->camera.pnt.z); if (dist>25000) return; // ray trace check spt.x=pnt->x; spt.y=pnt->y-size->y; spt.z=pnt->z; ept.x=view.render->camera.pnt.x; ept.y=view.render->camera.pnt.y; ept.z=view.render->camera.pnt.z; contact.obj.on=FALSE; contact.proj.on=FALSE; contact.origin=poly_ray_trace_origin_object; if (ray_trace_map_by_point(&spt,&ept,&contact)) return; // project the mid point win_pnt.x=pnt->x; win_pnt.y=pnt->y-size->y; win_pnt.z=pnt->z; gl_project_point(&win_pnt); // draw the info gl_2D_view_interface(); glDisable(GL_DEPTH_TEST); // covert to interface resolution x=(win_pnt.x*iface.scale_x)/view.screen.x_sz; y=((view.screen.y_sz-win_pnt.y)*iface.scale_y)/view.screen.y_sz; y-=(iface.font.text_size_small*count); // draw text col.r=col.b=1.0f; col.g=0.0f; gl_text_start(font_hud_index,iface.font.text_size_small,FALSE); for (n=0;n!=count;n++) { y+=iface.font.text_size_small; gl_text_draw(x,y,(char*)&strs[n*128],tx_center,FALSE,&col,1.0f); } gl_text_end(); glEnable(GL_DEPTH_TEST); // restore original projection gl_3D_view(); gl_3D_rotate(&view.render->camera.pnt,&view.render->camera.ang); }
bool weapon_add_projectile(int tick,obj_type *obj,weapon_type *weap,proj_setup_type *proj_setup,d3pnt *pt,d3ang *ang) { d3pnt spt,ept,hpt; proj_type *proj; ray_trace_contact_type contact; // create new projectile proj=projectile_create(tick,obj,weap,proj_setup); if (proj==NULL) return(FALSE); projectile_spawn_position(proj,pt,ang,obj); // call spawn scripts_post_event_console(&proj->attach,sd_event_spawn,0,0); // if this object is the player object, then spawn projectile in remotes if (net_setup.client.joined) { if ((obj->uid==server.player_obj_uid) || (obj->bot)) { net_client_send_projectile_add(obj->remote.uid,weap->name,proj_setup->name,pt,ang); } } // add in object motion proj->force.vct.x=obj->motion.vct.x*proj_setup->inherit_motion_factor; proj->force.vct.y=obj->motion.vct.y*proj_setup->inherit_motion_factor; proj->force.vct.z=obj->motion.vct.z*proj_setup->inherit_motion_factor; // detect weapons being fired into walls // if so, destroy projectile spt.x=obj->pnt.x; spt.y=obj->pnt.y-(obj->size.y>>1); spt.z=obj->pnt.z; ept.x=proj->pnt.x; ept.y=proj->pnt.y; ept.z=proj->pnt.z; contact.obj.on=TRUE; contact.proj.on=FALSE; contact.obj.ignore_uid=obj->uid; contact.hit_mode=poly_ray_trace_hit_mode_all; contact.origin=poly_ray_trace_origin_projectile; if (ray_trace_map_by_point(&spt,&ept,&hpt,&contact)) { proj->pnt.x=hpt.x; proj->pnt.y=hpt.y; proj->pnt.z=hpt.z; proj->contact.hit_poly.mesh_idx=contact.poly.mesh_idx; proj->contact.hit_poly.poly_idx=contact.poly.poly_idx; proj->contact.obj_uid=contact.obj.uid; proj->contact.proj_uid=-1; projectile_hit(tick,proj,FALSE); } return(TRUE); }
void camera_chase_calc_position(void) { int radius; float fang,fx,fy,fz; d3pnt spt,ept; ray_trace_contact_type contact; matrix_type mat; obj_type *obj; obj=server.obj_list.objs[camera.obj_idx]; // get camera starting position radius=object_get_radius(obj); fx=0; fy=0; fz=(float)(radius>>2); // always move camera back to protect against hitting walls in front of player fang=angle_add(camera.cur_pos.chase_ang.x,(obj->view_ang.x*2)); matrix_rotate_zyx(&mat,fang,camera.cur_pos.chase_ang.y,camera.cur_pos.chase_ang.z); matrix_vertex_multiply(&mat,&fx,&fy,&fz); spt.x=((int)fx)+obj->pnt.x; spt.y=((int)fy)+(obj->pnt.y+obj->size.eye_offset); spt.z=((int)fz)+obj->pnt.z; // get camera ending position fx=0; fy=0; fz=(float)map.camera.chase.distance; fang=angle_add(camera.cur_pos.chase_ang.x,-obj->view_ang.x); matrix_rotate_zyx(&mat,fang,camera.cur_pos.chase_ang.y,camera.cur_pos.chase_ang.z); matrix_vertex_multiply(&mat,&fx,&fy,&fz); ept.x=((int)fx)+obj->pnt.x; ept.y=((int)fy)+(obj->pnt.y+obj->size.eye_offset); ept.z=((int)fz)+obj->pnt.z; // setup contacts contact.obj.on=TRUE; contact.obj.ignore_idx=obj->idx; contact.proj.on=FALSE; contact.origin=poly_ray_trace_origin_unknown; ray_trace_map_by_point(&spt,&ept,&contact); // the position camera.cur_pos.pnt.x=contact.hpt.x+map.camera.pnt_offset.x; camera.cur_pos.pnt.y=contact.hpt.y+map.camera.pnt_offset.y; camera.cur_pos.pnt.z=contact.hpt.z+map.camera.pnt_offset.z; if (obj->bump.on) camera.cur_pos.pnt.y+=obj->bump.smooth_offset; // looking angles // need to reverse X looking angle so it // behaves opposite track X angle camera.cur_pos.ang.x=(camera.cur_pos.chase_ang.x-map.camera.ang_offset.x)-obj->view_ang.x; camera.cur_pos.ang.y=angle_add(camera.cur_pos.chase_ang.y,map.camera.ang_offset.y); camera.cur_pos.ang.z=camera.cur_pos.chase_ang.z+map.camera.ang_offset.z; }