File indexing completed on 2024-04-21 04:05:09

0001 /*
0002     SPDX-FileCopyrightText: 2008 Ian Wadham <iandw.au@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef KBK_MOVETRACKER_H
0008 #define KBK_MOVETRACKER_H
0009 
0010 #include <QObject>
0011 #include <QList>
0012 
0013 #include "kbkglobal.h"
0014 #include "cube.h"
0015 #include "quaternion.h"
0016 
0017 class QWidget;
0018 
0019 class MoveTracker : public QObject
0020 {
0021   Q_OBJECT
0022 
0023 public:
0024     /**
0025      * Constructor for the Move Tracker object.
0026      * @param parent    The parent widget.
0027      */
0028     explicit MoveTracker (QWidget * parent = nullptr);
0029 
0030     ~MoveTracker() override;
0031 
0032     void    init();
0033 
0034     /**
0035      * Procedure called by Game to handle mouse-input.  It calculates the
0036      * cube-picture and sticker that the mouse is pointing to.  Then it
0037      * works out whether a cube-move has been completed.
0038      */
0039     void    mouseInput (int sceneID, const QList<CubeView *> &cubeViews,
0040         Cube * cube, MouseEvent event, int button, int mX, int mY);
0041 
0042     void    usersRotation();    // Perform the user's rotation when rendering.
0043 
0044     void    realignCube     // Realign the cube to nearest orthogonal axes.
0045         (QList<Move *> & tempMoves);
0046 
0047     void    saveSceneInfo();
0048 
0049 Q_SIGNALS:
0050     /**
0051      * This signal is used to pass a move back to the Game object, after the
0052      * MoveTracker has found such a move by tracking the mouse.
0053      */
0054     void    newMove (Move * move);
0055 
0056     /**
0057      * This signal is used to tell the Game object that the user has rotated the
0058      * cube manually and it must be realigned before the next keyboard move.
0059      */
0060     void    cubeRotated();
0061 
0062 private:
0063     void    trackCubeRotation (int sceneID, const QList<CubeView *> &cubeViews,
0064             MouseEvent event, int mX, int mY);
0065     bool    calculateRotation (const int mX, const int mY,
0066             double axis [nAxes], double & degrees);
0067     void    trackSliceMove (int sceneID, const QList<CubeView *> &cubeViews,
0068             Cube * cube, MouseEvent event, int mX, int mY);
0069 
0070     int     findWhichCube (const int sceneID, const QList<CubeView *> &cubeViews,
0071             const double position[]);
0072 
0073     void    makeWholeCubeMoveList (QList<Move *> & tempMoves,
0074             const double to [nAxes * nAxes]);
0075     void    prepareWholeCubeMove (QList<Move *> & moveList,
0076             int to [nAxes][nAxes], const Axis a, const Rotation d);
0077     void    rotateAxes (const Quaternion & r, const double from[nAxes * nAxes],
0078             double to[nAxes * nAxes]);
0079     bool    getTurnVector (const double u1[nAxes], const double u2[nAxes],
0080             double turnAxis[nAxes], double & turnAngle);
0081 
0082     GLfloat getMousePosition (const int mX, const int mY, double pos[]);
0083     void    getAbsGLPosition (int sX, int sY, GLfloat depth, double pos[nAxes]);
0084     void    getGLPosition (int sX, int sY, GLfloat depth,
0085             double matrix[16], double pos[nAxes]);
0086 
0087     QWidget * myParent;
0088 
0089     CubeView * v;       // The cube-view that is being rotated/moved.
0090 
0091     double  position [nAxes];   // Mouse co-ords relative to centre of cube.
0092     double  handle   [nAxes];   // Mouse co-ords at the start of a rotation.
0093     bool    foundHandle;    // True if a rotation-handle has been found.
0094     double  R;          // Radius of handle-sphere.
0095     double  RR;         // Square of radius of handle-sphere.
0096 
0097     int     mX0, mY0;       // Mouse co-ordinates at the handle position.
0098     int     mX1, mY1;       // Last mouse co-ordinates when off-cube.
0099     int     noTurn;     // Selected slice cannot turn around this axis.
0100     bool    clickFace1;     // True if left mouse-button press found a face.
0101     int     face1 [nAxes];  // The centre of the starting face of the move.
0102     int     face2 [nAxes];  // The centre of the finishing face of the move.
0103     bool    foundFace1;     // True if starting face has been found.
0104     bool    foundFace2;     // True if finishing face has been found.
0105     int     currentButton;  // The button that is being pressed (if any).
0106     int     moveAngle;      // The angle that shows the next slice move.
0107 
0108     // The move the player is selecting or has just selected.
0109     Axis    currentMoveAxis;
0110     int     currentMoveSlice;
0111     Rotation currentMoveDirection;
0112 
0113     // Data that keeps track of the user's rotations of the whole cube.
0114     Quaternion rotationState;   // The combination of all the user's rotations.
0115     Matrix     rotationMatrix;  // The corresponding OpenGL rotation matrix.
0116 
0117     // Data about the current scene, with QOpenGLWidget only valid during paintGL
0118     GLdouble projectionMatrix[16];
0119     GLdouble modelViewMatrix[16];
0120     GLint    viewPort[4];
0121 };
0122 
0123 #endif  // KBK_MOVETRACKER_H