⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sensor_stacks.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005 *					All rights reserved * *  This file is part of GPAC / 3D rendering module * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include "render3d_nodes.h"/*for anchor*/#include "grouping.h"/*for anchor processing, which needs to be filtered at the inline scene level*/#include <gpac/internal/terminal_dev.h>typedef struct{	GF_Node *owner;	GF_Renderer *compositor;	GROUPINGNODESTACK	Bool enabled, active;	SensorHandler hdl;} AnchorStack;static void RenderAnchor(GF_Node *node, void *rs, Bool is_destroy){	AnchorStack *st = (AnchorStack *) gf_node_get_private(node);	RenderEffect3D *eff = (RenderEffect3D *)rs;	if (is_destroy) {		R3D_SensorDeleted(st->compositor, &st->hdl);		DeleteGroupingNode((GroupingNode *)st);		free(st);		return;	}	if (!st->compositor->user->EventProc) {		st->enabled = 0;		return;	}	/*note we don't clear dirty flag, this is done in traversing*/	if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) {		MFURL *url;		if (gf_node_get_tag(node)==TAG_MPEG4_Anchor) {			url = & ((M_Anchor *)node)->url;		} else {			url = & ((X_Anchor *)node)->url;		}		st->enabled = 0;		if (url->count && url->vals[0].url && strlen(url->vals[0].url) )			st->enabled = 1;	}	grouping_traverse((GroupingNode*)st, eff, NULL);}static void OnAnchor(SensorHandler *sh, Bool is_over, GF_Event *ev, RayHitInfo *hit_info){	GF_Event evt;	MFURL *url;	AnchorStack *st = (AnchorStack *) gf_node_get_private(sh->owner);	if ((ev->type==GF_EVENT_MOUSEDOWN) && (ev->mouse.button==GF_MOUSE_LEFT)) st->active = 1;	else if (st->active && (ev->type==GF_EVENT_MOUSEUP) && (ev->mouse.button==GF_MOUSE_LEFT) ) {		u32 i;		if (gf_node_get_tag(sh->owner)==TAG_MPEG4_Anchor) {			url = & ((M_Anchor *)sh->owner)->url;			evt.navigate.param_count = ((M_Anchor *)sh->owner)->parameter.count;			evt.navigate.parameters = (const char **) ((M_Anchor *)sh->owner)->parameter.vals;		} else {			url = & ((X_Anchor *)sh->owner)->url;			evt.navigate.param_count = ((X_Anchor *)sh->owner)->parameter.count;			evt.navigate.parameters = (const char **) ((X_Anchor *)sh->owner)->parameter.vals;		}		evt.type = GF_EVENT_NAVIGATE;		i=0;		while (i<url->count) {			evt.navigate.to_url = url->vals[i].url;			if (!evt.navigate.to_url) break;			/*current scene navigation*/			if (evt.navigate.to_url[0] == '#') {				GF_Node *bindable;				evt.navigate.to_url++;				bindable = gf_sg_find_node_by_name(gf_node_get_graph(sh->owner), (char *) evt.navigate.to_url);				if (bindable) {					Bindable_SetSetBind(bindable, 1);					break;				}			} else if (st->compositor->term) {				if (gf_is_process_anchor(sh->owner, &evt))					break;			} else if (st->compositor->user->EventProc) {				if (st->compositor->user->EventProc(st->compositor->user->opaque, &evt))					break;			}			i++;		}	} else if (ev->type==GF_EVENT_MOUSEMOVE) {		if (st->compositor->user->EventProc) {			evt.type = GF_EVENT_NAVIGATE_INFO;			if (gf_node_get_tag(sh->owner)==TAG_MPEG4_Anchor) {				evt.navigate.to_url = ((M_Anchor *)sh->owner)->description.buffer;				url = & ((M_Anchor *)sh->owner)->url;			} else {				evt.navigate.to_url = ((X_Anchor *)sh->owner)->description.buffer;				url = & ((X_Anchor *)sh->owner)->url;			}			if (!evt.navigate.to_url || !strlen(evt.navigate.to_url)) evt.navigate.to_url = url->vals[0].url;			st->compositor->user->EventProc(st->compositor->user->opaque, &evt);		}	}}static Bool anchor_is_enabled(GF_Node *node){	AnchorStack *st = (AnchorStack *) gf_node_get_private(node);	return st->enabled;}static void on_activate_anchor(GF_Node *node){	GF_Event ev;	AnchorStack *st = (AnchorStack *) gf_node_get_private(node);	if (!((M_Anchor *)node)->on_activate) return;	ev.type = GF_EVENT_MOUSEUP;	ev.mouse.x = ev.mouse.y = 0;	ev.mouse.button = GF_MOUSE_LEFT;	OnAnchor(&st->hdl, 0, &ev, NULL);}SensorHandler *r3d_anchor_get_handler(GF_Node *n){	AnchorStack *st = (AnchorStack *) gf_node_get_private(n);	return &st->hdl;}void R3D_InitAnchor(Render3D *sr, GF_Node *node){	AnchorStack *stack;	GF_SAFEALLOC(stack, AnchorStack);	stack->hdl.IsEnabled = anchor_is_enabled;	stack->hdl.OnUserEvent = OnAnchor;	stack->hdl.owner = node;	if (gf_node_get_tag(node)==TAG_MPEG4_Anchor) {		((M_Anchor *)node)->on_activate = on_activate_anchor;		SetupGroupingNode((GroupingNode*)stack, sr->compositor, node, & ((M_Anchor *)node)->children);	} else {		SetupGroupingNode((GroupingNode*)stack, sr->compositor, node, & ((X_Anchor *)node)->children);	}	sr->compositor->interaction_sensors++;	gf_node_set_private(node, stack);	gf_node_set_callback_function(node, RenderAnchor);}typedef struct {	SensorHandler hdl;	GF_Renderer *compositor;	Fixed start_angle;	GF_Matrix initial_matrix;} DiscSensorStack;static void DestroyDiscSensor(GF_Node *node, void *rs, Bool is_destroy){	if (is_destroy) {		DiscSensorStack *st = (DiscSensorStack *) gf_node_get_private(node);		R3D_SensorDeleted(st->compositor, &st->hdl);		free(st);	}}static Bool ds_is_enabled(GF_Node *n){	M_DiscSensor *ds = (M_DiscSensor *)n;	return (ds->enabled || ds->isActive);}static void OnDiscSensor(SensorHandler *sh, Bool is_over, GF_Event *ev, RayHitInfo *hit_info){	M_DiscSensor *ds = (M_DiscSensor *)sh->owner;	DiscSensorStack *stack = (DiscSensorStack *) gf_node_get_private(sh->owner);		if (ds->isActive && (!ds->enabled || ((ev->type==GF_EVENT_MOUSEUP) && (ev->mouse.button==GF_MOUSE_LEFT) ) ) ) {		if (ds->autoOffset) {			ds->offset = ds->rotation_changed;			/*that's an exposedField*/			gf_node_event_out_str(sh->owner, "offset");		}		ds->isActive = 0;		gf_node_event_out_str(sh->owner, "isActive");		R3D_SetGrabbed(stack->compositor, 0);	}	else if (!ds->isActive && (ev->type==GF_EVENT_MOUSEDOWN) && (ev->mouse.button==GF_MOUSE_LEFT)) {		/*store inverse matrix*/		gf_mx_copy(stack->initial_matrix, hit_info->local_to_world);		stack->start_angle = gf_atan2(hit_info->local_point.y, hit_info->local_point.x);		ds->isActive = 1;		gf_node_event_out_str(sh->owner, "isActive");		R3D_SetGrabbed(stack->compositor, 1);	}	else if (ds->isActive) {		GF_Ray loc_ray;		Fixed rot;		SFVec3f res;		loc_ray = hit_info->world_ray;		gf_mx_apply_ray(&stack->initial_matrix, &loc_ray);		R3D_Get2DPlaneIntersection(&loc_ray, &res);			rot = gf_atan2(res.y, res.x) - stack->start_angle + ds->offset;		if (ds->minAngle < ds->maxAngle) {			/*FIXME this doesn't work properly*/			if (rot < ds->minAngle) rot = ds->minAngle;			if (rot > ds->maxAngle) rot = ds->maxAngle;		}		ds->rotation_changed = rot;		gf_node_event_out_str(sh->owner, "rotation_changed");	   	ds->trackPoint_changed.x = res.x;	   	ds->trackPoint_changed.y = res.y;		gf_node_event_out_str(sh->owner, "trackPoint_changed");	}}SensorHandler *r3d_ds_get_handler(GF_Node *n){	DiscSensorStack *st = (DiscSensorStack *)gf_node_get_private(n);	return &st->hdl;}void R3D_InitDiscSensor(Render3D *sr, GF_Node *node){	DiscSensorStack *st;	GF_SAFEALLOC(st, DiscSensorStack);	st->hdl.IsEnabled = ds_is_enabled;	st->hdl.OnUserEvent = OnDiscSensor;	st->hdl.owner = node;	st->compositor = sr->compositor;	sr->compositor->interaction_sensors++;	gf_node_set_private(node, st);	gf_node_set_callback_function(node, DestroyDiscSensor);}typedef struct {	SFVec2f start_drag;	GF_Matrix initial_matrix;	GF_Renderer *compositor;	SensorHandler hdl;} PS2DStack;static void DestroyPlaneSensor2D(GF_Node *node, void *rs, Bool is_destroy){	if (is_destroy) {		PS2DStack *st = (PS2DStack *) gf_node_get_private(node);		R3D_SensorDeleted(st->compositor, &st->hdl);		free(st);	}}static Bool ps2D_is_enabled(GF_Node *n){	M_PlaneSensor2D *ps2d = (M_PlaneSensor2D *)n;	return (ps2d->enabled || ps2d->isActive);}static void OnPlaneSensor2D(SensorHandler *sh, Bool is_over, GF_Event *ev, RayHitInfo *hit_info){	M_PlaneSensor2D *ps = (M_PlaneSensor2D *)sh->owner;	PS2DStack *stack = (PS2DStack *) gf_node_get_private(sh->owner);	if (ps->isActive && (!ps->enabled || ((ev->type==GF_EVENT_MOUSEUP) && (ev->mouse.button==GF_MOUSE_LEFT)) )) {		if (ps->autoOffset) {			ps->offset = ps->translation_changed;			gf_node_event_out_str(sh->owner, "offset");		}		ps->isActive = 0;		gf_node_event_out_str(sh->owner, "isActive");		R3D_SetGrabbed(stack->compositor, 0);	} else if (!ps->isActive && (ev->type==GF_EVENT_MOUSEDOWN) && (ev->mouse.button==GF_MOUSE_LEFT)) {		gf_mx_copy(stack->initial_matrix, hit_info->local_to_world);		stack->start_drag.x = hit_info->local_point.x - ps->offset.x;		stack->start_drag.y = hit_info->local_point.y - ps->offset.y;		ps->isActive = 1;		gf_node_event_out_str(sh->owner, "isActive");		R3D_SetGrabbed(stack->compositor, 1);	} else if (ps->isActive) {		GF_Ray loc_ray;		SFVec3f res;		loc_ray = hit_info->world_ray;		gf_mx_apply_ray(&stack->initial_matrix, &loc_ray);		R3D_Get2DPlaneIntersection(&loc_ray, &res);		ps->trackPoint_changed.x = res.x;		ps->trackPoint_changed.y = res.y;		gf_node_event_out_str(sh->owner, "trackPoint_changed");		res.x -= stack->start_drag.x;		res.y -= stack->start_drag.y;		/*clip*/		if (ps->minPosition.x <= ps->maxPosition.x) {			if (res.x < ps->minPosition.x) res.x = ps->minPosition.x;			if (res.x > ps->maxPosition.x) res.x = ps->maxPosition.x;		}		if (ps->minPosition.y <= ps->maxPosition.y) {			if (res.y < ps->minPosition.y) res.y = ps->minPosition.y;			if (res.y > ps->maxPosition.y) res.y = ps->maxPosition.y;		}		ps->translation_changed.x = res.x;		ps->translation_changed.y = res.y;		gf_node_event_out_str(sh->owner, "translation_changed");	}}SensorHandler *r3d_ps2D_get_handler(GF_Node *n){	PS2DStack *st = (PS2DStack *)gf_node_get_private(n);	return &st->hdl;}void R3D_InitPlaneSensor2D(Render3D *sr, GF_Node *node){	PS2DStack *st;	GF_SAFEALLOC(st, PS2DStack);	st->hdl.IsEnabled = ps2D_is_enabled;	st->hdl.OnUserEvent = OnPlaneSensor2D;	st->hdl.owner = node;	st->compositor = sr->compositor;	st->compositor->interaction_sensors++;	gf_node_set_private(node, st);	gf_node_set_callback_function(node, DestroyPlaneSensor2D);}typedef struct {	Double last_time;	GF_Renderer *compositor;	SensorHandler hdl;} Prox2DStack;static void DestroyProximitySensor2D(GF_Node *node, void *rs, Bool is_destroy){	if (is_destroy) {		Prox2DStack *st = (Prox2DStack *) gf_node_get_private(node);		R3D_SensorDeleted(st->compositor, &st->hdl);		free(st);	}}static Bool prox2D_is_enabled(GF_Node *n){	return ((M_ProximitySensor2D *) n)->enabled;}static Bool prox2D_is_in_sensor(Prox2DStack *st, M_ProximitySensor2D *ps, Fixed X, Fixed Y){	if (X < ps->center.x - ps->size.x/2) return 0;	if (X > ps->center.x + ps->size.x/2) return 0;	if (Y < ps->center.y - ps->size.y/2) return 0;	if (Y > ps->center.y + ps->size.y/2) return 0;	return 1;}static void OnProximitySensor2D(SensorHandler *sh, Bool is_over, GF_Event *ev, RayHitInfo *hit_info){	M_ProximitySensor2D *ps = (M_ProximitySensor2D *)sh->owner;	Prox2DStack *stack = (Prox2DStack *) gf_node_get_private(sh->owner);		assert(ps->enabled);		if (is_over) {		stack->last_time = gf_node_get_scene_time(sh->owner);		if (prox2D_is_in_sensor(stack, ps, hit_info->local_point.x, hit_info->local_point.y)) {			ps->position_changed.x = hit_info->local_point.x;			ps->position_changed.y = hit_info->local_point.y;			gf_node_event_out_str(sh->owner, "position_changed");			if (!ps->isActive) {				ps->isActive = 1;				gf_node_event_out_str(sh->owner, "isActive");				ps->enterTime = stack->last_time;				gf_node_event_out_str(sh->owner, "enterTime");			}			return;		}	} 	/*either we're not over the shape or we're not in sensor*/	if (ps->isActive) {		ps->exitTime = stack->last_time;		gf_node_event_out_str(sh->owner, "exitTime");		ps->isActive = 0;		gf_node_event_out_str(sh->owner, "isActive");	}}SensorHandler *r3d_prox2D_get_handler(GF_Node *n){	Prox2DStack *st = (Prox2DStack *)gf_node_get_private(n);	return &st->hdl;}void R3D_InitProximitySensor2D(Render3D *sr, GF_Node *node){	Prox2DStack *st;	GF_SAFEALLOC(st, Prox2DStack);	st->hdl.IsEnabled = prox2D_is_enabled;	st->hdl.OnUserEvent = OnProximitySensor2D;	st->hdl.owner = node;	st->compositor = sr->compositor;	st->compositor->interaction_sensors++;	gf_node_set_private(node, st);	gf_node_set_callback_function(node, DestroyProximitySensor2D);}typedef struct {	SensorHandler hdl;	Bool mouse_down;	GF_Renderer *compositor;} TouchSensorStack;static void DestroyTouchSensor(GF_Node *node, void *rs, Bool is_destroy){	if (is_destroy) {		TouchSensorStack *st = (TouchSensorStack *) gf_node_get_private(node);		R3D_SensorDeleted(st->compositor, &st->hdl);		free(st);	}}static Bool ts_is_enabled(GF_Node *n){	return ((M_TouchSensor *) n)->enabled;}static void OnTouchSensor(SensorHandler *sh, Bool is_over, GF_Event *ev, RayHitInfo *hit_info){	M_TouchSensor *ts = (M_TouchSensor *)sh->owner;	TouchSensorStack *st = (TouchSensorStack *) gf_node_get_private(sh->owner);	//assert(ts->enabled);	/*isActive becomes false, send touch time*/	if ((ev->type==GF_EVENT_MOUSEUP) && (ev->mouse.button==GF_MOUSE_LEFT) && ts->isActive) {		ts->touchTime = gf_node_get_scene_time(sh->owner);		gf_node_event_out_str(sh->owner, "touchTime");		ts->isActive = 0;		gf_node_event_out_str(sh->owner, "isActive");		R3D_SetGrabbed(st->compositor, 0);	}	if (is_over != ts->isOver) {		ts->isOver = is_over;		gf_node_event_out_str(sh->owner, "isOver");	}	if (!ts->isActive && (ev->type==GF_EVENT_MOUSEDOWN) && (ev->mouse.button==GF_MOUSE_LEFT)) {		ts->isActive = 1;		gf_node_event_out_str(sh->owner, "isActive");		R3D_SetGrabbed(st->compositor, 1);	}	if (is_over) {		ts->hitPoint_changed = hit_info->local_point;		gf_node_event_out_str(sh->owner, "hitPoint_changed");		ts->hitNormal_changed = hit_info->hit_normal;		gf_node_event_out_str(sh->owner, "hitNormal_changed");		ts->hitTexCoord_changed = hit_info->hit_texcoords;		gf_node_event_out_str(sh->owner, "hitTexCoord_changed");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -