doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
VectorCtl.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 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.
23 
24 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.
25 
26 ===========================================================================
27 */
28 #include "../../idlib/precompiled.h"
29 #pragma hdrstop
30 
31 
32 #include "VectorCtl.h"
33 #include <math.h>
34 
35 BEGIN_MESSAGE_MAP(CVectorCtl, CButton)
36  //{{AFX_MSG_MAP(idGLWidget)
37  ON_WM_LBUTTONDOWN()
38  ON_WM_LBUTTONUP()
39  ON_WM_MOUSEMOVE()
40  //}}AFX_MSG_MAP
41 END_MESSAGE_MAP()
42 
44  m_bBmpCreated (FALSE),
45  m_bImageChange (TRUE),
46  m_bBackgroundBitmapUsed (FALSE),
47  m_clrDiffuse (DEFAULT_DIFFUSE),
48  m_clrAmbient (DEFAULT_AMBIENT),
49  m_clrLight (DEFAULT_LIGHT),
50  m_clrBackgroundStart (DEFAULT_START_BACKGROUND_COLOR),
51  m_clrBackgroundEnd (DEFAULT_END_BACKGROUND_COLOR),
52  m_dSpecularExponent (DEFAULT_SPEC_EXP),
53  m_bHasFocus (FALSE),
54  m_bSelected (FALSE),
55  m_bFrontVector (FALSE),
56  m_dSensitivity (20.0),
57  m_procVectorChanging (NULL),
58  m_procVectorChanged (NULL)
59 {
60  double DefaultVec[3] = DEFAULT_VEC;
61  for (int i=0; i<3; i++) {
62  m_dVec[i] = DefaultVec[i];
63  pCtl[i] = NULL;
64  }
65 
66  rotationQuat.Set( 0.0f, 0.0f, 0.0f, 1.0f );
67  lastPress.Zero();
68  radius = 0.6f;
69 }
70 
71 
73 {
74  if (m_bBmpCreated)
75  m_dcMem.SelectObject (m_pOldBitmap);
77 }
78 
79 // Owner-drawn control service function:
80 void CVectorCtl::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
81 {
82  CDC *pDC = CDC::FromHandle (lpDrawItemStruct->hDC); // Get CDC to draw
83 
84  if (!m_bSelected && lpDrawItemStruct->itemState & ODS_SELECTED) {
85  // Just got re-selected (user starts a new mouse dragging session)
86  } else if (m_bSelected && // Last state was selected
87  !(lpDrawItemStruct->itemState & ODS_SELECTED) && // New state is NOT selected
88  (lpDrawItemStruct->itemState & ODS_FOCUS) && // New state is still in focus
89  m_procVectorChanged) // User asked for a callback
90  // User has left the track-ball and asked for a callback.
92 
93  m_bHasFocus = lpDrawItemStruct->itemState & ODS_FOCUS; // Update focus status
94  m_bSelected = lpDrawItemStruct->itemState & ODS_SELECTED; // Update selection status
95 
96  if (!m_bBmpCreated) // 1st time
97  InitBitmap (lpDrawItemStruct, pDC);
98  if (m_bImageChange) { // Image has changes - recalc it!
99  if (m_procVectorChanging) // User has specified a callback
100  m_procVectorChanging ( rotationQuat ); // Call it!
101  BuildImage (lpDrawItemStruct);
103  }
104  pDC->BitBlt (0,0,m_iWidth, m_iHeight, &m_dcMem, 0, 0, SRCCOPY); // Update screen
105 }
106 
107 // Mouse was dragged
108 void CVectorCtl::OnMouseDrag (int ixMove, int iyMove)
109 {
110  RotateByXandY (double(-iyMove) / m_dSensitivity,
111  double(ixMove) / m_dSensitivity);
112 }
113 
114 // Recalc ball image
115 void CVectorCtl::BuildImage (LPDRAWITEMSTRUCT lpDrawItemStruct)
116 {
117  int xf, yf;
118 
119  for (int x=0; x<m_iWidth; x++) // Scan all columns
120  for (int y=0; y<m_iHeight; y++) { // Scan all rows
121  xf = x-m_iXCenter; // Find distance from center
122  yf = y-m_iYCenter;
123  if (xf*xf + yf*yf <= m_iSqrRadius) { // Point on ball surface
124  double vx = double(xf) / double(m_iRadius),
125  vy = double(yf) / double(m_iRadius),
126  vz = sqrt (1.0 - vx*vx - vy*vy); // Find ball's normal
127  m_dcMem.SetPixelV (x,y, CalcLight (vx,vy,vz));
128  }
129  }
130 }
131 
132 // Normalize a vector to unit size
134 {
135  double Norm = m_dVec[0] * m_dVec[0] + m_dVec[1] * m_dVec[1] + m_dVec[2] * m_dVec[2];
136 
137  if (Norm > EPS) {
138  Norm = sqrt (Norm);
139  m_dVec[0] /= Norm;
140  m_dVec[1] /= Norm;
141  m_dVec[2] /= Norm;
142  return TRUE;
143  } else { // Reset to defualt vector
144  double DefaultVec[3] = DEFAULT_VEC;
145  for (int i=0; i<3; i++)
146  m_dVec[i] = DefaultVec[i];
147  return FALSE;
148  }
149 }
150 
151 // Calculate lightning effect for specific pixel on ball's surface
152 COLORREF CVectorCtl::CalcLight (double dx, double dy, double dz)
153 {
154  double NL = dx * m_dVec[0] + dy * m_dVec[1] + dz * m_dVec[2],
155  RV = 2.0 * NL,
156  rx = m_dVec[0] - (dx * RV),
157  ry = m_dVec[1] - (dy * RV),
158  rz = m_dVec[2] - (dz * RV);
159 
160  if (NL < 0.0) // Diffuse coefficient
161  NL = 0.0;
162 
163  RV = max (0.0, -rz);
164  RV = double(pow (RV, m_dSpecularExponent));
165 
166  int r = int ( double(GetRValue(m_clrDiffuse)) * NL + // Diffuse
167  double(GetRValue(m_clrLight)) * RV + // Specular
168  double(GetRValue(m_clrAmbient))), // Ambient
169 
170  g = int ( double(GetGValue(m_clrDiffuse)) * NL + // Diffuse
171  double(GetGValue(m_clrLight)) * RV + // Specular
172  double(GetGValue(m_clrAmbient))), // Ambient
173 
174  b = int ( double(GetBValue(m_clrDiffuse)) * NL + // Diffuse
175  double(GetBValue(m_clrLight)) * RV + // Specular
176  double(GetBValue(m_clrAmbient))); // Ambient
177 
178  r = min (255, r); // Cutoff highlight
179  g = min (255, g);
180  b = min (255, b);
181  return RGB(BYTE(r),BYTE(g),BYTE(b));
182 }
183 
184 
185 // Start memory buffer bitmap and measure it
186 void CVectorCtl::InitBitmap (LPDRAWITEMSTRUCT lpDrawItemStruct, CDC *pDC)
187 {
188  m_iWidth = lpDrawItemStruct->rcItem.right - lpDrawItemStruct->rcItem.left;
189  m_iHeight = lpDrawItemStruct->rcItem.bottom - lpDrawItemStruct->rcItem.top;
190  m_bmpBuffer.CreateCompatibleBitmap (pDC, m_iWidth, m_iHeight);
192  m_dcMem.CreateCompatibleDC (pDC);
193  m_pOldBitmap = m_dcMem.SelectObject (&m_bmpBuffer);
194  SetRadius (max (min (m_iWidth, m_iHeight) - 2, 0) / 2);
195  SetCenter (m_iWidth / 2, m_iHeight / 2);
196  CreateBackground ();
197 }
198 
199 // Set new specular intensity
201 {
202  if (dExp < 1.0 || dExp > 200.0)
203  return FALSE;
204  m_dSpecularExponent = dExp;
205  Redraw ();
206  return TRUE;
207 }
208 
209 // Rotate our vector around the X and Y axis
210 void CVectorCtl::RotateByXandY (double XRot, double YRot)
211 { // Angles are in radians
212 
213  if (XRot == 0.0 && YRot == 0.0) {
214  return;
215  }
216 
217  double cx = cos(XRot),
218  sx = sin(XRot),
219  cy = cos(YRot),
220  sy = sin(YRot),
221  dx = m_dVec[0] * cy + m_dVec[1] * sx * sy + m_dVec[2] * cx * sy,
222  dy = m_dVec[1] * cx - m_dVec[2] * sx,
223  dz = -m_dVec[0] * sy + m_dVec[1] * sx * cy + m_dVec[2] * cx * cy;
224 
225  if (!m_bFrontVector || dz >= 0.0) { // Vector is bounds free
226  m_dVec[0] = dx;
227  m_dVec[1] = dy;
228  m_dVec[2] = dz;
229  } else { // Otherwise, do not allow Z to be negative (light shines from behind)
230  m_dVec[2] = 0.0;
231  m_dVec[0] = dx;
232  m_dVec[1] = dy;
233  Normalize ();
234  }
235  Redraw ();
236 }
237 
238 
240 {
241  CString cs;
242  for (int i=0; i<3; i++)
243  if (pCtl[i]) {
244  cs.Format ("%+1.5f",m_dVec[i]);
245  pCtl[i]->SetWindowText (cs);
246  }
247 }
248 
249 void CVectorCtl::SetAxisControl (int nXCtl, int nYCtl, int nZCtl)
250 {
251  pCtl[0] = GetParent()->GetDlgItem(nXCtl);
252  pCtl[1] = GetParent()->GetDlgItem(nYCtl);
253  pCtl[2] = GetParent()->GetDlgItem(nZCtl);
254 }
255 
257 {
258  m_iRadius = uRadius;
260  CreateBackground ();
261  Redraw (TRUE);
262 }
263 
264 
265 void CVectorCtl::SetCenter (UINT uHorizPos, UINT uVertPos)
266 {
267  m_iXCenter = uHorizPos;
268  m_iYCenter = uVertPos;
269  CreateBackground ();
270  Redraw (TRUE);
271 }
272 
273 
274 void CVectorCtl::SetAxis (double d, int nAxis)
275 {
276  if (fabs(d)>=1.0) {
277  m_dVec[nAxis]=d > 1.0 ? 1.0 : -1.0;
278  m_dVec[(nAxis+1) %3]=m_dVec[(nAxis+2) %3]=0.0;
279  Redraw ();
280  return;
281  }
282  m_dVec[nAxis] = d;
283  Normalize ();
284  Redraw ();
285 }
286 
287 void CVectorCtl::SetVector (double dx, double dy, double dz)
288 {
289  m_dVec[0] = dx;
290  m_dVec[1] = dy;
291  m_dVec[2] = dz;
292  Normalize ();
293  Redraw ();
294 }
295 
296 void CVectorCtl::SetBackgroundColor (COLORREF clrStart, COLORREF clrEnd)
297 {
299  m_clrBackgroundStart = clrStart;
300  m_clrBackgroundEnd = clrEnd;
301  CreateBackground ();
302 }
303 
304 
306 {
309  CreateBackground ();
310  }
311  if (!m_bmpBack.LoadBitmap (uBackgroundBitmapID))
312  return FALSE;
314  CreateBackground ();
315  return TRUE;
316 }
317 
319 {
320  if (!m_bBmpCreated)
321  return; // No image yet
322  if (!m_bBackgroundBitmapUsed) { // No background used - fill with gradient color
323  double r = GetRValue (m_clrBackgroundStart),
324  g = GetGValue (m_clrBackgroundStart),
325  b = GetBValue (m_clrBackgroundStart),
326  rd = double (GetRValue (m_clrBackgroundEnd) - r) / double (m_iHeight),
327  gd = double (GetGValue (m_clrBackgroundEnd) - g) / double (m_iHeight),
328  bd = double (GetBValue (m_clrBackgroundEnd) - b) / double (m_iHeight);
329  for (int j=0; j<m_iHeight; j++) {
330  for (int i=0; i<m_iWidth; i++)
331  m_dcMem.SetPixelV (i,j, RGB (BYTE(r),BYTE(g),BYTE(b)));
332  r+=rd; g+=gd; b+=bd;
333  }
334  Redraw (TRUE);
335  return;
336  }
337  // Bitmap used : tile it in back
338  CDC DCtmp;
339  BITMAP tmpBitmap;
340 
341  m_bmpBack.GetBitmap (&tmpBitmap);
342  int iTmpWidth = tmpBitmap.bmWidth,
343  iTmpHeight = tmpBitmap.bmHeight;
344 
345  DCtmp.CreateCompatibleDC (&m_dcMem);
346  m_pOldBitmap = DCtmp.SelectObject (&m_bmpBack);
347 
348  for (int i=0; i<m_iWidth; i++)
349  for (int j=0; j<m_iHeight; j++)
350  m_dcMem.SetPixelV (i,j, DCtmp.GetPixel (i % iTmpWidth, j % iTmpHeight));
351  DCtmp.SelectObject (m_pOldBitmap);
352  Redraw (TRUE);
353 }
354 
355 
357 {
359  return;
360  m_bmpBack.DeleteObject ();
362 }
363 
365 {
366  if (uSens == 0)
367  return FALSE;
368  m_dSensitivity = double(uSens);
369  return TRUE;
370 }
371 
372 void CVectorCtl::Redraw (BOOL bErase) {
375  Invalidate (bErase);
376 }
377 
378 void CVectorCtl::OnMouseMove(UINT nFlags, CPoint point) {
379 
380  if ( CWnd::GetCapture() != this ) {
381  return;
382  }
383 
384  float curX = ( float )( 2 * point.x - 64 ) / 64;
385  float curY = ( float )( 2 * point.y - 64 ) / 64;
386 
387  idVec3 to( -curX, -curY, 0.0f );
390 
391  idVec3 axis;
392  axis.Cross( to, lastPress );
393  float len = ( lastPress - to ).Length() / ( 2.0f * radius );
394  len = idMath::ClampFloat( -1.0f, 1.0f, len );
395  float phi = 2.0f * asin ( len ) ;
396 
397  axis.Normalize();
398  axis *= sin( phi / 2.0f );
399  idQuat rot( axis.z, axis.y, axis.x, cos( phi / 2.0f ) );
400  rot.Normalize();
401 
402  rotationQuat *= rot;
404 
405  lastPress = to;
406  lastPress.z = 0.0f;
407 
408  m_dVec = rotationQuat.ToMat3()[2];
409  m_dVec.Normalize();
410  Redraw();
411 }
412 
413 void CVectorCtl::OnLButtonDown(UINT nFlags, CPoint point) {
414  float curX = ( float )( 2 * point.x - 64 ) / 64;
415  float curY = ( float )( 2 * point.y - 64 ) / 64;
416  lastPress.Set( -curX, -curY, 0.0f );
417  SetCapture();
418 }
419 
420 void CVectorCtl::OnLButtonUp(UINT nFlags, CPoint point) {
421  ReleaseCapture();
422 }
423 
424 
GLubyte g
Definition: glext.h:4662
#define min(a, b)
void SetRadius(UINT uRadius)
Definition: VectorCtl.cpp:256
float Normalize(void)
Definition: Vector.h:646
afx_msg void OnLButtonUp(UINT nFlags, CPoint point)
Definition: VectorCtl.cpp:420
BOOL SetBackgroundImage(UINT uBackgroundBitmapID)
Definition: VectorCtl.cpp:305
CONST PIXELFORMATDESCRIPTOR UINT
Definition: win_qgl.cpp:47
idMat3 ToMat3(void) const
Definition: Quat.cpp:70
VectorCtlCallbackProc m_procVectorChanging
Definition: VectorCtl.h:216
BOOL m_bFrontVector
Definition: VectorCtl.h:186
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
Definition: VectorCtl.cpp:80
BOOL SetSensitivity(UINT uSens)
Definition: VectorCtl.cpp:364
void Set(const float x, const float y, const float z)
Definition: Vector.h:409
GLenum GLint GLint y
Definition: glext.h:2849
COLORREF m_clrLight
Definition: VectorCtl.h:199
float z
Definition: Vector.h:320
case const int
Definition: Callbacks.cpp:52
CBitmap m_bmpBack
Definition: VectorCtl.h:183
int m_iSqrRadius
Definition: VectorCtl.h:192
static float ClampFloat(float min, float max, float value)
Definition: Math.h:893
void InitBitmap(LPDRAWITEMSTRUCT lpDrawItemStruct, CDC *pDC)
Definition: VectorCtl.cpp:186
Definition: Vector.h:316
case const float
Definition: Callbacks.cpp:62
idQuat & Normalize(void)
Definition: Quat.h:265
#define DEFAULT_SPEC_EXP
Definition: VectorCtl.h:75
BOOL SetSpecularExponent(double dExp)
Definition: VectorCtl.cpp:200
GLenum GLsizei len
Definition: glext.h:3472
idVec3 Cross(const idVec3 &a) const
Definition: Vector.h:619
float x
Definition: Vector.h:318
GLenum GLint x
Definition: glext.h:2849
int i
Definition: process.py:33
#define BOOL
Definition: mprintf.c:71
#define DEFAULT_START_BACKGROUND_COLOR
Definition: VectorCtl.h:73
void SetCenter(UINT uHorizPos, UINT uVertPos)
Definition: VectorCtl.cpp:265
void SetVector(double dx, double dy, double dz)
Definition: VectorCtl.cpp:287
CDC m_dcMem
Definition: VectorCtl.h:185
void SetBackgroundColor(COLORREF clrStart, COLORREF clrEnd)
Definition: VectorCtl.cpp:296
int m_iXCenter
Definition: VectorCtl.h:192
BOOL m_bImageChange
Definition: VectorCtl.h:186
COLORREF m_clrBackgroundStart
Definition: VectorCtl.h:199
float radius
Definition: VectorCtl.h:213
void OnMouseDrag(int, int)
Definition: VectorCtl.cpp:108
idQuat rotationQuat
Definition: VectorCtl.h:210
void BuildImage(LPDRAWITEMSTRUCT lpDrawItemStruct)
Definition: VectorCtl.cpp:115
int m_iYCenter
Definition: VectorCtl.h:192
#define NULL
Definition: Lib.h:88
BOOL Normalize()
Definition: VectorCtl.cpp:133
double m_dSpecularExponent
Definition: VectorCtl.h:205
float y
Definition: Vector.h:319
#define DEFAULT_AMBIENT
Definition: VectorCtl.h:71
BOOL m_bBmpCreated
Definition: VectorCtl.h:186
void CreateBackground()
Definition: VectorCtl.cpp:318
void SetAxisControl(int nXCtl, int nYCtl, int nZCtl)
Definition: VectorCtl.cpp:249
int m_iHeight
Definition: VectorCtl.h:192
COLORREF m_clrAmbient
Definition: VectorCtl.h:199
CBitmap m_bmpBuffer
Definition: VectorCtl.h:183
VectorCtlCallbackProc m_procVectorChanged
Definition: VectorCtl.h:216
virtual ~CVectorCtl()
Definition: VectorCtl.cpp:72
void SetAxis(double d, int nAxis)
Definition: VectorCtl.cpp:274
void RotateByXandY(double XRot, double YRot)
Definition: VectorCtl.cpp:210
#define EPS
Definition: VectorCtl.h:67
#define DEFAULT_VEC
Definition: VectorCtl.h:69
afx_msg void OnLButtonDown(UINT nFlags, CPoint point)
Definition: VectorCtl.cpp:413
GLubyte GLubyte b
Definition: glext.h:4662
Definition: Quat.h:48
#define DEFAULT_LIGHT
Definition: VectorCtl.h:72
COLORREF m_clrBackgroundEnd
Definition: VectorCtl.h:199
#define DEFAULT_DIFFUSE
Definition: VectorCtl.h:70
GLdouble GLdouble GLdouble r
Definition: glext.h:2951
void ProjectSelfOntoSphere(const float radius)
Definition: Vector.cpp:284
void Redraw(BOOL bErase=FALSE)
Definition: VectorCtl.cpp:372
tuple f
Definition: idal.py:89
MFnDagNode * GetParent(MFnDagNode *joint)
Definition: maya_main.cpp:350
BOOL m_bSelected
Definition: VectorCtl.h:186
idVec3 lastPress
Definition: VectorCtl.h:212
#define DEFAULT_END_BACKGROUND_COLOR
Definition: VectorCtl.h:74
int m_iRadius
Definition: VectorCtl.h:192
#define FALSE
Definition: mprintf.c:70
idVec3 m_dVec
Definition: VectorCtl.h:208
int m_iWidth
Definition: VectorCtl.h:192
CWnd * pCtl[3]
Definition: VectorCtl.h:204
double m_dSensitivity
Definition: VectorCtl.h:205
#define TRUE
Definition: mprintf.c:69
GLint j
Definition: qgl.h:264
void UpdateAxisControls()
Definition: VectorCtl.cpp:239
BOOL m_bHasFocus
Definition: VectorCtl.h:186
COLORREF CalcLight(double dx, double dy, double dz)
Definition: VectorCtl.cpp:152
#define max(x, y)
Definition: os.h:70
void ClearBackgroundBitmap()
Definition: VectorCtl.cpp:356
COLORREF m_clrDiffuse
Definition: VectorCtl.h:199
BOOL m_bBackgroundBitmapUsed
Definition: VectorCtl.h:186
afx_msg void OnMouseMove(UINT nFlags, CPoint point)
Definition: VectorCtl.cpp:378
CBitmap * m_pOldBitmap
Definition: VectorCtl.h:198