예제 #1
0
void MobileVRInterface::set_position_from_sensors() {
	_THREAD_SAFE_METHOD_

	// this is a helper function that attempts to adjust our transform using our 9dof sensors
	// 9dof is a misleading marketing term coming from 3 accelerometer axis + 3 gyro axis + 3 magnetometer axis = 9 axis
	// but in reality this only offers 3 dof (yaw, pitch, roll) orientation

	uint64_t ticks = OS::get_singleton()->get_ticks_usec();
	uint64_t ticks_elapsed = ticks - last_ticks;
	float delta_time = (double)ticks_elapsed / 1000000.0;

	// few things we need
	Input *input = Input::get_singleton();
	Vector3 down(0.0, -1.0, 0.0); // Down is Y negative
	Vector3 north(0.0, 0.0, 1.0); // North is Z positive

	// make copies of our inputs
	bool has_grav = false;
	Vector3 acc = input->get_accelerometer();
	Vector3 gyro = input->get_gyroscope();
	Vector3 grav = input->get_gravity();
	Vector3 magneto = scale_magneto(input->get_magnetometer()); // this may be overkill on iOS because we're already getting a calibrated magnetometer reading

	if (sensor_first) {
		sensor_first = false;
	} else {
		acc = scrub(acc, last_accerometer_data, 2, 0.2);
		magneto = scrub(magneto, last_magnetometer_data, 3, 0.3);
	};

	last_accerometer_data = acc;
	last_magnetometer_data = magneto;

	if (grav.length() < 0.1) {
		// not ideal but use our accelerometer, this will contain shakey shakey user behaviour
		// maybe look into some math but I'm guessing that if this isn't available, its because we lack the gyro sensor to actually work out
		// what a stable gravity vector is
		grav = acc;
		if (grav.length() > 0.1) {
			has_grav = true;
		};
	} else {
		has_grav = true;
	};

	bool has_magneto = magneto.length() > 0.1;
	if (gyro.length() > 0.1) {
		/* this can return to 0.0 if the user doesn't move the phone, so once on, it's on */
		has_gyro = true;
	};

	if (has_gyro) {
		// start with applying our gyro (do NOT smooth our gyro!)
		Basis rotate;
		rotate.rotate(orientation.get_axis(0), gyro.x * delta_time);
		rotate.rotate(orientation.get_axis(1), gyro.y * delta_time);
		rotate.rotate(orientation.get_axis(2), gyro.z * delta_time);
		orientation = rotate * orientation;

		tracking_state = ARVRInterface::ARVR_NORMAL_TRACKING;
	};

	///@TODO improve this, the magnetometer is very fidgity sometimes flipping the axis for no apparent reason (probably a bug on my part)
	// if you have a gyro + accelerometer that combo tends to be better then combining all three but without a gyro you need the magnetometer..
	if (has_magneto && has_grav && !has_gyro) {
		// convert to quaternions, easier to smooth those out
		Quat transform_quat(orientation);
		Quat acc_mag_quat(combine_acc_mag(grav, magneto));
		transform_quat = transform_quat.slerp(acc_mag_quat, 0.1);
		orientation = Basis(transform_quat);

		tracking_state = ARVRInterface::ARVR_NORMAL_TRACKING;
	} else if (has_grav) {
		// use gravity vector to make sure down is down...
		// transform gravity into our world space
		grav.normalize();
		Vector3 grav_adj = orientation.xform(grav);
		float dot = grav_adj.dot(down);
		if ((dot > -1.0) && (dot < 1.0)) {
			// axis around which we have this rotation
			Vector3 axis = grav_adj.cross(down);
			axis.normalize();

			Basis drift_compensation(axis, acos(dot) * delta_time * 10);
			orientation = drift_compensation * orientation;
		};
	};

	// JIC
	orientation.orthonormalize();

	last_ticks = ticks;
};
예제 #2
0
void  GridMapEditor::_menu_option(int p_option) {


	switch(p_option) {

		case MENU_OPTION_CONFIGURE: {


		} break;
		case MENU_OPTION_LOCK_VIEW: {

			int index=options->get_popup()->get_item_index(MENU_OPTION_LOCK_VIEW);
			lock_view=!options->get_popup()->is_item_checked(index);

			options->get_popup()->set_item_checked(index,lock_view);
		} break;
		case MENU_OPTION_CLIP_DISABLED:
		case MENU_OPTION_CLIP_ABOVE:
		case MENU_OPTION_CLIP_BELOW: {

			clip_mode=ClipMode(p_option-MENU_OPTION_CLIP_DISABLED);
			for(int i=0;i<3;i++) {

				int index=options->get_popup()->get_item_index(MENU_OPTION_CLIP_DISABLED+i);
				options->get_popup()->set_item_checked(index,i==clip_mode);

			}

			_update_clip();
		} break;
		case MENU_OPTION_X_AXIS:
		case MENU_OPTION_Y_AXIS:
		case MENU_OPTION_Z_AXIS: {

			int new_axis = p_option-MENU_OPTION_X_AXIS;
			for(int i=0;i<3;i++) {
				int idx=options->get_popup()->get_item_index(MENU_OPTION_X_AXIS+i);
				options->get_popup()->set_item_checked(idx,i==new_axis);
			}
			edit_axis=Vector3::Axis(new_axis);
			update_grid();
			_update_clip();

		} break;
		case MENU_OPTION_CURSOR_ROTATE_Y: {
			Basis r;
			if (input_action==INPUT_DUPLICATE) {

				r.set_orthogonal_index(selection.duplicate_rot);
				r.rotate(Vector3(0,1,0),-Math_PI/2.0);
				selection.duplicate_rot=r.get_orthogonal_index();
				_update_duplicate_indicator();
				break;
			}
			r.set_orthogonal_index(cursor_rot);
			r.rotate(Vector3(0,1,0),-Math_PI/2.0);
			cursor_rot=r.get_orthogonal_index();
			_update_cursor_transform();
		} break;
		case MENU_OPTION_CURSOR_ROTATE_X: {
			Basis r;
			if (input_action==INPUT_DUPLICATE) {

				r.set_orthogonal_index(selection.duplicate_rot);
				r.rotate(Vector3(1,0,0),-Math_PI/2.0);
				selection.duplicate_rot=r.get_orthogonal_index();
				_update_duplicate_indicator();
				break;
			}

			r.set_orthogonal_index(cursor_rot);
			r.rotate(Vector3(1,0,0),-Math_PI/2.0);
			cursor_rot=r.get_orthogonal_index();
			_update_cursor_transform();
		} break;
		case MENU_OPTION_CURSOR_ROTATE_Z: {
			Basis r;
			if (input_action==INPUT_DUPLICATE) {

				r.set_orthogonal_index(selection.duplicate_rot);
				r.rotate(Vector3(0,0,1),-Math_PI/2.0);
				selection.duplicate_rot=r.get_orthogonal_index();
				_update_duplicate_indicator();
				break;
			}

			r.set_orthogonal_index(cursor_rot);
			r.rotate(Vector3(0,0,1),-Math_PI/2.0);
			cursor_rot=r.get_orthogonal_index();
			_update_cursor_transform();
		} break;
		case MENU_OPTION_CURSOR_BACK_ROTATE_Y: {
			Basis r;
			r.set_orthogonal_index(cursor_rot);
			r.rotate(Vector3(0,1,0),Math_PI/2.0);
			cursor_rot=r.get_orthogonal_index();
			_update_cursor_transform();
		} break;
		case MENU_OPTION_CURSOR_BACK_ROTATE_X: {
			Basis r;
			r.set_orthogonal_index(cursor_rot);
			r.rotate(Vector3(1,0,0),Math_PI/2.0);
			cursor_rot=r.get_orthogonal_index();
			_update_cursor_transform();
		} break;
		case MENU_OPTION_CURSOR_BACK_ROTATE_Z: {
			Basis r;
			r.set_orthogonal_index(cursor_rot);
			r.rotate(Vector3(0,0,1),Math_PI/2.0);
			cursor_rot=r.get_orthogonal_index();
			_update_cursor_transform();
		} break;
		case MENU_OPTION_CURSOR_CLEAR_ROTATION: {

			if (input_action==INPUT_DUPLICATE) {


				selection.duplicate_rot=0;
				_update_duplicate_indicator();
				break;
			}

			cursor_rot=0;
			_update_cursor_transform();
		} break;


		case MENU_OPTION_DUPLICATE_SELECTS: {
			int idx = options->get_popup()->get_item_index(MENU_OPTION_DUPLICATE_SELECTS);
			options->get_popup()->set_item_checked( idx, !options->get_popup()->is_item_checked( idx ) );
		} break;
		case MENU_OPTION_SELECTION_MAKE_AREA:
		case MENU_OPTION_SELECTION_MAKE_EXTERIOR_CONNECTOR: {

			if (!selection.active)
				break;
			int area = node->get_unused_area_id();
			Error err = node->create_area(area,Rect3(selection.begin,selection.end-selection.begin+Vector3(1,1,1)));
			if (err!=OK) {


			}
			if (p_option==MENU_OPTION_SELECTION_MAKE_EXTERIOR_CONNECTOR) {

				node->area_set_exterior_portal(area,true);
			}
			_update_areas_display();
			update_areas();


		} break;
		case MENU_OPTION_REMOVE_AREA: {
			if (selected_area<1)
				return;
			node->erase_area(selected_area);
			_update_areas_display();
			update_areas();
		} break;
		case MENU_OPTION_SELECTION_DUPLICATE:
			if (!(selection.active && input_action==INPUT_NONE))
				return;
			if (last_mouseover==Vector3(-1,-1,-1)) //nono mouseovering anythin
				break;

			input_action=INPUT_DUPLICATE;
			selection.click=last_mouseover;
			selection.current=last_mouseover;
			selection.duplicate_rot=0;
			_update_duplicate_indicator();
			break;
		case MENU_OPTION_SELECTION_CLEAR: {
			if (!selection.active)
				return;

			_delete_selection();


		} break;
		case MENU_OPTION_GRIDMAP_SETTINGS: {
			settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size() + Size2(50, 50));
		} break;

	}
}