|
|
|
@@ -120,6 +120,9 @@ struct cameraNavState_t {
|
|
|
|
|
static cameraNavConfig_t s_cameraNavConfig;
|
|
|
|
|
static cameraNavState_t s_cameraNavState;
|
|
|
|
|
static void CameraNav_GetIniPath(char* path, int pathSize);
|
|
|
|
|
static bool s_camWndDecalPreviewValid = false;
|
|
|
|
|
static HWND s_camWndDecalPreviewOwner = NULL;
|
|
|
|
|
static renderWorldDecal_t s_camWndDecalPreview;
|
|
|
|
|
|
|
|
|
|
static bool CamWnd_DecalPlacementEnabled() {
|
|
|
|
|
char iniPath[MAX_PATH];
|
|
|
|
@@ -135,13 +138,31 @@ static float CamWnd_DecalFloat(const char* key, const char* defaultValue) {
|
|
|
|
|
return (float)atof(value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CamWnd_DecalMaterial(idStr& material) {
|
|
|
|
|
static float s_camWndDecalPreviewRotation = 0.0f;
|
|
|
|
|
|
|
|
|
|
static void CamWnd_RotateDecalBasis(renderWorldDecal_t& decal, float degrees) {
|
|
|
|
|
const float radians = degrees * idMath::M_DEG2RAD;
|
|
|
|
|
const float s = sin(radians);
|
|
|
|
|
const float c = cos(radians);
|
|
|
|
|
const idVec3 oldU = decal.axisU;
|
|
|
|
|
const idVec3 oldV = decal.axisV;
|
|
|
|
|
decal.axisU = oldU * c + oldV * s;
|
|
|
|
|
decal.axisV = oldV * c - oldU * s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool CamWnd_DecalMaterial(idStr& material) {
|
|
|
|
|
const char* selected = g_qeglobals.d_texturewin.texdef.name;
|
|
|
|
|
if (selected && selected[0] && selected[0] != '(') {
|
|
|
|
|
material = selected;
|
|
|
|
|
return;
|
|
|
|
|
if (!selected || !selected[0] || selected[0] == '(') {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
material = "textures/decals/default";
|
|
|
|
|
|
|
|
|
|
const idMaterial* mat = declManager->FindMaterial(selected, false);
|
|
|
|
|
if (!mat || mat->TestMaterialFlag(MF_DEFAULTED)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
material = selected;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CamWnd_DecalColorFromSelectedMaterial(const idStr& material, idVec4& color) {
|
|
|
|
@@ -1074,6 +1095,10 @@ static const char* CAMWND_PROP_DECAL_EDITING = "QER_CamWnd_DecalEditing";
|
|
|
|
|
#define CAMWND_MENU_CMD_SHOW_TRIGGER_BRUSHES 62108
|
|
|
|
|
#define CAMWND_MENU_CMD_CUBIC_CLIPPING 62109
|
|
|
|
|
#define CAMWND_MENU_CMD_DECAL_EDITING 62110
|
|
|
|
|
#define CAMWND_MENU_CMD_DECAL_SCALE_UP 62111
|
|
|
|
|
#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_FILTER_HIDE_WORLD 0x00000001
|
|
|
|
|
#define CAMWND_FILTER_HIDE_PATCHES 0x00000002
|
|
|
|
@@ -1232,6 +1257,8 @@ static void CamWnd_ToggleRealtimeLighting(CCamWnd* cam) {
|
|
|
|
|
CamWnd_SetRealtimeLighting(cam, !CamWnd_RealtimeLightingEnabled(cam));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CamWnd_ClearDecalPreview(CCamWnd* cam);
|
|
|
|
|
|
|
|
|
|
static bool CamWnd_DecalEditingEnabled(CCamWnd* cam) {
|
|
|
|
|
if (!cam || !cam->GetSafeHwnd()) {
|
|
|
|
|
return false;
|
|
|
|
@@ -1243,6 +1270,9 @@ static void CamWnd_SetDecalEditing(CCamWnd* cam, bool enabled) {
|
|
|
|
|
if (!cam || !cam->GetSafeHwnd()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!enabled) {
|
|
|
|
|
CamWnd_ClearDecalPreview(cam);
|
|
|
|
|
}
|
|
|
|
|
CamWnd_SetIntProp(cam->GetSafeHwnd(), CAMWND_PROP_DECAL_EDITING, enabled ? 1 : 0);
|
|
|
|
|
CamWnd_RequestRedraw(cam);
|
|
|
|
|
}
|
|
|
|
@@ -1251,6 +1281,74 @@ static void CamWnd_ToggleDecalEditing(CCamWnd* cam) {
|
|
|
|
|
CamWnd_SetDecalEditing(cam, !CamWnd_DecalEditingEnabled(cam));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CamWnd_ClearDecalPreview(CCamWnd* cam = NULL) {
|
|
|
|
|
const bool wasValid = s_camWndDecalPreviewValid;
|
|
|
|
|
if (!cam || s_camWndDecalPreviewOwner == cam->GetSafeHwnd()) {
|
|
|
|
|
s_camWndDecalPreviewValid = false;
|
|
|
|
|
s_camWndDecalPreviewOwner = NULL;
|
|
|
|
|
if (wasValid && cam && cam->GetSafeHwnd()) {
|
|
|
|
|
cam->InvalidateRect(NULL, FALSE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CamWnd_ScaleSelectedDecal(CCamWnd* cam, float scale) {
|
|
|
|
|
if (Map_ScaleSelectedDecal(scale)) {
|
|
|
|
|
CamWnd_RequestRedraw(cam);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CamWnd_RotateStencil(CCamWnd* cam, float degrees) {
|
|
|
|
|
if (Map_GetSelectedDecal() >= 0) {
|
|
|
|
|
if (Map_RotateSelectedDecal(degrees)) {
|
|
|
|
|
CamWnd_RequestRedraw(cam);
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s_camWndDecalPreviewRotation += degrees;
|
|
|
|
|
if (s_camWndDecalPreviewRotation >= 360.0f || s_camWndDecalPreviewRotation <= -360.0f) {
|
|
|
|
|
s_camWndDecalPreviewRotation = fmod(s_camWndDecalPreviewRotation, 360.0f);
|
|
|
|
|
}
|
|
|
|
|
CamWnd_ClearDecalPreview(cam);
|
|
|
|
|
if (cam && cam->GetSafeHwnd()) {
|
|
|
|
|
CamWnd_RequestRedraw(cam);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool CamWnd_HandleDecalTransformChar(CCamWnd* cam, UINT nChar) {
|
|
|
|
|
if (!CamWnd_DecalEditingEnabled(cam)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (nChar) {
|
|
|
|
|
case '+':
|
|
|
|
|
case '=':
|
|
|
|
|
if (Map_GetSelectedDecal() >= 0) {
|
|
|
|
|
CamWnd_ScaleSelectedDecal(cam, 1.25f);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case '-':
|
|
|
|
|
case '_':
|
|
|
|
|
if (Map_GetSelectedDecal() >= 0) {
|
|
|
|
|
CamWnd_ScaleSelectedDecal(cam, 0.8f);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'q':
|
|
|
|
|
case 'Q':
|
|
|
|
|
CamWnd_RotateStencil(cam, -15.0f);
|
|
|
|
|
return true;
|
|
|
|
|
case 'e':
|
|
|
|
|
case 'E':
|
|
|
|
|
CamWnd_RotateStencil(cam, 15.0f);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CamWnd_ToggleFilterBit(CCamWnd* cam, int bit) {
|
|
|
|
|
int mask = CamWnd_GetFilterMask(cam);
|
|
|
|
|
mask ^= bit;
|
|
|
|
@@ -1286,6 +1384,18 @@ static void CamWnd_HandleMenuCommand(CCamWnd* cam, int command) {
|
|
|
|
|
case CAMWND_MENU_CMD_DECAL_EDITING:
|
|
|
|
|
CamWnd_ToggleDecalEditing(cam);
|
|
|
|
|
break;
|
|
|
|
|
case CAMWND_MENU_CMD_DECAL_SCALE_UP:
|
|
|
|
|
CamWnd_ScaleSelectedDecal(cam, 1.25f);
|
|
|
|
|
break;
|
|
|
|
|
case CAMWND_MENU_CMD_DECAL_SCALE_DOWN:
|
|
|
|
|
CamWnd_ScaleSelectedDecal(cam, 0.8f);
|
|
|
|
|
break;
|
|
|
|
|
case CAMWND_MENU_CMD_DECAL_ROTATE_CCW:
|
|
|
|
|
CamWnd_RotateStencil(cam, -15.0f);
|
|
|
|
|
break;
|
|
|
|
|
case CAMWND_MENU_CMD_DECAL_ROTATE_CW:
|
|
|
|
|
CamWnd_RotateStencil(cam, 15.0f);
|
|
|
|
|
break;
|
|
|
|
|
case CAMWND_MENU_CMD_SHOW_WORLD:
|
|
|
|
|
CamWnd_ToggleFilterBit(cam, CAMWND_FILTER_HIDE_WORLD);
|
|
|
|
|
break;
|
|
|
|
@@ -1356,6 +1466,14 @@ static void CamWnd_ShowDecalsMenu(HWND hWnd, CCamWnd* cam) {
|
|
|
|
|
|
|
|
|
|
menu = CreatePopupMenu();
|
|
|
|
|
AppendMenu(menu, MF_STRING | (CamWnd_DecalEditingEnabled(cam) ? MF_CHECKED : 0), CAMWND_MENU_CMD_DECAL_EDITING, "Enable decal editing");
|
|
|
|
|
AppendMenu(menu, MF_SEPARATOR, 0, NULL);
|
|
|
|
|
UINT scaleFlags = MF_STRING | (Map_GetSelectedDecal() >= 0 ? 0 : MF_GRAYED);
|
|
|
|
|
AppendMenu(menu, scaleFlags, CAMWND_MENU_CMD_DECAL_SCALE_UP, "Scale selected up (+)");
|
|
|
|
|
AppendMenu(menu, scaleFlags, CAMWND_MENU_CMD_DECAL_SCALE_DOWN, "Scale selected down (-)");
|
|
|
|
|
AppendMenu(menu, MF_SEPARATOR, 0, NULL);
|
|
|
|
|
UINT rotateFlags = MF_STRING | (CamWnd_DecalEditingEnabled(cam) ? 0 : MF_GRAYED);
|
|
|
|
|
AppendMenu(menu, rotateFlags, CAMWND_MENU_CMD_DECAL_ROTATE_CCW, "Rotate stencil left (Q)");
|
|
|
|
|
AppendMenu(menu, rotateFlags, CAMWND_MENU_CMD_DECAL_ROTATE_CW, "Rotate stencil right (E)");
|
|
|
|
|
|
|
|
|
|
command = TrackPopupMenu(menu, TPM_RETURNCMD | TPM_LEFTALIGN | TPM_TOPALIGN, pt.x, pt.y, 0, hWnd, NULL);
|
|
|
|
|
DestroyMenu(menu);
|
|
|
|
@@ -1816,29 +1934,24 @@ static void CamWnd_FaceExtrudeBuildRay(CCamWnd* cam, const CPoint& point, idVec3
|
|
|
|
|
dir.Normalize();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool CamWnd_DecalClick(CCamWnd* cam, const CPoint& point, UINT nFlags) {
|
|
|
|
|
if (!CamWnd_DecalEditingEnabled(cam) || cam == NULL) {
|
|
|
|
|
static bool CamWnd_BuildDecalAtPoint(CCamWnd* cam, const CPoint& point, renderWorldDecal_t& decal, const char** hitSource) {
|
|
|
|
|
if (cam == NULL) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
idVec3 dir;
|
|
|
|
|
CamWnd_FaceExtrudeBuildRay(cam, point, dir);
|
|
|
|
|
|
|
|
|
|
if (nFlags & MK_SHIFT) {
|
|
|
|
|
Map_SelectDecalByRay(cam->Camera().origin, dir);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
idVec3 hitPoint;
|
|
|
|
|
idVec3 hitNormal;
|
|
|
|
|
float hitDist = HUGE_DISTANCE;
|
|
|
|
|
bool hitBrush = false;
|
|
|
|
|
const char* hitSource = "none";
|
|
|
|
|
const char* localHitSource = "none";
|
|
|
|
|
|
|
|
|
|
qertrace_t trace = Test_Ray(cam->Camera().origin, dir, 0);
|
|
|
|
|
if (trace.brush != NULL && trace.face != NULL && trace.dist > 0.0f && trace.dist < hitDist) {
|
|
|
|
|
hitBrush = true;
|
|
|
|
|
hitSource = "brush";
|
|
|
|
|
localHitSource = "brush";
|
|
|
|
|
hitDist = trace.dist;
|
|
|
|
|
hitPoint = cam->Camera().origin + dir * trace.dist;
|
|
|
|
|
hitNormal = trace.face->plane.Normal();
|
|
|
|
@@ -1850,7 +1963,7 @@ static bool CamWnd_DecalClick(CCamWnd* cam, const CPoint& point, UINT nFlags) {
|
|
|
|
|
if (g_qeglobals.rw->Trace(modelTrace, cam->Camera().origin, end, 0.0f, false, false)) {
|
|
|
|
|
float modelDist = (modelTrace.point - cam->Camera().origin) * dir;
|
|
|
|
|
if (!hitBrush && modelDist > 0.0f && modelDist < hitDist) {
|
|
|
|
|
hitSource = "render";
|
|
|
|
|
localHitSource = "render";
|
|
|
|
|
hitDist = modelDist;
|
|
|
|
|
hitPoint = modelTrace.point;
|
|
|
|
|
hitNormal = modelTrace.normal;
|
|
|
|
@@ -1859,11 +1972,12 @@ static bool CamWnd_DecalClick(CCamWnd* cam, const CPoint& point, UINT nFlags) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (hitDist <= 0.0f || hitDist >= HUGE_DISTANCE || hitNormal.LengthSqr() < 0.0001f) {
|
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
renderWorldDecal_t decal;
|
|
|
|
|
CamWnd_DecalMaterial(decal.material);
|
|
|
|
|
if (!CamWnd_DecalMaterial(decal.material)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
CamWnd_DecalColorFromSelectedMaterial(decal.material, decal.color);
|
|
|
|
|
decal.origin = hitPoint;
|
|
|
|
|
decal.normal = hitNormal;
|
|
|
|
@@ -1875,9 +1989,147 @@ static bool CamWnd_DecalClick(CCamWnd* cam, const CPoint& point, UINT nFlags) {
|
|
|
|
|
decal.axisU = decal.normal.Cross(cam->Camera().vright);
|
|
|
|
|
}
|
|
|
|
|
decal.axisV = decal.normal.Cross(decal.axisU);
|
|
|
|
|
CamWnd_RotateDecalBasis(decal, s_camWndDecalPreviewRotation);
|
|
|
|
|
decal.size = CamWnd_DecalFloat("size", "64");
|
|
|
|
|
decal.depth = CamWnd_DecalFloat("depth", "8");
|
|
|
|
|
decal.opacity = CamWnd_DecalFloat("opacity", "1");
|
|
|
|
|
if (hitSource) {
|
|
|
|
|
*hitSource = localHitSource;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CamWnd_UpdateDecalPreview(CCamWnd* cam, const CPoint& point) {
|
|
|
|
|
if (!CamWnd_DecalEditingEnabled(cam) || cam == NULL || !cam->GetSafeHwnd()) {
|
|
|
|
|
CamWnd_ClearDecalPreview(cam);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (Map_GetSelectedDecal() >= 0) {
|
|
|
|
|
CamWnd_ClearDecalPreview(cam);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
renderWorldDecal_t preview;
|
|
|
|
|
if (!CamWnd_BuildDecalAtPoint(cam, point, preview, NULL)) {
|
|
|
|
|
CamWnd_ClearDecalPreview(cam);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s_camWndDecalPreview = preview;
|
|
|
|
|
s_camWndDecalPreviewOwner = cam->GetSafeHwnd();
|
|
|
|
|
s_camWndDecalPreviewValid = true;
|
|
|
|
|
cam->InvalidateRect(NULL, FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool CamWnd_HasDecalPreview(CCamWnd* cam) {
|
|
|
|
|
return cam && cam->GetSafeHwnd() && s_camWndDecalPreviewValid && s_camWndDecalPreviewOwner == cam->GetSafeHwnd();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CamWnd_SubmitWorldDecalsWithPreview(CCamWnd* cam) {
|
|
|
|
|
if (!g_qeglobals.rw) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!CamWnd_HasDecalPreview(cam)) {
|
|
|
|
|
g_qeglobals.rw->SubmitWorldDecalsToScreenSpace();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const int previewIndex = g_qeglobals.rw->AddWorldDecal(s_camWndDecalPreview);
|
|
|
|
|
g_qeglobals.rw->SubmitWorldDecalsToScreenSpace();
|
|
|
|
|
if (previewIndex >= 0) {
|
|
|
|
|
g_qeglobals.rw->RemoveWorldDecal(previewIndex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CamWnd_DecalCorners(const renderWorldDecal_t& decal, idVec3 corners[4]) {
|
|
|
|
|
const idVec3 axisU = decal.axisU * (decal.size * 0.5f);
|
|
|
|
|
const idVec3 axisV = decal.axisV * (decal.size * 0.5f);
|
|
|
|
|
corners[0] = decal.origin - axisU - axisV;
|
|
|
|
|
corners[1] = decal.origin + axisU - axisV;
|
|
|
|
|
corners[2] = decal.origin + axisU + axisV;
|
|
|
|
|
corners[3] = decal.origin - axisU + axisV;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CamWnd_DrawDecalOutlineGL(const renderWorldDecal_t& decal, const idVec4& color, float lineWidth) {
|
|
|
|
|
idVec3 corners[4];
|
|
|
|
|
CamWnd_DecalCorners(decal, corners);
|
|
|
|
|
|
|
|
|
|
const GLboolean depthEnabled = glIsEnabled(GL_DEPTH_TEST);
|
|
|
|
|
glPushAttrib(GL_CURRENT_BIT);
|
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
|
globalImages->BindNull();
|
|
|
|
|
glLineWidth(lineWidth);
|
|
|
|
|
glColor4f(color.x, color.y, color.z, color.w);
|
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
|
|
|
glVertex3fv(corners[i].ToFloatPtr());
|
|
|
|
|
}
|
|
|
|
|
glEnd();
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
|
glVertex3fv(decal.origin.ToFloatPtr());
|
|
|
|
|
idVec3 normalEnd = decal.origin + decal.normal * idMath::ClampFloat(4.0f, 32.0f, decal.size * 0.2f);
|
|
|
|
|
glVertex3fv(normalEnd.ToFloatPtr());
|
|
|
|
|
glEnd();
|
|
|
|
|
glLineWidth(1.0f);
|
|
|
|
|
if (depthEnabled) {
|
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
|
}
|
|
|
|
|
glPopAttrib();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CamWnd_DrawDecalSelectionOverlayGL(CCamWnd* cam) {
|
|
|
|
|
if (!cam || !g_qeglobals.rw || !CamWnd_DecalEditingEnabled(cam)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const int selected = Map_GetSelectedDecal();
|
|
|
|
|
if (selected >= 0) {
|
|
|
|
|
const renderWorldDecal_t* decal = g_qeglobals.rw->GetWorldDecal(selected);
|
|
|
|
|
if (decal) {
|
|
|
|
|
CamWnd_DrawDecalOutlineGL(*decal, idVec4(1.0f, 0.85f, 0.05f, 1.0f), 3.0f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (CamWnd_HasDecalPreview(cam)) {
|
|
|
|
|
CamWnd_DrawDecalOutlineGL(s_camWndDecalPreview, idVec4(0.1f, 0.8f, 1.0f, 1.0f), 1.5f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CamWnd_DebugDecalOutline(const renderWorldDecal_t& decal, const idVec4& color) {
|
|
|
|
|
if (!g_qeglobals.rw) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
idVec3 corners[4];
|
|
|
|
|
CamWnd_DecalCorners(decal, corners);
|
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
|
|
|
g_qeglobals.rw->DebugLine(color, corners[i], corners[(i + 1) & 3], 0, false);
|
|
|
|
|
}
|
|
|
|
|
g_qeglobals.rw->DebugLine(color, decal.origin, decal.origin + decal.normal * idMath::ClampFloat(4.0f, 32.0f, decal.size * 0.2f), 0, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool CamWnd_DecalClick(CCamWnd* cam, const CPoint& point, UINT nFlags) {
|
|
|
|
|
if (!CamWnd_DecalEditingEnabled(cam) || cam == NULL) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
idVec3 dir;
|
|
|
|
|
CamWnd_FaceExtrudeBuildRay(cam, point, dir);
|
|
|
|
|
|
|
|
|
|
if (nFlags & MK_SHIFT) {
|
|
|
|
|
const int selected = Map_SelectDecalByRay(cam->Camera().origin, dir);
|
|
|
|
|
if (selected >= 0) {
|
|
|
|
|
CamWnd_ClearDecalPreview(cam);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
renderWorldDecal_t decal;
|
|
|
|
|
const char* hitSource = "none";
|
|
|
|
|
if (!CamWnd_BuildDecalAtPoint(cam, point, decal, &hitSource)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Map_AddDecal(decal);
|
|
|
|
|
Sys_Status(va("Placed decal using %s on %s at %.2f %.2f %.2f\n", decal.material.c_str(), hitSource, decal.origin.x, decal.origin.y, decal.origin.z), 0);
|
|
|
|
@@ -2913,6 +3165,7 @@ CCamWnd::~CCamWnd() {
|
|
|
|
|
BEGIN_MESSAGE_MAP(CCamWnd, CWnd)
|
|
|
|
|
//{{AFX_MSG_MAP(CCamWnd)
|
|
|
|
|
ON_WM_KEYDOWN()
|
|
|
|
|
ON_WM_CHAR()
|
|
|
|
|
ON_WM_PAINT()
|
|
|
|
|
ON_WM_DESTROY()
|
|
|
|
|
ON_WM_CLOSE()
|
|
|
|
@@ -3024,6 +3277,10 @@ void CCamWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
|
|
|
|
|
CamWnd_FaceExtrudeEnd(this, false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (nChar == VK_ESCAPE && CamWnd_DecalEditingEnabled(this) && Map_GetSelectedDecal() >= 0) {
|
|
|
|
|
Map_ClearSelectedDecal();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (nChar == VK_DELETE && CamWnd_DecalEditingEnabled(this) && Map_GetSelectedDecal() >= 0) {
|
|
|
|
|
Map_DeleteSelectedDecal();
|
|
|
|
|
return;
|
|
|
|
@@ -3034,6 +3291,17 @@ void CCamWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
|
|
|
|
|
g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
=======================================================================================================================
|
|
|
|
|
=======================================================================================================================
|
|
|
|
|
*/
|
|
|
|
|
void CCamWnd::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) {
|
|
|
|
|
if (CamWnd_HandleDecalTransformChar(this, nChar)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
CWnd::OnChar(nChar, nRepCnt, nFlags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
brush_t* g_pSplitList = NULL;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@@ -3075,6 +3343,7 @@ void CCamWnd::SetXYFriend(CXYWnd* pWnd) {
|
|
|
|
|
void CCamWnd::OnDestroy() {
|
|
|
|
|
CamWnd_FaceExtrudeEnd(this, false);
|
|
|
|
|
CamWnd_GizmoEnd(this, false);
|
|
|
|
|
CamWnd_ClearDecalPreview(this);
|
|
|
|
|
CamWnd_DestroyMenuBar(this);
|
|
|
|
|
CWnd::OnDestroy();
|
|
|
|
|
}
|
|
|
|
@@ -3097,6 +3366,10 @@ void CCamWnd::OnMouseMove(UINT nFlags, CPoint point) {
|
|
|
|
|
CRect r;
|
|
|
|
|
GetClientRect(r);
|
|
|
|
|
|
|
|
|
|
if (GetCapture() != this) {
|
|
|
|
|
CamWnd_UpdateDecalPreview(this, point);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (CamWnd_FaceExtrudeMouseMove(this, point)) {
|
|
|
|
|
m_ptLastCursor = point;
|
|
|
|
|
return;
|
|
|
|
@@ -4265,8 +4538,16 @@ void CCamWnd::Cam_Draw() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CamWnd_DrawMoveSelectedBrushSides(brushFilter);
|
|
|
|
|
if (!renderMode && g_qeglobals.rw && CamWnd_DecalEditingEnabled(this)) {
|
|
|
|
|
g_qeglobals.rw->SubmitWorldDecalsToScreenSpace();
|
|
|
|
|
if (!renderMode && g_qeglobals.rw) {
|
|
|
|
|
if (CamWnd_DecalEditingEnabled(this)) {
|
|
|
|
|
CamWnd_UpdateDecalPreview(this, m_ptLastCursor);
|
|
|
|
|
CamWnd_SubmitWorldDecalsWithPreview(this);
|
|
|
|
|
CamWnd_DrawDecalSelectionOverlayGL(this);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
CamWnd_ClearDecalPreview(this);
|
|
|
|
|
g_qeglobals.rw->SubmitWorldDecalsToScreenSpace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
CamWnd_FaceExtrudeDrawPreview(this);
|
|
|
|
|
CamWnd_GizmoDraw(this);
|
|
|
|
@@ -5866,14 +6147,28 @@ void CCamWnd::Cam_Render() {
|
|
|
|
|
}
|
|
|
|
|
Cam_SetGlobalFogFromWorldspawn(refdef);
|
|
|
|
|
|
|
|
|
|
if (CamWnd_DecalEditingEnabled(this)) {
|
|
|
|
|
CamWnd_UpdateDecalPreview(this, m_ptLastCursor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int previewDecalIndex = -1;
|
|
|
|
|
if (g_qeglobals.rw && CamWnd_HasDecalPreview(this)) {
|
|
|
|
|
previewDecalIndex = g_qeglobals.rw->AddWorldDecal(s_camWndDecalPreview);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (g_qeglobals.rw && CamWnd_DecalEditingEnabled(this)) {
|
|
|
|
|
for (int i = 0; i < g_qeglobals.rw->NumWorldDecals(); ++i) {
|
|
|
|
|
const renderWorldDecal_t* decal = g_qeglobals.rw->GetWorldDecal(i);
|
|
|
|
|
if (!decal) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
idVec4 color = (i == Map_GetSelectedDecal()) ? idVec4(1.0f, 0.85f, 0.1f, 1.0f) : idVec4(0.1f, 0.8f, 1.0f, 1.0f);
|
|
|
|
|
const bool selected = (i == Map_GetSelectedDecal());
|
|
|
|
|
const bool preview = (i == previewDecalIndex);
|
|
|
|
|
idVec4 color = selected ? idVec4(1.0f, 0.85f, 0.1f, 1.0f) : idVec4(0.1f, 0.8f, 1.0f, 1.0f);
|
|
|
|
|
g_qeglobals.rw->DebugCircle(color, decal->origin, decal->normal, decal->size * 0.5f, 32, 0, false);
|
|
|
|
|
if (selected || preview) {
|
|
|
|
|
CamWnd_DebugDecalOutline(*decal, color);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -5884,6 +6179,10 @@ void CCamWnd::Cam_Render() {
|
|
|
|
|
renderSystem->EndFrame(&frontEnd, &backEnd, false);
|
|
|
|
|
//common->Printf( "front:%i back:%i\n", frontEnd, backEnd );
|
|
|
|
|
|
|
|
|
|
if (g_qeglobals.rw && previewDecalIndex >= 0) {
|
|
|
|
|
g_qeglobals.rw->RemoveWorldDecal(previewDecalIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//glPopAttrib();
|
|
|
|
|
//DrawEntityData();
|
|
|
|
|
|
|
|
|
|