Added the ability to hide/show entities in the outliner

This commit is contained in:
Justin Marshall
2026-05-06 15:04:39 -07:00
parent c1defbad40
commit 7c5ddb4336
3 changed files with 557 additions and 7 deletions
+168 -2
View File
@@ -33,6 +33,7 @@ If you have questions concerning this license or the applicable additional terms
#include "Radiant.h"
#include "XYWnd.h"
#include "CamWnd.h"
#include "OutlinerDlg.h"
#include "splines.h"
#include <GL/glu.h>
@@ -826,6 +827,163 @@ static void CameraNav_DrawOverlay(CCamWnd* cam) {
}
/*
========================
Outliner-aware entity target/path lines
The original DrawPathLines() does not know about the outliner visibility list.
When no entity is hidden, keep using the original function so the normal editor
style is unchanged. When something is hidden, draw a filtered equivalent that
skips links where either endpoint is hidden.
========================
*/
static bool CamWnd_IsTargetLineKey(const char* key) {
if (key == NULL || key[0] == '\0') {
return false;
}
if (idStr::Icmp(key, "targetname") == 0) {
return false;
}
if (idStr::Icmp(key, "next") == 0) {
return true;
}
return idStr::Icmpn(key, "target", 6) == 0;
}
static bool CamWnd_EntityNameMatches(entity_t* ent, const char* name) {
if (ent == NULL || name == NULL || name[0] == '\0') {
return false;
}
const char* entName = ValueForKey(ent, "name");
if (entName != NULL && entName[0] != '\0' && idStr::Icmp(entName, name) == 0) {
return true;
}
const char* targetName = ValueForKey(ent, "targetname");
if (targetName != NULL && targetName[0] != '\0' && idStr::Icmp(targetName, name) == 0) {
return true;
}
return false;
}
static bool CamWnd_GetEntityLinePoint(entity_t* ent, idVec3& point) {
if (ent == NULL) {
return false;
}
if (GetVectorForKey(ent, "origin", point)) {
return true;
}
idBounds bounds;
bounds.Clear();
bool haveBounds = false;
for (brush_t* brush = ent->brushes.onext; brush != NULL && brush != &ent->brushes; brush = brush->onext) {
bounds.AddPoint(brush->mins);
bounds.AddPoint(brush->maxs);
haveBounds = true;
}
if (haveBounds) {
point = bounds.GetCenter();
return true;
}
return false;
}
static void CamWnd_DrawVisibleTargetLine(entity_t* source, entity_t* target) {
if (source == NULL || target == NULL || source == target) {
return;
}
if (!Outliner_IsEntityVisible(source) || !Outliner_IsEntityVisible(target)) {
return;
}
idVec3 start;
idVec3 end;
if (!CamWnd_GetEntityLinePoint(source, start) || !CamWnd_GetEntityLinePoint(target, end)) {
return;
}
glVertex3fv(start.ToFloatPtr());
glVertex3fv(end.ToFloatPtr());
}
static void CamWnd_DrawVisibleTargetLinesForName(entity_t* source, const char* targetName) {
if (targetName == NULL || targetName[0] == '\0') {
return;
}
if (world_entity != NULL && CamWnd_EntityNameMatches(world_entity, targetName)) {
CamWnd_DrawVisibleTargetLine(source, world_entity);
}
if (entities.next == NULL) {
return;
}
for (entity_t* target = entities.next; target != &entities; target = target->next) {
if (CamWnd_EntityNameMatches(target, targetName)) {
CamWnd_DrawVisibleTargetLine(source, target);
}
}
}
static void CamWnd_DrawVisibleTargetLinesForEntity(entity_t* source) {
if (source == NULL || !Outliner_IsEntityVisible(source)) {
return;
}
const int numKeys = source->epairs.GetNumKeyVals();
for (int keyIndex = 0; keyIndex < numKeys; keyIndex++) {
const idKeyValue* kv = source->epairs.GetKeyVal(keyIndex);
if (kv == NULL) {
continue;
}
if (!CamWnd_IsTargetLineKey(kv->GetKey().c_str())) {
continue;
}
CamWnd_DrawVisibleTargetLinesForName(source, kv->GetValue().c_str());
}
}
static void CamWnd_DrawVisiblePathLines() {
if (!Outliner_HasHiddenEntities()) {
DrawPathLines();
return;
}
glPushAttrib(GL_CURRENT_BIT);
globalImages->BindNull();
glDisable(GL_BLEND);
glLineWidth(1.0f);
glColor3f(1.0f, 0.75f, 0.0f);
glBegin(GL_LINES);
if (world_entity != NULL) {
CamWnd_DrawVisibleTargetLinesForEntity(world_entity);
}
if (entities.next != NULL) {
for (entity_t* source = entities.next; source != &entities; source = source->next) {
CamWnd_DrawVisibleTargetLinesForEntity(source);
}
}
glEnd();
glPopAttrib();
}
/*
========================
Camera window embedded menu bar
@@ -1213,7 +1371,15 @@ static void CamWnd_UpdateRuntimeState(CCamWnd* cam, bool renderMode, bool rebuil
}
static bool CamWnd_MenuFilterBrush(CCamWnd* cam, brush_t* brush) {
if (!cam || !brush) {
if (!brush) {
return false;
}
if (brush->owner != NULL && !Outliner_IsEntityVisible(brush->owner)) {
return true;
}
if (!cam) {
return false;
}
@@ -2475,7 +2641,7 @@ void CCamWnd::Cam_Draw() {
// draw pointfile
glEnable(GL_DEPTH_TEST);
DrawPathLines();
CamWnd_DrawVisiblePathLines();
if (g_qeglobals.d_pointfile_display_list) {
Pointfile_Draw();