Esempio n. 1
0
static Bool OnSphereSensor(GF_SensorHandler *sh, Bool is_over, Bool is_cancel, GF_Event *ev, GF_Compositor *compositor)
{
	Bool is_mouse = (ev->type<=GF_EVENT_MOUSEWHEEL) ? 1 : 0;
	M_SphereSensor *sphere = (M_SphereSensor *)sh->sensor;
	SphereSensorStack *st = (SphereSensorStack *) gf_node_get_private(sh->sensor);


	if (sphere->isActive && (!sphere->enabled
	                         || /*mouse*/((ev->type==GF_EVENT_MOUSEUP) && (ev->mouse.button==GF_MOUSE_LEFT))
	                         || /*keyboar*/(!is_mouse && (!is_over|| ((ev->type==GF_EVENT_KEYDOWN) && (ev->key.key_code==GF_KEY_ENTER))))
	                        ) ) {
		if (sphere->autoOffset) {
			sphere->offset = sphere->rotation_changed;
			if (!is_cancel) gf_node_event_out(sh->sensor, 2/*"offset"*/);
		}
		sphere->isActive = 0;
		if (!is_cancel) gf_node_event_out(sh->sensor, 3/*"isActive"*/);
		sh->grabbed = 0;
		return is_cancel ? 0 : 1;
	}
	else if (is_mouse) {
		if (!sphere->isActive && (ev->type==GF_EVENT_MOUSEDOWN) && (ev->mouse.button==GF_MOUSE_LEFT)) {
			st->center.x = st->center.y = st->center.z = 0;
			gf_mx_apply_vec(&compositor->hit_local_to_world, &st->center);
			st->radius = gf_vec_len(compositor->hit_local_point);
			if (!st->radius) st->radius = FIX_ONE;
			st->grab_vec = gf_vec_scale(compositor->hit_local_point, gf_invfix(st->radius));

			sphere->isActive = 1;
			gf_node_event_out(sh->sensor, 3/*"isActive"*/);
			sh->grabbed = 1;
			return 1;
		}
		else if (sphere->isActive) {
			SFVec3f vec, axis;
			SFVec4f q1, q2;
			SFRotation r;
			Fixed cl;
			if (is_over) {
				sphere->trackPoint_changed = compositor->hit_local_point;
				gf_node_event_out(sh->sensor, 5/*"trackPoint_changed"*/);
			} else {
				GF_Ray r;
				r = compositor->hit_world_ray;
				gf_mx_apply_ray(&compositor->hit_world_to_local, &r);
				if (!gf_ray_hit_sphere(&r, NULL, st->radius, &compositor->hit_local_point)) {
					vec.x = vec.y = vec.z = 0;
					/*doesn't work properly...*/
					compositor->hit_local_point = gf_closest_point_to_line(r.orig, r.dir, vec);
				}
			}

			vec = gf_vec_scale(compositor->hit_local_point, gf_invfix(st->radius));
			axis = gf_vec_cross(st->grab_vec, vec);
			cl = gf_vec_len(axis);

			if (cl < -FIX_ONE) cl = -FIX_ONE;
			else if (cl > FIX_ONE) cl = FIX_ONE;
			r.q = gf_asin(cl);
			if (gf_vec_dot(st->grab_vec, vec) < 0) r.q += GF_PI / 2;

			gf_vec_norm(&axis);
			r.x = axis.x;
			r.y = axis.y;
			r.z = axis.z;
			q1 = gf_quat_from_rotation(r);
			if (sphere->autoOffset) {
				q2 = gf_quat_from_rotation(sphere->offset);
				q1 = gf_quat_multiply(&q1, &q2);
			}
			sphere->rotation_changed = gf_quat_to_rotation(&q1);
			gf_node_event_out(sh->sensor, 4/*"rotation_changed"*/);
			return 1;
		}
	} else {
		if (!sphere->isActive && is_over && (ev->type==GF_EVENT_KEYDOWN) && (ev->key.key_code==GF_KEY_ENTER)) {
			sphere->isActive = 1;
			sphere->rotation_changed = sphere->offset;
			gf_node_event_out(sh->sensor, 3/*"isActive"*/);
			return 1;
		}
		else if (sphere->isActive && (ev->type==GF_EVENT_KEYDOWN)) {
			SFVec4f res, rot;
			Fixed diff = GF_PI/64;

			res = sphere->rotation_changed;
			switch (ev->key.key_code) {
			case GF_KEY_LEFT:
				diff = -diff;
			case GF_KEY_RIGHT:
				rot.x = 0;
				rot.y = FIX_ONE;
				rot.z = 0;
				rot.q = diff;
				res = gf_quat_from_rotation(res);
				rot = gf_quat_from_rotation(rot);
				rot = gf_quat_multiply(&rot, &res);
				res = gf_quat_to_rotation(&rot);
				break;
			case GF_KEY_DOWN:
				diff = -diff;
			case GF_KEY_UP:
				if (ev->key.flags & GF_KEY_MOD_SHIFT) {
					rot.x = 0;
					rot.z = FIX_ONE;
				} else {
					rot.x = FIX_ONE;
					rot.z = 0;
				}
				rot.y = 0;
				rot.q = diff;
				res = gf_quat_from_rotation(res);
				rot = gf_quat_from_rotation(rot);
				rot = gf_quat_multiply(&rot, &res);
				res = gf_quat_to_rotation(&rot);
				break;
			case GF_KEY_HOME:
				res = sphere->offset;
				break;
			default:
				return 0;
			}
			sphere->rotation_changed = res;
			gf_node_event_out(sh->sensor, 4/*"rotation_changed"*/);
			return 1;
		}
	}
	return 0;
}
Esempio n. 2
0
static Bool compositor_handle_navigation_2d(GF_VisualManager *visual, GF_Event *ev)
{
	Fixed x, y, dx, dy, key_trans, key_rot, zoom, new_zoom;
	u32 navigation_mode;
	s32 key_inv;
	Bool is_pixel_metrics = visual->compositor->traverse_state->pixel_metrics;
	u32 keys = visual->compositor->key_states;

	zoom = visual->compositor->zoom;
	navigation_mode = visual->compositor->navigate_mode;
#ifndef GPAC_DISABLE_3D
	if (visual->type_3d) navigation_mode = visual->camera.navigate_mode;
#endif

	if (navigation_mode==GF_NAVIGATE_NONE) return 0;
	if (!navigation_mode && !(keys & GF_KEY_MOD_ALT) ) return 0;


	x = y = 0;
	/*renorm between -1, 1*/
	if (ev->type<=GF_EVENT_MOUSEWHEEL) {
		x = INT2FIX(ev->mouse.x);
		y = INT2FIX(ev->mouse.y);
	}
	dx = x - visual->compositor->grab_x;
	if (visual->center_coords) {
		dy = visual->compositor->grab_y - y;
	} else {
		dy = y - visual->compositor->grab_y;
	}
	if (!is_pixel_metrics) {
		dx /= visual->width;
		dy /= visual->height;
	}

	key_inv = 1;
	key_trans = INT2FIX(2);
	key_rot = GF_PI/100;

	if (keys & GF_KEY_MOD_SHIFT) {
		dx *= 4;
		dy *= 4;
		key_rot *= 4;
		key_trans*=4;
	}

	if (!is_pixel_metrics) {
		key_trans /= visual->width;
	}

	switch (ev->type) {
	case GF_EVENT_MOUSEDOWN:
		/*left*/
		if (ev->mouse.button==GF_MOUSE_LEFT) {
			visual->compositor->grab_x = x;
			visual->compositor->grab_y = y;
			visual->compositor->navigation_state = 1;
			/*update zoom center*/
			if (keys & GF_KEY_MOD_CTRL) {
				visual->compositor->trans_x -= visual->compositor->grab_x - INT2FIX(visual->width)/2;
				visual->compositor->trans_y += INT2FIX(visual->height)/2 - visual->compositor->grab_y;
				nav_set_zoom_trans_2d(visual, visual->compositor->zoom, 0, 0);
			}
			return 0;
		}
		break;

	case GF_EVENT_MOUSEUP:
		if (ev->mouse.button==GF_MOUSE_LEFT) {
			visual->compositor->navigation_state = 0;
			return 0;
		}
		break;

	case GF_EVENT_MOUSEWHEEL:
		switch (navigation_mode) {
		case GF_NAVIGATE_SLIDE:
			new_zoom = zoom + INT2FIX(ev->mouse.wheel_pos)/10;
			nav_set_zoom_trans_2d(visual, new_zoom, 0, 0);
			return 1;
		case GF_NAVIGATE_EXAMINE:
			if (ev->mouse.wheel_pos>0)
				visual->compositor->rotation += gf_asin( GF_PI / 10);
			else
				visual->compositor->rotation -= gf_asin( GF_PI / 10);
			nav_set_zoom_trans_2d(visual, zoom, 0, 0);
			return 1;
		}
		return 0;

	case GF_EVENT_MOUSEMOVE:
		if (!visual->compositor->navigation_state) return 0;
		visual->compositor->navigation_state++;
		switch (navigation_mode) {
		case GF_NAVIGATE_SLIDE:
			if (keys & GF_KEY_MOD_CTRL) {
				if (dy) {
					new_zoom = zoom;
					if (new_zoom > FIX_ONE) new_zoom += dy/20;
					else new_zoom += dy/80;
					nav_set_zoom_trans_2d(visual, new_zoom, 0, 0);
				}
			} else {
				nav_set_zoom_trans_2d(visual, zoom, dx, dy);
			}
			break;
		case GF_NAVIGATE_EXAMINE:
		{
			Fixed sin = gf_mulfix(GF_PI, dy) / visual->height;
			//truncate in [-1;1] for arcsin()
			if (sin < -FIX_ONE)
				sin = -FIX_ONE;
			if (sin >  FIX_ONE)
				sin =  FIX_ONE;
			visual->compositor->rotation += gf_asin(sin);
			nav_set_zoom_trans_2d(visual, zoom, 0, 0);
		}
		break;
		}
		visual->compositor->grab_x = x;
		visual->compositor->grab_y = y;
		return 1;
	case GF_EVENT_KEYDOWN:
		switch (ev->key.key_code) {
		case GF_KEY_BACKSPACE:
			gf_sc_reset_graphics(visual->compositor);
			return 1;
		case GF_KEY_HOME:
			if (!visual->compositor->navigation_state) {
				visual->compositor->trans_x = visual->compositor->trans_y = 0;
				visual->compositor->rotation = 0;
				visual->compositor->zoom = FIX_ONE;
				nav_set_zoom_trans_2d(visual, FIX_ONE, 0, 0);
			}
			return 1;
		case GF_KEY_LEFT:
			key_inv = -1;
		case GF_KEY_RIGHT:
			if (navigation_mode == GF_NAVIGATE_SLIDE) {
				nav_set_zoom_trans_2d(visual, zoom, key_inv*key_trans, 0);
			}
			else {
				visual->compositor->rotation -= key_inv * key_rot;
				nav_set_zoom_trans_2d(visual, zoom, 0, 0);
			}
			return 1;
		case GF_KEY_DOWN:
			key_inv = -1;
		case GF_KEY_UP:
			if (navigation_mode == GF_NAVIGATE_SLIDE) {
				if (keys & GF_KEY_MOD_CTRL) {
					Fixed new_zoom = zoom;
					if (new_zoom > FIX_ONE) new_zoom += key_inv*FIX_ONE/10;
					else new_zoom += key_inv*FIX_ONE/20;
					nav_set_zoom_trans_2d(visual, new_zoom, 0, 0);
				} else {
					nav_set_zoom_trans_2d(visual, zoom, 0, key_inv*key_trans);
				}
			}
			else {
				visual->compositor->rotation += key_inv*key_rot;
				nav_set_zoom_trans_2d(visual, zoom, 0, 0);
			}
			return 1;
		}
		break;
	}
	return 0;
}
Esempio n. 3
0
static void OnSphereSensor(SensorHandler *sh, Bool is_over, GF_Event *ev, RayHitInfo *hit_info)
{
	M_SphereSensor *sphere = (M_SphereSensor *)sh->owner;
	SphereSensorStack *st = (SphereSensorStack *) gf_node_get_private(sh->owner);

	if (sphere->isActive && (!sphere->enabled || ((ev->type==GF_EVENT_MOUSEUP) && (ev->mouse.button==GF_MOUSE_LEFT)) ) ) {
		if (sphere->autoOffset) {
			sphere->offset = sphere->rotation_changed;
			gf_node_event_out_str(sh->owner, "offset");
		}
		sphere->isActive = 0;
		gf_node_event_out_str(sh->owner, "isActive");
		R3D_SetGrabbed(st->compositor, 0);
	}
	else if (!sphere->isActive && (ev->type==GF_EVENT_MOUSEDOWN) && (ev->mouse.button==GF_MOUSE_LEFT)) {
		st->center.x = st->center.y = st->center.z = 0;
		gf_mx_apply_vec(&hit_info->local_to_world, &st->center);
		st->radius = gf_vec_len(hit_info->local_point);
		if (!st->radius) st->radius = FIX_ONE;
		st->grab_vec = gf_vec_scale(hit_info->local_point, gf_invfix(st->radius));

		sphere->isActive = 1;
		gf_node_event_out_str(sh->owner, "isActive");
		R3D_SetGrabbed(st->compositor, 1);
	}
	else if (sphere->isActive) {
		SFVec3f vec, axis;
		SFVec4f q1, q2;
		SFRotation r;
		Fixed cl;
		if (is_over) {
			sphere->trackPoint_changed = hit_info->local_point;
			gf_node_event_out_str(sh->owner, "trackPoint_changed");
		} else {
			GF_Ray r;
			r = hit_info->world_ray;
			gf_mx_apply_ray(&hit_info->world_to_local, &r);
			if (!gf_ray_hit_sphere(&r, NULL, st->radius, &hit_info->local_point)) {
				vec.x = vec.y = vec.z = 0;
				/*doesn't work properly...*/
				hit_info->local_point = gf_closest_point_to_line(r.orig, r.dir, vec);
			}
		}

		vec = gf_vec_scale(hit_info->local_point, gf_invfix(st->radius));
		axis = gf_vec_cross(st->grab_vec, vec);
		cl = gf_vec_len(axis);

		if (cl < -FIX_ONE) cl = -FIX_ONE;
		else if (cl > FIX_ONE) cl = FIX_ONE;
		r.q = gf_asin(cl);
		if (gf_vec_dot(st->grab_vec, vec) < 0) r.q += GF_PI / 2;

		gf_vec_norm(&axis);
		r.x = axis.x; r.y = axis.y; r.z = axis.z;
		q1 = gf_quat_from_rotation(r);
		if (sphere->autoOffset) {
			q2 = gf_quat_from_rotation(sphere->offset);
			q1 = gf_quat_multiply(&q1, &q2);
		}
		sphere->rotation_changed = gf_quat_to_rotation(&q1);
		gf_node_event_out_str(sh->owner, "rotation_changed");
	}
}