aboutsummaryrefslogtreecommitdiff
path: root/mayaPlug/shaveCursorCtx.h
diff options
context:
space:
mode:
Diffstat (limited to 'mayaPlug/shaveCursorCtx.h')
-rw-r--r--mayaPlug/shaveCursorCtx.h262
1 files changed, 262 insertions, 0 deletions
diff --git a/mayaPlug/shaveCursorCtx.h b/mayaPlug/shaveCursorCtx.h
new file mode 100644
index 0000000..d262b84
--- /dev/null
+++ b/mayaPlug/shaveCursorCtx.h
@@ -0,0 +1,262 @@
+#ifndef shaveCursorCtx_h
+#define shaveCursorCtx_h
+
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+//Qt headers must be included before any others !!!
+#include <QtCore/QEvent>
+#include <QtCore/QElapsedTimer>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QTabletEvent>
+
+#if QT_VERSION < 0x050000
+# include <QtGui/QApplication>
+# include <QtGui/QWidget>
+#else
+# include <QtWidgets/QApplication>
+# include <QtWidgets/QWidget>
+#endif
+
+#include <vector>
+
+#include <maya/M3dView.h>
+#include <maya/MCursor.h>
+#include <maya/MDagPathArray.h>
+#include <maya/MEventMessage.h>
+#include <maya/MGlobal.h>
+#include <maya/MPxContext.h>
+#include <maya/MString.h>
+#include <maya/MMatrix.h>
+
+#include "shaveHairShape.h"
+#include "shaveSDKTYPES.h"
+
+#if MAYA_API_VERSION < 20180000
+class MEvent;
+#endif
+
+class shaveBrushManip;
+class shaveCursorCtx;
+
+//Qt mouse test -- vlad|17Mar2010
+class shaveQtMouseWatcher : public QObject
+{
+public:
+ shaveQtMouseWatcher(shaveCursorCtx* ctx)
+ {
+ m_ctx = ctx;
+ m_busy = false;
+ }
+ virtual ~shaveQtMouseWatcher(){}
+
+ static bool IsBusy() {return m_busy;}
+
+protected:
+
+ bool eventFilter(QObject* obj, QEvent* event);
+
+private:
+ shaveCursorCtx* m_ctx;
+ static bool m_busy;
+
+};
+
+void CheckGlobalQtViewport20Tracker();
+
+class globalQtViewport20Tracker : public QObject
+{
+public:
+ globalQtViewport20Tracker(){}
+ virtual ~globalQtViewport20Tracker(){}
+
+protected:
+ bool eventFilter(QObject* obj, QEvent* event);
+ MMatrix worldToCam;
+};
+
+//#define GLOBAL_FALLBACK
+#ifdef GLOBAL_FALLBACK
+void CheckAndSetGlobalQtWatcher();
+
+void SetEventsHappen();
+bool GetEventsHappen();
+void ClearEvents();
+bool IsMouseDown();
+bool IsToolActive();
+
+
+class globalQtMouseWatcher : public QObject
+{
+public:
+ globalQtMouseWatcher(){}
+ virtual ~globalQtMouseWatcher(){}
+
+protected:
+ bool eventFilter(QObject* obj, QEvent* event);
+};
+
+void StartQTimer();
+QElapsedTimer& GetQTimer();
+qint64 GetLastMoveTime();
+void SetLastMoveTime(qint64 t);
+
+#endif
+
+class NotBusyEvent : public QEvent {
+public:
+ enum {aType = 4500};
+ NotBusyEvent():QEvent((QEvent::Type)aType){};
+};
+
+//LARGE_INTEGER GetLastMoveTime();
+
+class shaveCursorCtx : public MPxContext
+{
+ friend class shaveQtMouseWatcher;
+public:
+ shaveCursorCtx();
+ virtual ~shaveCursorCtx();
+
+ virtual void deleteAction() {}
+ void enableFalloff(bool enable) { mFalloffEnabled = enable; }
+ float getBrushSize() const { return mBrushSize; }
+ float getBrushStren() const { return mBrushStren; }
+ virtual void getClassName(MString& name) const = 0;
+ bool isFalloffEnabled() const { return mFalloffEnabled; }
+ bool isResizing() const { return mIsResizing; }
+ void resizeKeyPressed(bool isPressed);
+ void setBrushSize(float size);
+ void setBrushStren(float stren) { mBrushStren = stren; }
+
+ //
+ // 'screenPos' is normalized to the range 0.0 to 1.0 for both view
+ // dimensions. Thus (0, 0) is the lower left corner of the view and
+ // (1, 1) is the upper right.
+ //
+ // If a derived class is only interested in mouse clicks, not strokes,
+ // then it should perform its click operation in this method and then
+ // return MS::kEndOfFile to indicate that the remainder of the stroke
+ // can be ignored. Otherwise it should return MS::kSuccess on success
+ // or any of the other failure codes for failure.
+ //
+ virtual MStatus strokeBegin(
+ VERT& eyePoint,
+ VERT& viewDir,
+ VERT& upDir,
+ VERT& screenPos,
+ VERT& worldPos
+ ) { return MS::kSuccess; }
+
+ //
+ // 'screenPos' and 'screenDelta' are normalized to the range 0.0 to 1.0
+ // for both view dimensions. Thus (0, 0) is the lower left corner of
+ // the view and (1, 1) is the upper right. If the drag extends beyond
+ // the edges of the view then the values passed in may lie outside that
+ // range.
+ //
+ // Derived classes are guaranteed that the position of the cursor in
+ // the final strokeDrag() will be identical to that when strokeEnd() is
+ // called.
+ //
+ virtual MStatus strokeDrag(
+ VERT& screenPos,
+ VERT& worldPos,
+ VERT& screenDelta,
+ VERT& worldDelta
+ ) { return MS::kSuccess; }
+
+ virtual MStatus strokeEnd() { return MS::kSuccess; }
+
+
+protected:
+ typedef enum
+ {
+ kMouseMoved,
+ kMouseLeftWindow
+ } MouseEventType;
+
+ typedef struct
+ {
+ MouseEventType type;
+ MNativeWindowHdl window;
+ int x;
+ int y;
+ } EventData;
+
+ //
+ // Internal Methods
+ //
+ static void activeViewChanged(void* clientData);
+ void catchActiveViewEvents();
+ void cleanupStroke();
+
+ static shaveCursorCtx*
+ getActiveCtx() { return mActiveCtx; }
+ MPoint getWorldPt(
+ const M3dView& view, short viewX, short viewY
+ ) const;
+
+ void hideHair();
+ void leaveWindow(MNativeWindowHdl window, int x, int y);
+ void pointerMoved(MNativeWindowHdl window, int x, int y);
+ void motionEventHandler(EventData* event);
+ void uncatchActiveViewEvents();
+ void unhideHair();
+#if defined _WIN32
+ static LRESULT CALLBACK
+ WinEventHandler(int nCode, WPARAM wParam, LPARAM lParam);
+#elif defined LINUX
+ static void XEventHandler(
+ Widget widget,
+ XtPointer clientData,
+ XEvent* event,
+ Boolean* continueDispatch
+ );
+#elif defined OSMac_
+ //Qt stuff should be used
+#endif
+
+ static shaveCursorCtx* mActiveCtx;
+ MCallbackId mActiveViewChangedId;
+ float mBrushSize;
+ float mBrushStren;
+ double mCentroidFraction;
+ bool mDoingStroke;
+ static MCursor mDoubleArrowCursor;
+ MNativeWindowHdl mEventWindow;
+ bool mFalloffEnabled;
+ bool mFastBrush;
+ MDagPathArray mHiddenHairNodes;
+ bool mIsActive;
+ bool mIsResizing;
+ shaveBrushManip* mManip;
+ MDagPath mProxyPath;
+ bool mResizeKeyPressed;
+ short mStrokeLastX;
+ short mStrokeLastY;
+ float mStrokeStartBrushSize;
+ VERT mStrokeStartWorld;
+ short mStrokeStartX;
+ short mStrokeStartY;
+ shaveHairShape::HairDisplayMode
+ mTargetDisplayMode;
+ shaveHairShape* mTargetShape;
+#ifdef _WIN32
+ HHOOK mMouseHookId;
+ bool mTrackingLeaveWindow;
+#endif
+
+private:
+ virtual MStatus doPress (MEvent& event, MHWRender::MUIDrawManager& drawMgr, const MHWRender::MFrameContext& context){ return doPress(event);}
+ virtual MStatus doDrag (MEvent& event, MHWRender::MUIDrawManager& drawMgr, const MHWRender::MFrameContext& context){ return doDrag(event);}
+ virtual MStatus doRelease (MEvent& event, MHWRender::MUIDrawManager& drawMgr, const MHWRender::MFrameContext& context){ return doRelease(event);}
+ virtual MStatus doDrag(MEvent& event);
+ virtual MStatus doPress(MEvent& event);
+ virtual MStatus doRelease(MEvent& event);
+ virtual void toolOffCleanup();
+ virtual void toolOnSetup(MEvent& event);
+};
+
+#endif