diff --git a/qglengine/core/glshaders_headers.h b/qglengine/core/glshaders_headers.h index de625aa..28a3447 100644 --- a/qglengine/core/glshaders_headers.h +++ b/qglengine/core/glshaders_headers.h @@ -95,14 +95,8 @@ const char qgl_structs[] = "};\n" "struct QGLLightParameter {\n" " vec4 color;\n" - " float intensity;\n" - " float startAngle;\n" - " float startAngleCos;\n" - " float endAngle;\n" - " float endAngleCos;\n" - " float constantAttenuation;\n" - " float linearAttenuation;\n" - " float quadraticAttenuation;\n" + " vec4 decay_intensity;\n" + " vec4 angles;\n" //" sampler2DShadow shadow;\n" //" sampler2D shadowColor\n" //" mat4 shadowMatrix;\n" diff --git a/qglengine/core/glshaders_types.h b/qglengine/core/glshaders_types.h index 9db90c4..a7b7180 100644 --- a/qglengine/core/glshaders_types.h +++ b/qglengine/core/glshaders_types.h @@ -124,15 +124,8 @@ struct QGLMaterial { }; struct QGLLightParameter { QVector4D color; - //QVector4D shadowColor; - GLfloat intensity; - GLfloat startAngle; - GLfloat startAngleCos; - GLfloat endAngle; - GLfloat endAngleCos; - GLfloat constantAttenuation; - GLfloat linearAttenuation; - GLfloat quadraticAttenuation; + QVector4D decay_intensity; // [^0, ^1, ^2, intensity] + QVector4D angles; // [start, cos(start), end, cos(end)] //GLfloat shadow; //GLfloat shadowMatrix[16]; }; diff --git a/qglengine/core/gltransform.cpp b/qglengine/core/gltransform.cpp index cafdd54..df2e793 100644 --- a/qglengine/core/gltransform.cpp +++ b/qglengine/core/gltransform.cpp @@ -158,6 +158,15 @@ Transform::Transform(): m_scale(1.0f, 1.0f, 1.0f), } +Transform & Transform::operator =(const Transform & t) { + m_scale = t.m_scale; + m_translation = t.m_translation; + m_eulerRotationAngles = t.m_eulerRotationAngles; + m_matrixDirty = true; + return *this; +} + + void Transform::setMatrix(const QMatrix4x4 & m) { if (m != matrix()) { m_matrix = m; diff --git a/qglengine/core/gltransform.h b/qglengine/core/gltransform.h index 84bc887..3efc689 100644 --- a/qglengine/core/gltransform.h +++ b/qglengine/core/gltransform.h @@ -29,6 +29,7 @@ class Transform { friend QDataStream & operator >>(QDataStream & s, Transform & v); public: Transform(); + Transform & operator =(const Transform & t); float scale() const; QVector3D scale3D() const; @@ -61,6 +62,7 @@ public: void setTranslationZ(float t); void setMatrix(const QMatrix4x4 & matrix); + void setDirty(bool yes = true) {m_matrixDirty = yes;} static QQuaternion fromAxisAndAngle(const QVector3D & axis, float angle); diff --git a/qglengine/formats/loader_assimp.cpp b/qglengine/formats/loader_assimp.cpp index 14724a7..5fd6790 100644 --- a/qglengine/formats/loader_assimp.cpp +++ b/qglengine/formats/loader_assimp.cpp @@ -132,6 +132,8 @@ Material * assimpMaterial(const aiMaterial * m) { Light * assimpLight(const aiLight * l) { if (!l) return 0; + if (l->mType != aiLightSource_POINT && l->mType != aiLightSource_SPOT) + return 0; Light * ret = new Light(); ret->setName(fromAiString(l->mName)); ret->setPos(fromAiVector3D(l->mPosition)); @@ -221,28 +223,32 @@ Scene * loadScene(const QString & filepath) { lights << assimpLight(ais->mLights[i]); QMap light_by_name; foreach (Light * l, lights) - light_by_name[l->name()] = l; + if (l) + light_by_name[l->name()] = l; QVector out_lights; ObjectBaseList rootl = assimpObject(ais->mRootNode, meshes, ais->mMeshes, materials, light_by_name, out_lights); if (rootl.isEmpty()) return 0; ObjectBase * root = rootl[0]; + root->transferTransformToChildren(true); ObjectBaseList rcl = root->children(true); foreach (ObjectBase * c, rcl) { foreach (Light * l, out_lights) { if (c->name() == (l->name() + ".Target")) { - l->setAim((l->worldTransform().inverted() * QVector4D(c->worldPos(), 1)).toVector3D()); + l->setDistance((l->worldPos() - c->worldPos()).length()); delete c; break; } } } + root->cleanTree(); Scene * scene = new Scene(); scene->setName(root->name()); foreach (ObjectBase * o, root->children()) scene->addObject(o); + lights.removeAll(0); qDeleteAll(lights); return scene; diff --git a/qglengine/globject.cpp b/qglengine/globject.cpp index 44d5ce4..5224aea 100644 --- a/qglengine/globject.cpp +++ b/qglengine/globject.cpp @@ -273,6 +273,11 @@ void ObjectBase::calculateBoundingBox() { } +void ObjectBase::updateTransform() { + buildTransform(true); +} + + void ObjectBase::setProperty(const QString & pn, const QVariant & v) { meta[pn] = v; } @@ -316,6 +321,28 @@ QVector3D ObjectBase::inParentSpace(const QVector3D & v) const { } +void ObjectBase::transferTransformToChildren(bool only_scale) { + QMatrix4x4 m = trans.matrix(); + if (only_scale) m = trans.matrixScale(); + foreach (ObjectBase * i, children_) + i->trans.setMatrix(m * i->trans.matrix()); + if (only_scale) resetScale(); + else setMatrix(QMatrix4x4()); +} + + +void ObjectBase::cleanTree() { + for (int i = 0; i < children_.size(); ++i) { + ObjectBase * o = children_[i]; + if (!o->hasChildren() && !o->mesh() && (o->type() == glMesh)) { + delete o; + --i; + } + o->cleanTree(); + } +} + + bool ObjectBase::isSelected(bool check_parents) const { if (!check_parents) return selected_; if (selected_) return true; @@ -373,7 +400,8 @@ void ObjectBase::setMesh(Mesh * v) { } -void ObjectBase::buildTransform() { +void ObjectBase::buildTransform(bool force) { + if (force) trans.setDirty(); itransform_.setToIdentity(); ObjectBase * p = parent_; if (p) @@ -386,7 +414,7 @@ void ObjectBase::buildTransform() { localTransform(itransform_); //qDebug() << name_ << itransform_; foreach (ObjectBase * i, children_) - i->buildTransform(); + i->buildTransform(force); setObjectsChanged(); } diff --git a/qglengine/globject.h b/qglengine/globject.h index 6754235..a797c3d 100644 --- a/qglengine/globject.h +++ b/qglengine/globject.h @@ -63,7 +63,7 @@ public: ObjectBase * parent() {return parent_;} void setParent(ObjectBase * o) {parent_ = o;} bool hasParent() const {return parent_ != nullptr;} - bool hasChildren() const {return children_.size() != 0;} + bool hasChildren() const {return !children_.isEmpty();} void setScene(Scene * v); void addChild(ObjectBase * o); @@ -147,6 +147,8 @@ public: QMatrix4x4 matrix() const; bool isRawMatrix() {return raw_matrix;} QVector3D inParentSpace(const QVector3D & v) const; + void transferTransformToChildren(bool only_scale = true); + void cleanTree(); bool isAcceptLight() const {return accept_light;} void setAcceptLight(bool yes) {accept_light = yes;} @@ -182,6 +184,7 @@ public: Mesh * mesh() {return mesh_;} void calculateBoundingBox(); + void updateTransform(); void setProperty(const QString & pn, const QVariant & v); QVariant property(const QString & pn, bool * exists = 0) const; @@ -195,11 +198,11 @@ public: protected: virtual void transformChanged() {} void addChildren(ObjectBaseList & list, ObjectBase * where); - void buildTransform(); + void buildTransform(bool force = false); void initInternal(); void setSceneTreeChanged(); void setObjectsChanged(); - virtual void localTransform(QMatrix4x4 & m); + void localTransform(QMatrix4x4 & m); QMatrix4x4 worldMatrix(QMatrix4x4 parent) const; int prev_pass; // Pass diff --git a/qglengine/glscene.cpp b/qglengine/glscene.cpp index 89fea9e..2bf22d3 100644 --- a/qglengine/glscene.cpp +++ b/qglengine/glscene.cpp @@ -474,7 +474,7 @@ void Scene::destroy() { void Scene::destroyUnused(QOpenGLExtraFunctions * f) { - if (!td_geometries.isEmpty()) qDebug() << "destroyUnused" << td_geometries.size(); + //if (!td_geometries.isEmpty()) qDebug() << "destroyUnused" << td_geometries.size(); foreach (Mesh * i, td_geometries) i->destroy(f); qDeleteAll(td_geometries); diff --git a/qglengine/renderer_base.cpp b/qglengine/renderer_base.cpp index 5a0adfd..e22e877 100644 --- a/qglengine/renderer_base.cpp +++ b/qglengine/renderer_base.cpp @@ -233,15 +233,15 @@ void RendererBase::reloadLightsParameters(const QMap> & light if (l->light_type == Light::Omni) ang_start = ang_end = 180.; //qDebug() << "light" << light->name() << ulightn << pos; - so.intensity = l->intensity; - so.startAngle = ang_start; - so.startAngleCos = cos(ang_start * deg2rad); - so.endAngle = ang_end; - so.endAngleCos = cos(ang_end * deg2rad); so.color = QColor2QVector(l->color_); - so.constantAttenuation = l->decay_const; - so.linearAttenuation = l->decay_linear; - so.quadraticAttenuation = l->decay_quadratic; + so.angles[0] = ang_start; + so.angles[1] = cos(ang_start * deg2rad); + so.angles[2] = ang_end; + so.angles[3] = cos(ang_end * deg2rad); + so.decay_intensity[0] = l->decay_const; + so.decay_intensity[1] = l->decay_linear; + so.decay_intensity[2] = l->decay_quadratic; + so.decay_intensity[3] = l->intensity; //so.shadow = shadow; //so.shadowColor = shadow; } diff --git a/qglengine/widgets/scene_tree.cpp b/qglengine/widgets/scene_tree.cpp index f960aae..9fcbac2 100644 --- a/qglengine/widgets/scene_tree.cpp +++ b/qglengine/widgets/scene_tree.cpp @@ -102,6 +102,7 @@ QList SceneTree::actionsSelection() { ret << ui->actionFocus << newSeparator() << ui->actionGroup << ui->actionClone << newSeparator() << ui->actionSelect_parent << ui->actionSelect_by_mesh << ui->actionSelect_by_material << newSeparator() + << ui->actionTransfer_transform_to_children << newSeparator() << ui->actionRemove; return ret; } @@ -387,6 +388,14 @@ void SceneTree::on_actionGroup_triggered() { } +void SceneTree::on_actionTransfer_transform_to_children_triggered() { + if (!view) return; + ObjectBaseList sol = view->scene()->selectedObjects(true); + foreach (ObjectBase * o, sol) + o->transferTransformToChildren(); +} + + void SceneTree::on_actionSelect_parent_triggered() { if (!view) return; ObjectBaseList sol = view->scene()->selectedObjects(true); diff --git a/qglengine/widgets/scene_tree.h b/qglengine/widgets/scene_tree.h index 5cdad37..7caade0 100644 --- a/qglengine/widgets/scene_tree.h +++ b/qglengine/widgets/scene_tree.h @@ -71,6 +71,7 @@ private slots: void on_actionRemove_triggered() {removeObjects();} void on_actionClone_triggered(); void on_actionGroup_triggered(); + void on_actionTransfer_transform_to_children_triggered(); void on_actionSelect_parent_triggered(); void on_actionSelect_by_mesh_triggered(); @@ -84,6 +85,7 @@ private slots: void filter(); void __objectDeleted(ObjectBase * o); + public slots: signals: diff --git a/qglengine/widgets/scene_tree.ui b/qglengine/widgets/scene_tree.ui index 44b8a06..7a98713 100644 --- a/qglengine/widgets/scene_tree.ui +++ b/qglengine/widgets/scene_tree.ui @@ -260,6 +260,11 @@ Cameras + + + Transfer transform to children + +