void camera_static_get_position(d3pnt *pnt,d3ang *ang) { obj_type *obj; // get position memmove(pnt,&camera_static_pnt,sizeof(d3pnt)); if (ang==NULL) return; // if following an object, point camera at object if (camera.static_follow) { obj=object_find_uid(camera.obj_uid); ang->y=angle_find(camera_static_pnt.x,camera_static_pnt.z,obj->pnt.x,obj->pnt.z); ang->x=-(180.0f-angle_find(camera_static_pnt.y,camera_static_pnt.z,obj->pnt.y,obj->pnt.z)); ang->z=camera.ang.z; return; } // if in walk and not following // then point way specified in node if (camera.auto_walk.on) { ang->x=angle_add(camera_static_walk_ang.x,camera.ang.x); ang->y=angle_add(camera_static_walk_ang.y,camera.ang.y); ang->z=angle_add(camera_static_walk_ang.z,camera.ang.z); return; } // else just use camera offset memmove(ang,&camera.ang,sizeof(d3ang)); }
bool view_draw_node(int tick,node_type *node,int pixel_size) { d3pnt pnt; d3ang ang; // switch out to node render glViewport(0,0,pixel_size,pixel_size); view.render=&view_node_render; // camera position memmove(&view.render->camera.pnt,&node->pnt,sizeof(d3pnt)); if (!node->follow_camera) { memmove(&view.render->camera.ang,&node->ang,sizeof(d3ang)); } else { camera_get_position(&pnt,&ang); view.render->camera.ang.x=angle_find(node->pnt.y,node->pnt.z,pnt.y,pnt.z); view.render->camera.ang.y=angle_find(node->pnt.x,node->pnt.z,pnt.x,pnt.z); view.render->camera.ang.z=angle_find(node->pnt.x,node->pnt.y,pnt.x,pnt.y); } view.render->camera.fov=camera.plane.fov; view.render->camera.flip=TRUE; view.render->camera.under_liquid_idx=-1; view.render->no_shadow=TRUE; view.render->force_camera_obj=TRUE; // draw the scene glClearColor(0.0f,0.0f,0.0f,1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // build the scene view_draw_scene_build(tick); // render the scene view_draw_scene_render(tick,NULL,NULL); // restore the normal rendering glViewport(render_info.view_x,render_info.view_y,setup.screen.x_sz,setup.screen.y_sz); view.render=&view_camera_render; return(TRUE); }
void object_auto_walk_object(obj_type *obj) { float ang_y; bool cwise; obj_type *seek_obj; // get object seek_obj=object_find_uid(obj->auto_walk.obj_uid); if (seek_obj==NULL) { obj->auto_walk.mode=aw_none; return; } // turn towards object on y ang_y=angle_find(obj->pnt.x,obj->pnt.z,seek_obj->pnt.x,seek_obj->pnt.z); 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); } // if flying, put in a seek angle object_auto_walk_set_vertical_move(obj,(seek_obj->pnt.y-(seek_obj->size.y>>1)),seek_obj->pnt.z); }
void object_setup_touch(obj_type *obj,obj_type *source_obj,bool stand) { obj_touch *touch; touch=&obj->touch; touch->obj_uid=source_obj->uid; touch->pnt.x=(obj->pnt.x+source_obj->pnt.x)>>1; touch->pnt.y=(obj->pnt.y+source_obj->pnt.y)>>1; touch->pnt.z=(obj->pnt.z+source_obj->pnt.z)>>1; touch->ang.x=angle_find(source_obj->pnt.y,source_obj->pnt.z,obj->pnt.y,obj->pnt.z); touch->ang.y=angle_find(source_obj->pnt.x,source_obj->pnt.z,obj->pnt.x,obj->pnt.z); touch->ang.z=angle_find(source_obj->pnt.x,source_obj->pnt.y,obj->pnt.x,obj->pnt.y); touch->stand=stand; }
void camera_get_angle_from(d3pnt *pt,d3ang *ang) { int dist; d3pnt pnt; d3ang temp_ang; // get camera position camera_get_position(&pnt,&temp_ang); // find angle dist=distance_2D_get(0,0,(pnt.x-pt->x),(pnt.z-pt->z)); ang->x=-angle_find(0,0,(pnt.y-pt->y),dist); ang->y=angle_find(pt->x,pt->z,pnt.x,pnt.z); ang->z=0.0f; }
void object_watch_setup(obj_type *obj,int watch_obj_idx,int base_team,char *sound_name,d3pnt *pnt) { obj_type *watch_obj; // object ID, team, // and sound obj->watch.obj_idx=watch_obj_idx; obj->watch.base_team=base_team; if (sound_name==NULL) { obj->watch.sound_name[0]=0x0; } else { strcpy(obj->watch.sound_name,sound_name); } // position and angle if (pnt!=NULL) { obj->watch.pnt.x=pnt->x; obj->watch.pnt.y=pnt->y; obj->watch.pnt.z=pnt->z; } else { obj->watch.pnt.x=0; obj->watch.pnt.y=0; obj->watch.pnt.z=0; if (watch_obj_idx!=-1) { watch_obj=server.obj_list.objs[watch_obj_idx]; if (watch_obj!=NULL) { obj->watch.pnt.x=watch_obj->pnt.x; obj->watch.pnt.y=watch_obj->pnt.y; obj->watch.pnt.z=watch_obj->pnt.z; } } } obj->watch.ang.x=angle_find(obj->pnt.y,obj->pnt.z,obj->watch.pnt.y,obj->watch.pnt.z); obj->watch.ang.y=angle_find(obj->pnt.x,obj->pnt.z,obj->watch.pnt.x,obj->watch.pnt.z); obj->watch.ang.z=angle_find(obj->pnt.x,obj->pnt.y,obj->watch.pnt.x,obj->watch.pnt.y); }
JSValueRef js_map_object_get_angle_to_func(JSContextRef cx,JSObjectRef func,JSObjectRef j_obj,size_t argc,const JSValueRef argv[],JSValueRef *exception) { d3pnt pnt; d3ang ang; 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); // get angles to ang.x=angle_find(pnt.y,pnt.z,obj->pnt.y,obj->pnt.z); ang.y=angle_find(pnt.x,pnt.z,obj->pnt.x,obj->pnt.z); ang.z=angle_find(pnt.x,pnt.y,obj->pnt.x,obj->pnt.y); return(script_angle_to_value(cx,&ang)); }
void object_auto_walk_set_vertical_move(obj_type *obj,int to_y,int to_z) { int y; obj->vert_move.seeking=FALSE; if (!obj->fly) return; // under slop? y=obj->pnt.y-(obj->size.y>>1); if (abs(to_y-y)<obj->vert_move.slop) return; // get seek angle obj->vert_move.seeking=TRUE; obj->vert_move.seek_ang=angle_find(y,obj->pnt.z,to_y,to_z); }
void object_auto_walk_position(obj_type *obj) { float ang_y; bool cwise; // turn towards position on y ang_y=angle_find(obj->pnt.x,obj->pnt.z,obj->auto_walk.pnt.x,obj->auto_walk.pnt.z); 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); } // if flying, put in a seek angle object_auto_walk_set_vertical_move(obj,obj->auto_walk.pnt.y,obj->auto_walk.pnt.z); }
JSValueRef js_map_object_is_facing_id_func(JSContextRef cx,JSObjectRef func,JSObjectRef j_obj,size_t argc,const JSValueRef argv[],JSValueRef *exception) { float ang_y,ang_dif; bool cwise; obj_type *obj,*obj2; if (!script_check_param_count(cx,func,argc,3,exception)) return(script_null_to_value(cx)); // uids obj=script_find_obj_from_uid_arg(cx,argv[0],exception); if (obj==NULL) return(script_null_to_value(cx)); obj2=script_find_obj_from_uid_arg(cx,argv[1],exception); if (obj2==NULL) return(script_null_to_value(cx)); // get angles to ang_y=angle_find(obj->pnt.x,obj->pnt.z,obj2->pnt.x,obj2->pnt.z); ang_dif=angle_dif(ang_y,angle_add(obj->ang.y,obj->face.ang.y),&cwise); return(script_bool_to_value(cx,ang_dif<script_value_to_float(cx,argv[2]))); }
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 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 map_prepare_mesh_poly_slope_ang(map_mesh_type *mesh,map_mesh_poly_type *poly) { int n,tx,bx,tz,bz,t_add,b_add; float dist,fx,fz; d3pnt *pt; // separate polygon vertexes by Ys tx=bx=tz=bz=0; t_add=b_add=0; for (n=0;n!=poly->ptsz;n++) { pt=&mesh->vertexes[poly->v[n]]; if (pt->y<poly->box.mid.y) { tx+=pt->x; tz+=pt->z; t_add++; } else { bx+=pt->x; bz+=pt->z; b_add++; } } // find points between Y extremes if (t_add!=0) { tx/=t_add; tz/=t_add; } else { tx=poly->box.mid.x; tz=poly->box.mid.z; } if (b_add!=0) { bx/=b_add; bz/=b_add; } else { bx=poly->box.mid.x; bz=poly->box.mid.z; } // xz distance fx=(float)(bx-tx); fz=(float)(bz-tz); dist=sqrtf((fx*fx)+(fz*fz)); if (dist==0.0f) { poly->slope.ang_y=0.0f; return; } // find the angle between points poly->slope.ang_y=angle_find(bx,bz,tx,tz); }
bool object_move_xz_slide_line(obj_type *obj,int *xadd,int *yadd,int *zadd,int lx,int rx,int lz,int rz) { int n,xadd2,yadd2,zadd2,mx,mz; float f,ang,rang; bool hit,cwise; d3vct line_vct,obj_vct; // special check for horizontal/vertical walls if (lx==rx) { xadd2=0; yadd2=0; zadd2=*zadd; if (collide_object_to_map(obj,&xadd2,&yadd2,&zadd2)) return(FALSE); obj->pnt.z+=zadd2; xadd2=*xadd; yadd2=0; zadd2=0; if (collide_object_to_map(obj,&xadd2,&yadd2,&zadd2)) return(FALSE); obj->pnt.x+=xadd2; return(FALSE); } if (lz==rz) { xadd2=*xadd; yadd2=0; zadd2=0; if (collide_object_to_map(obj,&xadd2,&yadd2,&zadd2)) return(FALSE); obj->pnt.x+=xadd2; xadd2=0; yadd2=0; zadd2=*zadd; if (collide_object_to_map(obj,&xadd2,&yadd2,&zadd2)) return(FALSE); obj->pnt.z+=zadd2; return(FALSE); } // get angle between the line and the object movement obj_vct.x=(float)*xadd; obj_vct.y=0.0f; obj_vct.z=(float)*zadd; vector_normalize(&obj_vct); vector_create(&line_vct,lx,0,lz,rx,0,rz); // perpendicular vector (swap x/z) // get the angle between them f=vector_dot_product(&obj_vct,&line_vct); f=((float)acos(f))*RAD_to_ANG; // get angle of wall. If the angle between the // collision lines is less than 90, then head down // the line the opposite way ang=angle_find(lx,lz,rx,rz); if (f<90.0f) ang=angle_add(ang,180.0f); // change the motion to reflect the angle of the wall // uses facing instead of motion to check so we // don't get motion build up from sliding against a wall rang=obj->ang.y; if (obj->forward_move.reverse) rang=angle_add(rang,180.0f); if (angle_dif(rang,ang,&cwise)<90.0f) { if (!obj->forward_move.reverse) { obj->motion.ang.y=ang; } else { obj->motion.ang.y=angle_add(ang,180.0f); } } // reduce movement to slide against the walls mz=*zadd/ws_step_factor; mx=*xadd/ws_step_factor; for (n=0;n!=ws_step_factor;n++) { // try z then x movement first xadd2=0; yadd2=0; zadd2=mz; hit=collide_object_to_map(obj,&xadd2,&yadd2,&zadd2); if (!hit) { obj->pnt.z+=zadd2; xadd2=mx; yadd2=0; zadd2=0; if (!collide_object_to_map(obj,&xadd2,&yadd2,&zadd2)) { obj->pnt.x+=xadd2; } continue; } // try x then z movement next xadd2=mx; yadd2=0; zadd2=0; hit=collide_object_to_map(obj,&xadd2,&yadd2,&zadd2); if (!hit) { obj->pnt.x+=xadd2; xadd2=0; yadd2=0; zadd2=mz; if (!collide_object_to_map(obj,&xadd2,&yadd2,&zadd2)) { obj->pnt.z+=zadd2; } } } return(FALSE); }
bool weapon_get_projectile_position_angle_weapon_barrel(int tick,obj_type *obj,weapon_type *weap,d3pnt *fire_pnt,d3ang *fire_ang,char *err_str) { int pose_idx,bone_idx,dist; d3pnt barrel_pnt; model_type *mdl; model_draw *draw; model_draw_setup *setup; // get weapon model mdl=model_find_uid(weap->draw.uid); if (mdl==NULL) { if (err_str!=NULL) strcpy(err_str,"Weapon has no model"); return(FALSE); } // get current pose pose_idx=model_find_pose(mdl,weap->proj.fire_pose_name); if (pose_idx==-1) { if (err_str!=NULL) strcpy(err_str,"Weapon has missing or no fire pose"); return(FALSE); } // get 'fire' bone offset and calc bone_idx=model_find_bone(mdl,weap->proj.fire_bone_tag); if (bone_idx==-1) { if (err_str!=NULL) strcpy(err_str,"Weapon has missing or no fire bone"); return(FALSE); } model_draw_setup_weapon(tick,obj,weap,TRUE,weap->dual.in_dual); if (weap->dual.in_dual) { draw=&weap->draw_dual; } else { draw=&weap->draw; } setup=&draw->setup; setup->move.x=setup->move.y=setup->move.z=0; setup->sway.x=setup->sway.y=setup->sway.z=0.0f; model_calc_draw_bone_position(mdl,setup,pose_idx,bone_idx,&fire_pnt->x,&fire_pnt->y,&fire_pnt->z); if (draw->flip_x) fire_pnt->x=-fire_pnt->x; fire_pnt->x+=draw->pnt.x; fire_pnt->y+=draw->pnt.y; fire_pnt->z+=draw->pnt.z; if (draw->no_rot.on) gl_project_fix_rotation(&fire_pnt->x,&fire_pnt->y,&fire_pnt->z); // get 'barrel' bone offset (draw bones already calced above) bone_idx=model_find_bone(mdl,weap->proj.barrel_bone_tag); if (bone_idx==-1) { if (err_str!=NULL) strcpy(err_str,"Weapon has missing or no barrel bone"); return(FALSE); } model_get_draw_bone_position(setup,bone_idx,&barrel_pnt.x,&barrel_pnt.y,&barrel_pnt.z); if (draw->flip_x) barrel_pnt.x=-barrel_pnt.x; barrel_pnt.x+=draw->pnt.x; barrel_pnt.y+=draw->pnt.y; barrel_pnt.z+=draw->pnt.z; if (draw->no_rot.on) gl_project_fix_rotation(&barrel_pnt.x,&barrel_pnt.y,&barrel_pnt.z); // angles between them dist=distance_2D_get(0,0,(fire_pnt->x-barrel_pnt.x),(fire_pnt->z-barrel_pnt.z)); fire_ang->x=-(180.0f-angle_find(0,0,(fire_pnt->y-barrel_pnt.y),dist)); fire_ang->y=angle_find(barrel_pnt.x,barrel_pnt.z,fire_pnt->x,fire_pnt->z); fire_ang->z=0.0f; return(TRUE); }