289 lines
10 KiB
C++
289 lines
10 KiB
C++
/*
|
|
GLObjectBase & Light
|
|
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
|
|
|
|
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 GLOBJECT_H
|
|
#define GLOBJECT_H
|
|
|
|
#include "glframebuffer.h"
|
|
#include "glmaterial.h"
|
|
#include "gltypes.h"
|
|
|
|
|
|
class ObjectBase
|
|
{
|
|
friend class QGLView;
|
|
friend class Scene;
|
|
friend class Renderer;
|
|
friend class RendererService;
|
|
friend class RendererSelection;
|
|
friend QDataStream & operator <<(QDataStream & s, const ObjectBase * p);
|
|
friend QDataStream & operator >>(QDataStream & s, ObjectBase *& p);
|
|
friend QDataStream & operator >>(QDataStream & s, Scene *& p);
|
|
public:
|
|
enum Type {glMesh, glLight, glCamera, glParticlesSystem};
|
|
enum Pass {Solid, Transparent, Reflection, User};
|
|
enum RenderMode {View = 0, Point = GL_POINT, Line = GL_LINE, Fill = GL_FILL};
|
|
|
|
explicit ObjectBase(Mesh * geom = 0, Material * mat = 0);
|
|
virtual ~ObjectBase();
|
|
|
|
virtual ObjectBase * clone(bool withChildren = true);
|
|
void destroy();
|
|
|
|
QString name() const {return name_;}
|
|
void setName(const QString & name) {name_ = name;}
|
|
//virtual GLuint hList() {return list;}
|
|
virtual void init();
|
|
virtual void update() {}
|
|
bool isInit() const {return is_init;}
|
|
bool isTexturesLoaded() const {return is_tex_loaded;}
|
|
Type type() const {return type_;}
|
|
|
|
RenderMode renderMode() const {return render_mode;}
|
|
void setRenderMode(RenderMode mode) {render_mode = mode;}
|
|
|
|
float lineWidth() const {return line_width;}
|
|
void setLineWidth(const float & width) {line_width = width;}
|
|
|
|
ObjectBase * parent() {return parent_;}
|
|
void setParent(ObjectBase * o) {parent_ = o;}
|
|
bool hasParent() const {return parent_ != nullptr;}
|
|
bool hasChildren() const {return children_.size() != 0;}
|
|
void setScene(Scene * v);
|
|
|
|
void addChild(ObjectBase * o);
|
|
void removeChild(ObjectBase * o);
|
|
void removeChild(int index);
|
|
void clearChildren(bool deleteAll = false);
|
|
int childCount() const {return children_.size();}
|
|
ObjectBase * child(int index);
|
|
ObjectBase * child(const QString & name);
|
|
const ObjectBase * child(int index) const;
|
|
const ObjectBase * child(const QString & name) const;
|
|
QList<ObjectBase * > children(bool all_ = false);
|
|
|
|
bool isVisible(bool check_parents = false) const;
|
|
bool isHidden(bool check_parents = false) const {return !isVisible(check_parents);}
|
|
void setVisible(bool v);
|
|
void setHidden(bool v) {setVisible(!v);}
|
|
void show() {setVisible(true);}
|
|
void hide() {setVisible(false);}
|
|
|
|
bool isReceiveShadows() const {return rec_shadow;}
|
|
bool isCastShadows() const {return cast_shadow;}
|
|
void setReceiveShadows(bool on) {rec_shadow = on;}
|
|
void setCastShadows(bool on) {cast_shadow = on;}
|
|
|
|
void move(const QVector3D & dv) {pos_ += dv; buildTransform();}
|
|
void moveTo(const QVector3D & dv) {pos_ = dv; buildTransform();}
|
|
void move(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {move(QVector3D(dx, dy, dz)); buildTransform();}
|
|
void moveTo(GLfloat dx, GLfloat dy, GLfloat dz = 0.) {moveTo(QVector3D(dx, dy, dz)); buildTransform();}
|
|
void moveX(GLfloat o) {pos_.setX(pos_.x() + o); buildTransform();}
|
|
void moveY(GLfloat o) {pos_.setY(pos_.y() + o); buildTransform();}
|
|
void moveZ(GLfloat o) {pos_.setZ(pos_.z() + o); buildTransform();}
|
|
void setPosX(GLfloat o) {pos_.setX(o); buildTransform();}
|
|
void setPosY(GLfloat o) {pos_.setY(o); buildTransform();}
|
|
void setPosZ(GLfloat o) {pos_.setZ(o); buildTransform();}
|
|
void setPos(GLfloat x, GLfloat y, GLfloat z) {pos_ = QVector3D(x, y, z); buildTransform();}
|
|
void setPos(const QVector3D & p) {pos_ = p; buildTransform();}
|
|
void resetPos() {pos_ = QVector3D(0., 0., 0.); buildTransform();}
|
|
|
|
QVector3D pos() const {return pos_;}
|
|
float posX() const {return pos_.x();}
|
|
float posY() const {return pos_.y();}
|
|
float posZ() const {return pos_.z();}
|
|
QVector3D worldPos() const {return (itransform_ * QVector4D(0, 0, 0, 1.)).toVector3D();}
|
|
QMatrix4x4 worldTransform() const {return itransform_;}
|
|
|
|
QVector3D rotation() const {return angles_;}
|
|
float rotationX() const {return angles_.x();}
|
|
float rotationY() const {return angles_.y();}
|
|
float rotationZ() const {return angles_.z();}
|
|
void rotateX(GLfloat a);
|
|
void rotateY(GLfloat a);
|
|
void rotateZ(GLfloat a);
|
|
void setRotationX(GLfloat a);
|
|
void setRotationY(GLfloat a);
|
|
void setRotationZ(GLfloat a);
|
|
void setRotation(const QVector3D & a);
|
|
void resetRotation();
|
|
|
|
QVector3D scale() {return scale_;}
|
|
float scaleX() {return scale_.x();}
|
|
float scaleY() {return scale_.y();}
|
|
float scaleZ() {return scale_.z();}
|
|
void scale(const QVector3D & sv) {raw_matrix = false; scale_ *= sv; buildTransform();}
|
|
void scale(GLfloat sx, GLfloat sy, GLfloat sz) {raw_matrix = false; scale(QVector3D(sx, sy, sz)); buildTransform();}
|
|
void scale(GLfloat sx, GLfloat sy) {raw_matrix = false; scale(QVector3D(sx, sy, sy)); buildTransform();}
|
|
void scale(GLfloat sx) {raw_matrix = false; scale(QVector3D(sx, sx, sx)); buildTransform();}
|
|
void scaleX(GLfloat a) {raw_matrix = false; scale_.setX(scale_.x() + a); buildTransform();}
|
|
void scaleY(GLfloat a) {raw_matrix = false; scale_.setY(scale_.y() + a); buildTransform();}
|
|
void scaleZ(GLfloat a) {raw_matrix = false; scale_.setZ(scale_.z() + a); buildTransform();}
|
|
void setScale(const QVector3D & a) {raw_matrix = false; scale_ = a; buildTransform();}
|
|
void setScale(GLfloat a) {raw_matrix = false; scale_ = QVector3D(a, a, a); buildTransform();}
|
|
void setScaleX(GLfloat a) {raw_matrix = false; scale_.setX(a); buildTransform();}
|
|
void setScaleY(GLfloat a) {raw_matrix = false; scale_.setY(a); buildTransform();}
|
|
void setScaleZ(GLfloat a) {raw_matrix = false; scale_.setZ(a); buildTransform();}
|
|
void resetScale() {raw_matrix = false; scale_ = QVector3D(1., 1., 1.); buildTransform();}
|
|
|
|
QMatrix4x4 transform() {return mat_;}
|
|
void setTransform(const QMatrix4x4 & t);
|
|
bool isRawMatrix() {return raw_matrix;}
|
|
|
|
bool isAcceptLight() const {return accept_light;}
|
|
void setAcceptLight(bool yes) {accept_light = yes;}
|
|
|
|
bool isAcceptFog() const {return accept_fog;}
|
|
void setAcceptFog(bool yes) {accept_fog = yes;}
|
|
|
|
bool isSelected(bool check_parents = false) const;
|
|
void setSelected(bool yes);
|
|
void select() {setSelected(true);}
|
|
void deselect() {setSelected(false);}
|
|
ObjectBase * selectedParent() const;
|
|
|
|
bool isSelectable() const {return select_;}
|
|
void setSelectable(bool yes) {select_ = yes;}
|
|
/*
|
|
bool isWriteDepth() const {return write_depth_;}
|
|
void setWriteDepth(bool yes) {write_depth_ = yes;}*/
|
|
|
|
GLenum srcAlpha() const {return blend_src;}
|
|
GLenum destAlpha() const {return blend_dest;}
|
|
void setSrcAlpha(GLenum mode) {blend_src = mode;}
|
|
void setDestAlpha(GLenum mode) {blend_dest = mode;}
|
|
|
|
void setMaterial(Material * m, bool with_children = false);
|
|
Material * material() {return material_;}
|
|
|
|
void setColor(QColor c, bool with_children = false);
|
|
QColor color() {return color_;}
|
|
|
|
const Box3D & boundingBox() const {return bound;}
|
|
void setMesh(Mesh * v);
|
|
Mesh * mesh() {return mesh_;}
|
|
|
|
void calculateBoundingBox();
|
|
|
|
void setProperty(const QString & pn, const QVariant & v);
|
|
QVariant property(const QString & pn, bool * exists = 0) const;
|
|
bool hasProperty(const QString & pn) const;
|
|
void removeProperty(const QString & pn);
|
|
|
|
QVector3D pos_h;
|
|
|
|
//QVector<GLfloat> d_vertices, d_normals, d_uvs;
|
|
|
|
protected:
|
|
void addChildren(QList<ObjectBase * > & list, ObjectBase * where);
|
|
void loadTextures(bool with_children = false);
|
|
//void deleteTextures() {foreach (GLuint i, textures) currentQGLView->deleteTexture(i); textures.clear();}
|
|
void buildTransform();
|
|
void initInternal();
|
|
void checkPass();
|
|
void setSceneTreeChanged();
|
|
void setMeshChanged();
|
|
virtual void localTransform(QMatrix4x4 & m);
|
|
QMatrix4x4 worldMatrix(QMatrix4x4 parent) const;
|
|
|
|
int pass_; // Pass
|
|
bool is_init, is_tex_loaded, accept_light, accept_fog, /*write_depth_,*/ visible_, cast_shadow, rec_shadow, select_, selected_, raw_matrix;
|
|
bool is_root;
|
|
float line_width;
|
|
QColor color_;
|
|
uint id_;
|
|
Type type_;
|
|
RenderMode render_mode;
|
|
Box3D bound;
|
|
QVector3D pos_, angles_, scale_;
|
|
QList<ObjectBase * > children_;
|
|
QMatrix4x4 itransform_, mat_;
|
|
QString name_;
|
|
GLenum blend_src, blend_dest;
|
|
ObjectBase * parent_;
|
|
Scene * scene_;
|
|
Material * material_;
|
|
Mesh * mesh_;
|
|
QVariantMap meta;
|
|
|
|
};
|
|
|
|
inline bool operator <(const ObjectBase & f, const ObjectBase & s) {return f.pos_h.z() < s.pos_h.z();}
|
|
|
|
|
|
class AimedObject: public ObjectBase {
|
|
friend class QGLView;
|
|
friend class GLRendererBase;
|
|
friend class Light;
|
|
friend class Camera;
|
|
public:
|
|
AimedObject();
|
|
~AimedObject() {}
|
|
QVector3D aim() const {return aim_;}
|
|
QVector3D worldAim() const {return (itransform_ * QVector4D(aim_, 1.)).toVector3D();}
|
|
void setAim(const QVector3D & p);
|
|
QVector3D direction() const;
|
|
void setDirection(const QVector3D & d);
|
|
void setDirection(double x, double y, double z) {setDirection(QVector3D(x, y, z));}
|
|
protected:
|
|
QVector3D aim_;
|
|
};
|
|
|
|
|
|
class Light: public AimedObject {
|
|
friend class QGLView;
|
|
friend class RendererBase;
|
|
public:
|
|
enum Type {Omni, Directional, Cone};
|
|
|
|
Light();
|
|
Light(const QVector3D & p, const QColor & c = Qt::white, float i = 1.);
|
|
virtual ObjectBase * clone(bool withChildren = true);
|
|
virtual void init() {shadow_map.resize(512, 512); is_init = true;}
|
|
void apply();
|
|
|
|
float angle_start;
|
|
float angle_end;
|
|
float intensity;
|
|
float decay_const;
|
|
float decay_linear;
|
|
float decay_quadratic;
|
|
float decay_start;
|
|
float decay_end;
|
|
Type light_type;
|
|
Framebuffer shadow_map;
|
|
QMatrix4x4 shadow_matrix;
|
|
|
|
protected:
|
|
|
|
};
|
|
|
|
template <class T>
|
|
inline T globject_cast(ObjectBase * object) {return reinterpret_cast<T>(object);}
|
|
|
|
template <class T>
|
|
inline T globject_cast(const ObjectBase * object) {return reinterpret_cast<T>(object);}
|
|
|
|
|
|
QDataStream & operator <<(QDataStream & s, const ObjectBase * p);
|
|
QDataStream & operator >>(QDataStream & s, ObjectBase *& p);
|
|
|
|
inline QList<ObjectBase*> light2objectList(const QList<Light*> & v) {QList<ObjectBase*> ret; foreach (Light*i, v) ret << (ObjectBase*)i; return ret;}
|
|
|
|
#endif // GLOBJECT_H
|