]> de.git.xonotic.org Git - xonotic/netradiant.git/commitdiff
new command: regroup entities.
authordivverent <divverent@61c419a2-8eb2-4b30-bcec-8cead039b335>
Fri, 2 Jan 2009 08:40:46 +0000 (08:40 +0000)
committerdivverent <divverent@61c419a2-8eb2-4b30-bcec-8cead039b335>
Fri, 2 Jan 2009 08:40:46 +0000 (08:40 +0000)
Moves all selected brushes into the selected entity.
Usage:

- Select brush from entity
- Hit Ctrl-Alt-E
- Select some other brush
- Regroup

The other brush will get added to the entity.

- Select brush from entity
- Regroup

The brush will get removed from the entity, and moved to worldspawn.

git-svn-id: svn://svn.icculus.org/netradiant/trunk@147 61c419a2-8eb2-4b30-bcec-8cead039b335

radiant/commands.cpp
radiant/entity.cpp
tools/quake3/q3map2/map.c

index cee1711747ab747d47fae01b1b244779f8d38499..03daeea566930320b3bffdfcac6ab0d9c2216d39 100644 (file)
@@ -359,7 +359,7 @@ public:
 
       // strBuff has been cleaned of it's modifiers .. switch between a regular key and a virtual one
       // based on length
-      if(keyEnd - value == 1 && std::isalpha(value[0])) // most often case.. deal with first
+      if(keyEnd - value == 1 && std::isalnum(value[0])) // most often case.. deal with first
       {
         accelerator.key = std::toupper(value[0]);
         ++m_count;
index c2a31091b1b07556d12b5ea21102444a597eb23a..7a08d0980c871bf2dc6bd8c05ad4ae5b28b721da 100644 (file)
@@ -156,6 +156,88 @@ void Entity_ungroupSelected()
 }
 
 
+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;
+    }
+  }
+};
+
+class EntityGroupSelected : public scene::Graph::Walker
+{
+  NodeSmartReference group;
+public:
+  EntityGroupSelected(const scene::Path &p): group(p.top().get())
+  {
+  }
+  bool pre(const scene::Path& path, scene::Instance& instance) const
+  {
+    return true;
+  }
+  void post(const scene::Path& path, scene::Instance& instance) const
+  {
+    if(Instance_getSelectable(instance)->isSelected())
+    { 
+         Entity* entity = Node_getEntity(path.top());
+         if(entity == 0 && Node_isPrimitive(path.top()))
+         {
+                 NodeSmartReference child(path.top().get());
+                 NodeSmartReference parent(path.parent().get());
+
+                 Node_getTraversable(parent)->erase(child);
+                 Node_getTraversable(group)->insert(child);
+
+                 if(Node_getTraversable(parent)->empty() && path.size() >= 3 && parent != Map_FindOrInsertWorldspawn(g_map))
+                 {
+                         NodeSmartReference parentparent(path[path.size() - 3].get());
+                         Node_getTraversable(parentparent)->erase(parent);
+                 }
+         }
+    }
+  }
+};
+
+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)));
+
+  EntityFindSelected fse;
+  GlobalSceneGraph().traverse(fse);
+  if(fse.groupPath)
+  {
+         GlobalSceneGraph().traverse(EntityGroupSelected(*fse.groupPath));
+  }
+  else
+  {
+         GlobalSceneGraph().traverse(EntityGroupSelected(world_path));
+  }
+}
+
+
 
 void Entity_connectSelected()
 {
@@ -454,6 +536,7 @@ void Entity_registerPreferencesPage()
 
 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");
@@ -468,6 +551,7 @@ void Entity_Construct()
 {
   GlobalCommands_insert("EntityColor", FreeCaller<Entity_setColour>(), Accelerator('K'));
   GlobalCommands_insert("ConnectSelection", FreeCaller<Entity_connectSelected>(), Accelerator('K', (GdkModifierType)GDK_CONTROL_MASK));
+  GlobalCommands_insert("GroupSelection", FreeCaller<Entity_groupSelected>());
   GlobalCommands_insert("UngroupSelection", FreeCaller<Entity_ungroupSelected>());
 
   GlobalPreferenceSystem().registerPreference("SI_Colors5", Vector3ImportStringCaller(g_entity_globals.color_entity), Vector3ExportStringCaller(g_entity_globals.color_entity));
index 18ab6b216fa8ee0066baa27f95f47aa19214604b..82d7d2bf3b4cbb4d39c466cc44b5e9542c533953 100644 (file)
@@ -599,6 +599,9 @@ static void MergeOrigin(entity_t *ent, vec3_t origin)
 {
        vec3_t adjustment;
 
+       /* we have not parsed the brush completely yet... */
+       GetVectorForKey( ent, "origin", ent->origin );
+
        VectorMA(origin, -1, ent->originbrush_origin, adjustment);
        VectorAdd(adjustment, ent->origin, ent->origin);
        VectorCopy(origin, ent->originbrush_origin);
@@ -624,6 +627,9 @@ brush_t *FinishBrush( void )
                char    string[ 32 ];
                vec3_t  origin;
 
+               Sys_Printf( "Entity %i, Brush %i: origin brush detected\n", 
+                               mapEnt->mapEntityNum, entitySourceBrushes );
+
                if( numEntities == 1 )
                {
                        Sys_Printf( "Entity %i, Brush %i: origin brushes not allowed in world\n", 
@@ -1079,11 +1085,17 @@ adds them to the world's brush list
 (used by func_group)
 */
 
+void AdjustBrushesForOrigin( entity_t *ent );
 void MoveBrushesToWorld( entity_t *ent )
 {
        brush_t         *b, *next;
        parseMesh_t     *pm;
 
+       /* we need to undo the common/origin adjustment, and instead shift them by the entity key origin */
+       VectorScale(ent->origin, -1, ent->originbrush_origin);
+       Sys_Printf("func_group: adjusting by %f %f %f\n", ent->originbrush_origin[0], ent->originbrush_origin[1], ent->originbrush_origin[2]);
+       AdjustBrushesForOrigin(ent);
+       VectorClear(ent->originbrush_origin);
        
        /* move brushes */
        for( b = ent->brushes; b != NULL; b = next )
@@ -1146,7 +1158,8 @@ void AdjustBrushesForOrigin( entity_t *ent )
        brush_t         *b;
        parseMesh_t     *p;
        
-       
+       Sys_Printf("origin: adjusting by %f %f %f\n", ent->originbrush_origin[0], ent->originbrush_origin[1], ent->originbrush_origin[2]);
+
        /* walk brush list */
        for( b = ent->brushes; b != NULL; b = b->next )
        {
@@ -1157,7 +1170,7 @@ void AdjustBrushesForOrigin( entity_t *ent )
                        s = &b->sides[ i ];
                        
                        /* offset side plane */
-                       newdist = mapplanes[ s->planenum ].dist - DotProduct( mapplanes[ s->planenum ].normal, ent->origin );
+                       newdist = mapplanes[ s->planenum ].dist - DotProduct( mapplanes[ s->planenum ].normal, ent->originbrush_origin );
                        
                        /* find a new plane */
                        s->planenum = FindFloatPlane( mapplanes[ s->planenum ].normal, newdist, 0, NULL );
@@ -1171,7 +1184,7 @@ void AdjustBrushesForOrigin( entity_t *ent )
        for( p = ent->patches; p != NULL; p = p->next )
        {
                for( i = 0; i < (p->mesh.width * p->mesh.height); i++ )
-                       VectorSubtract( p->mesh.verts[ i ].xyz, ent->origin, p->mesh.verts[ i ].xyz );
+                       VectorSubtract( p->mesh.verts[ i ].xyz, ent->originbrush_origin, p->mesh.verts[ i ].xyz );
        }
 }
 
@@ -1595,7 +1608,7 @@ static qboolean ParseMapEntity( qboolean onlyLights )
        
        /* get entity origin and adjust brushes */
        GetVectorForKey( mapEnt, "origin", mapEnt->origin );
-       if( mapEnt->origin[ 0 ] || mapEnt->origin[ 1 ] || mapEnt->origin[ 2 ] )
+       if( mapEnt->originbrush_origin[ 0 ] || mapEnt->originbrush_origin[ 1 ] || mapEnt->originbrush_origin[ 2 ] )
                AdjustBrushesForOrigin( mapEnt );
 
        /* group_info entities are just for editor grouping (fixme: leak!) */