Updated mouse workflow to avoid switching actions as often.

This commit is contained in:
leo 2012-07-31 05:27:40 +00:00
parent bfe1abc094
commit 524e2d3be2
8 changed files with 304 additions and 216 deletions

View file

@ -282,6 +282,11 @@ inline float lcLength(const lcVector3& a)
return a.Length(); return a.Length();
} }
inline float lcLengthSquared(const lcVector3& a)
{
return a.LengthSquared();
}
inline lcVector3 lcNormalize(const lcVector3& a) inline lcVector3 lcNormalize(const lcVector3& a)
{ {
lcVector3 Ret(a); lcVector3 Ret(a);

View file

@ -308,6 +308,7 @@ void Project::LoadDefaults(bool cameras)
strcpy(m_strBackground, Sys_ProfileLoadString ("Default", "BMP", "")); strcpy(m_strBackground, Sys_ProfileLoadString ("Default", "BMP", ""));
m_pTerrain->LoadDefaults(true); m_pTerrain->LoadDefaults(true);
m_OverlayActive = false; m_OverlayActive = false;
m_RestoreAction = false;
for (i = 0; i < m_ViewList.GetSize (); i++) for (i = 0; i < m_ViewList.GetSize (); i++)
{ {
@ -2074,7 +2075,7 @@ void Project::RenderSceneObjects(View* view)
void Project::RenderOverlays(View* view) void Project::RenderOverlays(View* view)
{ {
// Draw the selection rectangle. // Draw the selection rectangle.
if ((m_nCurAction == LC_ACTION_SELECT) && (m_nTracking == LC_TRACK_LEFT) && (m_ActiveView == view)) if ((m_nCurAction == LC_ACTION_SELECT) && (m_nTracking == LC_TRACK_LEFT) && (m_ActiveView == view) && (m_OverlayMode == LC_OVERLAY_NONE))
{ {
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
@ -2110,12 +2111,14 @@ void Project::RenderOverlays(View* view)
const float OverlayScale = view->m_OverlayScale; const float OverlayScale = view->m_OverlayScale;
if (m_nCurAction == LC_ACTION_MOVE) if ((m_nCurAction == LC_ACTION_MOVE || m_nCurAction == LC_ACTION_SELECT) && (m_OverlayMode >= LC_OVERLAY_NONE && m_OverlayMode <= LC_OVERLAY_ROTATE_XYZ))
{ {
const float OverlayMovePlaneSize = 0.5f; const float OverlayMovePlaneSize = 0.5f * OverlayScale;
const float OverlayMoveArrowSize = 1.5f; const float OverlayMoveArrowSize = 1.5f * OverlayScale;
const float OverlayMoveArrowCapSize = 0.9f; const float OverlayMoveArrowCapSize = 0.9f * OverlayScale;
const float OverlayMoveArrowCapRadius = 0.1f; const float OverlayMoveArrowCapRadius = 0.1f * OverlayScale;
const float OverlayRotateArrowStart = 1.0f * OverlayScale;
const float OverlayRotateArrowEnd = 1.5f * OverlayScale;
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
@ -2134,7 +2137,7 @@ void Project::RenderOverlays(View* view)
} }
// Draw a quad if we're moving on a plane. // Draw a quad if we're moving on a plane.
if ((m_OverlayMode == LC_OVERLAY_XY) || (m_OverlayMode == LC_OVERLAY_XZ) || (m_OverlayMode == LC_OVERLAY_YZ)) if ((m_OverlayMode == LC_OVERLAY_MOVE_XY) || (m_OverlayMode == LC_OVERLAY_MOVE_XZ) || (m_OverlayMode == LC_OVERLAY_MOVE_YZ))
{ {
glPushMatrix(); glPushMatrix();
glTranslatef(m_OverlayCenter[0], m_OverlayCenter[1], m_OverlayCenter[2]); glTranslatef(m_OverlayCenter[0], m_OverlayCenter[1], m_OverlayCenter[2]);
@ -2142,9 +2145,9 @@ void Project::RenderOverlays(View* view)
if (Focus) if (Focus)
glRotatef(Rot[3], Rot[0], Rot[1], Rot[2]); glRotatef(Rot[3], Rot[0], Rot[1], Rot[2]);
if (m_OverlayMode == LC_OVERLAY_XZ) if (m_OverlayMode == LC_OVERLAY_MOVE_XZ)
glRotatef(90.0f, 0.0f, 0.0f, -1.0f); glRotatef(90.0f, 0.0f, 0.0f, -1.0f);
else if (m_OverlayMode == LC_OVERLAY_XY) else if (m_OverlayMode == LC_OVERLAY_MOVE_XY)
glRotatef(90.0f, 0.0f, 1.0f, 0.0f); glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -2153,9 +2156,9 @@ void Project::RenderOverlays(View* view)
glBegin(GL_QUADS); glBegin(GL_QUADS);
glColor4f(0.8f, 0.8f, 0.0f, 0.3f); glColor4f(0.8f, 0.8f, 0.0f, 0.3f);
glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, OverlayScale * OverlayMovePlaneSize, 0.0f); glVertex3f(0.0f, OverlayMovePlaneSize, 0.0f);
glVertex3f(0.0f, OverlayScale * OverlayMovePlaneSize, OverlayScale * OverlayMovePlaneSize); glVertex3f(0.0f, OverlayMovePlaneSize, OverlayMovePlaneSize);
glVertex3f(0.0f, 0.0f, OverlayScale * OverlayMovePlaneSize); glVertex3f(0.0f, 0.0f, OverlayMovePlaneSize);
glEnd(); glEnd();
glDisable(GL_BLEND); glDisable(GL_BLEND);
@ -2169,19 +2172,19 @@ void Project::RenderOverlays(View* view)
switch (i) switch (i)
{ {
case 0: case 0:
if ((m_OverlayMode == LC_OVERLAY_X) || (m_OverlayMode == LC_OVERLAY_XY) || (m_OverlayMode == LC_OVERLAY_XZ)) if ((m_OverlayMode == LC_OVERLAY_MOVE_X) || (m_OverlayMode == LC_OVERLAY_MOVE_XY) || (m_OverlayMode == LC_OVERLAY_MOVE_XZ))
glColor4f(0.8f, 0.8f, 0.0f, 1.0f); glColor4f(0.8f, 0.8f, 0.0f, 1.0f);
else else
glColor4f(0.8f, 0.0f, 0.0f, 1.0f); glColor4f(0.8f, 0.0f, 0.0f, 1.0f);
break; break;
case 1: case 1:
if ((m_OverlayMode == LC_OVERLAY_Y) || (m_OverlayMode == LC_OVERLAY_XY) || (m_OverlayMode == LC_OVERLAY_YZ)) if ((m_OverlayMode == LC_OVERLAY_MOVE_Y) || (m_OverlayMode == LC_OVERLAY_MOVE_XY) || (m_OverlayMode == LC_OVERLAY_MOVE_YZ))
glColor4f(0.8f, 0.8f, 0.0f, 1.0f); glColor4f(0.8f, 0.8f, 0.0f, 1.0f);
else else
glColor4f(0.0f, 0.8f, 0.0f, 1.0f); glColor4f(0.0f, 0.8f, 0.0f, 1.0f);
break; break;
case 2: case 2:
if ((m_OverlayMode == LC_OVERLAY_Z) || (m_OverlayMode == LC_OVERLAY_XZ) || (m_OverlayMode == LC_OVERLAY_YZ)) if ((m_OverlayMode == LC_OVERLAY_MOVE_Z) || (m_OverlayMode == LC_OVERLAY_MOVE_XZ) || (m_OverlayMode == LC_OVERLAY_MOVE_YZ))
glColor4f(0.8f, 0.8f, 0.0f, 1.0f); glColor4f(0.8f, 0.8f, 0.0f, 1.0f);
else else
glColor4f(0.0f, 0.0f, 0.8f, 1.0f); glColor4f(0.0f, 0.0f, 0.8f, 1.0f);
@ -2195,31 +2198,64 @@ void Project::RenderOverlays(View* view)
glRotatef(Rot[3], Rot[0], Rot[1], Rot[2]); glRotatef(Rot[3], Rot[0], Rot[1], Rot[2]);
if (i == 1) if (i == 1)
glRotatef(90.0f, 0.0f, 0.0f, 1.0f); glMultMatrixf(lcMatrix44(lcVector4(0, 1, 0, 0), lcVector4(1, 0, 0, 0), lcVector4(0, 0, 1, 0), lcVector4(0, 0, 0, 1)));
else if (i == 2) else if (i == 2)
glRotatef(90.0f, 0.0f, -1.0f, 0.0f); glMultMatrixf(lcMatrix44(lcVector4(0, 0, 1, 0), lcVector4(0, 1, 0, 0), lcVector4(1, 0, 0, 0), lcVector4(0, 0, 0, 1)));
glBegin(GL_LINES); glBegin(GL_LINES);
glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(OverlayScale * OverlayMoveArrowSize, 0.0f, 0.0f); glVertex3f(OverlayMoveArrowSize, 0.0f, 0.0f);
glEnd(); glEnd();
glBegin(GL_TRIANGLE_FAN); glBegin(GL_TRIANGLE_FAN);
glVertex3f(OverlayScale * OverlayMoveArrowSize, 0.0f, 0.0f); glVertex3f(OverlayMoveArrowSize, 0.0f, 0.0f);
for (int j = 0; j < 9; j++) for (int j = 0; j < 9; j++)
{ {
float y = cosf(LC_2PI * j / 8) * OverlayMoveArrowCapRadius * OverlayScale; float y = cosf(LC_2PI * j / 8) * OverlayMoveArrowCapRadius;
float z = sinf(LC_2PI * j / 8) * OverlayMoveArrowCapRadius * OverlayScale; float z = sinf(LC_2PI * j / 8) * OverlayMoveArrowCapRadius;
glVertex3f(OverlayScale * OverlayMoveArrowCapSize, y, z); glVertex3f(OverlayMoveArrowCapSize, y, z);
} }
glEnd(); glEnd();
if (m_nCurAction == LC_ACTION_SELECT)
{
switch (i)
{
case 0:
if (m_OverlayMode == LC_OVERLAY_ROTATE_X)
glColor4f(0.8f, 0.8f, 0.0f, 1.0f);
else
glColor4f(0.8f, 0.0f, 0.0f, 1.0f);
break;
case 1:
if (m_OverlayMode == LC_OVERLAY_ROTATE_Y)
glColor4f(0.8f, 0.8f, 0.0f, 1.0f);
else
glColor4f(0.0f, 0.8f, 0.0f, 1.0f);
break;
case 2:
if (m_OverlayMode == LC_OVERLAY_ROTATE_Z)
glColor4f(0.8f, 0.8f, 0.0f, 1.0f);
else
glColor4f(0.0f, 0.0f, 0.8f, 1.0f);
break;
}
glBegin(GL_QUADS);
glVertex3f(0.0f, OverlayRotateArrowStart, OverlayRotateArrowStart);
glVertex3f(0.0f, OverlayRotateArrowEnd, OverlayRotateArrowStart);
glVertex3f(0.0f, OverlayRotateArrowEnd, OverlayRotateArrowEnd);
glVertex3f(0.0f, OverlayRotateArrowStart, OverlayRotateArrowEnd);
glEnd();
}
glPopMatrix(); glPopMatrix();
} }
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
} }
else if (m_nCurAction == LC_ACTION_ROTATE)
if (m_nCurAction == LC_ACTION_ROTATE)
{ {
const float OverlayRotateRadius = 2.0f; const float OverlayRotateRadius = 2.0f;
@ -2250,17 +2286,17 @@ void Project::RenderOverlays(View* view)
switch (m_OverlayMode) switch (m_OverlayMode)
{ {
case LC_OVERLAY_X: case LC_OVERLAY_ROTATE_X:
glColor4f(0.8f, 0.0f, 0.0f, 0.3f); glColor4f(0.8f, 0.0f, 0.0f, 0.3f);
Angle = m_MouseTotalDelta[0]; Angle = m_MouseTotalDelta[0];
Rotation = lcVector4(0.0f, 0.0f, 0.0f, 0.0f); Rotation = lcVector4(0.0f, 0.0f, 0.0f, 0.0f);
break; break;
case LC_OVERLAY_Y: case LC_OVERLAY_ROTATE_Y:
glColor4f(0.0f, 0.8f, 0.0f, 0.3f); glColor4f(0.0f, 0.8f, 0.0f, 0.3f);
Angle = m_MouseTotalDelta[1]; Angle = m_MouseTotalDelta[1];
Rotation = lcVector4(90.0f, 0.0f, 0.0f, 1.0f); Rotation = lcVector4(90.0f, 0.0f, 0.0f, 1.0f);
break; break;
case LC_OVERLAY_Z: case LC_OVERLAY_ROTATE_Z:
glColor4f(0.0f, 0.0f, 0.8f, 0.3f); glColor4f(0.0f, 0.0f, 0.8f, 0.3f);
Angle = m_MouseTotalDelta[2]; Angle = m_MouseTotalDelta[2];
Rotation = lcVector4(90.0f, 0.0f, -1.0f, 0.0f); Rotation = lcVector4(90.0f, 0.0f, -1.0f, 0.0f);
@ -2370,7 +2406,7 @@ void Project::RenderOverlays(View* view)
// Draw each axis circle. // Draw each axis circle.
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
if (m_OverlayMode == LC_OVERLAY_X + i) if (m_OverlayMode == LC_OVERLAY_ROTATE_X + i)
{ {
glColor4f(0.8f, 0.8f, 0.0f, 1.0f); glColor4f(0.8f, 0.8f, 0.0f, 1.0f);
} }
@ -2430,7 +2466,7 @@ void Project::RenderOverlays(View* view)
// Draw tangent vector. // Draw tangent vector.
if (m_nTracking != LC_TRACK_NONE) if (m_nTracking != LC_TRACK_NONE)
{ {
if ((m_OverlayMode == LC_OVERLAY_X) || (m_OverlayMode == LC_OVERLAY_Y) || (m_OverlayMode == LC_OVERLAY_Z)) if ((m_OverlayMode == LC_OVERLAY_ROTATE_X) || (m_OverlayMode == LC_OVERLAY_ROTATE_Y) || (m_OverlayMode == LC_OVERLAY_ROTATE_Z))
{ {
lcVector3 Normal = lcNormalize(m_OverlayTrackStart - m_OverlayCenter); lcVector3 Normal = lcNormalize(m_OverlayTrackStart - m_OverlayCenter);
lcVector3 Tangent; lcVector3 Tangent;
@ -2438,15 +2474,15 @@ void Project::RenderOverlays(View* view)
switch (m_OverlayMode) switch (m_OverlayMode)
{ {
case LC_OVERLAY_X: case LC_OVERLAY_ROTATE_X:
Angle = m_MouseTotalDelta[0]; Angle = m_MouseTotalDelta[0];
Tangent = lcVector3(0.0f, -Normal[2], Normal[1]); Tangent = lcVector3(0.0f, -Normal[2], Normal[1]);
break; break;
case LC_OVERLAY_Y: case LC_OVERLAY_ROTATE_Y:
Angle = m_MouseTotalDelta[1]; Angle = m_MouseTotalDelta[1];
Tangent = lcVector3(Normal[2], 0.0f, -Normal[0]); Tangent = lcVector3(Normal[2], 0.0f, -Normal[0]);
break; break;
case LC_OVERLAY_Z: case LC_OVERLAY_ROTATE_Z:
Angle = m_MouseTotalDelta[2]; Angle = m_MouseTotalDelta[2];
Tangent = lcVector3(-Normal[1], Normal[0], 0.0f); Tangent = lcVector3(-Normal[1], Normal[0], 0.0f);
break; break;
@ -3049,7 +3085,7 @@ void Project::UpdateSelection()
if (m_nTracking == LC_TRACK_NONE) if (m_nTracking == LC_TRACK_NONE)
{ {
ActivateOverlay(); ActivateOverlay(m_ActiveView, m_nCurAction, LC_OVERLAY_NONE);
} }
SystemUpdateSelected(flags, SelectedCount, Focus); SystemUpdateSelected(flags, SelectedCount, Focus);
@ -3301,7 +3337,7 @@ void Project::HandleNotify(LC_NOTIFY id, unsigned long param)
SetModifiedFlag(true); SetModifiedFlag(true);
CheckPoint("Modifying"); CheckPoint("Modifying");
ActivateOverlay(); ActivateOverlay(m_ActiveView, m_nCurAction, LC_OVERLAY_NONE);
UpdateAllViews(); UpdateAllViews();
} break; } break;
@ -4694,9 +4730,6 @@ void Project::HandleCommand(LC_COMMANDS id, unsigned long nParam)
UpdateSelection(); UpdateSelection();
SystemPieceComboAdd(m_pCurPiece->m_strDescription); SystemPieceComboAdd(m_pCurPiece->m_strDescription);
if (m_nSnap & LC_DRAW_MOVE)
SetAction(LC_ACTION_MOVE);
// AfxGetMainWnd()->PostMessage(WM_LC_UPDATE_INFO, (WPARAM)pNew, OT_PIECE); // AfxGetMainWnd()->PostMessage(WM_LC_UPDATE_INFO, (WPARAM)pNew, OT_PIECE);
UpdateAllViews(); UpdateAllViews();
SetModifiedFlag(true); SetModifiedFlag(true);
@ -5894,34 +5927,64 @@ void Project::HandleCommand(LC_COMMANDS id, unsigned long nParam)
void Project::SetAction(int nAction) void Project::SetAction(int nAction)
{ {
bool Redraw = false;
if (m_nCurAction == LC_ACTION_INSERT)
Redraw = true;
m_PreviousAction = m_nCurAction; m_PreviousAction = m_nCurAction;
m_nCurAction = nAction; m_nCurAction = nAction;
SystemUpdateAction(m_nCurAction, m_PreviousAction); SystemUpdateAction(m_nCurAction, m_PreviousAction);
if ((m_nCurAction == LC_ACTION_MOVE) || (m_nCurAction == LC_ACTION_ROTATE) || ActivateOverlay(m_ActiveView, m_nCurAction, LC_OVERLAY_NONE);
(m_nCurAction == LC_ACTION_ROTATE_VIEW))
{
ActivateOverlay();
if (m_OverlayActive) UpdateAllViews();
Redraw = true; }
}
else int Project::GetAction() const
{
int Action = m_nCurAction;
if (m_OverlayActive)
{ {
if (m_OverlayActive) switch (m_OverlayMode)
{ {
m_OverlayActive = false; case LC_OVERLAY_NONE:
Redraw = true; break;
case LC_OVERLAY_MOVE_X:
case LC_OVERLAY_MOVE_Y:
case LC_OVERLAY_MOVE_Z:
case LC_OVERLAY_MOVE_XY:
case LC_OVERLAY_MOVE_XZ:
case LC_OVERLAY_MOVE_YZ:
case LC_OVERLAY_MOVE_XYZ:
Action = LC_ACTION_MOVE;
break;
case LC_OVERLAY_ROTATE_X:
case LC_OVERLAY_ROTATE_Y:
case LC_OVERLAY_ROTATE_Z:
case LC_OVERLAY_ROTATE_XY:
case LC_OVERLAY_ROTATE_XZ:
case LC_OVERLAY_ROTATE_YZ:
case LC_OVERLAY_ROTATE_XYZ:
Action = LC_ACTION_ROTATE;
break;
case LC_OVERLAY_ZOOM:
Action = LC_ACTION_ZOOM;
break;
case LC_OVERLAY_PAN:
Action = LC_ACTION_PAN;
break;
case LC_OVERLAY_ROTATE_VIEW_X:
case LC_OVERLAY_ROTATE_VIEW_Y:
case LC_OVERLAY_ROTATE_VIEW_Z:
case LC_OVERLAY_ROTATE_VIEW_XYZ:
Action = LC_ACTION_ROTATE_VIEW;
break;
} }
} }
if (Redraw) return Action;
UpdateAllViews();
} }
// Remove unused groups // Remove unused groups
@ -6314,6 +6377,8 @@ bool Project::StopTracking(bool bAccept)
if (m_nTracking == LC_TRACK_NONE) if (m_nTracking == LC_TRACK_NONE)
return false; return false;
int Action = GetAction();
if ((m_nTracking == LC_TRACK_START_LEFT) || (m_nTracking == LC_TRACK_START_RIGHT)) if ((m_nTracking == LC_TRACK_START_LEFT) || (m_nTracking == LC_TRACK_START_RIGHT))
{ {
if (m_pTrackFile) if (m_pTrackFile)
@ -6334,13 +6399,13 @@ bool Project::StopTracking(bool bAccept)
// Reset the mouse overlay. // Reset the mouse overlay.
if (m_OverlayActive) if (m_OverlayActive)
{ {
ActivateOverlay(); ActivateOverlay(m_ActiveView, m_nCurAction, LC_OVERLAY_NONE);
UpdateAllViews(); UpdateAllViews();
} }
if (bAccept) if (bAccept)
{ {
switch (m_nCurAction) switch (Action)
{ {
case LC_ACTION_SELECT: case LC_ACTION_SELECT:
{ {
@ -7319,14 +7384,11 @@ void Project::OnLeftButtonDown(View* view, int x, int y, bool bControl, bool bSh
m_fTrack[0] = point[0]; m_fTrack[1] = point[1]; m_fTrack[2] = point[2]; m_fTrack[0] = point[0]; m_fTrack[1] = point[1]; m_fTrack[2] = point[2];
if (Sys_KeyDown(KEY_ALT)) if (Sys_KeyDown(KEY_ALT))
{ ActivateOverlay(view, LC_ACTION_ROTATE_VIEW, LC_OVERLAY_ROTATE_VIEW_XYZ);
SetAction(LC_ACTION_ROTATE_VIEW);
m_RestoreAction = true;
}
else
m_RestoreAction = false;
switch (m_nCurAction) int Action = GetAction();
switch (Action)
{ {
case LC_ACTION_SELECT: case LC_ACTION_SELECT:
case LC_ACTION_ERASER: case LC_ACTION_ERASER:
@ -7334,7 +7396,7 @@ void Project::OnLeftButtonDown(View* view, int x, int y, bool bControl, bool bSh
{ {
Object* Closest = FindObjectFromPoint(view, x, y); Object* Closest = FindObjectFromPoint(view, x, y);
if (m_nCurAction == LC_ACTION_SELECT) if (Action == LC_ACTION_SELECT)
{ {
if (Closest != NULL) if (Closest != NULL)
{ {
@ -7377,7 +7439,7 @@ void Project::OnLeftButtonDown(View* view, int x, int y, bool bControl, bool bSh
StartTracking(LC_TRACK_START_LEFT); StartTracking(LC_TRACK_START_LEFT);
} }
if ((m_nCurAction == LC_ACTION_ERASER) && (Closest != NULL)) if ((Action == LC_ACTION_ERASER) && (Closest != NULL))
{ {
switch (Closest->GetType ()) switch (Closest->GetType ())
{ {
@ -7436,7 +7498,7 @@ void Project::OnLeftButtonDown(View* view, int x, int y, bool bControl, bool bSh
// AfxGetMainWnd()->PostMessage(WM_LC_UPDATE_INFO, NULL, OT_PIECE); // AfxGetMainWnd()->PostMessage(WM_LC_UPDATE_INFO, NULL, OT_PIECE);
} }
if ((m_nCurAction == LC_ACTION_PAINT) && (Closest != NULL) && (Closest->GetType() == LC_OBJECT_PIECE)) if ((Action == LC_ACTION_PAINT) && (Closest != NULL) && (Closest->GetType() == LC_OBJECT_PIECE))
{ {
Piece* pPiece = (Piece*)Closest; Piece* pPiece = (Piece*)Closest;
@ -7455,7 +7517,7 @@ void Project::OnLeftButtonDown(View* view, int x, int y, bool bControl, bool bSh
case LC_ACTION_INSERT: case LC_ACTION_INSERT:
case LC_ACTION_LIGHT: case LC_ACTION_LIGHT:
{ {
if (m_nCurAction == LC_ACTION_INSERT) if (Action == LC_ACTION_INSERT)
{ {
lcVector3 Pos; lcVector3 Pos;
lcVector4 Rot; lcVector4 Rot;
@ -7478,10 +7540,9 @@ void Project::OnLeftButtonDown(View* view, int x, int y, bool bControl, bool bSh
SystemPieceComboAdd(m_pCurPiece->m_strDescription); SystemPieceComboAdd(m_pCurPiece->m_strDescription);
SystemUpdateFocus(pPiece); SystemUpdateFocus(pPiece);
if (m_nSnap & LC_DRAW_MOVE) SetAction(LC_ACTION_SELECT);
SetAction(LC_ACTION_MOVE);
} }
else if (m_nCurAction == LC_ACTION_LIGHT) else if (Action == LC_ACTION_LIGHT)
{ {
GLint max; GLint max;
int count = 0; int count = 0;
@ -7615,7 +7676,7 @@ void Project::OnLeftButtonDown(View* view, int x, int y, bool bControl, bool bSh
m_OverlayTrackStart[0] = (float)x; m_OverlayTrackStart[0] = (float)x;
m_OverlayTrackStart[1] = (float)y; m_OverlayTrackStart[1] = (float)y;
StartTracking(LC_TRACK_START_LEFT); StartTracking(LC_TRACK_START_LEFT);
ActivateOverlay(); ActivateOverlay(view, m_nCurAction, LC_OVERLAY_NONE);
} break; } break;
case LC_ACTION_ZOOM: case LC_ACTION_ZOOM:
@ -7709,11 +7770,8 @@ void Project::OnLeftButtonUp(View* view, int x, int y, bool bControl, bool bShif
SystemPieceComboAdd(m_pCurPiece->m_strDescription); SystemPieceComboAdd(m_pCurPiece->m_strDescription);
SystemUpdateFocus(pPiece); SystemUpdateFocus(pPiece);
if (m_nSnap & LC_DRAW_MOVE) SetAction(LC_ACTION_SELECT);
{ m_RestoreAction = false;
SetAction(LC_ACTION_MOVE);
m_RestoreAction = false;
}
} }
m_pCurPiece->DeRef(); m_pCurPiece->DeRef();
@ -7748,12 +7806,9 @@ void Project::OnMiddleButtonDown(View* view, int x, int y, bool bControl, bool b
m_fTrack[0] = point[0]; m_fTrack[1] = point[1]; m_fTrack[2] = point[2]; m_fTrack[0] = point[0]; m_fTrack[1] = point[1]; m_fTrack[2] = point[2];
if (Sys_KeyDown(KEY_ALT)) if (Sys_KeyDown(KEY_ALT))
{ ActivateOverlay(view, LC_ACTION_PAN, LC_OVERLAY_PAN);
SetAction(LC_ACTION_PAN);
m_RestoreAction = true;
}
switch (m_nCurAction) switch (GetAction())
{ {
case LC_ACTION_PAN: case LC_ACTION_PAN:
{ {
@ -7790,12 +7845,9 @@ void Project::OnRightButtonDown(View* view, int x, int y, bool bControl, bool bS
m_fTrack[0] = point[0]; m_fTrack[1] = point[1]; m_fTrack[2] = point[2]; m_fTrack[0] = point[0]; m_fTrack[1] = point[1]; m_fTrack[2] = point[2];
if (Sys_KeyDown(KEY_ALT)) if (Sys_KeyDown(KEY_ALT))
{ ActivateOverlay(view, LC_ACTION_ZOOM, LC_OVERLAY_ZOOM);
SetAction(LC_ACTION_ZOOM);
m_RestoreAction = true;
}
switch (m_nCurAction) switch (GetAction())
{ {
case LC_ACTION_MOVE: case LC_ACTION_MOVE:
{ {
@ -7886,7 +7938,7 @@ void Project::OnMouseMove(View* view, int x, int y, bool bControl, bool bShift)
lcVector3 tmp = lcUnprojectPoint(lcVector3((float)x, (float)y, 0.9f), ModelView, Projection, Viewport); lcVector3 tmp = lcUnprojectPoint(lcVector3((float)x, (float)y, 0.9f), ModelView, Projection, Viewport);
ptx = tmp[0]; pty = tmp[1]; ptz = tmp[2]; ptx = tmp[0]; pty = tmp[1]; ptz = tmp[2];
switch (m_nCurAction) switch (GetAction())
{ {
case LC_ACTION_SELECT: case LC_ACTION_SELECT:
{ {
@ -7905,6 +7957,9 @@ void Project::OnMouseMove(View* view, int x, int y, bool bControl, bool bShift)
m_fTrack[0] = (float)ptx; m_fTrack[0] = (float)ptx;
m_fTrack[1] = (float)pty; m_fTrack[1] = (float)pty;
if (m_nTracking != LC_TRACK_NONE)
UpdateOverlayScale();
UpdateAllViews(); UpdateAllViews();
} break; } break;
@ -7968,7 +8023,7 @@ void Project::OnMouseMove(View* view, int x, int y, bool bControl, bool bShift)
Camera* Camera = view->m_Camera; Camera* Camera = view->m_Camera;
bool Redraw; bool Redraw;
if ((m_OverlayActive && (m_OverlayMode != LC_OVERLAY_XYZ)) || (!Camera->IsSide())) if ((m_OverlayActive && (m_OverlayMode != LC_OVERLAY_MOVE_XYZ)) || (!Camera->IsSide()))
{ {
lcVector3 ScreenX = lcNormalize(lcCross(Camera->mTargetPosition - Camera->mPosition, Camera->mUpVector)); lcVector3 ScreenX = lcNormalize(lcCross(Camera->mTargetPosition - Camera->mPosition, Camera->mUpVector));
lcVector3 ScreenY = Camera->mUpVector; lcVector3 ScreenY = Camera->mUpVector;
@ -7977,35 +8032,35 @@ void Project::OnMouseMove(View* view, int x, int y, bool bControl, bool bShift)
int OverlayMode; int OverlayMode;
if (m_OverlayActive && (m_OverlayMode != LC_OVERLAY_XYZ)) if (m_OverlayActive && (m_OverlayMode != LC_OVERLAY_MOVE_XYZ))
OverlayMode = m_OverlayMode; OverlayMode = m_OverlayMode;
else if (m_nTracking == LC_TRACK_LEFT) else if (m_nTracking == LC_TRACK_LEFT)
OverlayMode = LC_OVERLAY_XY; OverlayMode = LC_OVERLAY_MOVE_XY;
else else
OverlayMode = LC_OVERLAY_Z; OverlayMode = LC_OVERLAY_MOVE_Z;
switch (OverlayMode) switch (OverlayMode)
{ {
case LC_OVERLAY_X: case LC_OVERLAY_MOVE_X:
Dir1 = lcVector3(1, 0, 0); Dir1 = lcVector3(1, 0, 0);
break; break;
case LC_OVERLAY_Y: case LC_OVERLAY_MOVE_Y:
Dir1 = lcVector3(0, 1, 0); Dir1 = lcVector3(0, 1, 0);
break; break;
case LC_OVERLAY_Z: case LC_OVERLAY_MOVE_Z:
Dir1 = lcVector3(0, 0, 1); Dir1 = lcVector3(0, 0, 1);
break; break;
case LC_OVERLAY_XY: case LC_OVERLAY_MOVE_XY:
Dir1 = lcVector3(1, 0, 0); Dir1 = lcVector3(1, 0, 0);
Dir2 = lcVector3(0, 1, 0); Dir2 = lcVector3(0, 1, 0);
SingleDir = false; SingleDir = false;
break; break;
case LC_OVERLAY_XZ: case LC_OVERLAY_MOVE_XZ:
Dir1 = lcVector3(1, 0, 0); Dir1 = lcVector3(1, 0, 0);
Dir2 = lcVector3(0, 0, 1); Dir2 = lcVector3(0, 0, 1);
SingleDir = false; SingleDir = false;
break; break;
case LC_OVERLAY_YZ: case LC_OVERLAY_MOVE_YZ:
Dir1 = lcVector3(0, 1, 0); Dir1 = lcVector3(0, 1, 0);
Dir2 = lcVector3(0, 0, 1); Dir2 = lcVector3(0, 0, 1);
SingleDir = false; SingleDir = false;
@ -8133,6 +8188,10 @@ void Project::OnMouseMove(View* view, int x, int y, bool bControl, bool bShift)
} }
SystemUpdateFocus(NULL); SystemUpdateFocus(NULL);
if (m_nTracking != LC_TRACK_NONE)
UpdateOverlayScale();
if (Redraw) if (Redraw)
UpdateAllViews(); UpdateAllViews();
} break; } break;
@ -8142,7 +8201,7 @@ void Project::OnMouseMove(View* view, int x, int y, bool bControl, bool bShift)
Camera* Camera = m_ActiveView->m_Camera; Camera* Camera = m_ActiveView->m_Camera;
bool Redraw; bool Redraw;
if ((m_OverlayActive && (m_OverlayMode != LC_OVERLAY_XYZ)) || (!Camera->IsSide())) if ((m_OverlayActive && (m_OverlayMode != LC_OVERLAY_ROTATE_XYZ)) || (!Camera->IsSide()))
{ {
lcVector3 ScreenX = lcNormalize(lcCross(Camera->mTargetPosition - Camera->mPosition, Camera->mUpVector)); lcVector3 ScreenX = lcNormalize(lcCross(Camera->mTargetPosition - Camera->mPosition, Camera->mUpVector));
lcVector3 ScreenY = Camera->mUpVector; lcVector3 ScreenY = Camera->mUpVector;
@ -8151,35 +8210,35 @@ void Project::OnMouseMove(View* view, int x, int y, bool bControl, bool bShift)
int OverlayMode; int OverlayMode;
if (m_OverlayActive && (m_OverlayMode != LC_OVERLAY_XYZ)) if (m_OverlayActive && (m_OverlayMode != LC_OVERLAY_ROTATE_XYZ))
OverlayMode = m_OverlayMode; OverlayMode = m_OverlayMode;
else if (m_nTracking == LC_TRACK_LEFT) else if (m_nTracking == LC_TRACK_LEFT)
OverlayMode = LC_OVERLAY_XY; OverlayMode = LC_OVERLAY_ROTATE_XY;
else else
OverlayMode = LC_OVERLAY_Z; OverlayMode = LC_OVERLAY_ROTATE_Z;
switch (OverlayMode) switch (OverlayMode)
{ {
case LC_OVERLAY_X: case LC_OVERLAY_ROTATE_X:
Dir1 = lcVector3(1, 0, 0); Dir1 = lcVector3(1, 0, 0);
break; break;
case LC_OVERLAY_Y: case LC_OVERLAY_ROTATE_Y:
Dir1 = lcVector3(0, 1, 0); Dir1 = lcVector3(0, 1, 0);
break; break;
case LC_OVERLAY_Z: case LC_OVERLAY_ROTATE_Z:
Dir1 = lcVector3(0, 0, 1); Dir1 = lcVector3(0, 0, 1);
break; break;
case LC_OVERLAY_XY: case LC_OVERLAY_ROTATE_XY:
Dir1 = lcVector3(1, 0, 0); Dir1 = lcVector3(1, 0, 0);
Dir2 = lcVector3(0, 1, 0); Dir2 = lcVector3(0, 1, 0);
SingleDir = false; SingleDir = false;
break; break;
case LC_OVERLAY_XZ: case LC_OVERLAY_ROTATE_XZ:
Dir1 = lcVector3(1, 0, 0); Dir1 = lcVector3(1, 0, 0);
Dir2 = lcVector3(0, 0, 1); Dir2 = lcVector3(0, 0, 1);
SingleDir = false; SingleDir = false;
break; break;
case LC_OVERLAY_YZ: case LC_OVERLAY_ROTATE_YZ:
Dir1 = lcVector3(0, 1, 0); Dir1 = lcVector3(0, 1, 0);
Dir2 = lcVector3(0, 0, 1); Dir2 = lcVector3(0, 0, 1);
SingleDir = false; SingleDir = false;
@ -8359,19 +8418,19 @@ void Project::OnMouseMove(View* view, int x, int y, bool bControl, bool bShift)
switch (m_OverlayMode) switch (m_OverlayMode)
{ {
case LC_OVERLAY_XYZ: case LC_OVERLAY_ROTATE_VIEW_XYZ:
m_ActiveView->m_Camera->DoRotate(x - m_nDownX, y - m_nDownY, m_nMouse, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys, bs); m_ActiveView->m_Camera->DoRotate(x - m_nDownX, y - m_nDownY, m_nMouse, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys, bs);
break; break;
case LC_OVERLAY_X: case LC_OVERLAY_ROTATE_VIEW_X:
m_ActiveView->m_Camera->DoRotate(x - m_nDownX, 0, m_nMouse, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys, bs); m_ActiveView->m_Camera->DoRotate(x - m_nDownX, 0, m_nMouse, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys, bs);
break; break;
case LC_OVERLAY_Y: case LC_OVERLAY_ROTATE_VIEW_Y:
m_ActiveView->m_Camera->DoRotate(0, y - m_nDownY, m_nMouse, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys, bs); m_ActiveView->m_Camera->DoRotate(0, y - m_nDownY, m_nMouse, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys, bs);
break; break;
case LC_OVERLAY_Z: case LC_OVERLAY_ROTATE_VIEW_Z:
m_ActiveView->m_Camera->DoRoll(x - m_nDownX, m_nMouse, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys); m_ActiveView->m_Camera->DoRoll(x - m_nDownX, m_nMouse, m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation, m_bAddKeys);
break; break;
} }
@ -8429,9 +8488,14 @@ void Project::MouseUpdateOverlays(View* view, int x, int y)
{ {
const float OverlayScale = view->m_OverlayScale; const float OverlayScale = view->m_OverlayScale;
if (m_nCurAction == LC_ACTION_MOVE) if (m_nCurAction == LC_ACTION_SELECT || m_nCurAction == LC_ACTION_MOVE)
{ {
const float OverlayMoveArrowSize = 1.5f; const float OverlayMovePlaneSize = 0.5f * OverlayScale;
const float OverlayMoveArrowSize = 1.5f * OverlayScale;
const float OverlayMoveArrowCapSize = 0.9f * OverlayScale;
const float OverlayMoveArrowCapRadius = 0.1f * OverlayScale;
const float OverlayRotateArrowStart = 1.0f * OverlayScale;
const float OverlayRotateArrowEnd = 1.5f * OverlayScale;
int Viewport[4] = { 0, 0, view->GetWidth(), view->GetHeight() }; int Viewport[4] = { 0, 0, view->GetWidth(), view->GetHeight() };
float Aspect = (float)Viewport[2]/(float)Viewport[3]; float Aspect = (float)Viewport[2]/(float)Viewport[3];
@ -8440,13 +8504,12 @@ void Project::MouseUpdateOverlays(View* view, int x, int y)
const lcMatrix44& ModelView = Cam->mWorldView; const lcMatrix44& ModelView = Cam->mWorldView;
lcMatrix44 Projection = lcMatrix44Perspective(Cam->m_fovy, Aspect, Cam->m_zNear, Cam->m_zFar); lcMatrix44 Projection = lcMatrix44Perspective(Cam->m_fovy, Aspect, Cam->m_zNear, Cam->m_zFar);
// Array of points for the arrow edges. // Intersect the mouse with the 3 planes.
lcVector3 Points[4] = lcVector3 PlaneNormals[3] =
{ {
lcVector3(m_OverlayCenter[0], m_OverlayCenter[1], m_OverlayCenter[2]), lcVector3(1.0f, 0.0f, 0.0f),
lcVector3(OverlayMoveArrowSize * OverlayScale, 0, 0), lcVector3(0.0f, 1.0f, 0.0f),
lcVector3(0, OverlayMoveArrowSize * OverlayScale, 0), lcVector3(0.0f, 0.0f, 1.0f),
lcVector3(0, 0, OverlayMoveArrowSize * OverlayScale),
}; };
// Find the rotation from the focused piece if relative snap is enabled. // Find the rotation from the focused piece if relative snap is enabled.
@ -8458,70 +8521,69 @@ void Project::MouseUpdateOverlays(View* view, int x, int y)
{ {
const lcMatrix44& RotMat = ((Piece*)Focus)->mModelWorld; const lcMatrix44& RotMat = ((Piece*)Focus)->mModelWorld;
for (int i = 1; i < 4; i++) for (int i = 0; i < 3; i++)
Points[i] = lcMul30(Points[i], RotMat); PlaneNormals[i] = lcMul30(PlaneNormals[i], RotMat);
} }
} }
int i, Mode = -1; int Mode = (m_nCurAction == LC_ACTION_MOVE) ? LC_OVERLAY_MOVE_XYZ : LC_OVERLAY_NONE;
lcVector3 Pt((float)x, (float)y, 0); lcVector3 Start = lcUnprojectPoint(lcVector3((float)x, (float)y, 0.0f), ModelView, Projection, Viewport);
lcVector3 End = lcUnprojectPoint(lcVector3((float)x, (float)y, 1.0f), ModelView, Projection, Viewport);
float ClosestIntersectionDistance = FLT_MAX;
for (i = 1; i < 4; i++) for (int AxisIndex = 0; AxisIndex < 3; AxisIndex++)
{ {
Points[i] += Points[0]; lcVector4 Plane(PlaneNormals[AxisIndex], -lcDot(PlaneNormals[AxisIndex], m_OverlayCenter));
Points[i] = lcProjectPoint(Points[i], ModelView, Projection, Viewport); lcVector3 Intersection;
}
Points[0] = lcProjectPoint(Points[0], ModelView, Projection, Viewport); if (!lcLinePlaneIntersection(&Intersection, Start, End, Plane))
// Check if the mouse is over an arrow.
for (i = 1; i < 4; i++)
{
lcVector3 Line = Points[i] - Points[0];
lcVector3 Vec = Pt - Points[0];
float u = lcDot(Vec, Line) / Line.LengthSquared();
// Point is outside the line segment.
if (u < 0.0f || u > 1.0f)
continue; continue;
// Closest point in the line segment to the mouse. float IntersectionDistance = lcLengthSquared(Intersection - Start);
lcVector3 Closest = Points[0] + Line * u;
if ((Closest - Pt).LengthSquared() < 400.0f) if (IntersectionDistance > ClosestIntersectionDistance)
continue;
lcVector3 Dir(Intersection - m_OverlayCenter);
float Proj1 = lcDot(Dir, PlaneNormals[(AxisIndex + 1) % 3]);
float Proj2 = lcDot(Dir, PlaneNormals[(AxisIndex + 2) % 3]);
if (Proj1 > 0.0f && Proj1 < OverlayMovePlaneSize && Proj2 > 0.0f && Proj2 < OverlayMovePlaneSize)
{ {
// If we already know the mouse is close to another axis, select a plane. LC_OVERLAY_MODES PlaneModes[] = { LC_OVERLAY_MOVE_YZ, LC_OVERLAY_MOVE_XZ, LC_OVERLAY_MOVE_XY };
if (Mode != -1)
{
if (Mode == LC_OVERLAY_X)
{
if (i == 2)
{
Mode = LC_OVERLAY_XY;
}
else
{
Mode = LC_OVERLAY_XZ;
}
}
else
{
Mode = LC_OVERLAY_YZ;
}
break; Mode = PlaneModes[AxisIndex];
}
else ClosestIntersectionDistance = IntersectionDistance;
{
Mode = LC_OVERLAY_X + i - 1;
}
} }
}
if (Mode == -1) if (Proj1 > OverlayRotateArrowStart && Proj1 < OverlayRotateArrowEnd && Proj2 > OverlayRotateArrowStart && Proj2 < OverlayRotateArrowEnd)
{ {
Mode = LC_OVERLAY_XYZ; LC_OVERLAY_MODES PlaneModes[] = { LC_OVERLAY_ROTATE_X, LC_OVERLAY_ROTATE_Y, LC_OVERLAY_ROTATE_Z };
Mode = PlaneModes[AxisIndex];
ClosestIntersectionDistance = IntersectionDistance;
}
if (fabs(Proj1) < OverlayMoveArrowCapRadius && Proj2 > 0.0f && Proj2 < OverlayMoveArrowSize)
{
LC_OVERLAY_MODES DirModes[] = { LC_OVERLAY_MOVE_Z, LC_OVERLAY_MOVE_X, LC_OVERLAY_MOVE_Y };
Mode = DirModes[AxisIndex];
ClosestIntersectionDistance = IntersectionDistance;
}
if (fabs(Proj2) < OverlayMoveArrowCapRadius && Proj1 > 0.0f && Proj1 < OverlayMoveArrowSize)
{
LC_OVERLAY_MODES DirModes[] = { LC_OVERLAY_MOVE_Y, LC_OVERLAY_MOVE_Z, LC_OVERLAY_MOVE_X };
Mode = DirModes[AxisIndex];
ClosestIntersectionDistance = IntersectionDistance;
}
} }
if (Mode != m_OverlayMode) if (Mode != m_OverlayMode)
@ -8562,12 +8624,12 @@ void Project::MouseUpdateOverlays(View* view, int x, int y)
if (Distance > (OverlayRotateRadius * OverlayScale + Epsilon)) if (Distance > (OverlayRotateRadius * OverlayScale + Epsilon))
{ {
Mode = LC_OVERLAY_XYZ; Mode = LC_OVERLAY_ROTATE_XYZ;
} }
else if (Distance < (OverlayRotateRadius * OverlayScale + Epsilon)) else if (Distance < (OverlayRotateRadius * OverlayScale + Epsilon))
{ {
// 3D rotation unless we're over one of the axis circles. // 3D rotation unless we're over one of the axis circles.
Mode = LC_OVERLAY_XYZ; Mode = LC_OVERLAY_ROTATE_XYZ;
// Point P on a line defined by two points P1 and P2 is described by P = P1 + u (P2 - P1) // Point P on a line defined by two points P1 and P2 is described by P = P1 + u (P2 - P1)
// A sphere centered at P3 with radius r is described by (x - x3)^2 + (y - y3)^2 + (z - z3)^2 = r^2 // A sphere centered at P3 with radius r is described by (x - x3)^2 + (y - y3)^2 + (z - z3)^2 = r^2
@ -8640,12 +8702,12 @@ void Project::MouseUpdateOverlays(View* view, int x, int y)
if (dx < dz) if (dx < dz)
{ {
if (dx < Epsilon) if (dx < Epsilon)
Mode = LC_OVERLAY_X; Mode = LC_OVERLAY_ROTATE_X;
} }
else else
{ {
if (dz < Epsilon) if (dz < Epsilon)
Mode = LC_OVERLAY_Z; Mode = LC_OVERLAY_ROTATE_Z;
} }
} }
else else
@ -8653,26 +8715,26 @@ void Project::MouseUpdateOverlays(View* view, int x, int y)
if (dy < dz) if (dy < dz)
{ {
if (dy < Epsilon) if (dy < Epsilon)
Mode = LC_OVERLAY_Y; Mode = LC_OVERLAY_ROTATE_Y;
} }
else else
{ {
if (dz < Epsilon) if (dz < Epsilon)
Mode = LC_OVERLAY_Z; Mode = LC_OVERLAY_ROTATE_Z;
} }
} }
if (Mode != LC_OVERLAY_XYZ) if (Mode != LC_OVERLAY_ROTATE_XYZ)
{ {
switch (Mode) switch (Mode)
{ {
case LC_OVERLAY_X: case LC_OVERLAY_ROTATE_X:
Dist[0] = 0.0f; Dist[0] = 0.0f;
break; break;
case LC_OVERLAY_Y: case LC_OVERLAY_ROTATE_Y:
Dist[1] = 0.0f; Dist[1] = 0.0f;
break; break;
case LC_OVERLAY_Z: case LC_OVERLAY_ROTATE_Z:
Dist[2] = 0.0f; Dist[2] = 0.0f;
break; break;
} }
@ -8713,24 +8775,26 @@ void Project::MouseUpdateOverlays(View* view, int x, int y)
if ((d < r + SquareSize) && (d > r - SquareSize)) if ((d < r + SquareSize) && (d > r - SquareSize))
{ {
if ((cx - x < SquareSize) && (cx - x > -SquareSize)) if ((cx - x < SquareSize) && (cx - x > -SquareSize))
m_OverlayMode = LC_OVERLAY_Y; m_OverlayMode = LC_OVERLAY_ROTATE_VIEW_Y;
if ((cy - y < SquareSize) && (cy - y > -SquareSize)) if ((cy - y < SquareSize) && (cy - y > -SquareSize))
m_OverlayMode = LC_OVERLAY_X; m_OverlayMode = LC_OVERLAY_ROTATE_VIEW_X;
} }
else else
{ {
if (d < r) if (d < r)
m_OverlayMode = LC_OVERLAY_XYZ; m_OverlayMode = LC_OVERLAY_ROTATE_VIEW_XYZ;
else else
m_OverlayMode = LC_OVERLAY_Z; m_OverlayMode = LC_OVERLAY_ROTATE_VIEW_Z;
} }
} }
view->SetCursor(view->GetCursor());
} }
void Project::ActivateOverlay() void Project::ActivateOverlay(View* view, int Action, int OverlayMode)
{ {
if ((m_nCurAction == LC_ACTION_MOVE) || (m_nCurAction == LC_ACTION_ROTATE)) if ((Action == LC_ACTION_SELECT) || (Action == LC_ACTION_MOVE) || (Action == LC_ACTION_ROTATE))
{ {
if (GetFocusPosition(m_OverlayCenter)) if (GetFocusPosition(m_OverlayCenter))
m_OverlayActive = true; m_OverlayActive = true;
@ -8739,18 +8803,21 @@ void Project::ActivateOverlay()
else else
m_OverlayActive = false; m_OverlayActive = false;
} }
else if ((m_nCurAction == LC_ACTION_ZOOM_REGION) && (m_nTracking == LC_TRACK_START_LEFT)) else if ((Action == LC_ACTION_ZOOM_REGION) && (m_nTracking == LC_TRACK_START_LEFT))
m_OverlayActive = true; m_OverlayActive = true;
else if (m_nCurAction == LC_ACTION_ROTATE_VIEW) else if (Action == LC_ACTION_ZOOM || Action == LC_ACTION_PAN || Action == LC_ACTION_ROTATE_VIEW)
m_OverlayActive = true; m_OverlayActive = true;
else else
m_OverlayActive = false; m_OverlayActive = false;
if (m_OverlayActive) if (m_OverlayActive)
{ {
m_OverlayMode = LC_OVERLAY_XYZ; m_OverlayMode = OverlayMode;
UpdateOverlayScale(); UpdateOverlayScale();
} }
if (view)
view->SetCursor(view->GetCursor());
} }
void Project::UpdateOverlayScale() void Project::UpdateOverlayScale()

View file

@ -17,16 +17,30 @@ typedef enum
} LC_MOUSE_TRACK; } LC_MOUSE_TRACK;
// Mouse control overlays. // Mouse control overlays.
typedef enum enum LC_OVERLAY_MODES
{ {
LC_OVERLAY_XYZ, LC_OVERLAY_NONE,
LC_OVERLAY_X, LC_OVERLAY_MOVE_X,
LC_OVERLAY_Y, LC_OVERLAY_MOVE_Y,
LC_OVERLAY_Z, LC_OVERLAY_MOVE_Z,
LC_OVERLAY_XY, LC_OVERLAY_MOVE_XY,
LC_OVERLAY_XZ, LC_OVERLAY_MOVE_XZ,
LC_OVERLAY_YZ LC_OVERLAY_MOVE_YZ,
} LC_OVERLAY_MODES; LC_OVERLAY_MOVE_XYZ,
LC_OVERLAY_ROTATE_X,
LC_OVERLAY_ROTATE_Y,
LC_OVERLAY_ROTATE_Z,
LC_OVERLAY_ROTATE_XY,
LC_OVERLAY_ROTATE_XZ,
LC_OVERLAY_ROTATE_YZ,
LC_OVERLAY_ROTATE_XYZ,
LC_OVERLAY_ZOOM,
LC_OVERLAY_PAN,
LC_OVERLAY_ROTATE_VIEW_X,
LC_OVERLAY_ROTATE_VIEW_Y,
LC_OVERLAY_ROTATE_VIEW_Z,
LC_OVERLAY_ROTATE_VIEW_XYZ,
};
class Piece; class Piece;
class Camera; class Camera;
@ -87,8 +101,6 @@ public:
{ return m_nCurColor; } { return m_nCurColor; }
float* GetBackgroundColor() float* GetBackgroundColor()
{ return m_fBackground; } { return m_fBackground; }
unsigned char GetAction() const
{ return m_nCurAction; }
unsigned long GetSnap() const unsigned long GetSnap() const
{ return m_nSnap; } { return m_nSnap; }
int GetOverlayMode() const int GetOverlayMode() const
@ -223,7 +235,7 @@ protected:
lcVector3 m_OverlayTrackStart; lcVector3 m_OverlayTrackStart;
lcVector3 m_OverlayDelta; lcVector3 m_OverlayDelta;
void MouseUpdateOverlays(View* view, int x, int y); void MouseUpdateOverlays(View* view, int x, int y);
void ActivateOverlay(); void ActivateOverlay(View* view, int Action, int OverlayMode);
void UpdateOverlayScale(); void UpdateOverlayScale();
bool StopTracking(bool bAccept); bool StopTracking(bool bAccept);
@ -243,7 +255,13 @@ public:
void OnMouseMove(View* view, int x, int y, bool bControl, bool bShift); void OnMouseMove(View* view, int x, int y, bool bControl, bool bShift);
bool OnKeyDown(char nKey, bool bControl, bool bShift); bool OnKeyDown(char nKey, bool bControl, bool bShift);
void SetAction(int nAction); void SetAction(int Action);
int GetCurAction() const
{
return m_nCurAction;
}
int GetAction() const;
void HandleNotify(LC_NOTIFY id, unsigned long param); void HandleNotify(LC_NOTIFY id, unsigned long param);
void HandleCommand(LC_COMMANDS id, unsigned long nParam); void HandleCommand(LC_COMMANDS id, unsigned long nParam);
void HandleMessage(int Message, void* Data); void HandleMessage(int Message, void* Data);

View file

@ -22,7 +22,7 @@ View::~View()
m_Project->RemoveView(this); m_Project->RemoveView(this);
} }
LC_CURSOR_TYPE View::GetCursor(int Ptx, int Pty) const LC_CURSOR_TYPE View::GetCursor() const
{ {
// TODO: check if we're the focused window and return just the default arrow if we aren't. // TODO: check if we're the focused window and return just the default arrow if we aren't.
@ -70,13 +70,13 @@ LC_CURSOR_TYPE View::GetCursor(int Ptx, int Pty) const
case LC_ACTION_ROTATE_VIEW: case LC_ACTION_ROTATE_VIEW:
switch (m_Project->GetOverlayMode()) switch (m_Project->GetOverlayMode())
{ {
case LC_OVERLAY_X: case LC_OVERLAY_ROTATE_X:
return LC_CURSOR_ROTATEX; return LC_CURSOR_ROTATEX;
case LC_OVERLAY_Y: case LC_OVERLAY_ROTATE_Y:
return LC_CURSOR_ROTATEY; return LC_CURSOR_ROTATEY;
case LC_OVERLAY_Z: case LC_OVERLAY_ROTATE_Z:
return LC_CURSOR_ROLL; return LC_CURSOR_ROLL;
case LC_OVERLAY_XYZ: case LC_OVERLAY_ROTATE_XYZ:
default: default:
return LC_CURSOR_ROTATE_VIEW; return LC_CURSOR_ROTATE_VIEW;
} }

View file

@ -23,7 +23,7 @@ public:
void OnRightButtonUp(int x, int y, bool bControl, bool bShift); void OnRightButtonUp(int x, int y, bool bControl, bool bShift);
void OnMouseMove(int x, int y, bool bControl, bool bShift); void OnMouseMove(int x, int y, bool bControl, bool bShift);
LC_CURSOR_TYPE GetCursor(int x, int y) const; LC_CURSOR_TYPE GetCursor() const;
Project* m_Project; Project* m_Project;
Camera* m_Camera; Camera* m_Camera;

View file

@ -573,11 +573,7 @@ LONG CCADView::OnChangeCursor(UINT lParam, LONG /*wParam*/)
{ {
UINT Cursor; UINT Cursor;
POINT pt; switch (m_pView->GetCursor())
GetCursorPos(&pt);
ScreenToClient(&pt);
switch (m_pView->GetCursor(pt.x, pt.y))
{ {
case LC_CURSOR_DEFAULT: Cursor = NULL; break; case LC_CURSOR_DEFAULT: Cursor = NULL; break;
case LC_CURSOR_BRICK: Cursor = IDC_BRICK; break; case LC_CURSOR_BRICK: Cursor = IDC_BRICK; break;
@ -681,7 +677,7 @@ void CCADView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
// Update cursor for multiple selection. // Update cursor for multiple selection.
if (nChar == VK_CONTROL) if (nChar == VK_CONTROL)
{ {
if (lcGetActiveProject()->GetAction() == LC_ACTION_SELECT) if (lcGetActiveProject()->GetCurAction() == LC_ACTION_SELECT)
{ {
POINT pt; POINT pt;
@ -704,7 +700,7 @@ void CCADView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
// Update cursor for multiple selection. // Update cursor for multiple selection.
if (nChar == VK_CONTROL) if (nChar == VK_CONTROL)
{ {
if (lcGetActiveProject()->GetAction() == LC_ACTION_SELECT) if (lcGetActiveProject()->GetCurAction() == LC_ACTION_SELECT)
{ {
POINT pt; POINT pt;

View file

@ -237,7 +237,7 @@ void CMainFrame::Dump(CDumpContext& dc) const
void CMainFrame::OnUpdateAction(CCmdUI* pCmdUI) void CMainFrame::OnUpdateAction(CCmdUI* pCmdUI)
{ {
pCmdUI->SetRadio(pCmdUI->m_nID == ID_ACTION_SELECT + lcGetActiveProject()->GetAction()); pCmdUI->SetRadio(pCmdUI->m_nID == ID_ACTION_SELECT + lcGetActiveProject()->GetCurAction());
} }
void CMainFrame::OnUpdateSnap(CCmdUI* pCmdUI) void CMainFrame::OnUpdateSnap(CCmdUI* pCmdUI)

View file

@ -567,4 +567,6 @@ void GLWindow::SetCursor(LC_CURSOR_TYPE Cursor)
prv->Cursor = AfxGetApp()->LoadCursor(CursorResources[Cursor]); prv->Cursor = AfxGetApp()->LoadCursor(CursorResources[Cursor]);
else else
prv->Cursor = NULL; prv->Cursor = NULL;
::SetCursor(prv->Cursor);
} }