quadrilateralcowboy/tools/radiant/LightDlg.cpp

970 lines
27 KiB
C++

/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code 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 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../idlib/precompiled.h"
#pragma hdrstop
#include "qe3.h"
#include "Radiant.h"
#include "../../game/game.h"
#include "../comafx/DialogColorPicker.h"
#include "LightDlg.h"
#ifdef ID_DEBUG_MEMORY
#undef new
#undef DEBUG_NEW
#define DEBUG_NEW new
#endif
void CLightInfo::Defaults() {
pointLight = true;
fallOff = 1;
strTexture = "";
equalRadius = true;
explicitStartEnd = false;
lightRadius.Zero();
lightTarget.Zero();
lightRight.Zero();
lightUp.Zero();
lightStart.Zero();
lightEnd.Zero();
lightCenter.Zero();
hasCenter = false;
isParallel = false;
castShadows = true;
castSpecular = true;
castDiffuse = true;
rotate = false;
strobe = false;
rotateSpeed = 0;
strobeSpeed = 0;
color[0] = color[1] = color[2] = 255;
fogDensity[0] = fogDensity[1] = fogDensity[2] = 0;
fog = false;
lightRadius[0] = lightRadius[1] = lightRadius[2] = 300;
}
void CLightInfo::DefaultPoint() {
idVec3 oldColor = color;
Defaults();
color = oldColor;
pointLight = true;
}
void CLightInfo::DefaultProjected() {
idVec3 oldColor = color;
Defaults();
color = oldColor;
pointLight = false;
lightTarget[2] = -256;
lightUp[1] = -128;
lightRight[0] = -128;
}
void CLightInfo::FromDict( const idDict *e ) {
lightRadius.Zero();
lightTarget.Zero();
lightRight.Zero();
lightUp.Zero();
lightStart.Zero();
lightEnd.Zero();
lightCenter.Zero();
castShadows = !e->GetBool("noshadows");
castSpecular = !e->GetBool("nospecular");
castDiffuse = !e->GetBool("nodiffuse");
fallOff = e->GetFloat("falloff");
strTexture = e->GetString("texture");
isParallel = e->GetBool("parallel");
if (!e->GetVector("_color", "", color)) {
color[0] = color[1] = color[2] = 1;
}
// windows needs 0-255 scale
color[0] *= 255;
color[1] *= 255;
color[2] *= 255;
if (e->GetVec4("fog", "", fogDensity)) {
fog = true;
} else {
fog = false;
}
if (e->GetVector("light_right","", lightRight)) {
// projected light
pointLight = false;
e->GetVector("light_target", "", lightTarget);
e->GetVector("light_up", "", lightUp);
if (e->GetVector("light_start", "", lightStart)) {
// explicit start and end points
explicitStartEnd = true;
if (!e->GetVector("light_end", "", lightEnd)) {
// no end, use target
VectorCopy(lightTarget, lightEnd);
}
} else {
explicitStartEnd = false;
// create a start a quarter of the way to the target
lightStart = lightTarget * 0.25;
VectorCopy(lightTarget, lightEnd);
}
} else {
pointLight = true;
if (e->GetVector("light_radius", "", lightRadius)) {
equalRadius = false;
} else {
float radius = e->GetFloat("light");
if (radius == 0) {
radius = 300;
}
lightRadius[0] = lightRadius[1] = lightRadius[2] = radius;
equalRadius = true;
}
if (e->GetVector("light_center", "", lightCenter)) {
hasCenter = true;
}
}
}
void CLightInfo::ToDictFromDifferences ( idDict *e, const idDict *differences ) {
for ( int i = 0 ; i < differences->GetNumKeyVals () ; i ++ ) {
const idKeyValue *kv = differences->GetKeyVal( i );
if ( kv->GetValue().Length() > 0 ) {
e->Set ( kv->GetKey() ,kv->GetValue() );
} else {
e->Delete ( kv->GetKey() );
}
common->Printf( "Applied difference: %s %s\n" , kv->GetKey().c_str() , kv->GetValue().c_str() );
}
}
//write all info to a dict, regardless of light type
void CLightInfo::ToDictWriteAllInfo( idDict *e ) {
e->Set("noshadows", (!castShadows) ? "1" : "0");
e->Set("nospecular", (!castSpecular) ? "1" : "0");
e->Set("nodiffuse", (!castDiffuse) ? "1" : "0");
e->SetFloat("falloff",fallOff);
if (strTexture.GetLength() > 0 ) {
e->Set("texture", strTexture);
}
idVec3 temp = color;
temp /= 255;
e->SetVector("_color", temp);
if (!equalRadius) {
e->Set("light_radius", va("%g %g %g", lightRadius[0], lightRadius[1], lightRadius[2]));
} else {
e->Set("light_radius", va("%g %g %g", lightRadius[0], lightRadius[0], lightRadius[0]));
}
e->Set("light_center", va("%g %g %g", lightCenter[0], lightCenter[1], lightCenter[2]));
e->Set("parallel", isParallel?"1":"0");
e->Set("light_target", va("%g %g %g", lightTarget[0], lightTarget[1], lightTarget[2]));
e->Set("light_up", va("%g %g %g", lightUp[0], lightUp[1], lightUp[2]));
e->Set("light_right", va("%g %g %g", lightRight[0], lightRight[1], lightRight[2]));
e->Set("light_start", va("%g %g %g", lightStart[0], lightStart[1], lightStart[2]));
e->Set("light_end", va("%g %g %g", lightEnd[0], lightEnd[1], lightEnd[2]));
}
void CLightInfo::ToDict( idDict *e ) {
e->Delete("noshadows");
e->Delete("nospecular");
e->Delete("nodiffuse");
e->Delete("falloff");
e->Delete("parallel");
e->Delete("texture");
e->Delete("_color");
e->Delete("fog");
e->Delete("light_target");
e->Delete("light_right");
e->Delete("light_up");
e->Delete("light_start");
e->Delete("light_end");
e->Delete("light_radius");
e->Delete("light_center");
e->Delete("light");
e->Set("noshadows", (!castShadows) ? "1" : "0");
e->Set("nospecular", (!castSpecular) ? "1" : "0");
e->Set("nodiffuse", (!castDiffuse) ? "1" : "0");
e->SetFloat("falloff",fallOff);
if (strTexture.GetLength() > 0) {
e->Set("texture", strTexture);
}
idVec3 temp = color;
temp /= 255;
e->SetVector("_color", temp);
if (fog) {
e->Set("fog", va("%g %g %g %g", fogDensity[0]/255.0, fogDensity[1]/255.0, fogDensity[2]/255.0, fogDensity[3]/255.0));
}
if (pointLight) {
if (!equalRadius) {
e->Set("light_radius", va("%g %g %g", lightRadius[0], lightRadius[1], lightRadius[2]));
} else {
e->Set("light_radius", va("%g %g %g", lightRadius[0], lightRadius[0], lightRadius[0]));
}
if (hasCenter) {
e->Set("light_center", va("%g %g %g", lightCenter[0], lightCenter[1], lightCenter[2]));
}
if (isParallel) {
e->Set("parallel", "1");
}
} else {
e->Set("light_target", va("%g %g %g", lightTarget[0], lightTarget[1], lightTarget[2]));
e->Set("light_up", va("%g %g %g", lightUp[0], lightUp[1], lightUp[2]));
e->Set("light_right", va("%g %g %g", lightRight[0], lightRight[1], lightRight[2]));
if (explicitStartEnd) {
e->Set("light_start", va("%g %g %g", lightStart[0], lightStart[1], lightStart[2]));
e->Set("light_end", va("%g %g %g", lightEnd[0], lightEnd[1], lightEnd[2]));
}
}
}
CLightInfo::CLightInfo() {
Defaults();
}
/////////////////////////////////////////////////////////////////////////////
// CLightDlg dialog
CLightDlg *g_LightDialog = NULL;
CLightDlg::CLightDlg(CWnd* pParent /*=NULL*/)
: CDialog(CLightDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CLightDlg)
m_bEqualRadius = FALSE;
m_bExplicitFalloff = FALSE;
m_bPointLight = FALSE;
m_bCheckProjected = FALSE;
m_fFallloff = 0.0f;
m_nFalloff = -1;
m_bRotate = FALSE;
m_bShadows = FALSE;
m_bSpecular = FALSE;
m_bDiffuse = FALSE;
m_fEndX = 0.0f;
m_fEndY = 0.0f;
m_fEndZ = 0.0f;
m_fRadiusX = 0.0f;
m_fRadiusY = 0.0f;
m_fRadiusZ = 0.0f;
m_fRightX = 0.0f;
m_fRightY = 0.0f;
m_fRightZ = 0.0f;
m_fRotate = 0.0f;
m_fStartX = 0.0f;
m_fStartY = 0.0f;
m_fStartZ = 0.0f;
m_fTargetX = 0.0f;
m_fTargetY = 0.0f;
m_fTargetZ = 0.0f;
m_fUpX = 0.0f;
m_fUpY = 0.0f;
m_fUpZ = 0.0f;
m_hasCenter = FALSE;
m_centerX = 0.0f;
m_centerY = 0.0f;
m_centerZ = 0.0f;
m_bIsParallel = FALSE;
//}}AFX_DATA_INIT
m_drawMaterial = new idGLDrawableMaterial();
}
CLightDlg::~CLightDlg() {
delete m_drawMaterial;
}
void CLightDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CLightDlg)
if ( com_editorActive ) {
DDX_Control(pDX, IDC_LIGHTPREVIEW, m_wndPreview);
}
DDX_Control(pDX, IDC_COMBO_TEXTURE, m_wndLights);
DDX_Check(pDX, IDC_CHECK_EQUALRADIUS, m_bEqualRadius);
DDX_Check(pDX, IDC_CHECK_EXPLICITFALLOFF, m_bExplicitFalloff);
DDX_Check(pDX, IDC_CHECK_POINT, m_bPointLight);
DDX_Check(pDX, IDC_CHECK_PROJECTED, m_bCheckProjected);
DDX_Radio(pDX, IDC_RADIO_FALLOFF, m_nFalloff);
DDX_Check(pDX, IDC_CHECK_SHADOWS, m_bShadows);
DDX_Check(pDX, IDC_CHECK_SPECULAR, m_bSpecular);
DDX_Check(pDX, IDC_CHECK_DIFFUSE, m_bDiffuse);
DDX_Check(pDX , IDC_CHECK_PARALLEL , m_bIsParallel );
DDX_Text(pDX, IDC_EDIT_ENDX, m_fEndX);
DDX_Text(pDX, IDC_EDIT_ENDY, m_fEndY);
DDX_Text(pDX, IDC_EDIT_ENDZ, m_fEndZ);
DDX_Text(pDX, IDC_EDIT_RADIUSX, m_fRadiusX);
DDX_Text(pDX, IDC_EDIT_RADIUSY, m_fRadiusY);
DDX_Text(pDX, IDC_EDIT_RADIUSZ, m_fRadiusZ);
DDX_Text(pDX, IDC_EDIT_RIGHTX, m_fRightX);
DDX_Text(pDX, IDC_EDIT_RIGHTY, m_fRightY);
DDX_Text(pDX, IDC_EDIT_RIGHTZ, m_fRightZ);
DDX_Text(pDX, IDC_EDIT_STARTX, m_fStartX);
DDX_Text(pDX, IDC_EDIT_STARTY, m_fStartY);
DDX_Text(pDX, IDC_EDIT_STARTZ, m_fStartZ);
DDX_Text(pDX, IDC_EDIT_TARGETX, m_fTargetX);
DDX_Text(pDX, IDC_EDIT_TARGETY, m_fTargetY);
DDX_Text(pDX, IDC_EDIT_TARGETZ, m_fTargetZ);
DDX_Text(pDX, IDC_EDIT_UPX, m_fUpX);
DDX_Text(pDX, IDC_EDIT_UPY, m_fUpY);
DDX_Text(pDX, IDC_EDIT_UPZ, m_fUpZ);
DDX_Check(pDX, IDC_CHECK_CENTER, m_hasCenter);
DDX_Text(pDX, IDC_EDIT_CENTERX, m_centerX);
DDX_Text(pDX, IDC_EDIT_CENTERY, m_centerY);
DDX_Text(pDX, IDC_EDIT_CENTERZ, m_centerZ);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CLightDlg, CDialog)
//{{AFX_MSG_MAP(CLightDlg)
ON_BN_CLICKED(IDC_BTN_TEXTURE, OnBtnTexture)
ON_BN_CLICKED(IDC_CHECK_EQUALRADIUS, OnCheckEqualradius)
ON_BN_CLICKED(IDC_CHECK_EXPLICITFALLOFF, OnCheckExplicitfalloff)
ON_BN_CLICKED(IDC_CHECK_POINT, OnCheckPoint)
ON_BN_CLICKED(IDC_CHECK_PROJECTED, OnCheckProjected)
ON_BN_CLICKED(IDC_RADIO_FALLOFF, OnRadioFalloff)
ON_BN_CLICKED(IDC_APPLY, OnApply)
ON_BN_CLICKED(IDC_APPLY_DIFFERENT, OnApplyDifferences)
ON_BN_CLICKED(IDC_BTN_COLOR, OnBtnColor)
ON_WM_CTLCOLOR()
ON_CBN_SELCHANGE(IDC_COMBO_TEXTURE, OnSelchangeComboTexture)
ON_BN_CLICKED(IDC_CHECK_CENTER, OnCheckCenter)
ON_BN_CLICKED(IDC_CHECK_PARALLEL, OnCheckParallel)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CLightDlg message handlers
void CLightDlg::SetSpecifics() {
if (lightInfo.pointLight) {
GetDlgItem(IDC_EDIT_RADIUSY)->EnableWindow(!lightInfo.equalRadius);
GetDlgItem(IDC_EDIT_RADIUSZ)->EnableWindow(!lightInfo.equalRadius);
GetDlgItem(IDC_EDIT_CENTERX)->EnableWindow(lightInfo.hasCenter);
GetDlgItem(IDC_EDIT_CENTERY)->EnableWindow(lightInfo.hasCenter);
GetDlgItem(IDC_EDIT_CENTERZ)->EnableWindow(lightInfo.hasCenter);
} else {
GetDlgItem(IDC_EDIT_STARTX)->EnableWindow(lightInfo.explicitStartEnd);
GetDlgItem(IDC_EDIT_STARTY)->EnableWindow(lightInfo.explicitStartEnd);
GetDlgItem(IDC_EDIT_STARTZ)->EnableWindow(lightInfo.explicitStartEnd);
GetDlgItem(IDC_EDIT_ENDX)->EnableWindow(lightInfo.explicitStartEnd);
GetDlgItem(IDC_EDIT_ENDY)->EnableWindow(lightInfo.explicitStartEnd);
GetDlgItem(IDC_EDIT_ENDZ)->EnableWindow(lightInfo.explicitStartEnd);
}
}
void CLightDlg::EnableControls() {
GetDlgItem(IDC_CHECK_EQUALRADIUS)->EnableWindow(lightInfo.pointLight);
GetDlgItem(IDC_EDIT_RADIUSX)->EnableWindow(lightInfo.pointLight);
GetDlgItem(IDC_EDIT_RADIUSY)->EnableWindow(lightInfo.pointLight);
GetDlgItem(IDC_EDIT_RADIUSZ)->EnableWindow(lightInfo.pointLight);
GetDlgItem(IDC_RADIO_FALLOFF)->EnableWindow(lightInfo.pointLight);
GetDlgItem(IDC_RADIO_FALLOFF2)->EnableWindow(lightInfo.pointLight);
GetDlgItem(IDC_RADIO_FALLOFF3)->EnableWindow(lightInfo.pointLight);
GetDlgItem(IDC_EDIT_TARGETX)->EnableWindow(!lightInfo.pointLight);
GetDlgItem(IDC_EDIT_TARGETY)->EnableWindow(!lightInfo.pointLight);
GetDlgItem(IDC_EDIT_TARGETZ)->EnableWindow(!lightInfo.pointLight);
GetDlgItem(IDC_EDIT_RIGHTX)->EnableWindow(!lightInfo.pointLight);
GetDlgItem(IDC_EDIT_RIGHTY)->EnableWindow(!lightInfo.pointLight);
GetDlgItem(IDC_EDIT_RIGHTZ)->EnableWindow(!lightInfo.pointLight);
GetDlgItem(IDC_EDIT_UPX)->EnableWindow(!lightInfo.pointLight);
GetDlgItem(IDC_EDIT_UPY)->EnableWindow(!lightInfo.pointLight);
GetDlgItem(IDC_EDIT_UPZ)->EnableWindow(!lightInfo.pointLight);
GetDlgItem(IDC_EDIT_STARTX)->EnableWindow(!lightInfo.pointLight);
GetDlgItem(IDC_EDIT_STARTY)->EnableWindow(!lightInfo.pointLight);
GetDlgItem(IDC_EDIT_STARTZ)->EnableWindow(!lightInfo.pointLight);
GetDlgItem(IDC_EDIT_ENDX)->EnableWindow(!lightInfo.pointLight);
GetDlgItem(IDC_EDIT_ENDY)->EnableWindow(!lightInfo.pointLight);
GetDlgItem(IDC_EDIT_ENDZ)->EnableWindow(!lightInfo.pointLight);
GetDlgItem(IDC_CHECK_EXPLICITFALLOFF)->EnableWindow(!lightInfo.pointLight);
GetDlgItem(IDC_CHECK_POINT)->EnableWindow(!lightInfo.pointLight);
GetDlgItem(IDC_CHECK_PROJECTED)->EnableWindow(lightInfo.pointLight);
GetDlgItem(IDC_EDIT_CENTERX)->EnableWindow(lightInfo.pointLight);
GetDlgItem(IDC_EDIT_CENTERY)->EnableWindow(lightInfo.pointLight);
GetDlgItem(IDC_EDIT_CENTERZ)->EnableWindow(lightInfo.pointLight);
GetDlgItem(IDC_CHECK_CENTER)->EnableWindow(lightInfo.pointLight);
reinterpret_cast<CButton*>(GetDlgItem(IDC_CHECK_PROJECTED))->SetCheck(!lightInfo.pointLight);
reinterpret_cast<CButton*>(GetDlgItem(IDC_CHECK_POINT))->SetCheck(lightInfo.pointLight);
SetSpecifics();
}
void CLightDlg::UpdateDialogFromLightInfo( void ) {
m_hasCenter = lightInfo.hasCenter;
m_bEqualRadius = lightInfo.equalRadius;
m_bExplicitFalloff = lightInfo.explicitStartEnd;
m_bPointLight = lightInfo.pointLight;
m_bCheckProjected = !lightInfo.pointLight;
m_fFallloff = lightInfo.fallOff;
if (lightInfo.fallOff < 0.35) {
m_nFalloff = 0;
} else if (lightInfo.fallOff < 0.70) {
m_nFalloff = 1;
} else {
m_nFalloff = 2;
}
//m_bFog = lightInfo.fog;
m_bRotate = lightInfo.rotate;
m_bShadows = lightInfo.castShadows;
m_bSpecular = lightInfo.castSpecular;
//m_bStrobe = lightInfo.strobe;
//m_fStrobe = lightInfo.strobeSpeed;
int sel = m_wndLights.FindStringExact(-1, lightInfo.strTexture);
m_wndLights.SetCurSel(sel);
if (sel >= 0) {
m_drawMaterial->setMedia(lightInfo.strTexture);
} else {
m_drawMaterial->setMedia(lightInfo.strTexture);
}
m_bDiffuse = lightInfo.castDiffuse;
m_fEndX = lightInfo.lightEnd[0];
m_fEndY = lightInfo.lightEnd[1];
m_fEndZ = lightInfo.lightEnd[2];
m_fRadiusX = lightInfo.lightRadius[0];
m_fRadiusY = lightInfo.lightRadius[1];
m_fRadiusZ = lightInfo.lightRadius[2];
m_fRightX = lightInfo.lightRight[0];
m_fRightY = lightInfo.lightRight[1];
m_fRightZ = lightInfo.lightRight[2];
//m_bRotate = lightInfo.rotate;
//m_fRotate = lightInfo.rotateSpeed;
m_fStartX = lightInfo.lightStart[0];
m_fStartY = lightInfo.lightStart[1];
m_fStartZ = lightInfo.lightStart[2];
m_fTargetX = lightInfo.lightTarget[0];
m_fTargetY = lightInfo.lightTarget[1];
m_fTargetZ = lightInfo.lightTarget[2];
m_fUpX = lightInfo.lightUp[0];
m_fUpY = lightInfo.lightUp[1];
m_fUpZ = lightInfo.lightUp[2];
VectorCopy(lightInfo.color, color);
//m_fFogAlpha = lightInfo.fogDensity[3];
m_centerX = lightInfo.lightCenter[0];
m_centerY = lightInfo.lightCenter[1];
m_centerZ = lightInfo.lightCenter[2];
//jhefty - added parallel light updating
m_bIsParallel = lightInfo.isParallel;
UpdateData(FALSE);
}
void CLightDlg::UpdateLightInfoFromDialog( void ) {
UpdateData( TRUE );
lightInfo.pointLight = ( m_bPointLight != FALSE );
lightInfo.equalRadius = ( m_bEqualRadius != FALSE );
lightInfo.explicitStartEnd = ( m_bExplicitFalloff != FALSE );
if (lightInfo.pointLight) {
if (m_nFalloff == 0) {
m_fFallloff = 0.0;
} else if (m_nFalloff == 1) {
m_fFallloff = 0.5;
} else {
m_fFallloff = 1.0;
}
}
lightInfo.fallOff = m_fFallloff;
//lightInfo.fog = m_bFog;
lightInfo.rotate = ( m_bRotate != FALSE );
lightInfo.castShadows = ( m_bShadows != FALSE );
lightInfo.castSpecular = ( m_bSpecular != FALSE );
VectorCopy(color, lightInfo.color);
lightInfo.isParallel = (m_bIsParallel == TRUE);
//lightInfo.fogDensity[3] = m_fFogAlpha;
//lightInfo.strobe = m_bStrobe;
//lightInfo.strobeSpeed = m_fStrobe;
//lightInfo.rotate = m_bRotate;
//lightInfo.rotateSpeed = m_fRotate;
int sel = m_wndLights.GetCurSel();
CString str("");
if (sel >= 0) {
m_wndLights.GetLBText(sel, str);
}
lightInfo.strTexture = str;
lightInfo.castDiffuse = ( m_bDiffuse != FALSE );
lightInfo.lightEnd[0] = m_fEndX;
lightInfo.lightEnd[1] = m_fEndY;
lightInfo.lightEnd[2] = m_fEndZ;
lightInfo.lightRadius[0] = m_fRadiusX;
lightInfo.lightRadius[1] = m_fRadiusY;
lightInfo.lightRadius[2] = m_fRadiusZ;
lightInfo.lightRight[0] = m_fRightX;
lightInfo.lightRight[1] = m_fRightY;
lightInfo.lightRight[2] = m_fRightZ;
lightInfo.lightStart[0] = m_fStartX;
lightInfo.lightStart[1] = m_fStartY;
lightInfo.lightStart[2] = m_fStartZ;
lightInfo.lightTarget[0] = m_fTargetX;
lightInfo.lightTarget[1] = m_fTargetY;
lightInfo.lightTarget[2] = m_fTargetZ;
lightInfo.lightUp[0] = m_fUpX;
lightInfo.lightUp[1] = m_fUpY;
lightInfo.lightUp[2] = m_fUpZ;
lightInfo.hasCenter = ( m_hasCenter != FALSE );
lightInfo.lightCenter[0] = m_centerX;
lightInfo.lightCenter[1] = m_centerY;
lightInfo.lightCenter[2] = m_centerZ;
}
void CLightDlg::SaveLightInfo( const idDict *differences ) {
if ( com_editorActive ) {
// used from Radiant
for ( brush_t *b = selected_brushes.next; b && b != &selected_brushes; b = b->next ) {
if ( ( b->owner->eclass->nShowFlags & ECLASS_LIGHT ) && !b->entityModel ) {
if ( differences ) {
lightInfo.ToDictFromDifferences( &b->owner->epairs, differences );
} else {
lightInfo.ToDict( &b->owner->epairs );
}
Brush_Build( b );
}
}
} else {
// used in-game
idList<idEntity *> list;
list.SetNum( 128 );
int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() );
list.SetNum( count );
for ( int i = 0; i < count; i++ ) {
if ( differences ) {
gameEdit->EntityChangeSpawnArgs( list[i], differences );
gameEdit->EntityUpdateChangeableSpawnArgs( list[i], NULL );
} else {
idDict newArgs;
lightInfo.ToDict( &newArgs );
gameEdit->EntityChangeSpawnArgs( list[i], &newArgs );
gameEdit->EntityUpdateChangeableSpawnArgs( list[i], NULL );
}
gameEdit->EntityUpdateVisuals( list[i] );
}
}
}
void CLightDlg::ColorButtons() {
CRect r;
CClientDC dc(this);
CButton *pBtn = (CButton *)GetDlgItem(IDC_BTN_COLOR);
pBtn->GetClientRect(&r);
colorBitmap.DeleteObject();
colorBitmap.CreateCompatibleBitmap(&dc, r.Width(), r.Height());
CDC MemDC;
MemDC.CreateCompatibleDC(&dc);
CBitmap *pOldBmp = MemDC.SelectObject(&colorBitmap);
{
CBrush br(RGB(color[0], color[1], color[2]));
MemDC.FillRect(r,&br);
}
dc.SelectObject(pOldBmp);
pBtn->SetBitmap(HBITMAP(colorBitmap));
}
void CLightDlg::LoadLightTextures() {
int count = declManager->GetNumDecls( DECL_MATERIAL );
int i;
const idMaterial *mat;
for (i = 0; i < count; i++) {
mat = declManager->MaterialByIndex(i, false);
idStr str = mat->GetName();
str.ToLower();
if (str.Icmpn("lights/", strlen("lights/")) == 0 || str.Icmpn("fogs/", strlen("fogs/")) == 0) {
m_wndLights.AddString(mat->GetName());
}
}
}
BOOL CLightDlg::OnInitDialog()
{
CDialog::OnInitDialog();
com_editors |= EDITOR_LIGHT;
UpdateDialog( true );
LoadLightTextures();
if ( com_editorActive ) {
m_wndPreview.setDrawable(m_drawMaterial);
}
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CLightDlg::OnDestroy() {
com_editors &= ~EDITOR_LIGHT;
return CDialog::OnDestroy();
}
void CLightDlg::OnBtnTexture()
{
// TODO: Add your control notification handler code here
}
void CLightDlg::OnCheckEqualradius()
{
lightInfo.equalRadius = ( reinterpret_cast<CButton*>(GetDlgItem(IDC_CHECK_EQUALRADIUS))->GetCheck() != 0 );
SetSpecifics();
}
void CLightDlg::OnCheckExplicitfalloff()
{
lightInfo.explicitStartEnd = ( reinterpret_cast<CButton*>(GetDlgItem(IDC_CHECK_EXPLICITFALLOFF))->GetCheck() != 0 );
SetSpecifics();
}
void CLightDlg::OnCheckPoint()
{
lightInfo.DefaultPoint();
UpdateDialogFromLightInfo();
EnableControls();
}
void CLightDlg::OnCheckProjected()
{
lightInfo.DefaultProjected();
UpdateDialogFromLightInfo();
EnableControls();
}
void CLightDlg::OnRadioFalloff()
{
}
void CLightDlg::OnOK() {
UpdateLightInfoFromDialog();
SaveLightInfo( NULL );
Sys_UpdateWindows(W_ALL);
CDialog::OnOK();
}
entity_t *SingleLightSelected() {
if ( QE_SingleBrush( true, true ) ) {
brush_t *b = selected_brushes.next;
if ( ( b->owner->eclass->nShowFlags & ECLASS_LIGHT ) && !b->entityModel ) {
return b->owner;
}
}
return NULL;
}
void CLightDlg::UpdateDialog( bool updateChecks )
{
CString title;
lightInfo.Defaults();
lightInfoOriginal.Defaults ();
if ( com_editorActive ) {
// used from Radiant
entity_t *e = SingleLightSelected();
if ( e ) {
lightInfo.FromDict(&e->epairs);
lightInfoOriginal.FromDict(&e->epairs); //our original copy of the values that we compare against for apply differences
title = "Light Editor";
} else {
//find the last brush belonging to the last entity selected and use that as the source
e = NULL;
for ( brush_t *b = selected_brushes.next ; b != &selected_brushes ; b = b->next ) {
if ( ( b->owner->eclass->nShowFlags & ECLASS_LIGHT ) && !b->entityModel ) {
e = b->owner;
break;
}
}
if ( e ) {
lightInfo.FromDict( &e->epairs );
lightInfoOriginal.FromDict(&e->epairs); //our original copy of the values that we compaer against for apply differences
title = "Light Editor - (Multiple lights selected)";
} else {
title = "Light Editor - (No lights selected)";
}
}
} else {
// used in-game
idList<idEntity *> list;
list.SetNum( 128 );
int count = gameEdit->GetSelectedEntities( list.Ptr(), list.Num() );
list.SetNum( count );
if ( count > 0 ) {
lightInfo.FromDict( gameEdit->EntityGetSpawnArgs( list[count-1] ) );
title = "Light Editor";
} else {
title = "Light Editor - (No entities selected)";
}
}
SetWindowText( title );
UpdateDialogFromLightInfo();
ColorButtons();
if ( updateChecks ) {
EnableControls();
}
}
void LightEditorInit( const idDict *spawnArgs ) {
if ( renderSystem->IsFullScreen() ) {
common->Printf( "Cannot run the light editor in fullscreen mode.\n"
"Set r_fullscreen to 0 and vid_restart.\n" );
return;
}
if ( g_LightDialog == NULL ) {
InitAfx();
g_LightDialog = new CLightDlg();
}
if ( g_LightDialog->GetSafeHwnd() == NULL ) {
g_LightDialog->Create( IDD_DIALOG_LIGHT );
CRect rct;
LONG lSize = sizeof( rct );
if ( LoadRegistryInfo( "Radiant::LightWindow", &rct, &lSize ) ) {
g_LightDialog->SetWindowPos(NULL, rct.left, rct.top, 0,0, SWP_NOSIZE);
}
}
idKeyInput::ClearStates();
g_LightDialog->ShowWindow( SW_SHOW );
g_LightDialog->SetFocus();
g_LightDialog->UpdateDialog( true );
if ( spawnArgs ) {
// FIXME: select light based on spawn args
}
}
void LightEditorRun( void ) {
#if _MSC_VER >= 1300
MSG *msg = AfxGetCurrentMessage(); // TODO Robert fix me!!
#else
MSG *msg = &m_msgCur;
#endif
while( ::PeekMessage(msg, NULL, NULL, NULL, PM_NOREMOVE) ) {
// pump message
if ( !AfxGetApp()->PumpMessage() ) {
}
}
}
void LightEditorShutdown( void ) {
delete g_LightDialog;
g_LightDialog = NULL;
}
void UpdateLightInspector() {
if ( g_LightDialog && g_LightDialog->GetSafeHwnd() != NULL ) {
g_LightDialog->UpdateDialog(true); //jhefty - update ALL info about the light, including check boxes
}
}
void CLightDlg::OnApply() {
UpdateLightInfoFromDialog();
SaveLightInfo( NULL );
Sys_UpdateWindows( W_ALL );
}
void UpdateLightDialog( float r, float g, float b, float a ) {
UpdateRadiantColor( 0.0f, 0.0f, 0.0f, 0.0f );
g_LightDialog->UpdateColor( r, g, b, a );
}
void CLightDlg::UpdateColor( float r, float g, float b, float a ) {
color[0] = a * r;
color[1] = a * g;
color[2] = a * b;
ColorButtons();
UpdateLightInfoFromDialog();
SaveLightInfo( NULL );
Sys_UpdateWindows( W_CAMERA );
}
void CLightDlg::OnBtnColor() {
int r, g, b;
float ob;
r = color[0];
g = color[1];
b = color[2];
if ( DoNewColor( &r, &g, &b, &ob, UpdateLightDialog ) ) {
color[0] = ob * r;
color[1] = ob * g;
color[2] = ob * b;
ColorButtons();
}
}
void CLightDlg::OnCancel() {
CDialog::OnCancel();
}
HBRUSH CLightDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
return hbr;
}
BOOL CLightDlg::DestroyWindow()
{
if (GetSafeHwnd())
{
CRect rct;
GetWindowRect(rct);
SaveRegistryInfo("Radiant::LightWindow", &rct, sizeof(rct));
}
return CDialog::DestroyWindow();
}
void CLightDlg::OnSelchangeComboTexture()
{
UpdateData(TRUE);
int sel = m_wndLights.GetCurSel();
CString str;
if (sel >= 0) {
m_wndLights.GetLBText(sel, str);
m_drawMaterial->setMedia(str);
if ( com_editorActive ) {
m_wndPreview.RedrawWindow();
}
}
Sys_UpdateWindows(W_ALL);
}
void CLightDlg::OnCheckCenter()
{
if (reinterpret_cast<CButton*>(GetDlgItem(IDC_CHECK_CENTER))->GetCheck()) {
lightInfo.hasCenter = true;
lightInfo.lightCenter.x = 0;
lightInfo.lightCenter.y = 0;
lightInfo.lightCenter.z = 32;
} else {
lightInfo.hasCenter = false;
lightInfo.lightCenter.Zero();
}
UpdateDialogFromLightInfo();
SetSpecifics();
}
void CLightDlg::OnCheckParallel() {
if ( reinterpret_cast<CButton*>(GetDlgItem(IDC_CHECK_PARALLEL))->GetCheck() ) {
lightInfo.hasCenter = true;
lightInfo.isParallel = true;
lightInfo.lightCenter.x = 0;
lightInfo.lightCenter.y = 0;
lightInfo.lightCenter.z = 32;
} else {
lightInfo.isParallel = false;
lightInfo.hasCenter = false;
}
UpdateDialogFromLightInfo();
SetSpecifics();
}
//jhefty - only apply settings that are different
void CLightDlg::OnApplyDifferences () {
idDict differences, modified, original;
UpdateLightInfoFromDialog();
lightInfo.ToDict( &modified );
lightInfoOriginal.ToDictWriteAllInfo( &original );
differences = modified;
// jhefty - compile a set of modified values to apply
for ( int i = 0; i < modified.GetNumKeyVals (); i ++ ) {
const idKeyValue* valModified = modified.GetKeyVal ( i );
const idKeyValue* valOriginal = original.FindKey ( valModified->GetKey() );
//if it hasn't changed, remove it from the list of values to apply
if ( !valOriginal || ( valModified->GetValue() == valOriginal->GetValue() ) ) {
differences.Delete ( valModified->GetKey() );
}
}
SaveLightInfo( &differences );
lightInfoOriginal.FromDict( &modified );
Sys_UpdateWindows( W_ALL );
}