Esempio n. 1
0
void Spatial::_notification(int p_what) {

	switch(p_what) {
		case NOTIFICATION_ENTER_SCENE: {

			Node *p = get_parent();
			if (p)
				data.parent=p->cast_to<Spatial>();

			if (data.parent)
				data.C=data.parent->data.children.push_back(this);
			else
				data.C=NULL;

			if (data.toplevel && !get_scene()->is_editor_hint()) {

				if (data.parent) {
					data.local_transform = data.parent->get_global_transform() * get_transform();
					data.dirty=DIRTY_VECTORS; //global is always dirty upon entering a scene
				}
				data.toplevel_active=true;
			}

			data.dirty|=DIRTY_GLOBAL; //global is always dirty upon entering a scene
			_notify_dirty();

			notification(NOTIFICATION_ENTER_WORLD);

		} break;
		case NOTIFICATION_EXIT_SCENE: {

			notification(NOTIFICATION_EXIT_WORLD,true);
			if (xform_change.in_list())
				get_scene()->xform_change_list.remove(&xform_change);
			if (data.C)
				data.parent->data.children.erase(data.C);
			data.parent=NULL;
			data.C=NULL;
			data.toplevel_active=false;
		} break;
		case NOTIFICATION_ENTER_WORLD: {

			data.inside_world=true;
			data.viewport=NULL;
			Node *parent = get_parent();
			while(parent && !data.viewport) {
				data.viewport=parent->cast_to<Viewport>();
				parent=parent->get_parent();
			}

			ERR_FAIL_COND(!data.viewport);


			if (get_script_instance()) {

				Variant::CallError err;
				get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_enter_world,NULL,0);
			}
#ifdef TOOLS_ENABLED
			if (get_scene()->is_editor_hint()) {

//				get_scene()->call_group(SceneMainLoop::GROUP_CALL_REALTIME,SceneStringNames::get_singleton()->_spatial_editor_group,SceneStringNames::get_singleton()->_request_gizmo,this);
				get_scene()->call_group(0,SceneStringNames::get_singleton()->_spatial_editor_group,SceneStringNames::get_singleton()->_request_gizmo,this);
				if (!data.gizmo_disabled) {

					if (data.gizmo.is_valid())
						data.gizmo->create();
				}
			}
#endif

		} break;
		case NOTIFICATION_EXIT_WORLD: {

#ifdef TOOLS_ENABLED
			if (data.gizmo.is_valid()) {
				data.gizmo->free();
			}
#endif

			if (get_script_instance()) {

				Variant::CallError err;
				get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_exit_world,NULL,0);
			}

			data.viewport=NULL;
			data.inside_world=false;

		} break;


		case NOTIFICATION_TRANSFORM_CHANGED: {
		
#ifdef TOOLS_ENABLED
			if (data.gizmo.is_valid()) {
				data.gizmo->transform();
			}
#endif
		} break;
	
		default: {}
	}
}
Esempio n. 2
0
void Spatial::_propagate_transform_changed(Spatial *p_origin) {

	if (!is_inside_tree()) {
		return;
	}

	/*
	if (data.dirty&DIRTY_GLOBAL)
		return; //already dirty
	*/

	data.children_lock++;

	for (List<Spatial *>::Element *E = data.children.front(); E; E = E->next()) {

		if (E->get()->data.toplevel_active)
			continue; //don't propagate to a toplevel
		E->get()->_propagate_transform_changed(p_origin);
	}
#ifdef TOOLS_ENABLED
	if ((data.gizmo.is_valid() || data.notify_transform) && !data.ignore_notification && !xform_change.in_list()) {
#else
	if (data.notify_transform && !data.ignore_notification && !xform_change.in_list()) {
#endif
		get_tree()->xform_change_list.add(&xform_change);
	}
	data.dirty |= DIRTY_GLOBAL;

	data.children_lock--;
}

void Spatial::_notification(int p_what) {

	switch (p_what) {
		case NOTIFICATION_ENTER_TREE: {

			Node *p = get_parent();
			if (p)
				data.parent = Object::cast_to<Spatial>(p);

			if (data.parent)
				data.C = data.parent->data.children.push_back(this);
			else
				data.C = NULL;

			if (data.toplevel && !Engine::get_singleton()->is_editor_hint()) {

				if (data.parent) {
					data.local_transform = data.parent->get_global_transform() * get_transform();
					data.dirty = DIRTY_VECTORS; //global is always dirty upon entering a scene
				}
				data.toplevel_active = true;
			}

			data.dirty |= DIRTY_GLOBAL; //global is always dirty upon entering a scene
			_notify_dirty();

			notification(NOTIFICATION_ENTER_WORLD);

		} break;
		case NOTIFICATION_EXIT_TREE: {

			notification(NOTIFICATION_EXIT_WORLD, true);
			if (xform_change.in_list())
				get_tree()->xform_change_list.remove(&xform_change);
			if (data.C)
				data.parent->data.children.erase(data.C);
			data.parent = NULL;
			data.C = NULL;
			data.toplevel_active = false;
		} break;
		case NOTIFICATION_ENTER_WORLD: {

			data.inside_world = true;
			data.viewport = NULL;
			Node *parent = get_parent();
			while (parent && !data.viewport) {
				data.viewport = Object::cast_to<Viewport>(parent);
				parent = parent->get_parent();
			}

			ERR_FAIL_COND(!data.viewport);

			if (get_script_instance()) {

				get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_enter_world, NULL, 0);
			}
#ifdef TOOLS_ENABLED
			if (Engine::get_singleton()->is_editor_hint() && get_tree()->is_node_being_edited(this)) {

				//get_scene()->call_group(SceneMainLoop::GROUP_CALL_REALTIME,SceneStringNames::get_singleton()->_spatial_editor_group,SceneStringNames::get_singleton()->_request_gizmo,this);
				get_tree()->call_group_flags(0, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_request_gizmo, this);
				if (!data.gizmo_disabled) {

					if (data.gizmo.is_valid()) {
						data.gizmo->create();
						if (is_visible_in_tree()) {
							data.gizmo->redraw();
						}
						data.gizmo->transform();
					}
				}
			}
#endif

		} break;
		case NOTIFICATION_EXIT_WORLD: {

#ifdef TOOLS_ENABLED
			if (data.gizmo.is_valid()) {
				data.gizmo->free();
				data.gizmo.unref();
			}
#endif

			if (get_script_instance()) {

				get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_exit_world, NULL, 0);
			}

			data.viewport = NULL;
			data.inside_world = false;

		} break;

		case NOTIFICATION_TRANSFORM_CHANGED: {

#ifdef TOOLS_ENABLED
			if (data.gizmo.is_valid()) {
				data.gizmo->transform();
			}
#endif
		} break;

		default: {
		}
	}
}

void Spatial::set_transform(const Transform &p_transform) {

	data.local_transform = p_transform;
	data.dirty |= DIRTY_VECTORS;
	_change_notify("translation");
	_change_notify("rotation");
	_change_notify("rotation_degrees");
	_change_notify("scale");
	_propagate_transform_changed(this);
	if (data.notify_local_transform) {
		notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
	}
}