int map_find_nearest_node_by_point(map_type *map,d3pnt *pnt) { int n,idx,nnode,d,dist; node_type *node; idx=-1; dist=-1; nnode=map->nnode; node=map->nodes; for (n=0;n!=nnode;n++) { node=&map->nodes[n]; d=distance_get(pnt->x,pnt->y,pnt->z,node->pnt.x,node->pnt.y,node->pnt.z); if ((dist==-1) || (d<dist)) { dist=d; idx=n; } node++; } return(idx); }
int particle_get_effect_size(iface_particle_type *particle) { int x,y,z; x=particle->pt.x+(int)particle->vct.x; y=particle->pt.y+(int)particle->vct.y; z=particle->pt.z+(int)particle->vct.z; return(distance_get(0,0,0,x,y,z)); }
JSValueRef js_obj_position_distance_to_player_func(JSContextRef cx,JSObjectRef func,JSObjectRef j_obj,size_t argc,const JSValueRef argv[],JSValueRef *exception) { obj_type *obj,*player_obj; if (!script_check_param_count(cx,func,argc,0,exception)) return(script_null_to_value(cx)); obj=object_get_attach(j_obj); player_obj=server.obj_list.objs[server.player_obj_idx]; return(script_int_to_value(cx,distance_get(obj->pnt.x,obj->pnt.y,obj->pnt.z,player_obj->pnt.x,player_obj->pnt.y,player_obj->pnt.z))); }
JSValueRef js_obj_position_distance_to_object_func(JSContextRef cx,JSObjectRef func,JSObjectRef j_obj,size_t argc,const JSValueRef argv[],JSValueRef *exception) { obj_type *obj,*dist_obj; if (!script_check_param_count(cx,func,argc,1,exception)) return(script_null_to_value(cx)); obj=object_get_attach(j_obj); dist_obj=script_find_obj_from_uid_arg(cx,argv[0],exception); if (dist_obj==NULL) return(script_null_to_value(cx)); return(script_int_to_value(cx,distance_get(obj->pnt.x,obj->pnt.y,obj->pnt.z,dist_obj->pnt.x,dist_obj->pnt.y,dist_obj->pnt.z))); }
JSValueRef js_map_object_get_distance_func(JSContextRef cx,JSObjectRef func,JSObjectRef j_obj,size_t argc,const JSValueRef argv[],JSValueRef *exception) { d3pnt pnt; obj_type *obj; if (!script_check_param_count(cx,func,argc,2,exception)) return(script_null_to_value(cx)); obj=script_find_obj_from_uid_arg(cx,argv[0],exception); if (obj==NULL) return(script_null_to_value(cx)); script_value_to_point(cx,argv[1],&pnt); return(script_int_to_value(cx,distance_get(obj->pnt.x,obj->pnt.y,obj->pnt.z,pnt.x,pnt.y,pnt.z))); }
int map_node_to_node_distance(map_type *map,int from_idx,int to_idx) { int x,y,z,dist,idx; char node_hit[max_node]; node_type *node; if ((from_idx==-1) || (to_idx==-1)) return(-1); if (from_idx==to_idx) return(0); // detect circular references bzero(node_hit,max_node); node_hit[from_idx]=0x1; // starting position node=&map->nodes[from_idx]; x=node->pnt.x; y=node->pnt.y; z=node->pnt.z; idx=from_idx; dist=0; // run through all the distances while (TRUE) { idx=map_find_next_node_in_path(map,idx,to_idx); if (idx==-1) return(0); if (node_hit[idx]==0x1) return(0); // circular, get out node=&map->nodes[idx]; dist+=distance_get(x,y,z,node->pnt.x,node->pnt.y,node->pnt.z); x=node->pnt.x; y=node->pnt.y; z=node->pnt.z; if (idx==to_idx) break; node_hit[idx]=0x1; } return(dist); }
bool view_handle_create_rot_handle(editor_view_type *view,d3pnt *pnt,d3ang *ang,d3pnt *center_pnt,d3pnt *hand_pnt) { float len; d3vct vct; memmove(center_pnt,pnt,sizeof(d3pnt)); // create the handle points len=view_handle_length_min+(((float)distance_get(view->pnt.x,view->pnt.y,view->pnt.z,center_pnt->x,center_pnt->y,center_pnt->z)*view_handle_length_factor)); vct.x=len; vct.y=0.0f; vct.z=0.0f; view_handle_create_single_rot_handle(center_pnt,&vct,ang,&hand_pnt[0]); vct.x=0.0f; vct.y=-len; vct.z=0.0f; view_handle_create_single_rot_handle(center_pnt,&vct,ang,&hand_pnt[1]); vct.x=0.0f; vct.y=0.0f; vct.z=len; view_handle_create_single_rot_handle(center_pnt,&vct,ang,&hand_pnt[2]); // project the points // no points if z is behind the camera view_set_viewport(view,FALSE,FALSE); view_set_3D_projection(view,map.editor_setup.view_near_dist,map.editor_setup.view_far_dist,view_near_offset); if (!map_view_project_point_in_z(center_pnt)) return(FALSE); map_view_project_point(view,center_pnt); map_view_project_point(view,&hand_pnt[0]); map_view_project_point(view,&hand_pnt[1]); map_view_project_point(view,&hand_pnt[2]); return(TRUE); }
void object_watch_damage_alert(d3pnt *pnt,obj_type *damage_obj) { int n; obj_type *obj; // notify watching objects of damaged objects for (n=0;n!=max_obj_list;n++) { obj=server.obj_list.objs[n]; if (obj==NULL) continue; if ((obj->watch.on) && (obj->watch.dist!=0)) { if (distance_get(pnt->x,pnt->y,pnt->z,obj->pnt.x,obj->pnt.y,obj->pnt.z)<=obj->watch.dist) { object_watch_setup(obj,damage_obj->idx,-1,NULL,NULL); scripts_post_event_console(obj->script_idx,-1,sd_event_watch,sd_event_watch_object_damage,0); } } } }
void object_watch_sound_alert(d3pnt *pnt,int sound_obj_idx,char *sound_name) { int n; obj_type *obj; // notify watching objects of sounds for (n=0;n!=max_obj_list;n++) { obj=server.obj_list.objs[n]; if (obj==NULL) continue; if ((obj->watch.on) && (obj->watch.dist!=0)) { if (distance_get(pnt->x,pnt->y,pnt->z,obj->pnt.x,obj->pnt.y,obj->pnt.z)<=obj->watch.dist) { object_watch_setup(obj,sound_obj_idx,-1,sound_name,pnt); scripts_post_event_console(obj->script_idx,-1,sd_event_watch,sd_event_watch_object_sound,0); } } } }
void object_auto_walk_node(obj_type *obj) { int dist,chk_dist,seek_idx,dest_idx; float ang_y,dif_y; bool cwise; node_type *node; // get nodes seek_idx=obj->auto_walk.node_seek_idx; dest_idx=obj->auto_walk.node_dest_idx; // turn towards node node=&map.nodes[seek_idx]; ang_y=angle_find(obj->pnt.x,obj->pnt.z,node->pnt.x,node->pnt.z); dif_y=angle_dif(ang_y,obj->ang.y,&cwise); obj->turn.ang_to.y=ang_y; if (cwise) { obj->turn.ang_add.y=-object_get_turn_speed(obj); } else { obj->turn.ang_add.y=object_get_turn_speed(obj); } // stop walking if turn is too hard object_auto_walk_set_motion(obj); // if flying, put in a seek angle object_auto_walk_set_vertical_move(obj,node->pnt.y,node->pnt.z); // get node slop if (obj->forward_move.running) { chk_dist=(int)(obj->forward_move.max_run_speed*node_slop_speed_factor); } else { chk_dist=(int)(obj->forward_move.max_walk_speed*node_slop_speed_factor); } // near node? dist=distance_get(node->pnt.x,node->pnt.y,node->pnt.z,obj->pnt.x,obj->pnt.y,obj->pnt.z); if (dist>chk_dist) return; // move on to next node if (seek_idx!=dest_idx) { obj->auto_walk.node_last_seek_idx=obj->auto_walk.node_seek_idx; obj->auto_walk.node_seek_idx=map_find_next_node_in_path(&map,seek_idx,dest_idx); scripts_post_event_console(&obj->attach,sd_event_path,sd_event_path_node,node->event_id); return; } // at last node, send event obj->auto_walk.mode=aw_none; obj->auto_walk.node_seek_idx=-1; obj->auto_walk.node_dest_idx=-1; scripts_post_event_console(&obj->attach,sd_event_path,sd_event_path_done,obj->auto_walk.node_event_id); }
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 light_map_polys_start(char *err_str) { int n,k,sz,idx,nmesh, d,dist; int *mesh_idx_list; map_mesh_type *mesh,*chk_mesh; map_mesh_poly_type *poly; map_liquid_type *liq; light_map_poly_type *lm_poly; // build a list of meshes that // are close to each other to minimize // texture switches mesh_idx_list=(int*)malloc(map.mesh.nmesh*sizeof(int)); if (mesh_idx_list==NULL) { strcpy(err_str,"Out of Memory"); return(FALSE); } nmesh=0; for (n=0;n!=map.mesh.nmesh;n++) { mesh=&map.mesh.meshes[n]; // sort it idx=-1; dist=0; for (k=0;k!=nmesh;k++) { chk_mesh=&map.mesh.meshes[mesh_idx_list[k]]; d=distance_get(mesh->box.mid.x,mesh->box.mid.y,mesh->box.mid.z,chk_mesh->box.mid.x,chk_mesh->box.mid.y,chk_mesh->box.mid.z); if ((idx==-1) || (d<dist)) { idx=k; dist=d; } } if (idx==-1) idx=nmesh; // move it into list sz=sizeof(int)*(nmesh-idx); if (sz>0) memmove(&mesh_idx_list[idx+1],&mesh_idx_list[idx],sz); mesh_idx_list[idx]=n; nmesh++; } // get poly count light_map_poly_count=light_map_get_poly_count(); sz=sizeof(light_map_poly_type)*light_map_poly_count; light_map_polys=(light_map_poly_type*)malloc(sz); if (light_map_polys==NULL) { free(mesh_idx_list); strcpy(err_str,"Out of Memory"); return(FALSE); } // build polys lm_poly=light_map_polys; // mesh polys for (n=0;n!=nmesh;n++) { idx=mesh_idx_list[n]; mesh=&map.mesh.meshes[idx]; // clear all light map textures poly=mesh->polys; for (k=0;k!=mesh->npoly;k++) { poly->lmap_txt_idx=-1; poly++; } // no light map mesh? if (mesh->flag.no_light_map) continue; // prepare meshes map_prepare_mesh_box(mesh); // build poly 2D vertexes // and 2D size poly=mesh->polys; for (k=0;k!=mesh->npoly;k++) { lm_poly->mesh_idx=idx; lm_poly->poly_idx=k; lm_poly->liquid_idx=-1; // flatten the poly map_prepare_mesh_poly(&map,mesh,poly); light_map_create_mesh_poly_flatten(mesh,poly,lm_poly); poly++; lm_poly++; } } // liquid polys liq=map.liquid.liquids; for (n=0;n!=map.liquid.nliquid;n++) { // clear light map texture liq->lmap_txt_idx=-1; // setup poly lm_poly->mesh_idx=-1; lm_poly->poly_idx=-1; lm_poly->liquid_idx=n; // flatten the poly light_map_create_liquid_poly_flatten(liq,lm_poly); liq++; lm_poly++; } return(TRUE); }
bool model_recalc_normals_determine_vector_in_out(model_type *model,int mesh_idx,int vertex_idx) { int x,y,z,k,pos_dist,neg_dist; float f_dist; bool is_out; d3pnt *pnt,min,max,center,pos_pt,neg_pt; d3vct face_vct; model_mesh_type *mesh; model_vertex_type *vertex; // get box for vertex. This will be the combination // of vertexes with the same material map_recalc_normals_get_vertex_box(model,mesh_idx,vertex_idx,&min,&max); // get the box center mesh=&model->meshes[mesh_idx]; vertex=&mesh->vertexes[vertex_idx]; pnt=&vertex->pnt; center.x=(min.x+max.x)>>1; center.y=(min.y+max.y)>>1; center.z=(min.z+max.z)>>1; // the dot product is the fall back position // if these specialized checks fail vector_create(&face_vct,pnt->x,pnt->y,pnt->z,center.x,center.y,center.z); is_out=(vector_dot_product(&vertex->tangent_space.normal,&face_vct)>0.0f); // get a point from the current normal vector // and inverse of the current normal vector, using 10% // of the distance to center f_dist=(float)distance_get(pnt->x,pnt->y,pnt->z,center.x,center.y,center.z); f_dist*=0.1f; pos_pt.x=pnt->x+(int)(vertex->tangent_space.normal.x*f_dist); pos_pt.y=pnt->y+(int)(vertex->tangent_space.normal.y*f_dist); pos_pt.z=pnt->z+(int)(vertex->tangent_space.normal.z*f_dist); neg_pt.x=pnt->x-(int)(vertex->tangent_space.normal.x*f_dist); neg_pt.y=pnt->y-(int)(vertex->tangent_space.normal.y*f_dist); neg_pt.z=pnt->z-(int)(vertex->tangent_space.normal.z*f_dist); // first we determine if we can think of the // poly's box (which is determined by all connected // polys) as a closed object in one direction // if one direction is at least 25% greater than the others // then consider it a tube like structure // if any distance calcs fail, fall back to dot product x=max.x-min.x; y=max.y-min.y; z=max.z-min.z; k=x-((x*25)/100); if ((x>y) && (x>z)) { pos_dist=distance_2D_get(pos_pt.y,pos_pt.z,center.y,center.z); neg_dist=distance_2D_get(neg_pt.y,neg_pt.z,center.y,center.z); if (pos_dist==neg_dist) return(is_out); return(pos_dist>neg_dist); } k=y-((y*25)/100); if ((y>x) && (y>z)) { pos_dist=distance_2D_get(pos_pt.x,pos_pt.z,center.x,center.z); neg_dist=distance_2D_get(neg_pt.x,neg_pt.z,center.x,center.z); if (pos_dist==neg_dist) return(is_out); return(pos_dist>neg_dist); } k=z-((z*25)/100); if ((z>x) && (z>y)) { pos_dist=distance_2D_get(pos_pt.x,pos_pt.y,center.x,center.y); neg_dist=distance_2D_get(neg_pt.x,neg_pt.y,center.x,center.y); if (pos_dist==neg_dist) return(is_out); return(pos_dist>neg_dist); } // finally fall back to dot product return(is_out); }
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); }
void camera_static_run(void) { int dist,seek_idx,dest_idx; float sx,sy,sz,tot; node_type *node; obj_type *player_obj; // auto-walk on? if (!camera.auto_walk.on) return; // get nodes seek_idx=camera.auto_walk.node_seek_idx; dest_idx=camera.auto_walk.node_dest_idx; node=&map.nodes[seek_idx]; // move towards node // get percentage of each different and use that // to adjust the speed sx=(float)abs(node->pnt.x-camera_static_pnt.x); sy=(float)abs(node->pnt.y-camera_static_pnt.y); sz=(float)abs(node->pnt.z-camera_static_pnt.z); tot=sx+sy+sz; sx=sx/tot; sy=sy/tot; sz=sz/tot; sx*=camera.auto_walk.speed; if (node->pnt.x<camera_static_pnt.x) sx=-sx; sy*=camera.auto_walk.speed; if (node->pnt.y<camera_static_pnt.y) sy=-sy; sz*=camera.auto_walk.speed; if (node->pnt.z<camera_static_pnt.z) sz=-sz; camera_static_pnt.x+=(int)sx; camera_static_pnt.y+=(int)sy; camera_static_pnt.z+=(int)sz; // distance to seek node dist=distance_get(node->pnt.x,node->pnt.y,node->pnt.z,camera_static_pnt.x,camera_static_pnt.y,camera_static_pnt.z); // get the look angle if not following if (!camera.static_follow) { camera_static_walk_ang.x=angle_turn_toward(camera_static_walk_ang.x,node->ang.x,camera.auto_walk.turn_speed); camera_static_walk_ang.y=angle_turn_toward(camera_static_walk_ang.y,node->ang.y,camera.auto_walk.turn_speed); camera_static_walk_ang.z=angle_turn_toward(camera_static_walk_ang.z,node->ang.z,camera.auto_walk.turn_speed); } // near current seek node? if (dist>(int)(camera.auto_walk.speed*node_slop_speed_factor)) return; // move on to next node if (seek_idx!=dest_idx) { camera.auto_walk.node_seek_idx=map_find_next_node_in_path(&map,seek_idx,dest_idx); scripts_post_event_console(&js.course_attach,sd_event_path,sd_event_path_node,node->event_id); return; } // at last node camera.auto_walk.on=FALSE; memmove(&camera_static_walk_ang,&node->ang,sizeof(d3ang)); // player freeze if (camera.auto_walk.in_freeze) { player_obj=object_find_uid(server.player_obj_uid); object_input_freeze(player_obj,FALSE); } // send event scripts_post_event_console(&js.course_attach,sd_event_path,sd_event_path_done,camera.auto_walk.event_id); }
int al_distance_to_listener(d3pnt *pnt) { return(distance_get(pnt->x,pnt->y,pnt->z,audio_listener_pnt.x,audio_listener_pnt.y,audio_listener_pnt.z)); }