示例#1
0
void rotate_vector3f(float *vector, float x, float y, float z)
{
    // rotation matrixes
    float rot_x[9];
    float rot_y[9];
    float rot_z[9];
    float result_x[3];
    float result_y[3];
    MAT3_ROT_X(rot_x, x * (M_PI / 180.0f));
    MAT3_ROT_Y(rot_y, y * (M_PI / 180.0f));
    MAT3_ROT_Z(rot_z, z * (M_PI / 180.0f));
    // rotate around x achsis
    MAT3_VECT3_MULT(result_x, rot_x, vector);
    // rotate around y achsis
    MAT3_VECT3_MULT(result_y, rot_y, result_x);
    // rotate around z achsis
    MAT3_VECT3_MULT(vector, rot_z, result_y);
}
示例#2
0
void update_camera()
{
	const float c_delta = 0.1f;

	static int last_update = 0;
	int time_diff = cur_time - last_update;

	static float old_camera_x = 0;
	static float old_camera_y = 0;
	static float old_camera_z = 0;
	float adjust;
	actor *me = get_our_actor();

	old_rx=rx;
	old_rz=rz;
	new_zoom_level=old_zoom_level=zoom_level;
	
	//printf("kludge: %f, hold: %f, rx: %f, rz %f, zoom: %f\n",camera_kludge, hold_camera,rx,rz,zoom_level);
	
	if (fol_cam && !fol_cam_behind)
		rz = hold_camera;
	if (me)
		camera_kludge = -me->z_rot;

	/* This is a BIG hack to not polluate the code but if this feature
	 * is accepted and the flag is removed, all the code that
	 * follows will have to be changed in order to get rid of
	 * camera_rotation_duration and camera_tilt_duration. */
	camera_rotation_duration = camera_rotation_speed != 0.0 ? time_diff : 0.0;
	camera_tilt_duration = camera_tilt_speed != 0.0 ? time_diff : 0.0;

	if(camera_rotation_duration > 0){
		if (time_diff <= camera_rotation_duration)
			rz+=camera_rotation_speed*time_diff;
		else
			rz+=camera_rotation_speed*camera_rotation_duration;
		camera_rotation_duration-=time_diff;
		adjust_view++;
	}
	if(camera_x_duration > 0){
		if(camera_x_speed>1E-4 || camera_x_speed<-1E-4){
			if (time_diff <= camera_x_duration)
				camera_x-=camera_x_speed*time_diff;
			else
				camera_x-=camera_x_speed*camera_x_duration;
			if(fabs(camera_x-old_camera_x) >= c_delta){
				adjust_view++;
			}
		}
		camera_x_duration-=time_diff;
	}
	if(camera_y_duration > 0){
		if(camera_y_speed>1E-4 || camera_y_speed<-1E-4){
			if (time_diff <= camera_y_duration)
				camera_y-=camera_y_speed*time_diff;
			else
				camera_y-=camera_y_speed*camera_y_duration;
			if(fabs(camera_y-old_camera_y) >= c_delta){
				adjust_view++;
			}
		}
		camera_y_duration-=time_diff;
	}
	if(camera_z_duration > 0){
		if(camera_z_speed>1E-4 || camera_z_speed<-1E-4){
			if (time_diff <= camera_z_duration)
				camera_z-=camera_z_speed*time_diff;
			else
				camera_z-=camera_z_speed*camera_z_duration;
			if(fabs(camera_z-old_camera_z) >= c_delta){
				adjust_view++;
			}
		}
		camera_z_duration-=time_diff;
	}

	if(camera_tilt_duration > 0) {
		if (time_diff <= camera_tilt_duration)
			rx+=camera_tilt_speed*time_diff;
		else
			rx+=camera_tilt_speed*camera_tilt_duration;
		camera_tilt_duration-=time_diff;
		adjust_view++;
	}
	if(camera_zoom_duration > 0) {
		if (time_diff <= camera_zoom_duration)
			new_zoom_level += camera_zoom_speed*(camera_zoom_dir==1?0.003f:-0.003f)*time_diff;
		else
			new_zoom_level += camera_zoom_speed*(camera_zoom_dir==1?0.003f:-0.003f)*camera_zoom_duration;
		camera_zoom_duration-=time_diff;
		adjust_view++;
	}
	else
		camera_zoom_speed = 1;


	if (camera_rotation_speed > 0.0)
	{
		camera_rotation_speed -= time_diff * camera_rotation_deceleration;
		if (camera_rotation_speed < 0.0)
			camera_rotation_speed = 0.0;
	}
	else if (camera_rotation_speed < 0.0)
	{
		camera_rotation_speed += time_diff * camera_rotation_deceleration;
		if (camera_rotation_speed > 0.0)
			camera_rotation_speed = 0.0;
	}
	if (camera_tilt_speed > 0.0)
	{
		camera_tilt_speed -= time_diff * camera_tilt_deceleration;
		if (camera_tilt_speed < 0.0)
			camera_tilt_speed = 0.0;
	}
	else if (camera_tilt_speed < 0.0)
	{
		camera_tilt_speed += time_diff * camera_tilt_deceleration;
		if (camera_tilt_speed > 0.0)
			camera_tilt_speed = 0.0;
	}

	clamp_camera();

	if (ext_cam && !first_person && me &&
		rx <= -min_tilt_angle && rx >= -max_tilt_angle)
	{
		float rot_x[9], rot_z[9], rot[9], dir[3];
		float vect[3] = {0.0, 0.0, new_zoom_level*camera_distance};
		int tx, ty;
		float tz;

		// we compute the camera position
		MAT3_ROT_X(rot_x, -rx*M_PI/180.0);
		MAT3_ROT_Z(rot_z, -rz*M_PI/180.0);
		MAT3_MULT(rot, rot_z, rot_x);
		MAT3_VECT3_MULT(dir, rot, vect);

		// we take the tile where the camera is
		tx = (int)((dir[0] - camera_x)*2);
		ty = (int)((dir[1] - camera_y)*2);

		if (get_tile_walkable(tx, ty))
		{
			tz = get_tile_height(tx, ty);
		}
		else
		{
			// if the tile is outside the map, we take the height at the actor position
			tz = get_tile_height(me->x_tile_pos, me->y_tile_pos);
		}
		// here we use a shift of 0.2 to avoid to be too close to the ground
		if (tz + 0.2 > dir[2] - camera_z)
		{
			if (ext_cam_auto_zoom) // new behaviour
			{
				// if the camera is under the ground, we change the zoom level
				if (fabsf(dir[2]) > 1E-4)
					new_zoom_level *= (tz + camera_z + 0.2) / dir[2];
				else
					new_zoom_level = 0.0;

				if (new_zoom_level < 1.0)
				{
					new_zoom_level = 1.0;
					camera_tilt_duration = camera_zoom_duration = 0;
					camera_tilt_speed = 0.0;
					if (fabsf(tz + camera_z + 0.2f) < fabsf(vect[2]) - 0.01)
						rx = -90.0 + 180.0 * asinf((tz + camera_z + 0.2) / vect[2]) / M_PI;
				}
				else if (new_zoom_level > old_zoom_level)
				{
					new_zoom_level = old_zoom_level;
					camera_tilt_duration = camera_zoom_duration = 0;
					camera_tilt_speed = 0.0;
				}
			}
			else // old freecam behaviour
			{
				new_zoom_level = old_zoom_level;
				camera_tilt_duration = camera_zoom_duration = 0;
				camera_tilt_speed = 0.0;
				if (fabsf(tz + camera_z + 0.2f) < fabsf(vect[2]) - 0.01)
					rx = -90.0 + 180.0 * asinf((tz + camera_z + 0.2) / vect[2]) / M_PI;
			}
		}
	}

	if(adjust_view){
		set_all_intersect_update_needed(main_bbox_tree);
		old_camera_x= camera_x;
		old_camera_y= camera_y;
		old_camera_z= camera_z;
	}

	
	hold_camera = rz;
	if (fol_cam) {
		static int fol_cam_stop = 0;

		if ((SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(2)) || camera_rotation_speed != 0)
			fol_cam_stop = 1;
		else if (me && me->moving && fol_cam_stop)
			fol_cam_stop = 0;

		if (last_kludge != camera_kludge && !fol_cam_stop) {
			set_all_intersect_update_needed(main_bbox_tree);
			adjust = (camera_kludge-last_kludge);

			//without this the camera will zip the wrong way when camera_kludge
			//flips from 180 <-> -180
			if      (adjust >=  180) adjust -= 360.0;
			else if (adjust <= -180) adjust += 360.0;

			if (fabs(adjust) < fol_strn) {
				last_kludge=camera_kludge;
			}
			else {
				last_kludge += fol_strn*(
					adjust*(fol_quad*fol_strn + fol_lin)+
					fol_con*(adjust>0?1:-1))/
					(fol_quad+fol_lin+fol_con+.000001f);//cheap no/0
			}
		}
		if (fol_cam_behind)
        {
            if (!fol_cam_stop)
                rz = -last_kludge;
            else
                last_kludge = -rz;
        }
		else
			rz -= last_kludge;
	}

	//Make Character Turn with Camera
	if (have_mouse && !on_the_move (get_our_actor ()))
	{
		adjust = rz;
		//without this the character will turn the wrong way when camera_kludge
		//and character are in certain positions
		if      (adjust >=  180) adjust -= 360.0;
		else if (adjust <= -180) adjust += 360.0;
		adjust+=camera_kludge;
		if      (adjust >=  180) adjust -= 360.0;
		else if (adjust <= -180) adjust += 360.0;
		if (adjust > 35){
			Uint8 str[2];
			str[0] = TURN_LEFT;
			my_tcp_send (my_socket, str, 1);
		} else if (adjust < -35){
			Uint8 str[2];
			str[0] = TURN_RIGHT;
			my_tcp_send (my_socket, str, 1);
		}
	}
	adjust_view = 0;
	last_update = cur_time;
}