Added terrain editing tool.

This commit is contained in:
Justin Marshall
2026-05-28 17:15:52 -07:00
parent 05d547a27b
commit e4c87fd5a4
91 changed files with 21538 additions and 199 deletions
+175 -2
View File
@@ -34,6 +34,7 @@ If you have questions concerning this license or the applicable additional terms
#include "EditorMap.h"
#include "XYWnd.h"
#include "CamWnd.h"
#include "Terrain.h"
#include "OutlinerDlg.h"
#include "splines.h"
#include <GL/glu.h>
@@ -1099,6 +1100,19 @@ static const char* CAMWND_PROP_DECAL_EDITING = "QER_CamWnd_DecalEditing";
#define CAMWND_MENU_CMD_DECAL_SCALE_DOWN 62112
#define CAMWND_MENU_CMD_DECAL_ROTATE_CCW 62113
#define CAMWND_MENU_CMD_DECAL_ROTATE_CW 62114
#define CAMWND_MENU_CMD_TERRAIN_EDITING 62115
#define CAMWND_MENU_CMD_TERRAIN_CREATE 62116
#define CAMWND_MENU_CMD_TERRAIN_RADIUS_UP 62117
#define CAMWND_MENU_CMD_TERRAIN_RADIUS_DOWN 62118
#define CAMWND_MENU_CMD_TERRAIN_STRENGTH_UP 62119
#define CAMWND_MENU_CMD_TERRAIN_STRENGTH_DOWN 62120
#define CAMWND_MENU_CMD_TERRAIN_LAYERS 62121
#define CAMWND_MENU_CMD_PAINT_MODE 62122
#define CAMWND_MENU_CMD_PAINT_LAYER_BASE 62123
#define CAMWND_MENU_CMD_PAINT_LAYER_1 62123
#define CAMWND_MENU_CMD_PAINT_LAYER_2 62124
#define CAMWND_MENU_CMD_PAINT_LAYER_3 62125
#define CAMWND_MENU_CMD_PAINT_LAYER_4 62126
#define CAMWND_FILTER_HIDE_WORLD 0x00000001
#define CAMWND_FILTER_HIDE_PATCHES 0x00000002
@@ -1198,15 +1212,23 @@ static void CamWnd_GetMenuItemRect(HWND hWnd, int item, RECT& rect) {
rect.left = 86;
rect.right = 156;
}
else {
else if (item == 2) {
rect.left = 156;
rect.right = 236;
}
else if (item == 3) {
rect.left = 236;
rect.right = 326;
}
else {
rect.left = 326;
rect.right = 396;
}
}
static int CamWnd_MenuHitTest(HWND hWnd, int x, int y) {
RECT rect;
for (int i = 0; i < 3; i++) {
for (int i = 0; i < 5; i++) {
CamWnd_GetMenuItemRect(hWnd, i, rect);
if (x >= rect.left && x < rect.right && y >= rect.top && y < rect.bottom) {
return i;
@@ -1373,7 +1395,24 @@ static void CamWnd_ToggleCubicClipping(CCamWnd* cam) {
}
}
static void CamWnd_SelectTerrainPaintLayer(CCamWnd* cam, int layer) {
if (Terrain_NumTerrains() <= 0) {
Sys_Status("Create a terrain before painting\n", 0);
return;
}
Terrain_SetEditMode(true);
Terrain_SetPaintMode(true);
Terrain_SelectPaintLayer(layer);
CamWnd_RequestRedraw(cam);
}
static void CamWnd_HandleMenuCommand(CCamWnd* cam, int command) {
if (command >= CAMWND_MENU_CMD_PAINT_LAYER_BASE && command < CAMWND_MENU_CMD_PAINT_LAYER_BASE + 4) {
CamWnd_SelectTerrainPaintLayer(cam, command - CAMWND_MENU_CMD_PAINT_LAYER_BASE);
return;
}
switch (command) {
case CAMWND_MENU_CMD_REALTIME_LIGHTING:
CamWnd_ToggleRealtimeLighting(cam);
@@ -1396,6 +1435,45 @@ static void CamWnd_HandleMenuCommand(CCamWnd* cam, int command) {
case CAMWND_MENU_CMD_DECAL_ROTATE_CW:
CamWnd_RotateStencil(cam, 15.0f);
break;
case CAMWND_MENU_CMD_TERRAIN_EDITING:
Terrain_ToggleEditMode();
CamWnd_RequestRedraw(cam);
break;
case CAMWND_MENU_CMD_TERRAIN_CREATE:
Terrain_CreateDefaultAtCamera(cam);
CamWnd_RequestRedraw(cam);
break;
case CAMWND_MENU_CMD_TERRAIN_LAYERS:
if (Terrain_ShowLayersDialog(cam)) {
CamWnd_RequestRedraw(cam);
}
break;
case CAMWND_MENU_CMD_TERRAIN_RADIUS_UP:
Terrain_AdjustBrushRadius(1.25f);
CamWnd_RequestRedraw(cam);
break;
case CAMWND_MENU_CMD_TERRAIN_RADIUS_DOWN:
Terrain_AdjustBrushRadius(0.8f);
CamWnd_RequestRedraw(cam);
break;
case CAMWND_MENU_CMD_TERRAIN_STRENGTH_UP:
Terrain_AdjustBrushStrength(1.25f);
CamWnd_RequestRedraw(cam);
break;
case CAMWND_MENU_CMD_TERRAIN_STRENGTH_DOWN:
Terrain_AdjustBrushStrength(0.8f);
CamWnd_RequestRedraw(cam);
break;
case CAMWND_MENU_CMD_PAINT_MODE:
if (Terrain_NumTerrains() > 0) {
Terrain_SetEditMode(true);
Terrain_SetPaintMode(true);
CamWnd_RequestRedraw(cam);
}
else {
Sys_Status("Create a terrain before painting\n", 0);
}
break;
case CAMWND_MENU_CMD_SHOW_WORLD:
CamWnd_ToggleFilterBit(cam, CAMWND_FILTER_HIDE_WORLD);
break;
@@ -1483,6 +1561,69 @@ static void CamWnd_ShowDecalsMenu(HWND hWnd, CCamWnd* cam) {
}
}
static void CamWnd_ShowTerrainMenu(HWND hWnd, CCamWnd* cam) {
RECT itemRect;
POINT pt;
HMENU menu;
int command;
CamWnd_GetMenuItemRect(hWnd, 3, itemRect);
pt.x = itemRect.left;
pt.y = itemRect.bottom;
ClientToScreen(hWnd, &pt);
menu = CreatePopupMenu();
AppendMenu(menu, MF_STRING | (Terrain_IsEditMode() ? MF_CHECKED : 0), CAMWND_MENU_CMD_TERRAIN_EDITING, "Enable terrain editing (T)");
AppendMenu(menu, MF_STRING, CAMWND_MENU_CMD_TERRAIN_CREATE, "Create default terrain (Ctrl+T)");
UINT terrainFlags = MF_STRING | (Terrain_NumTerrains() > 0 ? 0 : MF_GRAYED);
AppendMenu(menu, terrainFlags, CAMWND_MENU_CMD_TERRAIN_LAYERS, "Terrain layers...");
AppendMenu(menu, MF_SEPARATOR, 0, NULL);
UINT toolFlags = terrainFlags;
AppendMenu(menu, toolFlags, CAMWND_MENU_CMD_TERRAIN_RADIUS_UP, "Increase brush radius (])");
AppendMenu(menu, toolFlags, CAMWND_MENU_CMD_TERRAIN_RADIUS_DOWN, "Decrease brush radius ([)");
AppendMenu(menu, toolFlags, CAMWND_MENU_CMD_TERRAIN_STRENGTH_UP, "Increase brush strength (+)");
AppendMenu(menu, toolFlags, CAMWND_MENU_CMD_TERRAIN_STRENGTH_DOWN, "Decrease brush strength (-)");
command = TrackPopupMenu(menu, TPM_RETURNCMD | TPM_LEFTALIGN | TPM_TOPALIGN, pt.x, pt.y, 0, hWnd, NULL);
DestroyMenu(menu);
if (command) {
CamWnd_HandleMenuCommand(cam, command);
}
}
static void CamWnd_ShowPaintMenu(HWND hWnd, CCamWnd* cam) {
RECT itemRect;
POINT pt;
HMENU menu;
int command;
CamWnd_GetMenuItemRect(hWnd, 4, itemRect);
pt.x = itemRect.left;
pt.y = itemRect.bottom;
ClientToScreen(hWnd, &pt);
const bool hasTerrain = Terrain_NumTerrains() > 0;
const UINT paintFlags = MF_STRING | (hasTerrain ? 0 : MF_GRAYED);
menu = CreatePopupMenu();
AppendMenu(menu, paintFlags | (Terrain_IsEditMode() && Terrain_IsPaintMode() ? MF_CHECKED : 0), CAMWND_MENU_CMD_PAINT_MODE, "Paint mode (P)");
AppendMenu(menu, MF_SEPARATOR, 0, NULL);
for (int layer = 0; layer < 4; layer++) {
UINT layerFlags = paintFlags;
if (Terrain_GetPaintLayer() == layer) {
layerFlags |= MF_CHECKED;
}
AppendMenu(menu, layerFlags, CAMWND_MENU_CMD_PAINT_LAYER_BASE + layer, va("Paint layer %i (%i)", layer + 1, layer + 1));
}
command = TrackPopupMenu(menu, TPM_RETURNCMD | TPM_LEFTALIGN | TPM_TOPALIGN, pt.x, pt.y, 0, hWnd, NULL);
DestroyMenu(menu);
if (command) {
CamWnd_HandleMenuCommand(cam, command);
}
}
static void CamWnd_ShowFiltersMenu(HWND hWnd, CCamWnd* cam) {
RECT itemRect;
POINT pt;
@@ -1531,6 +1672,12 @@ static void CamWnd_ShowTopMenu(HWND hWnd, int item) {
else if (item == 2) {
CamWnd_ShowDecalsMenu(hWnd, cam);
}
else if (item == 3) {
CamWnd_ShowTerrainMenu(hWnd, cam);
}
else if (item == 4) {
CamWnd_ShowPaintMenu(hWnd, cam);
}
}
static void CamWnd_RegisterMenuBarClass() {
@@ -3096,6 +3243,12 @@ static LRESULT CALLBACK CamWnd_MenuBarProc(HWND hWnd, UINT uMsg, WPARAM wParam,
CamWnd_GetMenuItemRect(hWnd, 2, itemRect);
RoundRect(hDC, itemRect.left + 3, itemRect.top + 2, itemRect.right - 3, itemRect.bottom - 2, 6, 6);
DrawText(hDC, "Decals", -1, &itemRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
CamWnd_GetMenuItemRect(hWnd, 3, itemRect);
RoundRect(hDC, itemRect.left + 3, itemRect.top + 2, itemRect.right - 3, itemRect.bottom - 2, 6, 6);
DrawText(hDC, "Terrain", -1, &itemRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
CamWnd_GetMenuItemRect(hWnd, 4, itemRect);
RoundRect(hDC, itemRect.left + 3, itemRect.top + 2, itemRect.right - 3, itemRect.bottom - 2, 6, 6);
DrawText(hDC, "Paint", -1, &itemRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
::SelectObject(hDC, oldPen);
::SelectObject(hDC, oldBrush);
::DeleteObject(borderPen);
@@ -3207,6 +3360,7 @@ INT_PTR WINAPI CamWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (cam) {
CamWnd_FaceExtrudeEnd(cam, false);
CamWnd_GizmoEnd(cam, false);
Terrain_CancelStroke();
CameraNav_Stop(cam);
}
SendMessage(hWnd, WM_NCACTIVATE, FALSE, 0);
@@ -3289,6 +3443,9 @@ void CCamWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
Map_DeleteSelectedDecal();
return;
}
if (Terrain_HandleKeyDown(this, nChar)) {
return;
}
if (CameraNav_HandleKeyDown(this, nChar)) {
return;
}
@@ -3303,6 +3460,9 @@ void CCamWnd::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) {
if (CamWnd_HandleDecalTransformChar(this, nChar)) {
return;
}
if (Terrain_HandleChar(this, nChar)) {
return;
}
CWnd::OnChar(nChar, nRepCnt, nFlags);
}
@@ -3347,6 +3507,7 @@ void CCamWnd::SetXYFriend(CXYWnd* pWnd) {
void CCamWnd::OnDestroy() {
CamWnd_FaceExtrudeEnd(this, false);
CamWnd_GizmoEnd(this, false);
Terrain_CancelStroke();
CamWnd_ClearDecalPreview(this);
CamWnd_DestroyMenuBar(this);
CWnd::OnDestroy();
@@ -3370,6 +3531,11 @@ void CCamWnd::OnMouseMove(UINT nFlags, CPoint point) {
CRect r;
GetClientRect(r);
if (Terrain_MouseMove(this, point, nFlags)) {
m_ptLastCursor = point;
return;
}
if (GetCapture() != this) {
CamWnd_UpdateDecalPreview(this, point);
}
@@ -3428,6 +3594,9 @@ void CCamWnd::OnLButtonDown(UINT nFlags, CPoint point) {
Sys_UpdateWindows(W_ALL);
return;
}
if (Terrain_LButtonDown(this, point, nFlags)) {
return;
}
if ((nFlags & MK_CONTROL) && (nFlags & MK_SHIFT) && CamWnd_FaceExtrudeBegin(this, point)) {
return;
}
@@ -3448,6 +3617,9 @@ void CCamWnd::OnLButtonDown(UINT nFlags, CPoint point) {
=======================================================================================================================
*/
void CCamWnd::OnLButtonUp(UINT nFlags, CPoint point) {
if (Terrain_LButtonUp(this, point, nFlags)) {
return;
}
if (CamWnd_GizmoIsActive(this)) {
CamWnd_GizmoMouseMove(this, point, nFlags);
CamWnd_GizmoEnd(this, true);
@@ -4448,6 +4620,7 @@ void CCamWnd::Cam_Draw() {
CamWnd_DrawActiveBrushes(this, renderMode, entityMode, brushFilter);
CamWnd_DrawRadiantLightFrustums(this);
Terrain_DrawCam(this);
//glDepthMask ( 1 ); // Ok, write now