void get_turret_cam_orient(camera *cam, matrix *ori) { object_h obj(cam->get_object_host()); if(!obj.IsValid()) return; vm_vector_2_matrix(ori, &normal_cache, vm_vec_same(&normal_cache, &cam->get_object_host()->orient.vec.uvec)?NULL:&cam->get_object_host()->orient.vec.uvec, NULL); }
void prevent_spawning_collision(object *new_obj) { int collided; ship_obj *moveup; object *hit_check; ship *s_check; do { collided = 0; for (moveup = GET_FIRST(&Ship_obj_list); moveup != END_OF_LIST(&Ship_obj_list); moveup = GET_NEXT(moveup)) { // don't check the new object itself!! if (moveup->objnum == OBJ_INDEX(new_obj)) continue; hit_check = &Objects[moveup->objnum]; Assert(hit_check->type == OBJ_SHIP); Assert(hit_check->instance >= 0); if ((hit_check->type != OBJ_SHIP) || (hit_check->instance < 0)) continue; s_check = &Ships[hit_check->instance]; // just to make sure we don't get any strange magnitude errors if (vm_vec_same(&hit_check->pos, &new_obj->pos)) new_obj->pos.xyz.x += 1.0f; polymodel *pm = model_get(Ship_info[s_check->ship_info_index].model_num); WITHIN_BBOX(); if (collided) { MOVE_AWAY_BBOX(); break; } } } while (collided); }
void camera::get_info(vec3d *position, matrix *orientation) { if(position == NULL && orientation == NULL) return; eye* eyep = NULL; vec3d host_normal; //POSITION if(!(flags & CAM_STATIONARY_POS) || object_host.IsValid()) { c_pos = vmd_zero_vector; vec3d pt; pos_x.get(&pt.xyz.x, NULL); pos_y.get(&pt.xyz.y, NULL); pos_z.get(&pt.xyz.z, NULL); if(object_host.IsValid()) { object *objp = object_host.objp; int model_num = object_get_model(objp); polymodel *pm = NULL; if(model_num > -1) { pm = model_get(model_num); } if(object_host_submodel < 0 || pm == NULL) { vm_vec_unrotate(&c_pos, &pt, &object_host.objp->orient); vm_vec_add2(&c_pos, &object_host.objp->pos); } else { eyep = get_submodel_eye(pm, object_host_submodel); if(eyep) { vec3d c_pos_in; find_submodel_instance_point_normal( &c_pos_in, &host_normal, objp, eyep->parent, &eyep->pnt, &eyep->norm); vm_vec_unrotate(&c_pos, &c_pos_in, &objp->orient); vm_vec_add2(&c_pos, &objp->pos); } else { model_find_world_point( &c_pos, &pt, pm->id, object_host_submodel, &objp->orient, &objp->pos ); } } } else { c_pos = pt; } //Do custom position stuff, if needed if(func_custom_position != NULL && !eyep) { func_custom_position(this, &c_pos); } } if(position != NULL) *position = c_pos; //ORIENTATION if(orientation != NULL) { bool target_set = false; if(!(flags & CAM_STATIONARY_ORI) || object_target.IsValid() || object_host.IsValid()) { if(object_target.IsValid()) { object *objp = object_target.objp; int model_num = object_get_model(objp); polymodel *pm = NULL; vec3d target_pos = vmd_zero_vector; //See if we can get the model if(model_num > -1) { pm = model_get(model_num); } //If we don't have a submodel or don't have the model use object pos //Otherwise, find the submodel pos as it is rotated if(object_target_submodel < 0 || pm == NULL) { target_pos = objp->pos; } else { model_find_world_point( &target_pos, &vmd_zero_vector, pm->id, object_target_submodel, &objp->orient, &objp->pos ); } vec3d targetvec; vm_vec_normalized_dir(&targetvec, &target_pos, &c_pos); vm_vector_2_matrix(&c_ori, &targetvec, NULL, NULL); target_set = true; } else if(object_host.IsValid()) { if(eyep) { vm_vector_2_matrix(&c_ori, &host_normal, vm_vec_same(&host_normal, &object_host.objp->orient.vec.uvec)?NULL:&object_host.objp->orient.vec.uvec, NULL); target_set = true; } else { c_ori = object_host.objp->orient; } } else { c_ori = vmd_identity_matrix; } matrix mtxA = c_ori; matrix mtxB = IDENTITY_MATRIX; float pos = 0.0f; for(int i = 0; i < 9; i++) { ori[i].get(&pos, NULL); mtxB.a1d[i] = pos; } vm_matrix_x_matrix(&c_ori, &mtxA, &mtxB); vm_orthogonalize_matrix(&c_ori); } //Do custom orientation stuff, if needed if(func_custom_orientation != NULL && !target_set) { func_custom_orientation(this, &c_ori); } *orientation = c_ori; } }
void multi_respawn_place(object *new_obj, int team) { ship_obj *moveup; ship *s_check; ship *pri = NULL; object *pri_obj = NULL; object *hit_check; int collided, idx, lookup; // first determine if there are any appropriate priority ships to use pri = NULL; pri_obj = NULL; for(idx=0; idx<Multi_respawn_priority_count; idx++){ // all relevant ships if((Multi_respawn_priority_ships[idx].team == team) || !(Netgame.type_flags & NG_TYPE_TEAM)){ lookup = ship_name_lookup(Multi_respawn_priority_ships[idx].ship_name); if( (lookup >= 0) && ((pri == NULL) || (Ships[lookup].respawn_priority > pri->respawn_priority)) && (Ships[lookup].objnum >= 0) && (Ships[lookup].objnum < MAX_OBJECTS)){ pri = &Ships[lookup]; pri_obj = &Objects[Ships[lookup].objnum]; } } } // if we have a relevant respawn ship if((pri != NULL) && (pri_obj != NULL)){ // pick a point just outside his bounding box polymodel *pm = model_get(pri->modelnum); // hmm, ugly. Pick a point 2000 meters to the y direction if(pm == NULL){ vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.rvec, 2000.0f); } else { // pick a random direction int d = (int)frand_range(0.0f, 5.9f); switch(d){ case 0: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.rvec, (pm->maxs.xyz.x - pm->mins.xyz.x)); break; case 1: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.rvec, -(pm->maxs.xyz.x - pm->mins.xyz.x)); break; case 2: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.uvec, (pm->maxs.xyz.y - pm->mins.xyz.y)); break; case 3: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.uvec, -(pm->maxs.xyz.y - pm->mins.xyz.y)); break; case 4: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.fvec, (pm->maxs.xyz.z - pm->mins.xyz.z)); break; case 5: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.fvec, -(pm->maxs.xyz.z - pm->mins.xyz.z)); break; default: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.uvec, -(pm->maxs.xyz.y - pm->mins.xyz.y)); break; } } } // otherwise, resort to plain respawn points else { Assert(Multi_respawn_point_count > 0); // get the next appropriate respawn point by team lookup = 0; int count = 0; while(!lookup && (count < 13)){ if((team == TEAM_TRAITOR) || (team == Multi_respawn_points[Multi_next_respawn_point].team)){ lookup = 1; } // next item if(!lookup){ if(Multi_next_respawn_point >= (Multi_respawn_point_count-1)){ Multi_next_respawn_point = 0; } else { Multi_next_respawn_point++; } } count++; } // set respawn info new_obj->pos = Multi_respawn_points[Multi_next_respawn_point].pos; } // now make sure we're not colliding with anyone do { collided = 0; moveup = GET_FIRST(&Ship_obj_list); while(moveup!=END_OF_LIST(&Ship_obj_list)){ // don't check the new_obj itself!! if(Objects[moveup->objnum].net_signature != new_obj->net_signature){ hit_check = &Objects[moveup->objnum]; Assert(hit_check->type == OBJ_SHIP); Assert(hit_check->instance >= 0); if((hit_check->type != OBJ_SHIP) || (hit_check->instance < 0)){ continue; } s_check = &Ships[hit_check->instance]; // just to make sure we don't get any strange magnitude errors if(vm_vec_same(&hit_check->pos, &new_obj->pos)){ new_obj->pos.xyz.x += 1.0f; } WITHIN_BBOX(); if(collided){ MOVE_AWAY_BBOX(); break; } collided = 0; } moveup = GET_NEXT(moveup); } } while(collided); }