blob: 191d1203a0baa4b758d718013868fe197bac44a5 [file] [log] [blame]
// Copyright 2016 The Android Open Source Project
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
#pragma once
#include "android/skin/qt/gl-widget.h"
#include "GLES2/gl2.h"
#include <QMatrix4x4>
#include <QMouseEvent>
#include <QVector3D>
#include <string>
// A widget that displays a 3D model of a device and lets the user
// manipulate its rotation and position.
// The changes in rotation and position can be used to
// derive the values which should be reported by the virtual accelerometer
// and magnetometer.
class Accelerometer3DWidget : public GLWidget {
Q_OBJECT
Q_PROPERTY(QQuaternion rotation READ rotation WRITE setRotation NOTIFY rotationChanged USER true);
Q_PROPERTY(QVector2D position READ position WRITE setPosition NOTIFY positionChanged USER true);
public:
enum class OperationMode {
Rotate,
Move
};
Accelerometer3DWidget(QWidget *parent = 0);
~Accelerometer3DWidget();
signals:
// Emitted when the model's rotation changes.
void rotationChanged();
// Emitted when the position of the model changes.
void positionChanged();
// Emitted when the user begins dragging the model.
void dragStarted();
// Emitted when the usr stops dragging the model.
void dragStopped();
public slots:
// Sets the rotation quaternion.
void setRotation(const QQuaternion& quat) { mQuat = quat; }
// Sets the X and Y coordinates of the model's origin;
void setPosition(const QVector2D& pos) { mTranslation = pos; }
// Sets the widget's operation mode which determines how it reacts
// to mose dragging. It may either rotate the model or move it around.
void setOperationMode(OperationMode mode) { mOperationMode = mode; }
public:
// Returns the rotation quaternion.
const QQuaternion& rotation() const { return mQuat; }
// Returns the X and Y coordinates of the model's origin.
const QVector2D& position() const { return mTranslation; }
static constexpr float MaxX = 7.0;
static constexpr float MinX = -7.0;
static constexpr float MaxY = 4.0;
static constexpr float MinY = -4.0;
protected:
// This is called once, after the GL context is created, to do some one-off
// setup work.
bool initGL() override;
// Called every time the widget changes its dimensions.
void resizeGL(int, int) override;
// Called every time the widget needs to be repainted.
void repaintGL() override;
// This is called every time the mouse is moved.
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent* event);
private:
bool initProgram();
bool initModel();
bool initTextures();
// Returns the world coordinates of a point on the XY plane
// that corresponds to the given point on the screen.
QVector2D screenToXYPlane(int x, int y) const;
QQuaternion mQuat;
QVector2D mTranslation;
QMatrix4x4 mPerspective;
QMatrix4x4 mCameraTransform;
GLuint mProgram;
GLuint mVertexDataBuffer;
GLuint mVertexIndexBuffer;
GLuint mDiffuseMap;
GLuint mSpecularMap;
GLuint mGlossMap;
GLuint mEnvMap;
int mElementsCount;
GLuint mVertexPositionAttribute;
GLuint mVertexNormalAttribute;
GLuint mVertexUVAttribute;
int mPrevMouseX;
int mPrevMouseY;
QVector2D mPrevDragOrigin;
bool mTracking;
bool mDragging;
double mXYPlaneDepth;
OperationMode mOperationMode;
};