diff --git a/src/core/core/gltransform.cpp b/src/core/core/gltransform.cpp index cf7c646..c8d18f7 100644 --- a/src/core/core/gltransform.cpp +++ b/src/core/core/gltransform.cpp @@ -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(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) { m_scale = t.m_scale; m_translation = t.m_translation; diff --git a/src/core/core/gltransform.h b/src/core/core/gltransform.h index f0b45b1..ede25e6 100644 --- a/src/core/core/gltransform.h +++ b/src/core/core/gltransform.h @@ -32,6 +32,7 @@ class QGLENGINE_CORE_EXPORT Transform { public: Transform(); + Transform(const Transform & t); Transform & operator=(const Transform & t); float scale() const; diff --git a/src/core/render/renderer_base.cpp b/src/core/render/renderer_base.cpp index fed65b5..bcf3bd7 100644 --- a/src/core/render/renderer_base.cpp +++ b/src/core/render/renderer_base.cpp @@ -247,7 +247,7 @@ void RendererBase::reloadLightsParameters(const QMap> & ligh so.decay_intensity[2] = l->decay_quadratic; so.decay_intensity[3] = l->intensity; 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); } buffer_lights.bind(view); diff --git a/src/core/scene/globject.cpp b/src/core/scene/globject.cpp index 9f4f0e2..1be328b 100644 --- a/src/core/scene/globject.cpp +++ b/src/core/scene/globject.cpp @@ -26,22 +26,12 @@ // static int _count = 0; ObjectBase::ObjectBase(Mesh * geom, Material * mat) { - type_ = glMesh; - prev_pass = rpSolid; - 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; + blend_src = GL_SRC_ALPHA; + blend_dest = GL_ONE_MINUS_SRC_ALPHA; mat_.setToIdentity(); - scene_ = nullptr; - mesh_ = geom; - material_ = mat; + mesh_ = geom; + setPreset(0); + currentPreset().material = mat; // qDebug() << "ObjectBase, now" << ++_count; } @@ -65,9 +55,8 @@ ObjectBase * ObjectBase::clone(bool withChildren) { ObjectBase * o = new ObjectBase(); o->prev_pass = prev_pass; o->is_init = false; - o->accept_light = accept_light; - o->accept_fog = accept_fog; - o->visible_ = visible_; + o->presets = presets; + o->cur_preset = cur_preset; o->color_ = color_; o->type_ = type_; o->raw_matrix = raw_matrix; @@ -80,7 +69,6 @@ ObjectBase * ObjectBase::clone(bool withChildren) { o->blend_src = blend_src; o->blend_dest = blend_dest; o->pos_h = pos_h; - o->material_ = material_; o->mesh_ = mesh_; o->meta = meta; o->scene_ = nullptr; @@ -107,8 +95,8 @@ void ObjectBase::init() { RenderPass ObjectBase::pass() const { RenderPass ret = rpSolid; - if (material_) - if (material_->hasTransparency()) ret = rpTransparent; + if (currentPreset().material) + if (currentPreset().material->hasTransparency()) ret = rpTransparent; return ret; } @@ -206,11 +194,11 @@ ObjectBaseList ObjectBase::children(bool all_) { bool ObjectBase::isVisible(bool check_parents) const { - if (!check_parents) return visible_; - if (!visible_) return false; + if (!check_parents) return currentPreset().visible; + if (!currentPreset().visible) return false; ObjectBase * p = parent_; while (p) { - if (!p->visible_) return false; + if (!p->currentPreset().visible) return false; p = p->parent_; } return true; @@ -218,19 +206,116 @@ bool ObjectBase::isVisible(bool check_parents) const { void ObjectBase::setVisible(bool v) { - visible_ = v; + currentPreset().visible = v; setSceneTreeChanged(); } +void ObjectBase::setReceiveShadows(bool on) { + currentPreset().receive_shadow = on; + setObjectsChanged(); +} + + void ObjectBase::setCastShadows(bool on) { - cast_shadow = on; + currentPreset().cast_shadow = on; if (type_ == glLight) ((Light *)this)->apply(); else 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) { 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) { raw_matrix = false; 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) { trans = t; 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) { // raw_matrix = true; // 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 { if (!check_parents) return selected_; if (selected_) return true; @@ -409,7 +634,7 @@ ObjectBase * ObjectBase::selectedParent() const { void ObjectBase::setMaterial(Material * m, bool with_children) { - material_ = m; + currentPreset().material = m; if (with_children) foreach(ObjectBase * i, children_) 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) { ChunkStream cs; // qDebug() << "place" << p->name() << "..."; 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(8, p->line_width) .add(14, p->mat_) @@ -660,7 +894,8 @@ QDataStream & operator<<(QDataStream & s, const ObjectBase * p) { .add(18, p->meta) .add(19, p->color_) .add(20, p->trans) - .add(21, p->trans_texture); + .add(21, p->trans_texture) + .add(22, p->presets); // qDebug() << "place self done"; if (p->type_ == ObjectBase::glLight) { // qDebug() << "place light ..."; @@ -721,19 +956,19 @@ QDataStream & operator>>(QDataStream & s, ObjectBase *& p) { if (p) p->type_ = type; } break; case 2: - if (p) p->accept_light = cs.getData(); + if (p) p->currentPreset().accept_light = cs.getData(); break; case 3: - if (p) p->accept_fog = cs.getData(); + if (p) p->currentPreset().accept_fog = cs.getData(); break; case 4: - if (p) p->visible_ = cs.getData(); + if (p) p->currentPreset().visible = cs.getData(); break; case 5: - if (p) p->cast_shadow = cs.getData(); + if (p) p->currentPreset().cast_shadow = cs.getData(); break; case 6: - if (p) p->rec_shadow = cs.getData(); + if (p) p->currentPreset().receive_shadow = cs.getData(); break; case 7: if (p) p->raw_matrix = cs.getData(); @@ -762,6 +997,12 @@ QDataStream & operator>>(QDataStream & s, ObjectBase *& p) { case 21: if (p) p->trans_texture = cs.getData(); break; + case 22: + if (p) { + p->presets = cs.getData>(); + if (p->presets.isEmpty()) p->presets.resize(1); + } + break; case 100: if (l) l->setAim(cs.getData()); break; diff --git a/src/core/scene/globject.h b/src/core/scene/globject.h index 573c6f0..de1050b 100644 --- a/src/core/scene/globject.h +++ b/src/core/scene/globject.h @@ -30,6 +30,7 @@ class QGLENGINE_CORE_EXPORT ObjectBase { friend class RendererSelection; 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, const Scene * p); friend QGLENGINE_CORE_EXPORT QDataStream & operator>>(QDataStream & s, Scene *& p); public: @@ -40,7 +41,7 @@ public: glParticlesSystem }; - explicit ObjectBase(Mesh * geom = 0, Material * mat = 0); + explicit ObjectBase(Mesh * geom = nullptr, Material * mat = nullptr); virtual ~ObjectBase(); virtual ObjectBase * clone(bool withChildren = true); @@ -82,66 +83,24 @@ public: 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; - setObjectsChanged(); - } + bool isReceiveShadows() const { return currentPreset().receive_shadow; } + bool isCastShadows() const { return currentPreset().cast_shadow; } + void setReceiveShadows(bool on); void setCastShadows(bool on); - void move(const QVector3D & dv) { - trans.setTranslation(pos() + dv); - buildTransform(); - } - void moveTo(const QVector3D & dv) { - trans.setTranslation(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) { - 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(); - } + void move(const QVector3D & dv); + void moveTo(const QVector3D & dv); + void move(GLfloat dx, GLfloat dy, GLfloat dz = 0.); + void moveTo(GLfloat dx, GLfloat dy, GLfloat dz = 0.); + void moveX(GLfloat o); + void moveY(GLfloat o); + void moveZ(GLfloat o); + void setPosX(GLfloat o); + void setPosY(GLfloat o); + void setPosZ(GLfloat o); + void setPos(GLfloat x, GLfloat y, GLfloat z); + void setPos(const QVector3D & p); + void resetPos(); QVector3D pos() const { return trans.translation(); } float posX() const { return trans.translation().x(); } @@ -154,108 +113,32 @@ public: float rotationX() const { return rotation().x(); } float rotationY() const { return rotation().y(); } float rotationZ() const { return rotation().z(); } - void rotateX(GLfloat a) { - raw_matrix = false; - trans.setRotationX(trans.rotationX() + a); - buildTransform(); - } - void rotateY(GLfloat a) { - raw_matrix = false; - trans.setRotationY(trans.rotationY() + a); - buildTransform(); - } + void rotateX(GLfloat a); + void rotateY(GLfloat a); void rotateZ(GLfloat a); - void setRotationX(GLfloat a) { - raw_matrix = false; - trans.setRotationX(a); - buildTransform(); - } - void setRotationY(GLfloat a) { - raw_matrix = false; - trans.setRotationY(a); - buildTransform(); - } + void setRotationX(GLfloat a); + void setRotationY(GLfloat a); void setRotationZ(GLfloat a); - void setRotation(const QVector3D & a) { - raw_matrix = false; - trans.setRotation(a); - buildTransform(); - } - void resetRotation() { - raw_matrix = false; - trans.setRotation(QVector3D()); - buildTransform(); - } + void setRotation(const QVector3D & a); + void resetRotation(); QVector3D scale() { return trans.scale3D(); } float scaleX() { return trans.scale3D().x(); } float scaleY() { return trans.scale3D().y(); } float scaleZ() { return trans.scale3D().z(); } - void scale(const QVector3D & sv) { - raw_matrix = false; - trans.setScale(trans.scale3D() * 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; - 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(); - } + void scale(const QVector3D & sv); + void scale(GLfloat sx, GLfloat sy, GLfloat sz); + void scale(GLfloat sx, GLfloat sy); + void scale(GLfloat sx); + void scaleX(GLfloat a); + void scaleY(GLfloat a); + void scaleZ(GLfloat a); + void setScale(const QVector3D & a); + void setScale(GLfloat a); + void setScaleX(GLfloat a); + void setScaleY(GLfloat a); + void setScaleZ(GLfloat a); + void resetScale(); Transform transform() { return trans; } void setTransform(const Transform & t); @@ -273,17 +156,11 @@ public: QMatrix4x4 textureMatrix() const; QGenericMatrix<3, 2, float> textureGLMatrix() const; - bool isAcceptLight() const { return accept_light; } - void setAcceptLight(bool yes) { - accept_light = yes; - setObjectsChanged(); - } + bool isAcceptLight() const { return currentPreset().accept_light; } + void setAcceptLight(bool yes); - bool isAcceptFog() const { return accept_fog; } - void setAcceptFog(bool yes) { - accept_fog = yes; - setObjectsChanged(); - } + bool isAcceptFog() const { return currentPreset().accept_fog; } + void setAcceptFog(bool yes); bool isSelected(bool check_parents = false) const; void setSelected(bool yes); @@ -302,7 +179,7 @@ public: void setDestAlpha(GLenum mode) { blend_dest = mode; } 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); QColor color() { return color_; } @@ -319,9 +196,22 @@ public: bool hasProperty(const QString & pn) const; void removeProperty(const QString & pn); + void setPreset(int preset); + QVector3D pos_h; 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() {} void addChildren(ObjectBaseList & list, ObjectBase * where); void buildTransform(bool force = false); @@ -330,24 +220,27 @@ protected: void setObjectsChanged(); void localTransform(QMatrix4x4 & m); QMatrix4x4 worldMatrix(QMatrix4x4 parent) const; + const Preset & currentPreset() const { return presets[cur_preset]; } + Preset & currentPreset() { return presets[cur_preset]; } - int prev_pass; // Pass - bool is_init, accept_light, accept_fog, visible_, cast_shadow, rec_shadow, select_, selected_, raw_matrix; - bool is_root, selected_aim; - float line_width; - QColor color_; - uint id_; - Type type_; + int prev_pass = rpSolid; // Pass + int cur_preset = 0; + bool is_init = false, select_ = true, selected_ = false, raw_matrix = false; + bool is_root = false, selected_aim = false; + float line_width = -1.f; + QVector presets; + QColor color_ = Qt::white; + uint id_ = 0; + Type type_ = glMesh; Box3D bound; Transform trans, trans_texture; ObjectBaseList children_; QMatrix4x4 itransform_, mat_; QString name_; GLenum blend_src, blend_dest; - ObjectBase * parent_; - Scene * scene_; - Material * material_; - Mesh * mesh_; + ObjectBase * parent_ = nullptr; + Scene * scene_ = nullptr; + Mesh * mesh_ = nullptr; 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, ObjectBase *& p); diff --git a/src/core/scene/glscene.cpp b/src/core/scene/glscene.cpp index a3969da..5e047d2 100644 --- a/src/core/scene/glscene.cpp +++ b/src/core/scene/glscene.cpp @@ -91,6 +91,7 @@ void Scene::assignFrom(const Scene * s) { addObject(s->root_->child(i)->clone()); // qDebug() << i << o->child(i)->pos(); } + setPreset(s->preset()); 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) { if (!m || !materials.contains(m)) return; ObjectBaseList ol = root_->children(true); - foreach(ObjectBase * o, ol) - if (o->material_ == m) o->setMaterial(0); + for (auto * o: ol) + for (auto & p: o->presets) + if (p.material == m) { + p.material = nullptr; + o->setObjectsChanged(); + } 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() { qDebug() << "Scene" << name(); qDebug() << "Meshes:" << geometries.size(); @@ -371,28 +386,31 @@ void Scene::attachObject(ObjectBase * o) { o->setMesh(attachMesh(o->mesh())); setObjectMeshChanged(o); } - if (o->material()) { // search suitable material in this scene - uint ohash = o->material()->hash(); - bool need_new = true; - foreach(Material * m, materials) { - if (m == o->material()) { // already exists by ptr - need_new = false; - break; + for (auto & p: o->presets) { + if (p.material) { // search suitable material in this scene + uint ohash = p.material->hash(); + bool need_new = true; + foreach(Material * m, materials) { + if (m == p.material) { // already exists by ptr + 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 - need_new = false; - o->setMaterial(m); - break; + if (need_new) { // need to clone material and add to scene + Material * nmat = new Material(); + *nmat = *(p.material); + 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(); } @@ -507,15 +525,25 @@ void Scene::destroyUnused(QOpenGLExtraFunctions * f) { QDataStream & operator<<(QDataStream & s, const Scene * p) { ChunkStream cs; // qDebug() << "place" << p->name() << "..."; - QVector geom_ind, mat_ind; + QVector geom_ind, mats; + QVector> mat_ind; ObjectBaseList cl = p->root_->children(true); geom_ind.reserve(cl.size()); mat_ind.reserve(cl.size()); - foreach(ObjectBase * c, cl) { + for (auto * c: cl) { 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()); return s; } @@ -525,7 +553,9 @@ QDataStream & operator>>(QDataStream & s, Scene *& p) { s >> ba; ba = qUncompress(ba); ChunkStream cs(ba); - QVector geom_ind, mat_ind; + QVector geom_ind, mat_ind_v0; + QVector> mat_ind_v1; + int version = 0, preset = 0; while (!cs.atEnd()) { switch (cs.read()) { case 1: cs.get(p->name_); break; @@ -536,16 +566,44 @@ QDataStream & operator>>(QDataStream & s, Scene *& p) { p->root_->setScene(p); 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(); 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) { ObjectBase * c(cl[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; } diff --git a/src/core/scene/glscene.h b/src/core/scene/glscene.h index 6a1475c..c259f92 100644 --- a/src/core/scene/glscene.h +++ b/src/core/scene/glscene.h @@ -90,6 +90,9 @@ public: void removeLight(Light * l); + void setPreset(int preset); + int preset() const { return cur_preset; } + void dump(); void destroy(QOpenGLExtraFunctions * f); void destroyUnused(QOpenGLExtraFunctions * f); @@ -126,6 +129,7 @@ protected: QList cameras_used; QVector changed_materials; + int cur_preset = 0; SelectionMode sel_mode_; ObjectBaseList selected_, selected_top; @@ -136,6 +140,7 @@ signals: void __destroyed(); void treeChanged(); void selectionChanged(); + void presetChanged(int); }; diff --git a/src/qglview_test/qglview_window.ui b/src/qglview_test/qglview_window.ui index a239273..577d978 100644 --- a/src/qglview_test/qglview_window.ui +++ b/src/qglview_test/qglview_window.ui @@ -662,7 +662,7 @@ 0 - + @@ -854,7 +854,7 @@ - + :/icons/application-exit.png:/icons/application-exit.png @@ -863,7 +863,7 @@ - + :/icons/document-import.png:/icons/document-import.png @@ -887,7 +887,7 @@ - + :/icons/document-save-all.png:/icons/document-save-all.png @@ -899,7 +899,7 @@ - + :/icons/document-new.png:/icons/document-new.png @@ -985,6 +985,12 @@ + + PIValueTreeEdit + QWidget +
pivaluetree_edit.h
+ 1 +
SpinSlider QWidget @@ -1032,16 +1038,10 @@
textures_editor.h
1
- - PIValueTreeEdit - QWidget -
pivaluetree_edit.h
- 1 -
- + diff --git a/src/widgets/view_editor.cpp b/src/widgets/view_editor.cpp index 51e202d..4714b4f 100644 --- a/src/widgets/view_editor.cpp +++ b/src/widgets/view_editor.cpp @@ -46,6 +46,8 @@ void ViewEditor::assignQGLView(QGLView * v) { view = v; if (!view) return; 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->spinDepthStart->setValue(view->depthStart()); 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) { if (!view || !active) return; view->setFogColor(color); diff --git a/src/widgets/view_editor.h b/src/widgets/view_editor.h index 627a8eb..ffaa22f 100644 --- a/src/widgets/view_editor.h +++ b/src/widgets/view_editor.h @@ -63,6 +63,7 @@ private slots: void on_checkVSync_clicked(bool val); void on_buttonHDRClear_clicked(); void on_buttonHDRSelect_clicked(); + void on_buttonPresetSet_clicked(); void on_colorFogBack_colorChanged(const QColor & color); void on_spinFogDensity_valueChanged(double arg1); void on_spinFogDecay_valueChanged(double arg1); diff --git a/src/widgets/view_editor.ui b/src/widgets/view_editor.ui index 26fd5d5..2f39eb8 100644 --- a/src/widgets/view_editor.ui +++ b/src/widgets/view_editor.ui @@ -7,7 +7,7 @@ 0 0 479 - 737 + 897 @@ -36,8 +36,8 @@ 0 0 - 453 - 885 + 479 + 897 @@ -205,6 +205,54 @@
+ + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Preset: + + + + + + + + + + + 1 + 1 + + + + Set + + + + + + + 0 + + + + + +