// Miner3D_viewerCtl.cpp : Implementation of the CMiner3D_viewerCtrl ActiveX Control class.
#include "stdafx.h"
#include "Miner3D_viewer.h"
#include "Miner3D_viewerCtl.h"
#include "Miner3D_viewerPpg.h"
#include <Mmsystem.h>
#include "PlayMidi.h"
#include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNCREATE(CMiner3D_viewerCtrl, COleControl)
/////////////////////////////////////////////////////////////////////////////
// Message map
BEGIN_MESSAGE_MAP(CMiner3D_viewerCtrl, COleControl)
//{{AFX_MSG_MAP(CMiner3D_viewerCtrl)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_TIMER()
ON_WM_SIZE()
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
//}}AFX_MSG_MAP
ON_MESSAGE(OCM_COMMAND, OnOcmCommand)
ON_MESSAGE(MM_MCINOTIFY, OnMciNotify)
ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// Dispatch map
BEGIN_DISPATCH_MAP(CMiner3D_viewerCtrl, COleControl)
//{{AFX_DISPATCH_MAP(CMiner3D_viewerCtrl)
DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "Interval", m_interval, OnIntervalChanged, VT_I4)
DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "CharRotateDegree", m_charRotateDegree, OnCharRotateDegreeChanged, VT_R8)
DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "SeeAngle", m_seeAngle, OnSeeAngleChanged, VT_R8)
DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "SeeNearest", m_seeNearest, OnSeeNearestChanged, VT_R8)
DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "SeeFarthest", m_seeFarthest, OnSeeFarthestChanged, VT_R8)
DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "FogColor", m_fogColor, OnFogColorChanged, VT_COLOR)
DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "FogDensity", m_fogDensity, OnFogDensityChanged, VT_R4)
DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "PickLessExact", m_pickLessExact, OnPickLessExactChanged, VT_R8)
DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "CamPosX", m_camPosX, OnCamPosXChanged, VT_R8)
DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "CamPosY", m_camPosY, OnCamPosYChanged, VT_R8)
DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "CamPosZ", m_camPosZ, OnCamPosZChanged, VT_R8)
DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "CamAxz", m_camAxz, OnCamAxzChanged, VT_R8)
DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "CamAzy", m_camAzy, OnCamAzyChanged, VT_R8)
DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "Light1", m_light1, OnLight1Changed, VT_BOOL)
DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "WireVisible", m_wireVisible, OnWireVisibleChanged, VT_BOOL)
DISP_FUNCTION(CMiner3D_viewerCtrl, "ClearAll", ClearAll, VT_EMPTY, VTS_NONE)
DISP_FUNCTION(CMiner3D_viewerCtrl, "AddTile", AddTile, VT_BOOL, VTS_I4 VTS_R8 VTS_R8 VTS_R8)
DISP_FUNCTION(CMiner3D_viewerCtrl, "AddChar", AddChar, VT_BOOL, VTS_I2 VTS_R8 VTS_R8 VTS_R8)
DISP_FUNCTION(CMiner3D_viewerCtrl, "OpenTile", OpenTile, VT_EMPTY, VTS_I4)
DISP_FUNCTION(CMiner3D_viewerCtrl, "ChangeTileColor", ChangeTileColor, VT_EMPTY, VTS_I4 VTS_COLOR)
DISP_FUNCTION(CMiner3D_viewerCtrl, "AddColorTile", AddColorTile, VT_BOOL, VTS_I4 VTS_R8 VTS_R8 VTS_R8 VTS_COLOR)
DISP_FUNCTION(CMiner3D_viewerCtrl, "Pick", Pick, VT_I4, VTS_R8 VTS_R8 VTS_PBOOL)
DISP_FUNCTION(CMiner3D_viewerCtrl, "PlayMidiFile", PlayMidiFile, VT_EMPTY, VTS_BSTR)
DISP_FUNCTION(CMiner3D_viewerCtrl, "StopPlayMidi", StopPlayMidi, VT_EMPTY, VTS_NONE)
DISP_FUNCTION(CMiner3D_viewerCtrl, "GetCamDirX", GetCamDirX, VT_R8, VTS_NONE)
DISP_FUNCTION(CMiner3D_viewerCtrl, "GetCamDirY", GetCamDirY, VT_R8, VTS_NONE)
DISP_FUNCTION(CMiner3D_viewerCtrl, "GetCamDirZ", GetCamDirZ, VT_R8, VTS_NONE)
DISP_FUNCTION(CMiner3D_viewerCtrl, "AddPoint", AddPoint, VT_BOOL, VTS_R8 VTS_R8 VTS_R8)
DISP_FUNCTION(CMiner3D_viewerCtrl, "AddFace", AddFace, VT_BOOL, VTS_I2 VTS_R8 VTS_R8 VTS_R8 VTS_R8 VTS_COLOR)
DISP_FUNCTION(CMiner3D_viewerCtrl, "GetTilePos", GetTilePos, VT_BOOL, VTS_I2 VTS_PR8 VTS_PR8 VTS_PR8)
DISP_FUNCTION(CMiner3D_viewerCtrl, "AddWireTile", AddWireTile, VT_BOOL, VTS_R8 VTS_R8 VTS_R8)
DISP_FUNCTION(CMiner3D_viewerCtrl, "AddColorWireTile", AddColorWireTile, VT_BOOL, VTS_R8 VTS_R8 VTS_R8 VTS_COLOR)
DISP_FUNCTION(CMiner3D_viewerCtrl, "GetHandleActiveWindow", GetHandleActiveWindow, VT_HANDLE, VTS_NONE)
DISP_DEFVALUE(CMiner3D_viewerCtrl, "BackColor")
DISP_STOCKPROP_BACKCOLOR()
DISP_FUNCTION_ID(CMiner3D_viewerCtrl, "Refresh", DISPID_REFRESH, Refresh, VT_EMPTY, VTS_NONE)
//}}AFX_DISPATCH_MAP
DISP_FUNCTION_ID(CMiner3D_viewerCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()
/////////////////////////////////////////////////////////////////////////////
// Event map
BEGIN_EVENT_MAP(CMiner3D_viewerCtrl, COleControl)
//{{AFX_EVENT_MAP(CMiner3D_viewerCtrl)
EVENT_CUSTOM("Timer", FireTimer, VTS_NONE)
EVENT_CUSTOM("LeftButtonDown", FireLeftButtonDown, VTS_I4 VTS_I4 VTS_BOOL VTS_BOOL)
EVENT_CUSTOM("RightButtonDown", FireRightButtonDown, VTS_I4 VTS_I4 VTS_BOOL VTS_BOOL)
EVENT_CUSTOM("EndPlayMidi", FireEndPlayMidi, VTS_NONE)
EVENT_CUSTOM("VcKeyDown", FireVcKeyDown, VTS_I4 VTS_I2)
EVENT_CUSTOM("VcKeyUp", FireVcKeyUp, VTS_I4 VTS_I2)
EVENT_STOCK_KEYDOWN()
EVENT_STOCK_KEYUP()
EVENT_STOCK_MOUSEDOWN()
EVENT_STOCK_MOUSEUP()
EVENT_STOCK_MOUSEMOVE()
EVENT_STOCK_DBLCLICK()
//}}AFX_EVENT_MAP
END_EVENT_MAP()
/////////////////////////////////////////////////////////////////////////////
// Property pages
// TODO: Add more property pages as needed. Remember to increase the count!
BEGIN_PROPPAGEIDS(CMiner3D_viewerCtrl, 1)
PROPPAGEID(CMiner3D_viewerPropPage::guid)
END_PROPPAGEIDS(CMiner3D_viewerCtrl)
/////////////////////////////////////////////////////////////////////////////
// Initialize class factory and guid
IMPLEMENT_OLECREATE_EX(CMiner3D_viewerCtrl, "MINER3DVIEWER.Miner3DviewerCtrl.1",
0xe5a0ff08, 0x1c29, 0x11d8, 0xb8, 0x18, 0, 0x6, 0x7b, 0x2, 0xba, 0x6f)
/////////////////////////////////////////////////////////////////////////////
// Type library ID and version
IMPLEMENT_OLETYPELIB(CMiner3D_viewerCtrl, _tlid, _wVerMajor, _wVerMinor)
/////////////////////////////////////////////////////////////////////////////
// Interface IDs
const IID BASED_CODE IID_DMiner3D_viewer =
{ 0xe5a0ff06, 0x1c29, 0x11d8, { 0xb8, 0x18, 0, 0x6, 0x7b, 0x2, 0xba, 0x6f } };
const IID BASED_CODE IID_DMiner3D_viewerEvents =
{ 0xe5a0ff07, 0x1c29, 0x11d8, { 0xb8, 0x18, 0, 0x6, 0x7b, 0x2, 0xba, 0x6f } };
/////////////////////////////////////////////////////////////////////////////
// Control type information
static const DWORD BASED_CODE _dwMiner3D_viewerOleMisc =
OLEMISC_ACTIVATEWHENVISIBLE |
OLEMISC_SETCLIENTSITEFIRST |
OLEMISC_INSIDEOUT |
OLEMISC_CANTLINKINSIDE |
OLEMISC_RECOMPOSEONRESIZE;
IMPLEMENT_OLECTLTYPE(CMiner3D_viewerCtrl, IDS_MINER3D_VIEWER, _dwMiner3D_viewerOleMisc)
/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::CMiner3D_viewerCtrlFactory::UpdateRegistry -
// Adds or removes system registry entries for CMiner3D_viewerCtrl
BOOL CMiner3D_viewerCtrl::CMiner3D_viewerCtrlFactory::UpdateRegistry(BOOL bRegister)
{
// TODO: Verify that your control follows apartment-model threading rules.
// Refer to MFC TechNote 64 for more information.
// If your control does not conform to the apartment-model rules, then
// you must modify the code below, changing the 6th parameter from
// afxRegApartmentThreading to 0.
if (bRegister)
return AfxOleRegisterControlClass(
AfxGetInstanceHandle(),
m_clsid,
m_lpszProgID,
IDS_MINER3D_VIEWER,
IDB_MINER3D_VIEWER,
afxRegApartmentThreading,
_dwMiner3D_viewerOleMisc,
_tlid,
_wVerMajor,
_wVerMinor);
else
return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
}
/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::CMiner3D_viewerCtrl - Constructor
CMiner3D_viewerCtrl::CMiner3D_viewerCtrl()
{
InitializeIIDs(&IID_DMiner3D_viewer, &IID_DMiner3D_viewerEvents);
// TODO: Initialize your control's instance data here.
}
/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::~CMiner3D_viewerCtrl - Destructor
CMiner3D_viewerCtrl::~CMiner3D_viewerCtrl()
{
// TODO: Cleanup your control's instance data here.
}
/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::OnDraw - Drawing function
void CMiner3D_viewerCtrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
DoSuperclassPaint(pdc, rcBounds);
}
/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::DoPropExchange - Persistence support
void CMiner3D_viewerCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
// TODO: Call PX_ functions for each persistent custom property.
PX_Long(pPX,"Interval",m_interval,0);
PX_Double(pPX,"CharRotateDegree",m_charRotateDegree,0);
PX_Double(pPX,"SeeAngle",m_seeAngle,45.0);
PX_Double(pPX,"SeeNearest",m_seeNearest,1.0);
PX_Double(pPX,"SeeFarthest",m_seeFarthest,25.0);
PX_Double(pPX,"CamPosX",m_camPosX,0.0);
PX_Double(pPX,"CamPosY",m_camPosY,0.0);
PX_Double(pPX,"CamPosZ",m_camPosZ,-8.0);
PX_Double(pPX,"CamAxz",m_camAxz,3.1415/2);
PX_Double(pPX,"CamAzy",m_camAzy,0.0);
PX_Double(pPX,"PickLessExact",m_pickLessExact,5.0);
PX_Color(pPX,"FogColor",m_fogColor,0x00808080);
PX_Float(pPX,"FogDensity",m_fogDensity,0);
PX_Bool(pPX,"Light1",m_light1,TRUE);
PX_Bool(pPX,"WireVisible",m_wireVisible,TRUE);
}
/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::GetControlFlags -
// Flags to customize MFC's implementation of ActiveX controls.
//
// For information on using these flags, please see MFC technical note
// #nnn, "Optimizing an ActiveX Control".
DWORD CMiner3D_viewerCtrl::GetControlFlags()
{
DWORD dwFlags = COleControl::GetControlFlags();
// The control will not be redrawn when making the transition
// between the active and inactivate state.
dwFlags |= noFlickerActivate;
return dwFlags;
}
/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::OnResetState - Reset control to default state
void CMiner3D_viewerCtrl::OnResetState()
{
COleControl::OnResetState(); // Resets defaults found in DoPropExchange
// TODO: Reset any other control state here.
}
/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::AboutBox - Display an "About" box to the user
void CMiner3D_viewerCtrl::AboutBox()
{
CDialog dlgAbout(IDD_ABOUTBOX_MINER3D_VIEWER);
dlgAbout.DoModal();
}
/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::PreCreateWindow - Modify parameters for CreateWindowEx
BOOL CMiner3D_viewerCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
//cs.lpszClass = _T("STATIC");
return COleControl::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::IsSubclassedControl - This is a subclassed control
BOOL CMiner3D_viewerCtrl::IsSubclassedControl()
{
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::OnOcmCommand - Handle command messages
LRESULT CMiner3D_viewerCtrl::OnOcmCommand(WPARAM wParam, LPARAM lParam)
{
#ifdef _WIN32
WORD wNotifyCode = HIWORD(wParam);
#else
WORD wNotifyCode = HIWORD(lParam);
#endif
// TODO: Switch on wNotifyCode here.
return 0;
}
/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl message handlers
int CMiner3D_viewerCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (COleControl::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
hRC=SetUpOpenGL(m_hWnd);
m_cc.Init(m_hWnd,hRC);
m_tc.Add(1,0,0,0);
UpdateCamDir();
if (m_interval) SetTimer(1000,m_interval,NULL);
m_cc.rotate=m_charRotateDegree;
return 0;
}
void CMiner3D_viewerCtrl::OnDestroy()
{
COleControl::OnDestroy();
// TODO: Add your message handler code here
KillTimer(1000);
}
void CMiner3D_viewerCtrl::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if(nIDEvent==1000)
{
FireTimer();
RedrawWindow();
}
COleControl::OnTimer(nIDEvent);
}
void CMiner3D_viewerCtrl::OnSize(UINT nType, int cx, int cy)
{
COleControl::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
HDC hDC = ::GetDC(this->m_hWnd);
wglMakeCurrent(hDC,hRC);
//**Write code for GL resize here!
m_intWidth = (GLsizei)cx;
m_intHeight = (GLsizei)cy;
m_dblAspect = (GLdouble)m_intWidth/(GLdouble)m_intHeight;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0,0,m_intWidth,m_intHeight);
gluPerspective(m_seeAngle,m_dblAspect,m_seeNearest,m_seeFarthest);
//**End code for GL resize!
wglMakeCurrent( NULL, NULL );
::ReleaseDC( this->m_hWnd, hDC );
}
void CMiner3D_viewerCtrl::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
wglMakeCurrent(dc.m_hDC,hRC);
//**Draw GL here!
COLORREF color=TranslateColor(GetBackColor());
if (m_fogDensity)
{
glEnable(GL_FOG);
{
GLfloat fogColor[4] = {
((float)(m_fogColor&0xFF))/255,
((float)((m_fogColor&0xFF00)>>8))/255,
((float)((m_fogColor&0xFF0000)>>16))/255,
1.0};
glFogi (GL_FOG_MODE, GL_EXP);
glFogfv (GL_FOG_COLOR, fogColor);
glFogf (GL_FOG_DENSITY, m_fogDensity);
glHint (GL_FOG_HINT, GL_DONT_CARE);
}
}
glClearColor(
((float)(color&0xFF))/255,
((float)((color&0xFF00)>>8))/255,
((float)((color&0xFF0000)>>16))/255,
0.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(m_camPosX,m_camPosY,m_camPosZ,
m_camPosX+m_camDirX,m_camPosY+m_camDirY,m_camPosZ+m_camDirZ,
0.0,1.0,0.0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
if(m_light1)
{
GLfloat light1_diffuse[] = { 0.4f, 0.4f, 0.4f, 0.4f };
GLfloat light1_position[] = { 0.0f, 1000.0f, 0.0f, 1.0f };
glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
glEnable(GL_LIGHT1);
}
m_tc.Draw(GL_RENDER);
m_cc.Draw();
m_pc.Draw();
m_fc.Draw();
if (m_wireVisible) m_wc.Draw();
if(m_light1) glDisable(GL_LIGHT1);
glDisable(GL_LIGHT0);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
if (m_fogDensity) glDisable(GL_FOG);
//**End code for draw GL!
SwapBuffers(dc.m_hDC);
wglMakeCurrent(NULL,NULL);
//int cx=m_intWidth/2,cy=m_intHeight/2;
//dc.Ellipse(CRect(cx-2,cy-2,cx+2,cy+2));
//dc.SetBkMode(TRANSPARENT);
//dc.SetTextColor(0x00ffffff);
//dc.DrawText("",-1,CRect(0,0,m_intHeight,m_intWidth),DT_SINGLELINE);
// Do not call COleControl::OnPaint() for painting messages
}
////////////////////////properties
void CMiner3D_viewerCtrl::OnIntervalChanged()
{
// TODO: Add notification handler code
KillTimer(1000);
if (m_interval) SetTimer(1000,m_interval,NULL);
SetModifiedFlag();
}
void CMiner3D_viewerCtrl::OnCharRotateDegreeChanged()
{
// TODO: Add notification handler code
m_cc.rotate=m_charRotateDegree;
SetModifiedFlag();
}
void CMiner3D_viewerCtrl::OnSeeAngleChanged()
{
// TODO: Add notification handler code
RefreshSize();
SetModifiedFlag();
}
void CMiner3D_viewerCtrl::OnSeeNearestChanged()
{
// TODO: Add notification handler code
RefreshSize();
SetModifiedFlag();
}
void CMiner3D_viewerCtrl::OnSeeFarthestChanged()
{
// TODO: Add notification handler code
RefreshSize();
SetModifiedFlag();
}
void CMiner3D_viewerCtrl::OnFogColorChanged()
{
// TODO: Add notification handler code
SetModifiedFlag();
}
void CMiner3D_viewerCtrl::OnFogDensityChanged()
{
// TODO: Add notification handler code
SetModifiedFlag();
}
void CMiner3D_viewerCtrl::OnPickLessExactChanged()
{
// TODO: Add notification handler code
SetModifiedFlag();
}
void CMiner3D_viewerCtrl::OnCamPosXChanged()
{
// TODO: Add notification handler code
SetModifiedFlag();
}
void CMiner3D_viewerCtrl::OnCamPosYChanged()
{
// TODO: Add notification handler code
SetModifiedFlag();
}
void CMiner3D_viewerCtrl::OnCamPosZChanged()
{
// TODO: Add notification handler code
SetModifiedFlag();
}
void CMiner3D_viewerCtrl::OnCamAxzChanged()
{
// TODO: Add notification handler code
UpdateCamDir();
SetModifiedFlag();
}
void CMiner3D_viewerCtrl::OnCamAzyChanged()
{
// TODO: Add notification handler code
UpdateCamDir();
SetModifiedFlag();
}
////////////////////////Method
void CMiner3D_viewerCtrl::ClearAll()
{
// TODO: Add your dispatch handler code here
m_cc.RemoveAll();
m_tc.RemoveAll();
m_pc.RemoveAll();
m_fc.RemoveAll();
m_wc.RemoveAll();
}
BOOL CMiner3D_viewerCtrl::AddTile(long id, double x, double y, double z)
{
// TODO: Add your dispatch handler code here
if (m_tc.Add(id,x,y,z)==NULL) return FALSE;
return TRUE;
}
BOOL CMiner3D_viewerCtrl::AddChar(short c, double x, double y, double z)
{
// TODO: Add your dispatch handler code here
if (m_cc.Add(c,x,y,z)==NULL) return FALSE;
return TRUE;
}
void CMiner3D_viewerCtrl::Refresh()
{
// TODO: Add your dispatch handler code here
RedrawWindow();
}
void CMiner3D_viewerCtrl::OpenTile(long id)
{
// TODO: Add your dispatch handler code here
TileNode *p=m_tc.Get(id);
if (p==NULL) return;
p->opening=TRUE;
}
void CMiner3D_viewerCtrl::ChangeTileColor(long id, OLE_COLOR color)
{
// TODO: Add your dispatch handler code here
TileNode *p=m_tc.Get(id);
if (p==NULL) return;
p->t.m_materialColor[0]=((float)(color&0xFF))/255;
p->t.m_materialColor[1]=((float)((color&0xFF00)>>8))/255;
p->t.m_materialColor[2]=((float)((color&0xFF0000)>>16))/255;
}
BOOL CMiner3D_viewerCtrl::AddColorTile(long id, double x, double y, double z, OLE_COLOR color)
{
// TODO: Add your dispatch handler code here
TileNode *p=m_tc.Add(id,x,y,z);
if (p==NULL) return FALSE;
p->t.m_materialColor[0]=((float)(color&0xFF))/255;
p->t.m_materialColor[1]=((float)((color&0xFF00)>>8))/255;
p->t.m_materialColor[2]=((float)((color&0xFF0000)>>16))/255;
return TRUE;
}
long CMiner3D_viewerCtrl::Pick(double x, double y, BOOL FAR* miss)
{
// TODO: Add your dispatch handler code here
GLuint selectBuf[4096];
GLint hits;
GLint viewport[4];
int n=0;
try
{
GLdouble px=m_camPosX;
GLdouble py=m_camPosY;
GLdouble pz=m_camPosZ;
HDC hDC = ::GetDC(this->m_hWnd);
wglMakeCurrent(hDC,hRC);
glGetIntegerv (GL_VIEWPORT, viewport);
glSelectBuffer (4096, selectBuf);
glRenderMode(GL_SELECT); // Enter the SELECT render mode
glInitNames();
glPushName(-1);
glMatrixMode (GL_PROJECTION);
glPushMatrix ();
glLoadIdentity ();
gluPickMatrix((GLdouble)x, (GLdouble) (viewport[3] -y), m_pickLessExact, m_pickLessExact, viewport);
gluPerspective(m_seeAngle,m_dblAspect,m_seeNearest,m_seeFarthest);
glMatrixMode(GL_MODELVIEW);
//m_cc.Draw(GL_SELECT);
m_tc.Draw(GL_SELECT);
glPopMatrix ();
glFlush ();
hits = glRenderMode (GL_RENDER);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0,0,m_intWidth,m_intHeight);
gluPerspective(m_seeAngle,m_dblAspect,m_seeNearest,m_seeFarthest);
wglMakeCurrent( NULL, NULL );
::ReleaseDC( this->m_hWnd, hDC );
if (hits)
{
TileNode *tp=m_tc.Get(selectBuf[3]);
double d,minz=SqrDistance(tp->t.x,tp->t.y,tp->t.z,px,py,pz);
//CString str;str.Format("%d %f %f",selectBuf[3+n*4],d,minz);AfxMessageBox(str);
for(int i=1;i<hits;i++)
{
tp=m_tc.Get(selectBuf[3+i*4]);
d=SqrDistance(tp->t.x,tp->t.y,tp->t.z,px,py,pz);
if (d<minz) {n=i;minz=d;}
}
*miss=FALSE;
}
else
{
*miss=TRUE;
return 0;
}
//CString str;str.Format("%d",selectBuf[3+n*4]);AfxMessageBox(str);
}
catch(...)
{
AfxMessageBox("???");
}
return selectBuf[3+n*4];
}
BOOL CMiner3D_viewerCtrl::OnProperties(LPMSG lpMsg, HWND hWndParent, LPCRECT lpRect)
{
// TODO: Add your specialized code here and/or call the base class
return TRUE;//return COleControl::OnProperties(lpMsg, hWndParent, lpRect);
}
void CMiner3D_viewerCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (point.x>=0 && point.x<=m_intWidth && point.y>=0 && point.y<=m_intHeight)
FireLeftButtonDown(point.x,point.y,(nFlags&MK_CONTROL)?TRUE:FALSE,(nFlags&MK_SHIFT)?TRUE:FALSE);
COleControl::OnLButtonDown(nFlags, point);
}
void CMiner3D_viewerCtrl::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (point.x>=0 && point.x<=m_intWidth && point.y>=0 && point.y<=m_intHeight)
FireRightButtonDown(point.x,point.y,(nFlags&MK_CONTROL)?TRUE:FALSE,(nFlags&MK_SHIFT)?TRUE:FALSE);
COleControl::OnRButtonDown(nFlags, point);
}
void CMiner3D_viewerCtrl::RefreshSize()
{
HDC hDC = ::GetDC(this->m_hWnd);
wglMakeCurrent(hDC,hRC);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0,0,m_intWidth,m_intHeight);
gluPerspective(m_seeAngle,m_dblAspect,m_seeNearest,m_seeFarthest);
wglMakeCurrent( NULL, NULL );
::ReleaseDC( this->m_hWnd, hDC );
}
void CMiner3D_viewerCtrl::PlayMidiFile(LPCTSTR filename)
{
// TODO: Add your dispatch handler code here
PlayMusic(m_hWnd,filename);
}
void CMiner3D_viewerCtrl::StopPlayMidi()
{
// TODO: Add your dispatch handler code here
CloseMusic();
}
void CMiner3D_viewerCtrl::OnMciNotify(WPARAM w,LPARAM l)
{
if (w == MCI_NOTIFY_SUCCESSFUL) FireEndPlayMidi();
}
BOOL CMiner3D_viewerCtrl::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
switch (pMsg->message)
{
case WM_KEYDOWN:
if ((pMsg->lParam&0x40000000)==0)
FireVcKeyDown(pMsg->wParam,0);
break;
case WM_KEYUP:
FireVcKeyUp(pMsg->wParam,0);
break;
}
return COleControl::PreTranslateMessage(pMsg);
}
void CMiner3D_viewerCtrl::UpdateCamDir()
{
m_camDirX=cos(m_camAxz)*cos(m_camAzy);
m_camDirY=sin(m_camAzy);
m_camDirZ=sin(m_camAxz)*cos(m_camAzy);
}
double CMiner3D_viewerCtrl::GetCamDirX()
{
// TODO: Add your dispatch handler code here
return m_camDirX;
}
double CMiner3D_viewerCtrl::GetCamDirY()
{
// TODO: Add your dispatch handler code here
return m_camDirY;
return 0.0;
}
double CMiner3D_viewerCtrl::GetCamDirZ()
{
// TODO: Add your dispatch handler code here
return m_camDirZ;
return 0.0;
}
BOOL CMiner3D_viewerCtrl::AddPoint(double x, double y, double z)
{
// TODO: Add your dispatch handler code here
if (m_pc.Add(x,y,z)==NULL) return FALSE;
return TRUE;
}
BOOL CMiner3D_viewerCtrl::AddFace(short way, double c, double cx, double cy, double large, OLE_COLOR color)
{
// TODO: Add your dispatch handler code here
if (m_fc.Add(way,c,cx,cy,large,color)==NULL) return FALSE;
return TRUE;
}
void CMiner3D_viewerCtrl::OnLight1Changed()
{
// TODO: Add notification handler code
SetModifiedFlag();
}
double sqr(double d)
{
return d*d;
}
GLdouble CMiner3D_viewerCtrl::SqrDistance(GLdouble x1, GLdouble y1, GLdouble z1,GLdouble x2, GLdouble y2, GLdouble z2)
{
return(sqr(x1-x2)+sqr(y1-y2)+sqr(z1-z2));
}
BOOL CMiner3D_viewerCtrl::GetTilePos(short id, double FAR* x, double FAR* y, double FAR* z)
{
// TODO: Add your dispatch handler code here
TileNode *p=m_tc.Get(id);
if (p==NULL) return FALSE;
*x=p->t.x;
*y=p->t.y;
*z=p->t.z;
return TRUE;
}
BOOL CMiner3D_viewerCtrl::AddWireTile(double x, double y, double z)
{
// TODO: Add your dispatch handler code here
if (m_wc.Add(x,y,z)==NULL) return FALSE;
return TRUE;
}
BOOL CMiner3D_viewerCtrl::AddColorWireTile(double x, double y, double z, OLE_COLOR color)
{
// TODO: Add your dispatch handler code here
WireTileNode *p=m_wc.Add(x,y,z);
if (p==NULL) return FALSE;
p->t.m_materialColor[0]=((float)(color&0xFF))/255;
p->t.m_materialColor[1]=((float)((color&0xFF00)>>8))/255;
p->t.m_materialColor[2]=((float)((color&0xFF0000)>>16))/255;
return TRUE;
}
void CMiner3D_viewerCtrl::OnWireVisibleChanged()
{
// TODO: Add notification handler code
SetModifiedFlag();
}
OLE_HANDLE CMiner3D_viewerCtrl::GetHandleActiveWindow()
{
// TODO: Add your dispatch handler code here
CWnd *w=GetActiveWindow();
if(w==NULL) return NULL;
return (OLE_HANDLE)w->m_hWnd;
}