1
/****************************************************************************
2
3
This file is part of the wolfenqt project on http://qt.gitorious.org.
4
5
Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).*
6
All rights reserved.
7
8
Contact:  Nokia Corporation (qt-info@nokia.com)**
9
10
You may use this file under the terms of the BSD license as follows:
11
12
"Redistribution and use in source and binary forms, with or without
13
modification, are permitted provided that the following conditions are met:
14
* Redistributions of source code must retain the above copyright notice,
15
* this list of conditions and the following disclaimer.
16
* Redistributions in binary form must reproduce the above copyright notice,
17
* this list of conditions and the following disclaimer in the documentation
18
* and/or other materials provided with the distribution.
19
* Neither the name of Nokia Corporation and its Subsidiary(-ies) nor the
20
* names of its contributors may be used to endorse or promote products
21
* derived from this software without specific prior written permission.
22
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
POSSIBILITY OF SUCH DAMAGE."
33
34
****************************************************************************/
35
#ifndef MAZESCENE_H
36
#define MAZESCENE_H
37
38
#include <QGraphicsItem>
39
#include <QGraphicsScene>
40
#include <QGraphicsView>
41
#include <QLineEdit>
42
#include <QPlainTextEdit>
43
#include <QPointF>
44
#include <QPushButton>
45
#include <QTime>
46
#include <QTimeLine>
47
48
#include <QMatrix4x4>
49
50
class MazeScene;
51
class MediaPlayer;
52
class Entity;
53
class WalkingItem;
54
55
class View : public QGraphicsView
56
{
57
    Q_OBJECT
58
public:
59
    View();
60
    void resizeEvent(QResizeEvent *event);
61
    void setScene(MazeScene *scene);
62
    void paintEvent(QPaintEvent *event);
63
64
private:
65
    MazeScene *m_scene;
66
    bool m_firstPaint;
67
};
68
69
class Camera
70
{
71
public:
72
    Camera()
73
        : m_yaw(0)
74
        , m_pitch(0)
75
        , m_fov(70)
76
        , m_time(0)
77
        , m_matrixDirty(true)
78
    {
79
    }
80
81
    qreal yaw() const { return m_yaw; }
82
    qreal pitch() const { return m_pitch; }
83
    qreal fov() const { return m_fov; }
84
    QPointF pos() const { return m_pos; }
85
86
    void setYaw(qreal yaw);
87
    void setPitch(qreal pitch);
88
    void setPos(const QPointF &pos);
89
    void setFov(qreal fov);
90
    void setTime(qreal time);
91
92
    const QMatrix4x4 &viewProjectionMatrix() const;
93
    const QMatrix4x4 &viewMatrix() const;
94
95
private:
96
    void updateMatrix() const;
97
98
    qreal m_yaw;
99
    qreal m_pitch;
100
    qreal m_fov;
101
    qreal m_time;
102
103
    QPointF m_pos;
104
105
    mutable bool m_matrixDirty;
106
    mutable QMatrix4x4 m_viewMatrix;
107
    mutable QMatrix4x4 m_viewProjectionMatrix;
108
};
109
110
class Light
111
{
112
public:
113
    Light() {}
114
    Light(const QPointF &pos, qreal intensity);
115
116
    qreal intensityAt(const QPointF &pos) const;
117
118
    QPointF pos() const { return m_pos; }
119
    qreal intensity() const { return m_intensity; }
120
121
private:
122
    QPointF m_pos;
123
    qreal m_intensity;
124
};
125
126
class ProjectedItem : public QGraphicsItem
127
{
128
public:
129
    ProjectedItem(const QRectF &bounds, bool shadow = true, bool opaque = true);
130
131
    QPointF a() const { return m_a; }
132
    QPointF b() const { return m_b; }
133
134
    virtual void updateTransform(const Camera &camera);
135
136
    void setOpaque(bool opaque);
137
    bool isOpaque() const;
138
139
    QRectF boundingRect() const;
140
141
    void setPosition(const QPointF &a, const QPointF &b);
142
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
143
    void setAnimationTime(qreal time);
144
    void setImage(const QImage &image);
145
    void updateLighting(const QVector<Light> &lights, bool useConstantLight);
146
147
    void setLightingEnabled(bool enabled);
148
149
    void setObscured(bool obscured);
150
    bool isObscured() const;
151
152
private:
153
    QPointF m_a;
154
    QPointF m_b;
155
    QRectF m_bounds;
156
    QRectF m_targetRect;
157
    QImage m_image;
158
    QGraphicsRectItem *m_shadowItem;
159
160
    bool m_opaque;
161
    bool m_obscured;
162
};
163
164
class WallItem : public ProjectedItem
165
{
166
public:
167
    WallItem(MazeScene *scene, const QPointF &a, const QPointF &b, int type);
168
169
    QGraphicsProxyWidget *childItem() const
170
    {
171
        return m_childItem;
172
    }
173
174
    int type() const { return m_type; }
175
176
    void childResized();
177
178
private:
179
    QGraphicsProxyWidget *m_childItem;
180
    int m_type;
181
    qreal m_scale;
182
};
183
184
class MazeScene : public QGraphicsScene
185
{
186
    Q_OBJECT
187
public:
188
    MazeScene(const QVector<Light> &lights, const char *map, int width, int height);
189
190
    void addProjectedItem(ProjectedItem *item);
191
    void addEntity(Entity *entity);
192
    void addWall(const QPointF &a, const QPointF &b, int type);
193
    void drawBackground(QPainter *painter, const QRectF &rect);
194
195
    bool tryMove(QPointF &pos, const QPointF &delta, Entity *entity = 0) const;
196
197
    Camera camera() const { return m_camera; }
198
199
    void viewResized(QGraphicsView *view);
200
    void setAcceleratedViewport(bool accelerated);
201
202
protected:
203
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
204
    void keyPressEvent(QKeyEvent *event);
205
    void keyReleaseEvent(QKeyEvent *event);
206
    bool eventFilter(QObject *target, QEvent *event);
207
208
    bool handleKey(int key, bool pressed);
209
210
public slots:
211
    void move();
212
    void toggleRenderer();
213
    void toggleDoors();
214
    void loadFinished();
215
216
private slots:
217
    void moveDoors(qreal value);
218
219
private:
220
    bool blocked(const QPointF &pos, Entity *entity) const;
221
    void updateTransforms();
222
    void updateRenderer();
223
224
    QVector<WallItem *> m_walls;
225
    QVector<WallItem *> m_doors;
226
    QVector<QGraphicsItem *> m_floorTiles;
227
    QVector<QPushButton *> m_buttons;
228
    QVector<Entity *> m_entities;
229
    QVector<Light> m_lights;
230
    QVector<ProjectedItem *> m_projectedItems;
231
232
    Camera m_camera;
233
234
    qreal m_walkingVelocity;
235
    qreal m_strafingVelocity;
236
    qreal m_turningSpeed;
237
    qreal m_pitchSpeed;
238
239
    qreal m_deltaYaw;
240
    qreal m_deltaPitch;
241
242
    QTime m_time;
243
    QTimeLine *m_doorAnimation;
244
    long m_simulationTime;
245
    long m_walkTime;
246
    int m_width;
247
    int m_height;
248
    MediaPlayer *m_player;
249
    QPointF m_playerPos;
250
251
    bool m_accelerated;
252
253
    WalkingItem *m_walkingItem;
254
};
255
256
#endif