PySide2学习总结(十四)3D场景中的带网格平面

在建模软件中,往往会有一个作为参考的带网格的平面,现在我们利用PySide2+qml来实现这个效果。

创建窗口

main.qml中利用ApplicationWindow 新建了一个窗口用于显示,Scene3D组件用于创建一个三维场景

import QtQuick 2.7
import QtQuick.Controls 2.3
import QtQuick.Scene3D 2.0


ApplicationWindow {
    id: rootWindow
    title: "Grid3D Test"
    width: 800
    height: 600
    visible: true

    Scene3D {
        id: scene3d
        anchors.fill: parent
        anchors.margins: 10
        focus: true
        aspects: ['input', 'logic']
        cameraAspectRatioMode: Scene3D.AutomaticAspectRatio
        hoverEnabled: true

        Viewer3D {}
    }
}

创建场景根实体

Viewer3D.qml

import QtQuick 2.7
import Qt3D.Core 2.1
import Qt3D.Render 2.1
import Qt3D.Extras 2.1
import Qt3D.Input 2.1


Entity {
    id: rootEntity

    Camera {
        id: mainCamera
        projectionType: CameraLens.PerspectiveProjection
        fieldOfView: 45
        nearPlane: 0.01
        farPlane: 1000.0
        position: Qt.vector3d(24.0, 20.0, -20.0)
        upVector: Qt.vector3d(0.0, 1.0, 0.0)
        viewCenter: Qt.vector3d(0.0, 0.0, 0.0)
    }

    FirstPersonCameraController { camera: mainCamera }

    components: [
        RenderSettings {
            activeFrameGraph: ForwardRenderer {
                camera: mainCamera
                clearColor: "transparent"
            }
        },
        InputSettings {}
    ]

    Grid3D { enabled: true }
}


绘制网格

Grid3D.qml

import QtQuick 2.7
import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Extras 2.0


Entity {
    id: gridEntity

    components: [
        PhongMaterial {
            // 冯氏光照模型参数设置
            ambient: "#FFF" // 环境光
            diffuse: "#222" // 散射光
            specular: diffuse // 镜面反射
            shininess: 0 // 光泽常数
        },

        GeometryRenderer {
            // 利用GeometryRenderer提供的基本类型(line)来进行几何图形的绘制
            primitiveType: GeometryRenderer.Lines
            // 几何数据的坐标
            geometry: Geometry {
                Attribute {
                    id: gridPosition
                    attributeType: Attribute.VertexAttribute
                    vertexBaseType: Attribute.Float // 定义顶点的数据类型
                    vertexSize: 3 // 顶点大小
                    count: 0
                    name: defaultPositionAttributeName
                    buffer: Buffer {
                        type: Buffer.VertexBuffer
                        data: {
                            function buildGrid(first, last, offset, attribute) {
                                var vertexCount = (((last - first) / offset) + 1) * 7;
                                var f32a = new Float32Array(vertexCount * 2);
                                for(var id = 0, i = first; i <= last; i += offset, id++){
                                    f32a[12*id] = i;
                                    f32a[12*id+1] = 0.0;
                                    f32a[12*id+2] = first;

                                    f32a[12*id+3] = i;
                                    f32a[12*id+4] = 0.0;
                                    f32a[12*id+5] = last;

                                    f32a[12*id+6] = first;
                                    f32a[12*id+7] = 0.0;
                                    f32a[12*id+8] = i;

                                    f32a[12*id+9] = last;
                                    f32a[12*id+10] = 0.0;
                                    f32a[12*id+11] = i;

                                    f32a[12*id+12] = i;
                                    f32a[12*id+13] = 0.0;
                                }
                                attribute.count = vertexCount
                                return f32a;
                            }
                            return buildGrid(-14, 14, 1, gridPosition);
                        }
                    }
                }
            }
        }
    ]
}

运行效果

PySide2学习总结(十四)3D场景中的带网格平面_第1张图片

你可能感兴趣的:(Python)