Initial commit
This commit is contained in:
505
engines/qdengine/qdcore/qd_camera.h
Normal file
505
engines/qdengine/qdcore/qd_camera.h
Normal file
@@ -0,0 +1,505 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QDENGINE_QDCORE_QD_CAMERA_H
|
||||
#define QDENGINE_QDCORE_QD_CAMERA_H
|
||||
|
||||
#include "qdengine/qdcore/qd_d3dutils.h"
|
||||
#include "qdengine/qdcore/qd_camera_mode.h"
|
||||
|
||||
namespace Common {
|
||||
class WriteStream;
|
||||
}
|
||||
|
||||
namespace QDEngine {
|
||||
|
||||
class sGridCell {
|
||||
public:
|
||||
//! Атрибуты
|
||||
enum cell_attribute_t {
|
||||
//! ячейка выделена
|
||||
CELL_SELECTED = 0x01,
|
||||
//! ячейка непроходима
|
||||
CELL_IMPASSABLE = 0x02,
|
||||
//! ячейка занята объектом
|
||||
CELL_OCCUPIED = 0x04,
|
||||
//! ячейка занята персонажем
|
||||
CELL_PERSONAGE_OCCUPIED = 0x08,
|
||||
//! по ячейке проходит путь персонажа
|
||||
CELL_PERSONAGE_PATH = 0x10
|
||||
};
|
||||
|
||||
sGridCell() {
|
||||
_attributes = CELL_IMPASSABLE;
|
||||
}
|
||||
sGridCell(uint16 atr, int16 h) {
|
||||
_attributes = atr;
|
||||
}
|
||||
~sGridCell() { }
|
||||
|
||||
bool is_walkable() const {
|
||||
return !check_attribute(CELL_IMPASSABLE);
|
||||
}
|
||||
void make_impassable() {
|
||||
set_attribute(CELL_IMPASSABLE);
|
||||
}
|
||||
void make_walkable() {
|
||||
drop_attribute(CELL_IMPASSABLE);
|
||||
}
|
||||
|
||||
void select() {
|
||||
set_attribute(CELL_SELECTED);
|
||||
}
|
||||
void deselect() {
|
||||
drop_attribute(CELL_SELECTED);
|
||||
}
|
||||
void toggle_select() {
|
||||
toggle_attribute(CELL_SELECTED);
|
||||
}
|
||||
bool is_selected() const {
|
||||
return check_attribute(CELL_SELECTED);
|
||||
}
|
||||
|
||||
int16 height() const {
|
||||
return 0;
|
||||
}
|
||||
void set_height(int16 h) { }
|
||||
|
||||
void set_attribute(uint32 attr) {
|
||||
_attributes |= attr;
|
||||
}
|
||||
void toggle_attribute(uint32 attr) {
|
||||
_attributes ^= attr;
|
||||
}
|
||||
void drop_attribute(uint32 attr) {
|
||||
_attributes &= ~attr;
|
||||
}
|
||||
bool check_attribute(uint32 attr) const {
|
||||
if (_attributes & attr) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
uint32 attributes() const {
|
||||
return _attributes;
|
||||
}
|
||||
void set_attributes(uint32 attr) {
|
||||
_attributes = attr;
|
||||
}
|
||||
|
||||
bool clear() {
|
||||
_attributes = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
byte _attributes;
|
||||
};
|
||||
|
||||
enum qdCameraRedrawMode {
|
||||
QDCAM_GRID_ABOVE,
|
||||
QDCAM_GRID_ZBUFFER,
|
||||
QDCAM_GRID_NONE
|
||||
};
|
||||
|
||||
class qdCamera {
|
||||
public:
|
||||
qdCamera();
|
||||
~qdCamera();
|
||||
|
||||
// Устанавливет параметры клетки с координатами cell_pos
|
||||
// по параметрам клетки cell
|
||||
bool set_grid_cell(const Vect2s &cell_pos, const sGridCell &cell);
|
||||
bool set_grid_cell_attributes(const Vect2s &cell_pos, int attr);
|
||||
|
||||
//! Устанавливает атрибуты для клеток из прямоугольника на сетке с ценром center_pos и размерами size.
|
||||
bool set_grid_attributes(const Vect2s ¢er_pos, const Vect2s &size, int attr);
|
||||
//! Очищает атрибуты для клеток из прямоугольника на сетке с ценром center_pos и размерами size.
|
||||
bool drop_grid_attributes(const Vect2s ¢er_pos, const Vect2s &size, int attr);
|
||||
//! Возвращает true, если в прямоугольнике на сетке ЕСТЬ ХОТЯ БЫ ОДНА ячейка с атрибутами attr.
|
||||
bool check_grid_attributes(const Vect2s ¢er_pos, const Vect2s &size, int attr) const;
|
||||
//! Возвращает количество ячеек в заданной области, имеющих именно аттрибуты attr
|
||||
int cells_num_with_exact_attributes(const Vect2s ¢er_pos, const Vect2s &size, int attr) const;
|
||||
|
||||
//! Устанавливает атрибуты для линии клеток.
|
||||
bool set_grid_line_attributes(const Vect2s &start_pos, const Vect2s &end_pos, const Vect2s &size, int attr);
|
||||
//! Очищает атрибуты для линии клеток.
|
||||
bool drop_grid_line_attributes(const Vect2s &start_pos, const Vect2s &end_pos, const Vect2s &size, int attr);
|
||||
//! Возвращает true, если в линии на сетке есть хотя бы одна ячейка с атрибутами attr.
|
||||
bool check_grid_line_attributes(const Vect2s &start_pos, const Vect2s &end_pos, const Vect2s &size, int attr) const;
|
||||
|
||||
bool is_walkable(const Vect2s ¢er_pos, const Vect2s &size, bool ignore_personages = false) const;
|
||||
|
||||
//! Устанавливает атрибуты attr для всех клеток сетки.
|
||||
bool set_grid_attributes(int attr);
|
||||
//! Очищает атрибуты attr для всех клеток сетки.
|
||||
bool drop_grid_attributes(int attr);
|
||||
|
||||
sGridCell *get_cell(const Vect2s &cell_pos);
|
||||
const sGridCell *get_cell(const Vect2s &cell_pos) const;
|
||||
|
||||
// Восстанавливает параметры клетки (сейчас - делает ее непроходимой
|
||||
// с нулевой высотой)
|
||||
bool restore_grid_cell(const Vect2s cell_pos);
|
||||
|
||||
void cycle_coords(int &x, int &y) const;
|
||||
|
||||
void set_redraw_mode(int md) const {
|
||||
_redraw_mode = md;
|
||||
}
|
||||
int get_redraw_mode() const {
|
||||
return _redraw_mode;
|
||||
}
|
||||
|
||||
void set_grid_size(int xs, int ys);
|
||||
|
||||
void scale_grid(int sx, int sy, int csx, int csy);
|
||||
void resize_grid(int sx, int sy);
|
||||
|
||||
int get_grid_sx() const {
|
||||
return _GSX;
|
||||
}
|
||||
int get_grid_sy() const {
|
||||
return _GSY;
|
||||
}
|
||||
|
||||
const sGridCell *get_grid() const {
|
||||
return _grid;
|
||||
}
|
||||
|
||||
int get_cell_sx() const {
|
||||
return _cellSX;
|
||||
}
|
||||
int get_cell_sy() const {
|
||||
return _cellSY;
|
||||
}
|
||||
|
||||
void set_cell_size(int csx, int csy) {
|
||||
_cellSX = csx;
|
||||
_cellSY = csy;
|
||||
}
|
||||
|
||||
void clear_grid();
|
||||
|
||||
// rotateAndScaling
|
||||
void rotate_and_scale(float XA, float YA, float ZA, float kX, float kY, float kZ);
|
||||
|
||||
float get_focus() const {
|
||||
return _focus;
|
||||
}
|
||||
void set_focus(float focus) {
|
||||
_focus = focus;
|
||||
}
|
||||
|
||||
void set_R(const float r);
|
||||
float get_R() const {
|
||||
return _m_fR;
|
||||
}
|
||||
|
||||
float get_x_angle() const {
|
||||
return _xAngle;
|
||||
}
|
||||
float get_y_angle() const {
|
||||
return _yAngle;
|
||||
}
|
||||
float get_z_angle() const {
|
||||
return _zAngle;
|
||||
}
|
||||
|
||||
inline void set_scr_size(int xs, int ys) {
|
||||
_scrSize.x = xs;
|
||||
_scrSize.y = ys;
|
||||
}
|
||||
|
||||
const Vect2i &get_scr_size() const {
|
||||
return _scrSize;
|
||||
}
|
||||
|
||||
// getScrSizeX
|
||||
int get_scr_sx() const {
|
||||
return _scrSize.x;
|
||||
}
|
||||
// getScrSizeY
|
||||
int get_scr_sy() const {
|
||||
return _scrSize.y;
|
||||
}
|
||||
|
||||
void set_scr_center(int xc, int yc) {
|
||||
_scrCenter.x = xc;
|
||||
_scrCenter.y = yc;
|
||||
}
|
||||
|
||||
const Vect2i &get_scr_center() const {
|
||||
return _scrCenter;
|
||||
}
|
||||
|
||||
int get_scr_center_x() const {
|
||||
return _scrCenter.x;
|
||||
}
|
||||
int get_scr_center_y() const {
|
||||
return _scrCenter.y;
|
||||
}
|
||||
|
||||
const Vect2i screen_center_limit_x() const;
|
||||
const Vect2i screen_center_limit_y() const;
|
||||
|
||||
const Vect2i &get_scr_offset() const {
|
||||
return _scrOffset;
|
||||
}
|
||||
void set_scr_offset(const Vect2i &offs) {
|
||||
_scrOffset = offs;
|
||||
}
|
||||
|
||||
const Vect2i &get_scr_center_initial() const {
|
||||
return _scrCenterInitial;
|
||||
}
|
||||
void set_scr_center_initial(const Vect2i &v) {
|
||||
_scrCenterInitial = v;
|
||||
}
|
||||
|
||||
void move_scr_center(int dxc, int dyc);
|
||||
|
||||
float scrolling_phase_x() const;
|
||||
float scrolling_phase_y() const;
|
||||
|
||||
const Vect3f scr2plane(const Vect2s &scrPoint) const;
|
||||
const Vect3f rscr2plane(const Vect2s &rscrPoint) const;
|
||||
|
||||
const Vect3f scr2plane_camera_coord(const Vect2s &scrPoint) const;
|
||||
const Vect3f rscr2plane_camera_coord(const Vect2s &scrPoint) const;
|
||||
const Vect2s plane2scr(const Vect3f &plnPoint) const;
|
||||
const Vect2s plane2rscr(const Vect3f &plnPoint) const;
|
||||
|
||||
const Vect3f rscr2camera_coord(const Vect2s &rScrPoint, float z) const;
|
||||
const Vect2s camera_coord2rscr(const Vect3f &coord) const;
|
||||
|
||||
const Vect2s rscr2scr(const Vect2s &v) const;
|
||||
const Vect2s scr2rscr(const Vect2s &v) const;
|
||||
|
||||
const Vect2s camera_coord2scr(const Vect3f &coord) const;
|
||||
|
||||
const Vect3f scr2global(const Vect2s &vScrPoint, float zInCameraCoord) const;
|
||||
const Vect3f rscr2global(const Vect2s rScrPoint, const float zInCameraCoord) const;
|
||||
const Vect3f global2camera_coord(const Vect3f &glCoord) const;
|
||||
const Vect3f camera_coord2global(const Vect3f &v) const;
|
||||
|
||||
const Vect2s global2scr(const Vect3f &glCoord) const;
|
||||
const Vect2s global2rscr(const Vect3f &glCoord) const;
|
||||
|
||||
//обрезание отрезка по плоскости отсечения камеры
|
||||
//возвращает false, если отрезок вообеще невидим
|
||||
bool line_cutting(Vect3f &b, Vect3f &e) const;
|
||||
//! Обрезка линиии, так чтобы она за сетку не выходила.
|
||||
/**
|
||||
Все координаты - сеточные, т.е. индексы ячеек сетки.
|
||||
*/
|
||||
bool clip_grid_line(Vect2s &v0, Vect2s &v1) const;
|
||||
|
||||
// getKScale
|
||||
float get_scale(const Vect3f &glCoord) const;
|
||||
|
||||
const Vect3f &get_grid_center() const {
|
||||
return _gridCenter;
|
||||
}
|
||||
void set_grid_center(const Vect3f &v) {
|
||||
_gridCenter = v;
|
||||
}
|
||||
|
||||
const sGridCell *get_cell(float X, float Y) const;
|
||||
const Vect2s get_cell_index(float X, float Y, bool grid_crop = true) const;
|
||||
const Vect2s get_cell_index(const Vect3f &v, bool grid_crop = true) const;
|
||||
const Vect3f get_cell_coords(int x_idx, int y_idx) const;
|
||||
const Vect3f get_cell_coords(const Vect2s &idxs) const;
|
||||
|
||||
void reset_all_select();
|
||||
//принимает глобальные координаты
|
||||
bool select_cell(int x, int y);
|
||||
|
||||
//принимает глобальные координаты
|
||||
bool deselect_cell(int x, int y);
|
||||
|
||||
void load_script(const xml::tag *p);
|
||||
bool save_script(Common::WriteStream &fh, int indent = 0) const;
|
||||
|
||||
//! Загрузка данных из сэйва.
|
||||
bool load_data(Common::SeekableReadStream &fh, int save_version);
|
||||
//! Запись данных в сэйв.
|
||||
bool save_data(Common::WriteStream &fh) const;
|
||||
|
||||
//! Инициализация данных, вызывается при старте и перезапуске игры.
|
||||
bool init();
|
||||
|
||||
bool draw_grid() const;
|
||||
bool draw_cell(int x, int y, int z, int penWidth, uint32 color) const;
|
||||
|
||||
//! Установка текущего режима камеры.
|
||||
/**
|
||||
Если объект нулевой, то берется объект по-умолчанию.
|
||||
*/
|
||||
bool set_mode(const qdCameraMode &mode, qdGameObjectAnimated *object = NULL);
|
||||
//! Возвращает true, если в данный момент можно менять режим камеры.
|
||||
bool can_change_mode() const;
|
||||
|
||||
//! Установка объекта, за которым камера следит по умолчанию.
|
||||
void set_default_object(qdGameObjectAnimated *p) {
|
||||
_default_object = p;
|
||||
}
|
||||
|
||||
//! Обсчет логики (движения камеры и т.д), параметр - время в секундах.
|
||||
bool quant(float dt);
|
||||
|
||||
//! Возвращает false, если вся рабочая область камеры находится за пределами экрана.
|
||||
/**
|
||||
Параметр - дополнительное смещение центра рабочей области камеры.
|
||||
*/
|
||||
bool is_visible(const Vect2i ¢er_offs = Vect2i(0, 0)) const;
|
||||
|
||||
void set_cycle(bool cx, bool cy) {
|
||||
_cycle_x = cx;
|
||||
_cycle_y = cy;
|
||||
}
|
||||
|
||||
void dump_grid(const char *file_name) const;
|
||||
|
||||
//! Параметры функции масштабирования
|
||||
float scale_pow() const {
|
||||
return _scale_pow;
|
||||
}
|
||||
void set_scale_pow(float sp) {
|
||||
_scale_pow = sp;
|
||||
}
|
||||
float scale_z_offset() const {
|
||||
return _scale_z_offset;
|
||||
};
|
||||
void set_scale_z_offset(float szo) {
|
||||
_scale_z_offset = szo;
|
||||
};
|
||||
|
||||
bool need_perspective_correction() const {
|
||||
return (fabs(_scale_pow - 1) > 0.001 || fabs(_scale_z_offset) > 0.001);
|
||||
}
|
||||
|
||||
//! Возвращает режим работы камеры по умолчанию.
|
||||
const qdCameraMode &default_mode() const {
|
||||
return _default_mode;
|
||||
}
|
||||
//! Установка режима работы камеры по умолчанию.
|
||||
void set_default_mode(const qdCameraMode &mode) {
|
||||
_default_mode = mode;
|
||||
}
|
||||
|
||||
static qdCamera *current_camera() {
|
||||
return _current_camera;
|
||||
}
|
||||
static void set_current_camera(qdCamera *p) {
|
||||
_current_camera = p;
|
||||
}
|
||||
|
||||
MATRIX3D const &get_view_matrix() const {
|
||||
return _m_cam;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
MATRIX3D _m_cam;
|
||||
float _m_fR;
|
||||
float _xAngle, _yAngle, _zAngle;
|
||||
|
||||
int _GSX, _GSY;
|
||||
sGridCell *_grid;
|
||||
|
||||
bool _cycle_x;
|
||||
bool _cycle_y;
|
||||
|
||||
int _cellSX, _cellSY;
|
||||
float _focus;//! расстояние до ближней плоскости отсечения
|
||||
// расстояние от центра рабочей области до
|
||||
// верхнего левого угла окна
|
||||
Vect2i _scrCenter;
|
||||
|
||||
// начальное расстояние от центра рабочей области до
|
||||
// верхнего левого угла окна
|
||||
Vect2i _scrCenterInitial;
|
||||
|
||||
// размер рабочей области
|
||||
Vect2i _scrSize;
|
||||
// смещение рабочей области
|
||||
Vect2i _scrOffset;
|
||||
|
||||
// Координаты центра сетки
|
||||
Vect3f _gridCenter;
|
||||
|
||||
mutable int _redraw_mode;
|
||||
|
||||
//! Текущий режим работы камеры.
|
||||
qdCameraMode _current_mode;
|
||||
|
||||
//! Время в секуднах с установки текущего режима.
|
||||
float _current_mode_work_time;
|
||||
bool _current_mode_switch;
|
||||
|
||||
//! Объект, за которым следит камера.
|
||||
qdGameObjectAnimated *_current_object;
|
||||
|
||||
//! Объект, за которым камера следит по умолчанию.
|
||||
qdGameObjectAnimated *_default_object;
|
||||
//! Режим работы камеры по умолчанию.
|
||||
qdCameraMode _default_mode;
|
||||
|
||||
//! Параметры функции ускоренного масштабирования из get_scale()
|
||||
float _scale_pow;
|
||||
float _scale_z_offset;
|
||||
|
||||
static qdCamera *_current_camera;
|
||||
|
||||
static const float _NEAR_PLANE; //ближная плоскость отсечения
|
||||
static const float _FAR_PLANE; //дальняя
|
||||
|
||||
enum {
|
||||
clLEFT = 1,
|
||||
clRIGHT = 2,
|
||||
clBOTTOM = 4,
|
||||
clTOP = 8
|
||||
};
|
||||
|
||||
inline int clip_out_code(const Vect2s &v) const {
|
||||
int code = 0;
|
||||
if (v.y >= _GSY)
|
||||
code |= clTOP;
|
||||
else if (v.y < 0)
|
||||
code |= clBOTTOM;
|
||||
if (v.x >= _GSX)
|
||||
code |= clRIGHT;
|
||||
else if (v.x < 0)
|
||||
code |= clLEFT;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
void clip_center_coords(int &x, int &y) const;
|
||||
};
|
||||
|
||||
inline Vect3f To3D(const Vect2f &v) {
|
||||
return Vect3f(v.x, v.y, 0);
|
||||
}
|
||||
|
||||
} // namespace QDEngine
|
||||
|
||||
#endif // QDENGINE_QDCORE_QD_CAMERA_H
|
||||
Reference in New Issue
Block a user