multimaterial support, "preset"

each preset contains visibility, flags and material
This commit is contained in:
2023-05-16 18:18:26 +03:00
parent c275d006d5
commit 484a7f972f
11 changed files with 523 additions and 259 deletions

View File

@@ -161,6 +161,14 @@ inline void decomposeQMatrix4x4(const QMatrix4x4 & m, QVector3D & position, QVec
Transform::Transform(): m_scale(1.0f, 1.0f, 1.0f), m_translation(), m_eulerRotationAngles(), m_matrixDirty(false) {} Transform::Transform(): m_scale(1.0f, 1.0f, 1.0f), m_translation(), m_eulerRotationAngles(), m_matrixDirty(false) {}
Transform::Transform(const Transform & t) {
m_scale = t.m_scale;
m_translation = t.m_translation;
m_eulerRotationAngles = t.m_eulerRotationAngles;
m_matrixDirty = true;
}
Transform & Transform::operator=(const Transform & t) { Transform & Transform::operator=(const Transform & t) {
m_scale = t.m_scale; m_scale = t.m_scale;
m_translation = t.m_translation; m_translation = t.m_translation;

View File

@@ -32,6 +32,7 @@ class QGLENGINE_CORE_EXPORT Transform {
public: public:
Transform(); Transform();
Transform(const Transform & t);
Transform & operator=(const Transform & t); Transform & operator=(const Transform & t);
float scale() const; float scale() const;

View File

@@ -247,7 +247,7 @@ void RendererBase::reloadLightsParameters(const QMap<int, QList<Light *>> & ligh
so.decay_intensity[2] = l->decay_quadratic; so.decay_intensity[2] = l->decay_quadratic;
so.decay_intensity[3] = l->intensity; so.decay_intensity[3] = l->intensity;
so.size = l->size; so.size = l->size;
so.flags = l->cast_shadow ? 1 : 0; so.flags = l->isCastShadows() ? 1 : 0;
if (l->light_type == Light::Cone) l->light_map.copyToQGLMap(so.map); if (l->light_type == Light::Cone) l->light_map.copyToQGLMap(so.map);
} }
buffer_lights.bind(view); buffer_lights.bind(view);

View File

@@ -26,22 +26,12 @@
// static int _count = 0; // static int _count = 0;
ObjectBase::ObjectBase(Mesh * geom, Material * mat) { ObjectBase::ObjectBase(Mesh * geom, Material * mat) {
type_ = glMesh; blend_src = GL_SRC_ALPHA;
prev_pass = rpSolid; blend_dest = GL_ONE_MINUS_SRC_ALPHA;
parent_ = nullptr;
color_ = Qt::white;
is_root = is_init = selected_ = false;
visible_ = accept_fog = accept_light = cast_shadow = rec_shadow = select_ = true;
line_width = -1.;
id_ = 0;
blend_src = GL_SRC_ALPHA;
blend_dest = GL_ONE_MINUS_SRC_ALPHA;
type_ = glMesh;
raw_matrix = selected_aim = false;
mat_.setToIdentity(); mat_.setToIdentity();
scene_ = nullptr; mesh_ = geom;
mesh_ = geom; setPreset(0);
material_ = mat; currentPreset().material = mat;
// qDebug() << "ObjectBase, now" << ++_count; // qDebug() << "ObjectBase, now" << ++_count;
} }
@@ -65,9 +55,8 @@ ObjectBase * ObjectBase::clone(bool withChildren) {
ObjectBase * o = new ObjectBase(); ObjectBase * o = new ObjectBase();
o->prev_pass = prev_pass; o->prev_pass = prev_pass;
o->is_init = false; o->is_init = false;
o->accept_light = accept_light; o->presets = presets;
o->accept_fog = accept_fog; o->cur_preset = cur_preset;
o->visible_ = visible_;
o->color_ = color_; o->color_ = color_;
o->type_ = type_; o->type_ = type_;
o->raw_matrix = raw_matrix; o->raw_matrix = raw_matrix;
@@ -80,7 +69,6 @@ ObjectBase * ObjectBase::clone(bool withChildren) {
o->blend_src = blend_src; o->blend_src = blend_src;
o->blend_dest = blend_dest; o->blend_dest = blend_dest;
o->pos_h = pos_h; o->pos_h = pos_h;
o->material_ = material_;
o->mesh_ = mesh_; o->mesh_ = mesh_;
o->meta = meta; o->meta = meta;
o->scene_ = nullptr; o->scene_ = nullptr;
@@ -107,8 +95,8 @@ void ObjectBase::init() {
RenderPass ObjectBase::pass() const { RenderPass ObjectBase::pass() const {
RenderPass ret = rpSolid; RenderPass ret = rpSolid;
if (material_) if (currentPreset().material)
if (material_->hasTransparency()) ret = rpTransparent; if (currentPreset().material->hasTransparency()) ret = rpTransparent;
return ret; return ret;
} }
@@ -206,11 +194,11 @@ ObjectBaseList ObjectBase::children(bool all_) {
bool ObjectBase::isVisible(bool check_parents) const { bool ObjectBase::isVisible(bool check_parents) const {
if (!check_parents) return visible_; if (!check_parents) return currentPreset().visible;
if (!visible_) return false; if (!currentPreset().visible) return false;
ObjectBase * p = parent_; ObjectBase * p = parent_;
while (p) { while (p) {
if (!p->visible_) return false; if (!p->currentPreset().visible) return false;
p = p->parent_; p = p->parent_;
} }
return true; return true;
@@ -218,19 +206,116 @@ bool ObjectBase::isVisible(bool check_parents) const {
void ObjectBase::setVisible(bool v) { void ObjectBase::setVisible(bool v) {
visible_ = v; currentPreset().visible = v;
setSceneTreeChanged(); setSceneTreeChanged();
} }
void ObjectBase::setReceiveShadows(bool on) {
currentPreset().receive_shadow = on;
setObjectsChanged();
}
void ObjectBase::setCastShadows(bool on) { void ObjectBase::setCastShadows(bool on) {
cast_shadow = on; currentPreset().cast_shadow = on;
if (type_ == glLight) if (type_ == glLight)
((Light *)this)->apply(); ((Light *)this)->apply();
else else
setObjectsChanged(); setObjectsChanged();
} }
void ObjectBase::move(const QVector3D & dv) {
trans.setTranslation(pos() + dv);
buildTransform();
}
void ObjectBase::moveTo(const QVector3D & dv) {
trans.setTranslation(dv);
buildTransform();
}
void ObjectBase::move(GLfloat dx, GLfloat dy, GLfloat dz) {
move(QVector3D(dx, dy, dz));
buildTransform();
}
void ObjectBase::moveTo(GLfloat dx, GLfloat dy, GLfloat dz) {
moveTo(QVector3D(dx, dy, dz));
buildTransform();
}
void ObjectBase::moveX(GLfloat o) {
trans.setTranslationX(posX() + o);
buildTransform();
}
void ObjectBase::moveY(GLfloat o) {
trans.setTranslationY(posY() + o);
buildTransform();
}
void ObjectBase::moveZ(GLfloat o) {
trans.setTranslationZ(posZ() + o);
buildTransform();
}
void ObjectBase::setPosX(GLfloat o) {
trans.setTranslationX(o);
buildTransform();
}
void ObjectBase::setPosY(GLfloat o) {
trans.setTranslationY(o);
buildTransform();
}
void ObjectBase::setPosZ(GLfloat o) {
trans.setTranslationZ(o);
buildTransform();
}
void ObjectBase::setPos(GLfloat x, GLfloat y, GLfloat z) {
trans.setTranslation(QVector3D(x, y, z));
buildTransform();
}
void ObjectBase::setPos(const QVector3D & p) {
trans.setTranslation(p);
buildTransform();
}
void ObjectBase::resetPos() {
trans.setTranslation(QVector3D());
buildTransform();
}
void ObjectBase::rotateX(GLfloat a) {
raw_matrix = false;
trans.setRotationX(trans.rotationX() + a);
buildTransform();
}
void ObjectBase::rotateY(GLfloat a) {
raw_matrix = false;
trans.setRotationY(trans.rotationY() + a);
buildTransform();
}
void ObjectBase::rotateZ(GLfloat a) { void ObjectBase::rotateZ(GLfloat a) {
raw_matrix = false; raw_matrix = false;
@@ -242,6 +327,20 @@ void ObjectBase::rotateZ(GLfloat a) {
} }
void ObjectBase::setRotationX(GLfloat a) {
raw_matrix = false;
trans.setRotationX(a);
buildTransform();
}
void ObjectBase::setRotationY(GLfloat a) {
raw_matrix = false;
trans.setRotationY(a);
buildTransform();
}
void ObjectBase::setRotationZ(GLfloat a) { void ObjectBase::setRotationZ(GLfloat a) {
raw_matrix = false; raw_matrix = false;
trans.setRotationZ(a); trans.setRotationZ(a);
@@ -252,6 +351,111 @@ void ObjectBase::setRotationZ(GLfloat a) {
} }
void ObjectBase::setRotation(const QVector3D & a) {
raw_matrix = false;
trans.setRotation(a);
buildTransform();
}
void ObjectBase::resetRotation() {
raw_matrix = false;
trans.setRotation(QVector3D());
buildTransform();
}
void ObjectBase::scale(const QVector3D & sv) {
raw_matrix = false;
trans.setScale(trans.scale3D() * sv);
buildTransform();
}
void ObjectBase::scale(GLfloat sx, GLfloat sy, GLfloat sz) {
raw_matrix = false;
scale(QVector3D(sx, sy, sz));
buildTransform();
}
void ObjectBase::scale(GLfloat sx, GLfloat sy) {
raw_matrix = false;
scale(QVector3D(sx, sy, sy));
buildTransform();
}
void ObjectBase::scale(GLfloat sx) {
raw_matrix = false;
scale(QVector3D(sx, sx, sx));
buildTransform();
}
void ObjectBase::scaleX(GLfloat a) {
raw_matrix = false;
trans.setScaleX(trans.scale3D().x() + a);
buildTransform();
}
void ObjectBase::scaleY(GLfloat a) {
raw_matrix = false;
trans.setScaleY(trans.scale3D().y() + a);
buildTransform();
}
void ObjectBase::scaleZ(GLfloat a) {
raw_matrix = false;
trans.setScaleZ(trans.scale3D().z() + a);
buildTransform();
}
void ObjectBase::setScale(const QVector3D & a) {
raw_matrix = false;
trans.setScale(a);
buildTransform();
}
void ObjectBase::setScale(GLfloat a) {
raw_matrix = false;
trans.setScale(a);
buildTransform();
}
void ObjectBase::setScaleX(GLfloat a) {
raw_matrix = false;
trans.setScaleX(a);
buildTransform();
}
void ObjectBase::setScaleY(GLfloat a) {
raw_matrix = false;
trans.setScaleY(a);
buildTransform();
}
void ObjectBase::setScaleZ(GLfloat a) {
raw_matrix = false;
trans.setScaleZ(a);
buildTransform();
}
void ObjectBase::resetScale() {
raw_matrix = false;
trans.setScale(1.f);
buildTransform();
}
void ObjectBase::setTransform(const Transform & t) { void ObjectBase::setTransform(const Transform & t) {
trans = t; trans = t;
buildTransform(); buildTransform();
@@ -308,6 +512,15 @@ void ObjectBase::removeProperty(const QString & pn) {
} }
void ObjectBase::setPreset(int preset) {
if (preset < 0) preset = 0;
if (presets.size() <= preset) presets.resize(preset + 1);
cur_preset = preset;
for (auto * c: children_)
c->setPreset(preset);
}
void ObjectBase::setMatrix(const QMatrix4x4 & t) { void ObjectBase::setMatrix(const QMatrix4x4 & t) {
// raw_matrix = true; // raw_matrix = true;
// mat_ = t; // mat_ = t;
@@ -379,6 +592,18 @@ QGenericMatrix<3, 2, float> ObjectBase::textureGLMatrix() const {
} }
void ObjectBase::setAcceptLight(bool yes) {
currentPreset().accept_light = yes;
setObjectsChanged();
}
void ObjectBase::setAcceptFog(bool yes) {
currentPreset().accept_fog = yes;
setObjectsChanged();
}
bool ObjectBase::isSelected(bool check_parents) const { bool ObjectBase::isSelected(bool check_parents) const {
if (!check_parents) return selected_; if (!check_parents) return selected_;
if (selected_) return true; if (selected_) return true;
@@ -409,7 +634,7 @@ ObjectBase * ObjectBase::selectedParent() const {
void ObjectBase::setMaterial(Material * m, bool with_children) { void ObjectBase::setMaterial(Material * m, bool with_children) {
material_ = m; currentPreset().material = m;
if (with_children) if (with_children)
foreach(ObjectBase * i, children_) foreach(ObjectBase * i, children_)
i->setMaterial(m, true); i->setMaterial(m, true);
@@ -643,15 +868,24 @@ void Light::apply() {
} }
QDataStream & operator<<(QDataStream & s, const ObjectBase::Preset & p) {
ChunkStream cs;
cs.add(1, p.visible).add(2, p.accept_light).add(3, p.accept_fog).add(4, p.cast_shadow).add(5, p.receive_shadow);
s << cs.data();
return s;
}
QDataStream & operator>>(QDataStream & s, ObjectBase::Preset & p) {
ChunkStream cs(s);
cs.readAll();
cs.get(1, p.visible).get(2, p.accept_light).get(3, p.accept_fog).get(4, p.cast_shadow).get(5, p.receive_shadow);
return s;
}
QDataStream & operator<<(QDataStream & s, const ObjectBase * p) { QDataStream & operator<<(QDataStream & s, const ObjectBase * p) {
ChunkStream cs; ChunkStream cs;
// qDebug() << "place" << p->name() << "..."; // qDebug() << "place" << p->name() << "...";
cs.add(1, int(p->type_)) cs.add(1, int(p->type_))
.add(2, p->accept_light)
.add(3, p->accept_fog)
.add(4, p->visible_)
.add(5, p->cast_shadow)
.add(6, p->rec_shadow)
.add(7, p->raw_matrix) .add(7, p->raw_matrix)
.add(8, p->line_width) .add(8, p->line_width)
.add(14, p->mat_) .add(14, p->mat_)
@@ -660,7 +894,8 @@ QDataStream & operator<<(QDataStream & s, const ObjectBase * p) {
.add(18, p->meta) .add(18, p->meta)
.add(19, p->color_) .add(19, p->color_)
.add(20, p->trans) .add(20, p->trans)
.add(21, p->trans_texture); .add(21, p->trans_texture)
.add(22, p->presets);
// qDebug() << "place self done"; // qDebug() << "place self done";
if (p->type_ == ObjectBase::glLight) { if (p->type_ == ObjectBase::glLight) {
// qDebug() << "place light ..."; // qDebug() << "place light ...";
@@ -721,19 +956,19 @@ QDataStream & operator>>(QDataStream & s, ObjectBase *& p) {
if (p) p->type_ = type; if (p) p->type_ = type;
} break; } break;
case 2: case 2:
if (p) p->accept_light = cs.getData<bool>(); if (p) p->currentPreset().accept_light = cs.getData<bool>();
break; break;
case 3: case 3:
if (p) p->accept_fog = cs.getData<bool>(); if (p) p->currentPreset().accept_fog = cs.getData<bool>();
break; break;
case 4: case 4:
if (p) p->visible_ = cs.getData<bool>(); if (p) p->currentPreset().visible = cs.getData<bool>();
break; break;
case 5: case 5:
if (p) p->cast_shadow = cs.getData<bool>(); if (p) p->currentPreset().cast_shadow = cs.getData<bool>();
break; break;
case 6: case 6:
if (p) p->rec_shadow = cs.getData<bool>(); if (p) p->currentPreset().receive_shadow = cs.getData<bool>();
break; break;
case 7: case 7:
if (p) p->raw_matrix = cs.getData<bool>(); if (p) p->raw_matrix = cs.getData<bool>();
@@ -762,6 +997,12 @@ QDataStream & operator>>(QDataStream & s, ObjectBase *& p) {
case 21: case 21:
if (p) p->trans_texture = cs.getData<Transform>(); if (p) p->trans_texture = cs.getData<Transform>();
break; break;
case 22:
if (p) {
p->presets = cs.getData<QVector<ObjectBase::Preset>>();
if (p->presets.isEmpty()) p->presets.resize(1);
}
break;
case 100: case 100:
if (l) l->setAim(cs.getData<QVector3D>()); if (l) l->setAim(cs.getData<QVector3D>());
break; break;

View File

@@ -30,6 +30,7 @@ class QGLENGINE_CORE_EXPORT ObjectBase {
friend class RendererSelection; friend class RendererSelection;
friend QGLENGINE_CORE_EXPORT QDataStream & operator<<(QDataStream & s, const ObjectBase * p); friend QGLENGINE_CORE_EXPORT QDataStream & operator<<(QDataStream & s, const ObjectBase * p);
friend QGLENGINE_CORE_EXPORT QDataStream & operator>>(QDataStream & s, ObjectBase *& p); friend QGLENGINE_CORE_EXPORT QDataStream & operator>>(QDataStream & s, ObjectBase *& p);
friend QGLENGINE_CORE_EXPORT QDataStream & operator<<(QDataStream & s, const Scene * p);
friend QGLENGINE_CORE_EXPORT QDataStream & operator>>(QDataStream & s, Scene *& p); friend QGLENGINE_CORE_EXPORT QDataStream & operator>>(QDataStream & s, Scene *& p);
public: public:
@@ -40,7 +41,7 @@ public:
glParticlesSystem glParticlesSystem
}; };
explicit ObjectBase(Mesh * geom = 0, Material * mat = 0); explicit ObjectBase(Mesh * geom = nullptr, Material * mat = nullptr);
virtual ~ObjectBase(); virtual ~ObjectBase();
virtual ObjectBase * clone(bool withChildren = true); virtual ObjectBase * clone(bool withChildren = true);
@@ -82,66 +83,24 @@ public:
void show() { setVisible(true); } void show() { setVisible(true); }
void hide() { setVisible(false); } void hide() { setVisible(false); }
bool isReceiveShadows() const { return rec_shadow; } bool isReceiveShadows() const { return currentPreset().receive_shadow; }
bool isCastShadows() const { return cast_shadow; } bool isCastShadows() const { return currentPreset().cast_shadow; }
void setReceiveShadows(bool on) { void setReceiveShadows(bool on);
rec_shadow = on;
setObjectsChanged();
}
void setCastShadows(bool on); void setCastShadows(bool on);
void move(const QVector3D & dv) { void move(const QVector3D & dv);
trans.setTranslation(pos() + dv); void moveTo(const QVector3D & dv);
buildTransform(); void move(GLfloat dx, GLfloat dy, GLfloat dz = 0.);
} void moveTo(GLfloat dx, GLfloat dy, GLfloat dz = 0.);
void moveTo(const QVector3D & dv) { void moveX(GLfloat o);
trans.setTranslation(dv); void moveY(GLfloat o);
buildTransform(); void moveZ(GLfloat o);
} void setPosX(GLfloat o);
void move(GLfloat dx, GLfloat dy, GLfloat dz = 0.) { void setPosY(GLfloat o);
move(QVector3D(dx, dy, dz)); void setPosZ(GLfloat o);
buildTransform(); void setPos(GLfloat x, GLfloat y, GLfloat z);
} void setPos(const QVector3D & p);
void moveTo(GLfloat dx, GLfloat dy, GLfloat dz = 0.) { void resetPos();
moveTo(QVector3D(dx, dy, dz));
buildTransform();
}
void moveX(GLfloat o) {
trans.setTranslationX(posX() + o);
buildTransform();
}
void moveY(GLfloat o) {
trans.setTranslationY(posY() + o);
buildTransform();
}
void moveZ(GLfloat o) {
trans.setTranslationZ(posZ() + o);
buildTransform();
}
void setPosX(GLfloat o) {
trans.setTranslationX(o);
buildTransform();
}
void setPosY(GLfloat o) {
trans.setTranslationY(o);
buildTransform();
}
void setPosZ(GLfloat o) {
trans.setTranslationZ(o);
buildTransform();
}
void setPos(GLfloat x, GLfloat y, GLfloat z) {
trans.setTranslation(QVector3D(x, y, z));
buildTransform();
}
void setPos(const QVector3D & p) {
trans.setTranslation(p);
buildTransform();
}
void resetPos() {
trans.setTranslation(QVector3D());
buildTransform();
}
QVector3D pos() const { return trans.translation(); } QVector3D pos() const { return trans.translation(); }
float posX() const { return trans.translation().x(); } float posX() const { return trans.translation().x(); }
@@ -154,108 +113,32 @@ public:
float rotationX() const { return rotation().x(); } float rotationX() const { return rotation().x(); }
float rotationY() const { return rotation().y(); } float rotationY() const { return rotation().y(); }
float rotationZ() const { return rotation().z(); } float rotationZ() const { return rotation().z(); }
void rotateX(GLfloat a) { void rotateX(GLfloat a);
raw_matrix = false; void rotateY(GLfloat a);
trans.setRotationX(trans.rotationX() + a);
buildTransform();
}
void rotateY(GLfloat a) {
raw_matrix = false;
trans.setRotationY(trans.rotationY() + a);
buildTransform();
}
void rotateZ(GLfloat a); void rotateZ(GLfloat a);
void setRotationX(GLfloat a) { void setRotationX(GLfloat a);
raw_matrix = false; void setRotationY(GLfloat a);
trans.setRotationX(a);
buildTransform();
}
void setRotationY(GLfloat a) {
raw_matrix = false;
trans.setRotationY(a);
buildTransform();
}
void setRotationZ(GLfloat a); void setRotationZ(GLfloat a);
void setRotation(const QVector3D & a) { void setRotation(const QVector3D & a);
raw_matrix = false; void resetRotation();
trans.setRotation(a);
buildTransform();
}
void resetRotation() {
raw_matrix = false;
trans.setRotation(QVector3D());
buildTransform();
}
QVector3D scale() { return trans.scale3D(); } QVector3D scale() { return trans.scale3D(); }
float scaleX() { return trans.scale3D().x(); } float scaleX() { return trans.scale3D().x(); }
float scaleY() { return trans.scale3D().y(); } float scaleY() { return trans.scale3D().y(); }
float scaleZ() { return trans.scale3D().z(); } float scaleZ() { return trans.scale3D().z(); }
void scale(const QVector3D & sv) { void scale(const QVector3D & sv);
raw_matrix = false; void scale(GLfloat sx, GLfloat sy, GLfloat sz);
trans.setScale(trans.scale3D() * sv); void scale(GLfloat sx, GLfloat sy);
buildTransform(); void scale(GLfloat sx);
} void scaleX(GLfloat a);
void scale(GLfloat sx, GLfloat sy, GLfloat sz) { void scaleY(GLfloat a);
raw_matrix = false; void scaleZ(GLfloat a);
scale(QVector3D(sx, sy, sz)); void setScale(const QVector3D & a);
buildTransform(); void setScale(GLfloat a);
} void setScaleX(GLfloat a);
void scale(GLfloat sx, GLfloat sy) { void setScaleY(GLfloat a);
raw_matrix = false; void setScaleZ(GLfloat a);
scale(QVector3D(sx, sy, sy)); void resetScale();
buildTransform();
}
void scale(GLfloat sx) {
raw_matrix = false;
scale(QVector3D(sx, sx, sx));
buildTransform();
}
void scaleX(GLfloat a) {
raw_matrix = false;
trans.setScaleX(trans.scale3D().x() + a);
buildTransform();
}
void scaleY(GLfloat a) {
raw_matrix = false;
trans.setScaleY(trans.scale3D().y() + a);
buildTransform();
}
void scaleZ(GLfloat a) {
raw_matrix = false;
trans.setScaleZ(trans.scale3D().z() + a);
buildTransform();
}
void setScale(const QVector3D & a) {
raw_matrix = false;
trans.setScale(a);
buildTransform();
}
void setScale(GLfloat a) {
raw_matrix = false;
trans.setScale(a);
buildTransform();
}
void setScaleX(GLfloat a) {
raw_matrix = false;
trans.setScaleX(a);
buildTransform();
}
void setScaleY(GLfloat a) {
raw_matrix = false;
trans.setScaleY(a);
buildTransform();
}
void setScaleZ(GLfloat a) {
raw_matrix = false;
trans.setScaleZ(a);
buildTransform();
}
void resetScale() {
raw_matrix = false;
trans.setScale(1.f);
buildTransform();
}
Transform transform() { return trans; } Transform transform() { return trans; }
void setTransform(const Transform & t); void setTransform(const Transform & t);
@@ -273,17 +156,11 @@ public:
QMatrix4x4 textureMatrix() const; QMatrix4x4 textureMatrix() const;
QGenericMatrix<3, 2, float> textureGLMatrix() const; QGenericMatrix<3, 2, float> textureGLMatrix() const;
bool isAcceptLight() const { return accept_light; } bool isAcceptLight() const { return currentPreset().accept_light; }
void setAcceptLight(bool yes) { void setAcceptLight(bool yes);
accept_light = yes;
setObjectsChanged();
}
bool isAcceptFog() const { return accept_fog; } bool isAcceptFog() const { return currentPreset().accept_fog; }
void setAcceptFog(bool yes) { void setAcceptFog(bool yes);
accept_fog = yes;
setObjectsChanged();
}
bool isSelected(bool check_parents = false) const; bool isSelected(bool check_parents = false) const;
void setSelected(bool yes); void setSelected(bool yes);
@@ -302,7 +179,7 @@ public:
void setDestAlpha(GLenum mode) { blend_dest = mode; } void setDestAlpha(GLenum mode) { blend_dest = mode; }
void setMaterial(Material * m, bool with_children = false); void setMaterial(Material * m, bool with_children = false);
Material * material() { return material_; } Material * material() { return currentPreset().material; }
void setColor(QColor c, bool with_children = false); void setColor(QColor c, bool with_children = false);
QColor color() { return color_; } QColor color() { return color_; }
@@ -319,9 +196,22 @@ public:
bool hasProperty(const QString & pn) const; bool hasProperty(const QString & pn) const;
void removeProperty(const QString & pn); void removeProperty(const QString & pn);
void setPreset(int preset);
QVector3D pos_h; QVector3D pos_h;
protected: protected:
struct Preset {
bool visible = true;
bool accept_light = true;
bool accept_fog = true;
bool cast_shadow = true;
bool receive_shadow = true;
Material * material = nullptr;
};
friend QGLENGINE_CORE_EXPORT QDataStream & operator<<(QDataStream & s, const ObjectBase::Preset & p);
friend QGLENGINE_CORE_EXPORT QDataStream & operator>>(QDataStream & s, ObjectBase::Preset & p);
virtual void transformChanged() {} virtual void transformChanged() {}
void addChildren(ObjectBaseList & list, ObjectBase * where); void addChildren(ObjectBaseList & list, ObjectBase * where);
void buildTransform(bool force = false); void buildTransform(bool force = false);
@@ -330,24 +220,27 @@ protected:
void setObjectsChanged(); void setObjectsChanged();
void localTransform(QMatrix4x4 & m); void localTransform(QMatrix4x4 & m);
QMatrix4x4 worldMatrix(QMatrix4x4 parent) const; QMatrix4x4 worldMatrix(QMatrix4x4 parent) const;
const Preset & currentPreset() const { return presets[cur_preset]; }
Preset & currentPreset() { return presets[cur_preset]; }
int prev_pass; // Pass int prev_pass = rpSolid; // Pass
bool is_init, accept_light, accept_fog, visible_, cast_shadow, rec_shadow, select_, selected_, raw_matrix; int cur_preset = 0;
bool is_root, selected_aim; bool is_init = false, select_ = true, selected_ = false, raw_matrix = false;
float line_width; bool is_root = false, selected_aim = false;
QColor color_; float line_width = -1.f;
uint id_; QVector<Preset> presets;
Type type_; QColor color_ = Qt::white;
uint id_ = 0;
Type type_ = glMesh;
Box3D bound; Box3D bound;
Transform trans, trans_texture; Transform trans, trans_texture;
ObjectBaseList children_; ObjectBaseList children_;
QMatrix4x4 itransform_, mat_; QMatrix4x4 itransform_, mat_;
QString name_; QString name_;
GLenum blend_src, blend_dest; GLenum blend_src, blend_dest;
ObjectBase * parent_; ObjectBase * parent_ = nullptr;
Scene * scene_; Scene * scene_ = nullptr;
Material * material_; Mesh * mesh_ = nullptr;
Mesh * mesh_;
QVariantMap meta; QVariantMap meta;
}; };
@@ -441,6 +334,8 @@ inline T globject_cast(const ObjectBase * object) {
} }
QGLENGINE_CORE_EXPORT QDataStream & operator<<(QDataStream & s, const ObjectBase::Preset & p);
QGLENGINE_CORE_EXPORT QDataStream & operator>>(QDataStream & s, ObjectBase::Preset & p);
QGLENGINE_CORE_EXPORT QDataStream & operator<<(QDataStream & s, const ObjectBase * p); QGLENGINE_CORE_EXPORT QDataStream & operator<<(QDataStream & s, const ObjectBase * p);
QGLENGINE_CORE_EXPORT QDataStream & operator>>(QDataStream & s, ObjectBase *& p); QGLENGINE_CORE_EXPORT QDataStream & operator>>(QDataStream & s, ObjectBase *& p);

View File

@@ -91,6 +91,7 @@ void Scene::assignFrom(const Scene * s) {
addObject(s->root_->child(i)->clone()); addObject(s->root_->child(i)->clone());
// qDebug() << i << o->child(i)->pos(); // qDebug() << i << o->child(i)->pos();
} }
setPreset(s->preset());
tree_changed = mat_changed = lights_changed = need_reload_materials = tree_struct_changed = true; tree_changed = mat_changed = lights_changed = need_reload_materials = tree_struct_changed = true;
} }
@@ -321,11 +322,16 @@ Material * Scene::newMaterial(const QString & name) {
void Scene::removeMaterial(Material * m) { void Scene::removeMaterial(Material * m) {
if (!m || !materials.contains(m)) return; if (!m || !materials.contains(m)) return;
ObjectBaseList ol = root_->children(true); ObjectBaseList ol = root_->children(true);
foreach(ObjectBase * o, ol) for (auto * o: ol)
if (o->material_ == m) o->setMaterial(0); for (auto & p: o->presets)
if (p.material == m) {
p.material = nullptr;
o->setObjectsChanged();
}
materials.removeAll(m); materials.removeAll(m);
changed_materials.removeAll(m); changed_materials.removeAll(m);
mat_changed = true; mat_changed = true;
tree_changed = true;
} }
@@ -349,6 +355,15 @@ void Scene::removeLight(Light * l) {
} }
void Scene::setPreset(int preset) {
if (cur_preset == preset) return;
cur_preset = preset;
root_->setPreset(cur_preset);
mat_changed = tree_changed = tree_struct_changed = lights_changed = true;
emit presetChanged(cur_preset);
}
void Scene::dump() { void Scene::dump() {
qDebug() << "Scene" << name(); qDebug() << "Scene" << name();
qDebug() << "Meshes:" << geometries.size(); qDebug() << "Meshes:" << geometries.size();
@@ -371,28 +386,31 @@ void Scene::attachObject(ObjectBase * o) {
o->setMesh(attachMesh(o->mesh())); o->setMesh(attachMesh(o->mesh()));
setObjectMeshChanged(o); setObjectMeshChanged(o);
} }
if (o->material()) { // search suitable material in this scene for (auto & p: o->presets) {
uint ohash = o->material()->hash(); if (p.material) { // search suitable material in this scene
bool need_new = true; uint ohash = p.material->hash();
foreach(Material * m, materials) { bool need_new = true;
if (m == o->material()) { // already exists by ptr foreach(Material * m, materials) {
need_new = false; if (m == p.material) { // already exists by ptr
break; need_new = false;
break;
}
if (m->hash() == ohash) { // already exists by hash
need_new = false;
p.material = m;
break;
}
} }
if (m->hash() == ohash) { // already exists by hash if (need_new) { // need to clone material and add to scene
need_new = false; Material * nmat = new Material();
o->setMaterial(m); *nmat = *(p.material);
break; nmat->setMapsChanged();
p.material = nmat;
materials << nmat;
} }
} }
if (need_new) { // need to clone material and add to scene
Material * nmat = new Material();
*nmat = *(o->material());
nmat->setMapsChanged();
o->setMaterial(nmat);
materials << nmat;
}
} }
o->setPreset(cur_preset);
setTreeStructChanged(); setTreeStructChanged();
} }
@@ -507,15 +525,25 @@ void Scene::destroyUnused(QOpenGLExtraFunctions * f) {
QDataStream & operator<<(QDataStream & s, const Scene * p) { QDataStream & operator<<(QDataStream & s, const Scene * p) {
ChunkStream cs; ChunkStream cs;
// qDebug() << "place" << p->name() << "..."; // qDebug() << "place" << p->name() << "...";
QVector<short> geom_ind, mat_ind; QVector<short> geom_ind, mats;
QVector<QVector<short>> mat_ind;
ObjectBaseList cl = p->root_->children(true); ObjectBaseList cl = p->root_->children(true);
geom_ind.reserve(cl.size()); geom_ind.reserve(cl.size());
mat_ind.reserve(cl.size()); mat_ind.reserve(cl.size());
foreach(ObjectBase * c, cl) { for (auto * c: cl) {
geom_ind << p->geometries.indexOf(c->mesh()); geom_ind << p->geometries.indexOf(c->mesh());
mat_ind << p->materials.indexOf(c->material()); mats.clear();
for (auto i: c->presets)
mats << p->materials.indexOf(i.material);
mat_ind << mats;
} }
cs.add(1, p->name_).add(10, p->geometries).add(11, p->materials).add(20, p->root_).add(21, geom_ind).add(22, mat_ind); cs.add(1, p->name_)
.add(10, p->geometries)
.add(11, p->materials)
.add(20, p->root_)
.add(21, geom_ind)
.add(23, mat_ind)
.add(24, p->cur_preset);
s << qCompress(cs.data()); s << qCompress(cs.data());
return s; return s;
} }
@@ -525,7 +553,9 @@ QDataStream & operator>>(QDataStream & s, Scene *& p) {
s >> ba; s >> ba;
ba = qUncompress(ba); ba = qUncompress(ba);
ChunkStream cs(ba); ChunkStream cs(ba);
QVector<short> geom_ind, mat_ind; QVector<short> geom_ind, mat_ind_v0;
QVector<QVector<short>> mat_ind_v1;
int version = 0, preset = 0;
while (!cs.atEnd()) { while (!cs.atEnd()) {
switch (cs.read()) { switch (cs.read()) {
case 1: cs.get(p->name_); break; case 1: cs.get(p->name_); break;
@@ -536,16 +566,44 @@ QDataStream & operator>>(QDataStream & s, Scene *& p) {
p->root_->setScene(p); p->root_->setScene(p);
break; break;
case 21: cs.get(geom_ind); break; case 21: cs.get(geom_ind); break;
case 22: cs.get(mat_ind); break; case 22:
cs.get(mat_ind_v0);
version = 0;
break;
case 23:
cs.get(mat_ind_v1);
version = 1;
break;
case 24: cs.get(preset); break;
} }
} }
p->makeMaterialsUniqueNames(); p->makeMaterialsUniqueNames();
ObjectBaseList cl = p->root_->children(true); ObjectBaseList cl = p->root_->children(true);
int cnt = qMin(qMin(cl.size(), geom_ind.size()), mat_ind.size()); int cnt = qMin(cl.size(), geom_ind.size());
for (int i = 0; i < cnt; ++i) { for (int i = 0; i < cnt; ++i) {
ObjectBase * c(cl[i]); ObjectBase * c(cl[i]);
if (geom_ind[i] >= 0) c->mesh_ = p->geometries[geom_ind[i]]; if (geom_ind[i] >= 0) c->mesh_ = p->geometries[geom_ind[i]];
if (mat_ind[i] >= 0) c->material_ = p->materials[mat_ind[i]];
} }
if (version == 0) {
cnt = qMin(cl.size(), mat_ind_v0.size());
for (int i = 0; i < cnt; ++i) {
if (mat_ind_v0[i] >= 0) cl[i]->currentPreset().material = p->materials[mat_ind_v0[i]];
}
} else if (version == 1) {
cnt = qMin(cl.size(), mat_ind_v1.size());
for (int i = 0; i < cnt; ++i) {
ObjectBase * c(cl[i]);
const auto & matv(mat_ind_v1[i]);
if (c->presets.size() < matv.size()) c->presets.resize(matv.size());
for (int j = 0; j < matv.size(); ++j) {
if (matv[j] >= 0)
c->presets[j].material = p->materials[matv[j]];
else
c->presets[j].material = nullptr;
}
}
}
p->cur_preset = -1;
p->setPreset(preset);
return s; return s;
} }

View File

@@ -90,6 +90,9 @@ public:
void removeLight(Light * l); void removeLight(Light * l);
void setPreset(int preset);
int preset() const { return cur_preset; }
void dump(); void dump();
void destroy(QOpenGLExtraFunctions * f); void destroy(QOpenGLExtraFunctions * f);
void destroyUnused(QOpenGLExtraFunctions * f); void destroyUnused(QOpenGLExtraFunctions * f);
@@ -126,6 +129,7 @@ protected:
QList<Camera *> cameras_used; QList<Camera *> cameras_used;
QVector<Material *> changed_materials; QVector<Material *> changed_materials;
int cur_preset = 0;
SelectionMode sel_mode_; SelectionMode sel_mode_;
ObjectBaseList selected_, selected_top; ObjectBaseList selected_, selected_top;
@@ -136,6 +140,7 @@ signals:
void __destroyed(); void __destroyed();
void treeChanged(); void treeChanged();
void selectionChanged(); void selectionChanged();
void presetChanged(int);
}; };

View File

@@ -662,7 +662,7 @@
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<widget class="PIValueTreeEdit" name="widgetParameters" native="true"/> <widget class="PIValueTreeEdit" name="widgetParameters"/>
</item> </item>
<item> <item>
<spacer name="verticalSpacer_3"> <spacer name="verticalSpacer_3">
@@ -854,7 +854,7 @@
</widget> </widget>
<action name="actionExit"> <action name="actionExit">
<property name="icon"> <property name="icon">
<iconset resource="../core/qglengine_core.qrc"> <iconset resource="../../../qad/libs/qglview/qglview.qrc">
<normaloff>:/icons/application-exit.png</normaloff>:/icons/application-exit.png</iconset> <normaloff>:/icons/application-exit.png</normaloff>:/icons/application-exit.png</iconset>
</property> </property>
<property name="text"> <property name="text">
@@ -863,7 +863,7 @@
</action> </action>
<action name="actionImport"> <action name="actionImport">
<property name="icon"> <property name="icon">
<iconset resource="../core/qglengine_core.qrc"> <iconset resource="../../../qad/libs/qglview/qglview.qrc">
<normaloff>:/icons/document-import.png</normaloff>:/icons/document-import.png</iconset> <normaloff>:/icons/document-import.png</normaloff>:/icons/document-import.png</iconset>
</property> </property>
<property name="text"> <property name="text">
@@ -887,7 +887,7 @@
</action> </action>
<action name="actionSave"> <action name="actionSave">
<property name="icon"> <property name="icon">
<iconset resource="../../../qad/libs/widgets/qad_widgets.qrc"> <iconset resource="../../../qad/libs/qglview/qglview.qrc">
<normaloff>:/icons/document-save-all.png</normaloff>:/icons/document-save-all.png</iconset> <normaloff>:/icons/document-save-all.png</normaloff>:/icons/document-save-all.png</iconset>
</property> </property>
<property name="text"> <property name="text">
@@ -899,7 +899,7 @@
</action> </action>
<action name="actionReset"> <action name="actionReset">
<property name="icon"> <property name="icon">
<iconset resource="../../../qad/libs/widgets/qad_widgets.qrc"> <iconset resource="../../../qad/libs/qglview/qglview.qrc">
<normaloff>:/icons/document-new.png</normaloff>:/icons/document-new.png</iconset> <normaloff>:/icons/document-new.png</normaloff>:/icons/document-new.png</iconset>
</property> </property>
<property name="text"> <property name="text">
@@ -985,6 +985,12 @@
</action> </action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget>
<class>PIValueTreeEdit</class>
<extends>QWidget</extends>
<header>pivaluetree_edit.h</header>
<container>1</container>
</customwidget>
<customwidget> <customwidget>
<class>SpinSlider</class> <class>SpinSlider</class>
<extends>QWidget</extends> <extends>QWidget</extends>
@@ -1032,16 +1038,10 @@
<header>textures_editor.h</header> <header>textures_editor.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget>
<class>PIValueTreeEdit</class>
<extends>QWidget</extends>
<header>pivaluetree_edit.h</header>
<container>1</container>
</customwidget>
</customwidgets> </customwidgets>
<resources> <resources>
<include location="../../../qad/libs/blockview/qad_blockview.qrc"/> <include location="../../../qad/libs/blockview/qad_blockview.qrc"/>
<include location="../../../qad/libs/widgets/qad_widgets.qrc"/> <include location="../../../qad/libs/qglview/qglview.qrc"/>
<include location="../core/qglengine_core.qrc"/> <include location="../core/qglengine_core.qrc"/>
</resources> </resources>
<connections/> <connections/>

View File

@@ -46,6 +46,8 @@ void ViewEditor::assignQGLView(QGLView * v) {
view = v; view = v;
if (!view) return; if (!view) return;
active = false; active = false;
connect(view->scene(), &Scene::presetChanged, this, [this](int p) { ui->labelPreset->setNum(p); });
ui->labelPreset->setNum(view->scene()->preset());
ui->spinFOV->setValue(view->FOV()); ui->spinFOV->setValue(view->FOV());
ui->spinDepthStart->setValue(view->depthStart()); ui->spinDepthStart->setValue(view->depthStart());
ui->checkHoverHalo->setChecked(view->isHoverHaloEnabled()); ui->checkHoverHalo->setChecked(view->isHoverHaloEnabled());
@@ -213,6 +215,11 @@ void ViewEditor::on_buttonHDRSelect_clicked() {
} }
void ViewEditor::on_buttonPresetSet_clicked() {
view->scene()->setPreset(ui->spinPreset->value());
}
void ViewEditor::on_colorFogBack_colorChanged(const QColor & color) { void ViewEditor::on_colorFogBack_colorChanged(const QColor & color) {
if (!view || !active) return; if (!view || !active) return;
view->setFogColor(color); view->setFogColor(color);

View File

@@ -63,6 +63,7 @@ private slots:
void on_checkVSync_clicked(bool val); void on_checkVSync_clicked(bool val);
void on_buttonHDRClear_clicked(); void on_buttonHDRClear_clicked();
void on_buttonHDRSelect_clicked(); void on_buttonHDRSelect_clicked();
void on_buttonPresetSet_clicked();
void on_colorFogBack_colorChanged(const QColor & color); void on_colorFogBack_colorChanged(const QColor & color);
void on_spinFogDensity_valueChanged(double arg1); void on_spinFogDensity_valueChanged(double arg1);
void on_spinFogDecay_valueChanged(double arg1); void on_spinFogDecay_valueChanged(double arg1);

View File

@@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>479</width> <width>479</width>
<height>737</height> <height>897</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
@@ -36,8 +36,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>453</width> <width>479</width>
<height>885</height> <height>897</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
@@ -205,6 +205,54 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1">
<widget class="QWidget" name="widget_2" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_11">
<property name="text">
<string>Preset:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinPreset"/>
</item>
<item>
<widget class="QPushButton" name="buttonPresetSet">
<property name="minimumSize">
<size>
<width>1</width>
<height>1</height>
</size>
</property>
<property name="text">
<string>Set</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelPreset">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>