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: {} } }
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); } }