Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. 3D calculate normals
Qt 6.11 is out! See what's new in the release blog

3D calculate normals

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
1 Posts 1 Posters 220 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Martin1381
    wrote on last edited by
    #1

    I wanted to create a custom mesh. But the lighting is not working. Can anybody help me to calculate the right normals? The second problem is, that not all triangles are drawn, when I use a color. With textures they are drawn...

    main.qml

    import QtQuick
    import QtQuick3D
    import QtQuick3D.Helpers
    import MyCustomGeometry
    
    Window {
        width: 800
        height: 600
        visible: true
        title: qsTr("Basic Scene")
    
        View3D {
            camera: camera
            anchors.fill: parent
            width: 800
            height: 600
            x: 0
            y: 0
            id: view
    
            environment: SceneEnvironment {
                clearColor: "#ffffff"
                backgroundMode: SceneEnvironment.Color
                antialiasingMode: SceneEnvironment.ProgressiveAA
                antialiasingQuality: SceneEnvironment.VeryHigh
                depthTestEnabled: true
            }
    
            DirectionalLight {
                eulerRotation.x: -20
                eulerRotation.y: 110
                shadowMapQuality : Light.ShadowMapQualityHigh
                castsShadow: true
                brightness: 5
            }
    
            Node {
                id: originNode
                PerspectiveCamera {
                    id: cameraNode
                    z: 100
                    fieldOfView: 45
                }
            }
    
            OrbitCameraController {
                anchors.fill: parent
                origin: originNode
                camera: cameraNode
    
            }
    
            Model {
                position: Qt.vector3d(0, -50, 0)
                scale: Qt.vector3d(5, 5, 1)
                eulerRotation.x: -90
                source: "#Rectangle"
                materials: [
                    PrincipledMaterial { baseColor: "green"; }
                ]           
                receivesShadows: true
            }
    
    
            Model {
                id: sphere
                objectName: "sphere"
                visible: true
                usedInBakedLighting : true
                geometry: MyCustomGeometry {}
                materials: [DefaultMaterial {diffuseColor: "blue"}]
                eulerRotation.x: 90
                eulerRotation.z: 45
    
    //            materials: [
    //                DefaultMaterial {
    //                    objectName: ""
    //                    Texture {
    //                        id: baseColorMap
    //                        source: "qrc:/qt_logo_rect.png"
    //                    }
    //                    //lightProbe: baseColorMap
    //                    cullMode: DefaultMaterial.NoCulling
    //                    diffuseMap: baseColorMap
    //                    specularAmount: 0.5
    //                    // lighting : DefaultMaterial.FragmentLighting
    
    //                }
    //            ]
            }
        }
    }
    

    main.cpp

    #include <MyCustomGeometry.h>
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        qmlRegisterType<MyCustomGeometry>("MyCustomGeometry", 1, 0, "MyCustomGeometry");
    
        QQmlApplicationEngine engine;
        const QUrl url(u"qrc:/untitled9/main.qml"_qs);
        QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                         &app, [url](QObject *obj, const QUrl &objUrl) {
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
        engine.load(url);
    
        return app.exec();
    }
    

    mycustomgeometry.h

    #ifndef MYCUSTOMGEOMETRY_H
    #define MYCUSTOMGEOMETRY_H
    
    #include <QQuick3DGeometry>
    
    class MyCustomGeometry : public QQuick3DGeometry
    {
        Q_OBJECT
    public:
        MyCustomGeometry();
        virtual ~MyCustomGeometry();
    
        QVector3D GetNormal(QVector3D a, QVector3D b, QVector3D c);
    
    signals:
    
    public slots:
        void setData(QByteArray vertexData, QByteArray indexData);
    
    };
    
    #endif // MYCUSTOMGEOMETRY_H
    
    

    mycustomgeometry.cpp

    #include "mycustomgeometry.h"
    #include <QVector3D>
    
    MyCustomGeometry::MyCustomGeometry()
    {   
        QVector3D vectors[4] {
            QVector3D (-10.0f, -10.0f, -10.0f),
            QVector3D (10.0f, -10.0f, -10.0f),
            QVector3D (0.0f, -10.0f, -20.0f),
            QVector3D (-5.0f, -5.0f, -25.0f)
        };
    
        QByteArray i;
        i.resize(3 * 3 * sizeof(int));
        int *p1 = reinterpret_cast<int *>(i.data());
    
        *p1++ = 0; *p1++ = 3; *p1++ = 2;
        *p1++ = 0; *p1++ = 1; *p1++ = 3;
        *p1++ = 1; *p1++ = 2; *p1++ = 3;
    
        QByteArray v;
        v.resize((3 + 3 + 2) * 4 * sizeof(float));
        float *p = reinterpret_cast<float *>(v.data());
    
        QVector3D normals[4] {
            QVector3D (1.0f, 1.0f, 1.0f),
            QVector3D (1.0f, 1.0f, 1.0f),
            QVector3D (1.0f, 1.0f, 1.0f),
            QVector3D (1.0f, 1.0f, 1.0f)
        };
    
        for (int i = 0; i < 4; i++)
        {
            auto prev = i == 0 ? vectors[3] : vectors[i-1];
            auto next = i == 3 ? vectors[0] : vectors[i+1];
            auto current = vectors[i];
            normals[i] = GetNormal(current, prev, next);
        }
    
        // vertex
        *p++ = vectors[0].x(); *p++ = vectors[0].y(); *p++ = vectors[0].z();
        // normals
        *p++ = normals[0].x(); *p++ = normals[0].y(); *p++ = normals[0].z();
        // texture
        *p++ = 0.25f; *p++ = 0.0f;
    
        // vertex
        *p++ = vectors[1].x(); *p++ = vectors[1].y(); *p++ = vectors[1].z();
        // normals
        *p++ = normals[1].x(); *p++ = normals[1].y(); *p++ = normals[1].z();
        // texture
        *p++ = 2.0f; *p++ = 0.0f;
    
        // vertex
        *p++ = vectors[2].x(); *p++ = vectors[2].y(); *p++ = vectors[2].z();
        // normals
        *p++ = normals[2].x(); *p++ = normals[2].y(); *p++ = normals[2].z();
        // texture
        *p++ = 0.5f; *p++ = 2.0f;
    
        // vertex
        *p++ = vectors[3].x(); *p++ = vectors[3].y(); *p++ = vectors[3].z();
        // normals
        *p++ = normals[3].x(); *p++ = normals[3].y(); *p++ = normals[3].z();
        // texture
        *p++ = 0.5f; *p++ = 2.0f;
    
        setData(v, i);
    }
    
    MyCustomGeometry::~MyCustomGeometry()
    {
    }
    
    QVector3D MyCustomGeometry::GetNormal(QVector3D a, QVector3D b, QVector3D c)
    {
        QVector3D normVec;
        auto dir = normVec.crossProduct(b - a, c - a);
        dir.normalize();
        return dir;
    }
    
    void MyCustomGeometry::setData(QByteArray vertexData, QByteArray indexData)
    {
        clear();
        setPrimitiveType(PrimitiveType::Triangles);
        addAttribute(Attribute::PositionSemantic, 0, Attribute::F32Type);
        addAttribute(Attribute::IndexSemantic, 0, Attribute::U32Type);
    
        addAttribute(Attribute::NormalSemantic,
                     3 * sizeof(float),
                     Attribute::F32Type);
    
    
        addAttribute(QQuick3DGeometry::Attribute::TexCoordSemantic,
                     6 * sizeof(float),
                     QQuick3DGeometry::Attribute::F32Type);
    
    
        setVertexData(vertexData);
        setIndexData(indexData);
        setStride(sizeof(float) * (3 + 3 + 2));
    
        QVector3D boundsMin, boundsMax;
        auto vertices = reinterpret_cast<const float*>(vertexData.constData());
        for(size_t i = 0; i < vertexData.length() / sizeof(float); i += 8)
        {
            for(size_t j = 0; j < 3; j++)
            {
                boundsMin[j] = (std::min(vertices[i + j], i == 0 ? vertices[i + j] : boundsMin[j]));
                boundsMax[j] = (std::max(vertices[i + j], i == 0 ? vertices[i + j] : boundsMax[j]));
            }
        }
        setBounds(boundsMin, boundsMax);
    }
    
    1 Reply Last reply
    0

    • Login

    • Login or register to search.
    • First post
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt Extensions
    • Unsolved