X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=radiant%2Fentity.cpp;h=87cf9cd0158a872b474d3355fe125d8a649edeea;hb=a3d27eedb7107d7dd964fcc9d25c6464e3280b98;hp=52be82feed93405b0189f86754661886690b72cd;hpb=3d28ea324c6e5c9d22ae134618144bf1c11e1161;p=xonotic%2Fnetradiant.git diff --git a/radiant/entity.cpp b/radiant/entity.cpp index 52be82fe..87cf9cd0 100644 --- a/radiant/entity.cpp +++ b/radiant/entity.cpp @@ -1,24 +1,25 @@ /* -Copyright (C) 1999-2006 Id Software, Inc. and contributors. -For a list of contributors, see the accompanying CONTRIBUTORS file. + Copyright (C) 1999-2006 Id Software, Inc. and contributors. + For a list of contributors, see the accompanying CONTRIBUTORS file. -This file is part of GtkRadiant. + This file is part of GtkRadiant. -GtkRadiant is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -GtkRadiant 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 General Public License for more details. + GtkRadiant 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 General Public License for more details. -You should have received a copy of the GNU General Public License -along with GtkRadiant; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include #include "entity.h" #include "ientity.h" @@ -45,581 +46,537 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "qe3.h" #include "commands.h" +#include "uilib/uilib.h" + struct entity_globals_t { - Vector3 color_entity; + Vector3 color_entity; - entity_globals_t() : - color_entity(0.0f, 0.0f, 0.0f) - { - } + entity_globals_t() : + color_entity( 0.0f, 0.0f, 0.0f ){ + } }; entity_globals_t g_entity_globals; class EntitySetKeyValueSelected : public scene::Graph::Walker { - const char* m_key; - const char* m_value; +const char* m_key; +const char* m_value; public: - EntitySetKeyValueSelected(const char* key, const char* value) - : m_key(key), m_value(value) - { - } - bool pre(const scene::Path& path, scene::Instance& instance) const - { - return true; - } - void post(const scene::Path& path, scene::Instance& instance) const - { - Entity* entity = Node_getEntity(path.top()); - if(entity != 0 - && (instance.childSelected() || Instance_getSelectable(instance)->isSelected())) - { - entity->setKeyValue(m_key, m_value); - } - } +EntitySetKeyValueSelected( const char* key, const char* value ) + : m_key( key ), m_value( value ){ +} +bool pre( const scene::Path& path, scene::Instance& instance ) const { + return true; +} +void post( const scene::Path& path, scene::Instance& instance ) const { + Entity* entity = Node_getEntity( path.top() ); + if ( entity != 0 + && ( instance.childSelected() || Instance_getSelectable( instance )->isSelected() ) ) { + entity->setKeyValue( m_key, m_value ); + } +} }; class EntitySetClassnameSelected : public scene::Graph::Walker { - const char* m_classname; +const char* m_classname; public: - EntitySetClassnameSelected(const char* classname) - : m_classname(classname) - { - } - bool pre(const scene::Path& path, scene::Instance& instance) const - { - return true; - } - void post(const scene::Path& path, scene::Instance& instance) const - { - Entity* entity = Node_getEntity(path.top()); - if(entity != 0 - && (instance.childSelected() || Instance_getSelectable(instance)->isSelected())) - { - NodeSmartReference node(GlobalEntityCreator().createEntity(GlobalEntityClassManager().findOrInsert(m_classname, node_is_group(path.top())))); - - EntityCopyingVisitor visitor(*Node_getEntity(node)); - - entity->forEachKeyValue(visitor); - - NodeSmartReference child(path.top().get()); - NodeSmartReference parent(path.parent().get()); - Node_getTraversable(parent)->erase(child); - if(Node_getTraversable(child) != 0 - && Node_getTraversable(node) != 0 - && node_is_group(node)) - { - parentBrushes(child, node); - } - Node_getTraversable(parent)->insert(node); - } - } +EntitySetClassnameSelected( const char* classname ) + : m_classname( classname ){ +} +bool pre( const scene::Path& path, scene::Instance& instance ) const { + return true; +} +void post( const scene::Path& path, scene::Instance& instance ) const { + Entity* entity = Node_getEntity( path.top() ); + if ( entity != 0 + && ( instance.childSelected() || Instance_getSelectable( instance )->isSelected() ) ) { + NodeSmartReference node( GlobalEntityCreator().createEntity( GlobalEntityClassManager().findOrInsert( m_classname, node_is_group( path.top() ) ) ) ); + + EntityCopyingVisitor visitor( *Node_getEntity( node ) ); + + entity->forEachKeyValue( visitor ); + + NodeSmartReference child( path.top().get() ); + NodeSmartReference parent( path.parent().get() ); + Node_getTraversable( parent )->erase( child ); + if ( Node_getTraversable( child ) != 0 + && Node_getTraversable( node ) != 0 + && node_is_group( node ) ) { + parentBrushes( child, node ); + } + Node_getTraversable( parent )->insert( node ); + } +} }; -void Scene_EntitySetKeyValue_Selected(const char* key, const char* value) -{ - GlobalSceneGraph().traverse(EntitySetKeyValueSelected(key, value)); +void Scene_EntitySetKeyValue_Selected( const char* key, const char* value ){ + GlobalSceneGraph().traverse( EntitySetKeyValueSelected( key, value ) ); } -void Scene_EntitySetClassname_Selected(const char* classname) -{ - GlobalSceneGraph().traverse(EntitySetClassnameSelected(classname)); +void Scene_EntitySetClassname_Selected( const char* classname ){ + GlobalSceneGraph().traverse( EntitySetClassnameSelected( classname ) ); } -void Entity_ungroupSelected() -{ - if (GlobalSelectionSystem().countSelected() < 1) return; +void Entity_ungroupSelected(){ + if ( GlobalSelectionSystem().countSelected() < 1 ) { + return; + } - UndoableCommand undo("ungroupSelectedEntities"); + UndoableCommand undo( "ungroupSelectedEntities" ); - scene::Path world_path(makeReference(GlobalSceneGraph().root())); - world_path.push(makeReference(Map_FindOrInsertWorldspawn(g_map))); + scene::Path world_path( makeReference( GlobalSceneGraph().root() ) ); + world_path.push( makeReference( Map_FindOrInsertWorldspawn( g_map ) ) ); - scene::Instance &instance = GlobalSelectionSystem().ultimateSelected(); - scene::Path path = instance.path(); + scene::Instance &instance = GlobalSelectionSystem().ultimateSelected(); + scene::Path path = instance.path(); - if (!Node_isEntity(path.top())) path.pop(); + if ( !Node_isEntity( path.top() ) ) { + path.pop(); + } - if(Node_getEntity(path.top()) != 0 - && node_is_group(path.top())) - { - if(world_path.top().get_pointer() != path.top().get_pointer()) - { - parentBrushes(path.top(), world_path.top()); - Path_deleteTop(path); - } - } + if ( Node_getEntity( path.top() ) != 0 + && node_is_group( path.top() ) ) { + if ( world_path.top().get_pointer() != path.top().get_pointer() ) { + parentBrushes( path.top(), world_path.top() ); + Path_deleteTop( path ); + } + } } class EntityFindSelected : public scene::Graph::Walker { public: - mutable const scene::Path *groupPath; - mutable scene::Instance *groupInstance; - EntityFindSelected(): groupPath(0), groupInstance(0) - { - } - bool pre(const scene::Path& path, scene::Instance& instance) const - { - return true; - } - void post(const scene::Path& path, scene::Instance& instance) const - { - Entity* entity = Node_getEntity(path.top()); - if(entity != 0 - && Instance_getSelectable(instance)->isSelected() - && node_is_group(path.top()) - && !groupPath) - { - groupPath = &path; - groupInstance = &instance; - } - } +mutable const scene::Path *groupPath; +mutable scene::Instance *groupInstance; +EntityFindSelected() : groupPath( 0 ), groupInstance( 0 ){ +} +bool pre( const scene::Path& path, scene::Instance& instance ) const { + return true; +} +void post( const scene::Path& path, scene::Instance& instance ) const { + Entity* entity = Node_getEntity( path.top() ); + if ( entity != 0 + && Instance_getSelectable( instance )->isSelected() + && node_is_group( path.top() ) + && !groupPath ) { + groupPath = &path; + groupInstance = &instance; + } +} }; class EntityGroupSelected : public scene::Graph::Walker { - NodeSmartReference group; - //typedef std::pair DeletionPair; - //Stack deleteme; - public: - EntityGroupSelected(const scene::Path &p): group(p.top().get()) - { +NodeSmartReference group, worldspawn; +//typedef std::pair DeletionPair; +//Stack deleteme; +public: +EntityGroupSelected( const scene::Path &p ) : group( p.top().get() ), worldspawn( Map_FindOrInsertWorldspawn( g_map ) ){ +} +bool pre( const scene::Path& path, scene::Instance& instance ) const { + return true; +} +void post( const scene::Path& path, scene::Instance& instance ) const { + Selectable *selectable = Instance_getSelectable( instance ); + if ( selectable && selectable->isSelected() ) { + Entity* entity = Node_getEntity( path.top() ); + if ( entity == 0 && Node_isPrimitive( path.top() ) ) { + NodeSmartReference child( path.top().get() ); + NodeSmartReference parent( path.parent().get() ); + + if ( path.size() >= 3 && parent != worldspawn ) { + NodeSmartReference parentparent( path[path.size() - 3].get() ); + + Node_getTraversable( parent )->erase( child ); + Node_getTraversable( group )->insert( child ); + + if ( Node_getTraversable( parent )->empty() ) { + //deleteme.push(DeletionPair(parentparent, parent)); + Node_getTraversable( parentparent )->erase( parent ); + } + } + else + { + Node_getTraversable( parent )->erase( child ); + Node_getTraversable( group )->insert( child ); + } + } } - bool pre(const scene::Path& path, scene::Instance& instance) const - { - return true; +} +}; + +void Entity_groupSelected(){ + if ( GlobalSelectionSystem().countSelected() < 1 ) { + return; } - void post(const scene::Path& path, scene::Instance& instance) const - { - Selectable *selectable = Instance_getSelectable(instance); - if(selectable && selectable->isSelected()) - { - Entity* entity = Node_getEntity(path.top()); - if(entity == 0 && Node_isPrimitive(path.top())) - { - NodeSmartReference child(path.top().get()); - NodeSmartReference parent(path.parent().get()); - if(path.size() >= 3 && parent != Map_FindOrInsertWorldspawn(g_map)) - { - NodeSmartReference parentparent(path[path.size() - 3].get()); + UndoableCommand undo( "groupSelectedEntities" ); - Node_getTraversable(parent)->erase(child); - Node_getTraversable(group)->insert(child); + scene::Path world_path( makeReference( GlobalSceneGraph().root() ) ); + world_path.push( makeReference( Map_FindOrInsertWorldspawn( g_map ) ) ); - if(Node_getTraversable(parent)->empty()) - { - //deleteme.push(DeletionPair(parentparent, parent)); - Node_getTraversable(parentparent)->erase(parent); - } - } - else - { - Node_getTraversable(parent)->erase(child); - Node_getTraversable(group)->insert(child); - } - } - } + EntityFindSelected fse; + GlobalSceneGraph().traverse( fse ); + if ( fse.groupPath ) { + GlobalSceneGraph().traverse( EntityGroupSelected( *fse.groupPath ) ); } -}; + else + { + GlobalSceneGraph().traverse( EntityGroupSelected( world_path ) ); + } +} -void Entity_groupSelected() -{ - if (GlobalSelectionSystem().countSelected() < 1) return; - UndoableCommand undo("groupSelectedEntities"); - scene::Path world_path(makeReference(GlobalSceneGraph().root())); - world_path.push(makeReference(Map_FindOrInsertWorldspawn(g_map))); +void Entity_connectSelected(){ + if ( GlobalSelectionSystem().countSelected() == 2 ) { + GlobalEntityCreator().connectEntities( + GlobalSelectionSystem().penultimateSelected().path(), + GlobalSelectionSystem().ultimateSelected().path(), + 0 + ); + } + else + { + globalErrorStream() << "entityConnectSelected: exactly two instances must be selected\n"; + } +} - EntityFindSelected fse; - GlobalSceneGraph().traverse(fse); - if(fse.groupPath) - { - GlobalSceneGraph().traverse(EntityGroupSelected(*fse.groupPath)); - } - else - { - GlobalSceneGraph().traverse(EntityGroupSelected(world_path)); - } +void Entity_killconnectSelected(){ + if ( GlobalSelectionSystem().countSelected() == 2 ) { + GlobalEntityCreator().connectEntities( + GlobalSelectionSystem().penultimateSelected().path(), + GlobalSelectionSystem().ultimateSelected().path(), + 1 + ); + } + else + { + globalErrorStream() << "entityKillConnectSelected: exactly two instances must be selected\n"; + } } +AABB Doom3Light_getBounds( const AABB& workzone ){ + AABB aabb( workzone ); + Vector3 defaultRadius( 300, 300, 300 ); + if ( !string_parse_vector3( EntityClass_valueForKey( *GlobalEntityClassManager().findOrInsert( "light", false ), "light_radius" ), defaultRadius ) ) { + globalErrorStream() << "Doom3Light_getBounds: failed to parse default light radius\n"; + } -void Entity_connectSelected() -{ - if(GlobalSelectionSystem().countSelected() == 2) - { - GlobalEntityCreator().connectEntities( - GlobalSelectionSystem().penultimateSelected().path(), - GlobalSelectionSystem().ultimateSelected().path() - ); - } - else - { - globalErrorStream() << "entityConnectSelected: exactly two instances must be selected\n"; - } -} - -AABB Doom3Light_getBounds(const AABB& workzone) -{ - AABB aabb(workzone); - - Vector3 defaultRadius(300, 300, 300); - if(!string_parse_vector3(EntityClass_valueForKey(*GlobalEntityClassManager().findOrInsert("light", false), "light_radius"), defaultRadius)) - { - globalErrorStream() << "Doom3Light_getBounds: failed to parse default light radius\n"; - } - - if(aabb.extents[0] == 0) - { - aabb.extents[0] = defaultRadius[0]; - } - if(aabb.extents[1] == 0) - { - aabb.extents[1] = defaultRadius[1]; - } - if(aabb.extents[2] == 0) - { - aabb.extents[2] = defaultRadius[2]; - } - - if(aabb_valid(aabb)) - { - return aabb; - } - return AABB(Vector3(0, 0, 0), Vector3(64, 64, 64)); + if ( aabb.extents[0] == 0 ) { + aabb.extents[0] = defaultRadius[0]; + } + if ( aabb.extents[1] == 0 ) { + aabb.extents[1] = defaultRadius[1]; + } + if ( aabb.extents[2] == 0 ) { + aabb.extents[2] = defaultRadius[2]; + } + + if ( aabb_valid( aabb ) ) { + return aabb; + } + return AABB( Vector3( 0, 0, 0 ), Vector3( 64, 64, 64 ) ); } int g_iLastLightIntensity; -void Entity_createFromSelection(const char* name, const Vector3& origin) -{ +void Entity_createFromSelection( const char* name, const Vector3& origin ){ #if 0 - if(string_equal_nocase(name, "worldspawn")) - { - gtk_MessageBox(GTK_WIDGET(MainFrame_getWindow()), "Can't create an entity with worldspawn.", "info"); - return; - } + if ( string_equal_nocase( name, "worldspawn" ) ) { + ui::alert( GTK_WIDGET( MainFrame_getWindow() ), "Can't create an entity with worldspawn.", "info" ); + return; + } #endif - EntityClass* entityClass = GlobalEntityClassManager().findOrInsert(name, true); - - bool isModel = string_equal_nocase(name, "misc_model") - || string_equal_nocase(name, "misc_gamemodel") - || string_equal_nocase(name, "model_static") - || (GlobalSelectionSystem().countSelected() == 0 && string_equal_nocase(name, "func_static")); - - bool brushesSelected = Scene_countSelectedBrushes(GlobalSceneGraph()) != 0; - - if(!(entityClass->fixedsize || isModel) && !brushesSelected) - { - globalErrorStream() << "failed to create a group entity - no brushes are selected\n"; - return; - } - - AABB workzone(aabb_for_minmax(Select_getWorkZone().d_work_min, Select_getWorkZone().d_work_max)); - - - NodeSmartReference node(GlobalEntityCreator().createEntity(entityClass)); - - Node_getTraversable(GlobalSceneGraph().root())->insert(node); - - scene::Path entitypath(makeReference(GlobalSceneGraph().root())); - entitypath.push(makeReference(node.get())); - scene::Instance& instance = findInstance(entitypath); - - if(entityClass->fixedsize || (isModel && !brushesSelected)) - { - Select_Delete(); - - Transformable* transform = Instance_getTransformable(instance); - if(transform != 0) - { - transform->setType(TRANSFORM_PRIMITIVE); - transform->setTranslation(origin); - transform->freezeTransform(); - } - - GlobalSelectionSystem().setSelectedAll(false); - - Instance_setSelected(instance, true); - } - else - { - if (g_pGameDescription->mGameType == "doom3") - { - Node_getEntity(node)->setKeyValue("model", Node_getEntity(node)->getKeyValue("name")); - } - - Scene_parentSelectedBrushesToEntity(GlobalSceneGraph(), node); - Scene_forEachChildSelectable(SelectableSetSelected(true), instance.path()); - } - - // tweaking: when right clic dropping a light entity, ask for light value in a custom dialog box - // see SF bug 105383 - - if (g_pGameDescription->mGameType == "hl") - { - // FIXME - Hydra: really we need a combined light AND color dialog for halflife. - if (string_equal_nocase(name, "light") - || string_equal_nocase(name, "light_environment") - || string_equal_nocase(name, "light_spot")) - { - int intensity = g_iLastLightIntensity; - - if (DoLightIntensityDlg (&intensity) == eIDOK) - { - g_iLastLightIntensity = intensity; - char buf[30]; - sprintf( buf, "255 255 255 %d", intensity ); - Node_getEntity(node)->setKeyValue("_light", buf); - } - } - } - else if(string_equal_nocase(name, "light")) - { - if(g_pGameDescription->mGameType != "doom3") - { - int intensity = g_iLastLightIntensity; - - if (DoLightIntensityDlg (&intensity) == eIDOK) - { - g_iLastLightIntensity = intensity; - char buf[10]; - sprintf( buf, "%d", intensity ); - Node_getEntity(node)->setKeyValue("light", buf); - } - } - else if(brushesSelected) // use workzone to set light position/size for doom3 lights, if there are brushes selected - { - AABB bounds(Doom3Light_getBounds(workzone)); - StringOutputStream key(64); - key << bounds.origin[0] << " " << bounds.origin[1] << " " << bounds.origin[2]; - Node_getEntity(node)->setKeyValue("origin", key.c_str()); - key.clear(); - key << bounds.extents[0] << " " << bounds.extents[1] << " " << bounds.extents[2]; - Node_getEntity(node)->setKeyValue("light_radius", key.c_str()); - } - } - - if(isModel) - { - const char* model = misc_model_dialog(GTK_WIDGET(MainFrame_getWindow())); - if(model != 0) - { - Node_getEntity(node)->setKeyValue("model", model); - } - } + EntityClass* entityClass = GlobalEntityClassManager().findOrInsert( name, true ); + + bool isModel = ( string_compare_nocase_n( name, "misc_", 5 ) == 0 && string_equal_nocase( name + string_length( name ) - 5, "model" ) ) // misc_*model (also misc_model) + || string_equal_nocase( name, "model_static" ) + || ( GlobalSelectionSystem().countSelected() == 0 && string_equal_nocase( name, "func_static" ) ); + + bool brushesSelected = Scene_countSelectedBrushes( GlobalSceneGraph() ) != 0; + + if ( !( entityClass->fixedsize || isModel ) && !brushesSelected ) { + globalErrorStream() << "failed to create a group entity - no brushes are selected\n"; + return; + } + + AABB workzone( aabb_for_minmax( Select_getWorkZone().d_work_min, Select_getWorkZone().d_work_max ) ); + + + NodeSmartReference node( GlobalEntityCreator().createEntity( entityClass ) ); + + Node_getTraversable( GlobalSceneGraph().root() )->insert( node ); + + scene::Path entitypath( makeReference( GlobalSceneGraph().root() ) ); + entitypath.push( makeReference( node.get() ) ); + scene::Instance& instance = findInstance( entitypath ); + + if ( entityClass->fixedsize || ( isModel && !brushesSelected ) ) { + Select_Delete(); + + Transformable* transform = Instance_getTransformable( instance ); + if ( transform != 0 ) { + transform->setType( TRANSFORM_PRIMITIVE ); + transform->setTranslation( origin ); + transform->freezeTransform(); + } + + GlobalSelectionSystem().setSelectedAll( false ); + + Instance_setSelected( instance, true ); + } + else + { + if ( g_pGameDescription->mGameType == "doom3" ) { + Node_getEntity( node )->setKeyValue( "model", Node_getEntity( node )->getKeyValue( "name" ) ); + } + + Scene_parentSelectedBrushesToEntity( GlobalSceneGraph(), node ); + Scene_forEachChildSelectable( SelectableSetSelected( true ), instance.path() ); + } + + // tweaking: when right clic dropping a light entity, ask for light value in a custom dialog box + // see SF bug 105383 + + if ( g_pGameDescription->mGameType == "hl" ) { + // FIXME - Hydra: really we need a combined light AND color dialog for halflife. + if ( string_equal_nocase( name, "light" ) + || string_equal_nocase( name, "light_environment" ) + || string_equal_nocase( name, "light_spot" ) ) { + int intensity = g_iLastLightIntensity; + + if ( DoLightIntensityDlg( &intensity ) == eIDOK ) { + g_iLastLightIntensity = intensity; + auto buf = u::buffer<30>(); + sprintf( buf, "255 255 255 %d", intensity ); + Node_getEntity( node )->setKeyValue( "_light", buf ); + } + } + } + else if ( string_equal_nocase( name, "light" ) ) { + if ( g_pGameDescription->mGameType != "doom3" ) { + int intensity = g_iLastLightIntensity; + + if ( DoLightIntensityDlg( &intensity ) == eIDOK ) { + g_iLastLightIntensity = intensity; + auto buf = u::buffer<10>(); + sprintf( buf, "%d", intensity ); + Node_getEntity( node )->setKeyValue( "light", buf ); + } + } + else if ( brushesSelected ) { // use workzone to set light position/size for doom3 lights, if there are brushes selected + AABB bounds( Doom3Light_getBounds( workzone ) ); + StringOutputStream key( 64 ); + key << bounds.origin[0] << " " << bounds.origin[1] << " " << bounds.origin[2]; + Node_getEntity( node )->setKeyValue( "origin", key.c_str() ); + key.clear(); + key << bounds.extents[0] << " " << bounds.extents[1] << " " << bounds.extents[2]; + Node_getEntity( node )->setKeyValue( "light_radius", key.c_str() ); + } + } + + if ( isModel ) { + const char* model = misc_model_dialog(MainFrame_getWindow()); + if ( model != 0 ) { + Node_getEntity( node )->setKeyValue( "model", model ); + } + } } #if 0 -bool DoNormalisedColor(Vector3& color) -{ - if(!color_dialog(GTK_WIDGET(MainFrame_getWindow()), color)) - return false; - /* - ** scale colors so that at least one component is at 1.0F - */ - - float largest = 0.0F; - - if ( color[0] > largest ) - largest = color[0]; - if ( color[1] > largest ) - largest = color[1]; - if ( color[2] > largest ) - largest = color[2]; - - if ( largest == 0.0F ) - { - color[0] = 1.0F; - color[1] = 1.0F; - color[2] = 1.0F; - } - else - { - float scaler = 1.0F / largest; - - color[0] *= scaler; - color[1] *= scaler; - color[2] *= scaler; - } - - return true; -} -#endif - -void NormalizeColor(Vector3& color) -{ - // scale colors so that at least one component is at 1.0F - - float largest = 0.0F; - - if ( color[0] > largest ) - largest = color[0]; - if ( color[1] > largest ) - largest = color[1]; - if ( color[2] > largest ) - largest = color[2]; - - if ( largest == 0.0F ) - { - color[0] = 1.0F; - color[1] = 1.0F; - color[2] = 1.0F; - } - else - { - float scaler = 1.0F / largest; - - color[0] *= scaler; - color[1] *= scaler; - color[2] *= scaler; - } -} - -void Entity_normalizeColor() -{ - if(GlobalSelectionSystem().countSelected() != 0) +bool DoNormalisedColor( Vector3& color ){ + if ( !color_dialog( GTK_WIDGET( MainFrame_getWindow() ), color ) ) { + return false; + } + /* + ** scale colors so that at least one component is at 1.0F + */ + + float largest = 0.0F; + + if ( color[0] > largest ) { + largest = color[0]; + } + if ( color[1] > largest ) { + largest = color[1]; + } + if ( color[2] > largest ) { + largest = color[2]; + } + + if ( largest == 0.0F ) { + color[0] = 1.0F; + color[1] = 1.0F; + color[2] = 1.0F; + } + else + { + float scaler = 1.0F / largest; + + color[0] *= scaler; + color[1] *= scaler; + color[2] *= scaler; + } + + return true; +} +#endif + +void NormalizeColor( Vector3& color ){ + // scale colors so that at least one component is at 1.0F + + float largest = 0.0F; + + if ( color[0] > largest ) { + largest = color[0]; + } + if ( color[1] > largest ) { + largest = color[1]; + } + if ( color[2] > largest ) { + largest = color[2]; + } + + if ( largest == 0.0F ) { + color[0] = 1.0F; + color[1] = 1.0F; + color[2] = 1.0F; + } + else { + float scaler = 1.0F / largest; + + color[0] *= scaler; + color[1] *= scaler; + color[2] *= scaler; + } +} + +void Entity_normalizeColor(){ + if ( GlobalSelectionSystem().countSelected() != 0 ) { const scene::Path& path = GlobalSelectionSystem().ultimateSelected().path(); - Entity* entity = Node_getEntity(path.top()); + Entity* entity = Node_getEntity( path.top() ); - if(entity != 0) - { - const char* strColor = entity->getKeyValue("_color"); - if(!string_empty(strColor)) - { + if ( entity != 0 ) { + const char* strColor = entity->getKeyValue( "_color" ); + if ( !string_empty( strColor ) ) { Vector3 rgb; - if (string_parse_vector3(strColor, rgb)) - { + if ( string_parse_vector3( strColor, rgb ) ) { g_entity_globals.color_entity = rgb; - NormalizeColor(g_entity_globals.color_entity); + NormalizeColor( g_entity_globals.color_entity ); - char buffer[128]; - sprintf(buffer, "%g %g %g", g_entity_globals.color_entity[0], - g_entity_globals.color_entity[1], - g_entity_globals.color_entity[2]); + auto buffer = u::buffer<128>(); + sprintf( buffer, "%g %g %g", g_entity_globals.color_entity[0], + g_entity_globals.color_entity[1], + g_entity_globals.color_entity[2] ); - Scene_EntitySetKeyValue_Selected("_color", buffer); + Scene_EntitySetKeyValue_Selected( "_color", buffer ); } } } } } -void Entity_setColour() -{ - if(GlobalSelectionSystem().countSelected() != 0) - { - bool normalize = false; - const scene::Path& path = GlobalSelectionSystem().ultimateSelected().path(); - Entity* entity = Node_getEntity(path.top()); - - if(entity != 0) - { - const char* strColor = entity->getKeyValue("_color"); - if(!string_empty(strColor)) - { - Vector3 rgb; - if (string_parse_vector3(strColor, rgb)) - { - g_entity_globals.color_entity = rgb; - } - } - - if( g_pGameDescription->mGameType == "doom3" ) - normalize = false; - - if(color_dialog(GTK_WIDGET(MainFrame_getWindow()), g_entity_globals.color_entity)) - { - if( normalize ) - NormalizeColor(g_entity_globals.color_entity); - - char buffer[128]; - sprintf(buffer, "%g %g %g", g_entity_globals.color_entity[0], - g_entity_globals.color_entity[1], - g_entity_globals.color_entity[2]); - - Scene_EntitySetKeyValue_Selected("_color", buffer); - } - } - } -} - -const char* misc_model_dialog(GtkWidget* parent) -{ - StringOutputStream buffer(1024); - - buffer << g_qeglobals.m_userGamePath.c_str() << "models/"; - - if(!file_readable(buffer.c_str())) - { - // just go to fsmain - buffer.clear(); - buffer << g_qeglobals.m_userGamePath.c_str() << "/"; - } - - const char *filename = file_dialog (parent, TRUE, "Choose Model", buffer.c_str(), ModelLoader::Name()); - if (filename != 0) - { - // use VFS to get the correct relative path - const char* relative = path_make_relative(filename, GlobalFileSystem().findRoot(filename)); - if(relative == filename) - { - globalOutputStream() << "WARNING: could not extract the relative path, using full path instead\n"; - } - return relative; - } - return 0; -} - -void LightRadiiImport(EntityCreator& self, bool value) -{ - self.setLightRadii(value); +void Entity_setColour(){ + if ( GlobalSelectionSystem().countSelected() != 0 ) { + bool normalize = false; + const scene::Path& path = GlobalSelectionSystem().ultimateSelected().path(); + Entity* entity = Node_getEntity( path.top() ); + + if ( entity != 0 ) { + const char* strColor = entity->getKeyValue( "_color" ); + if ( !string_empty( strColor ) ) { + Vector3 rgb; + if ( string_parse_vector3( strColor, rgb ) ) { + g_entity_globals.color_entity = rgb; + } + } + + if ( g_pGameDescription->mGameType == "doom3" ) { + normalize = false; + } + + if ( color_dialog( MainFrame_getWindow(), g_entity_globals.color_entity ) ) { + if ( normalize ) { + NormalizeColor( g_entity_globals.color_entity ); + } + + auto buffer = u::buffer<128>(); + sprintf( buffer, "%g %g %g", g_entity_globals.color_entity[0], + g_entity_globals.color_entity[1], + g_entity_globals.color_entity[2] ); + + Scene_EntitySetKeyValue_Selected( "_color", buffer ); + } + } + } +} + +const char* misc_model_dialog( ui::Widget parent ){ + StringOutputStream buffer( 1024 ); + + buffer << g_qeglobals.m_userGamePath.c_str() << "models/"; + + if ( !file_readable( buffer.c_str() ) ) { + // just go to fsmain + buffer.clear(); + buffer << g_qeglobals.m_userGamePath.c_str() << "/"; + } + + const char *filename = parent.file_dialog( TRUE, "Choose Model", buffer.c_str(), ModelLoader::Name() ); + if ( filename != 0 ) { + // use VFS to get the correct relative path + const char* relative = path_make_relative( filename, GlobalFileSystem().findRoot( filename ) ); + if ( relative == filename ) { + globalOutputStream() << "WARNING: could not extract the relative path, using full path instead\n"; + } + return relative; + } + return 0; +} + +void LightRadiiImport( EntityCreator& self, bool value ){ + self.setLightRadii( value ); } typedef ReferenceCaller1 LightRadiiImportCaller; -void LightRadiiExport(EntityCreator& self, const BoolImportCallback& importer) -{ - importer(self.getLightRadii()); +void LightRadiiExport( EntityCreator& self, const BoolImportCallback& importer ){ + importer( self.getLightRadii() ); } typedef ReferenceCaller1 LightRadiiExportCaller; -void Entity_constructPreferences(PreferencesPage& page) -{ - page.appendCheckBox( - "Show", "Light Radii", - LightRadiiImportCaller(GlobalEntityCreator()), - LightRadiiExportCaller(GlobalEntityCreator()) - ); +void Entity_constructPreferences( PreferencesPage& page ){ + page.appendCheckBox( + "Show", "Light Radii", + LightRadiiImportCaller( GlobalEntityCreator() ), + LightRadiiExportCaller( GlobalEntityCreator() ) + ); } -void Entity_constructPage(PreferenceGroup& group) -{ - PreferencesPage page(group.createPage("Entities", "Entity Display Preferences")); - Entity_constructPreferences(page); +void Entity_constructPage( PreferenceGroup& group ){ + PreferencesPage page( group.createPage( "Entities", "Entity Display Preferences" ) ); + Entity_constructPreferences( page ); } -void Entity_registerPreferencesPage() -{ - PreferencesDialog_addDisplayPage(FreeCaller1()); +void Entity_registerPreferencesPage(){ + PreferencesDialog_addDisplayPage( FreeCaller1() ); } -void Entity_constructMenu(GtkMenu* menu) -{ - create_menu_item_with_mnemonic(menu, "_Regroup", "GroupSelection"); - create_menu_item_with_mnemonic(menu, "_Ungroup", "UngroupSelection"); - create_menu_item_with_mnemonic(menu, "_Connect", "ConnectSelection"); - create_menu_item_with_mnemonic(menu, "_Select Color...", "EntityColor"); - create_menu_item_with_mnemonic(menu, "_Normalize Color...", "NormalizeColor"); +void Entity_constructMenu( ui::Menu menu ){ + create_menu_item_with_mnemonic( menu, "_Regroup", "GroupSelection" ); + create_menu_item_with_mnemonic( menu, "_Ungroup", "UngroupSelection" ); + create_menu_item_with_mnemonic( menu, "_Connect", "ConnectSelection" ); + create_menu_item_with_mnemonic( menu, "_KillConnect", "KillConnectSelection" ); + create_menu_item_with_mnemonic( menu, "_Select Color...", "EntityColor" ); + create_menu_item_with_mnemonic( menu, "_Normalize Color...", "NormalizeColor" ); } @@ -627,21 +584,19 @@ void Entity_constructMenu(GtkMenu* menu) #include "preferencesystem.h" #include "stringio.h" -void Entity_Construct() -{ - GlobalCommands_insert("EntityColor", FreeCaller(), Accelerator('K')); - GlobalCommands_insert("NormalizeColor", FreeCaller()); - GlobalCommands_insert("ConnectSelection", FreeCaller(), Accelerator('K', (GdkModifierType)GDK_CONTROL_MASK)); - GlobalCommands_insert("GroupSelection", FreeCaller()); - GlobalCommands_insert("UngroupSelection", FreeCaller()); +void Entity_Construct(){ + GlobalCommands_insert( "EntityColor", FreeCaller(), Accelerator( 'K' ) ); + GlobalCommands_insert( "NormalizeColor", FreeCaller() ); + GlobalCommands_insert( "ConnectSelection", FreeCaller(), Accelerator( 'K', (GdkModifierType)GDK_CONTROL_MASK ) ); + GlobalCommands_insert( "KillConnectSelection", FreeCaller(), Accelerator( 'K', (GdkModifierType)( GDK_SHIFT_MASK ) ) ); + GlobalCommands_insert( "GroupSelection", FreeCaller() ); + GlobalCommands_insert( "UngroupSelection", FreeCaller() ); - GlobalPreferenceSystem().registerPreference("SI_Colors5", Vector3ImportStringCaller(g_entity_globals.color_entity), Vector3ExportStringCaller(g_entity_globals.color_entity)); - GlobalPreferenceSystem().registerPreference("LastLightIntensity", IntImportStringCaller(g_iLastLightIntensity), IntExportStringCaller(g_iLastLightIntensity)); + GlobalPreferenceSystem().registerPreference( "SI_Colors5", Vector3ImportStringCaller( g_entity_globals.color_entity ), Vector3ExportStringCaller( g_entity_globals.color_entity ) ); + GlobalPreferenceSystem().registerPreference( "LastLightIntensity", IntImportStringCaller( g_iLastLightIntensity ), IntExportStringCaller( g_iLastLightIntensity ) ); - Entity_registerPreferencesPage(); + Entity_registerPreferencesPage(); } -void Entity_Destroy() -{ +void Entity_Destroy(){ } -