当前位置: 首页 > article >正文

QQuick3D-Camera的介绍

QQuick3D-Camera的介绍

Camera的概述

  1. Camera类继承于 Node;Camera定义了怎样将一个3D场景(Scene)投影到2D的表面上;一个场景至少需要一个Camera来可视化其内容。

  2. Camera 可以像场景中任何节点一样,被定位和旋转;Camera节点的位置和方向决定了Camera在场景中的位置及其朝向;Camera的默认方向是,其前向矢量指向负Z轴,其上向矢量指向正Y轴。

  3. QQuick3D提供以下几种类型相机:
    ** PerspectiveCamera**:透视投影相机,具有近大远小特点
    OrthographicCamera:正交投影相机,提供了一种平截头体线条平行的相机,使物体的感知比例不受其与相机距离的影响。这种相机的典型用例是CAD(计算机辅助设计)应用程序和制图
    FrustumCamera
    CustomCamera : 自定义相机,由用户自定义 投影矩阵

  4. 属性frustumCullingEnabled : bool:当此属性为真时,相机平截头体之外的对象将被剔除,这意味着它们不会传递给渲染器。默认情况下,此属性设置为false。对于所有或大多数对象都在相机平截头体内的场景,平截头体剔除是一种不必要的性能开销。但对于大部分位于相机视野之外的复杂场景,启用平截头体剔除可能会提高性能

  5. 属性lookAtNode : Node: Node 非空时,当lookAtNode 观察节点位置发生变化时,相机的位置会跟随发生变化;默认值为null

  6. 方法vector3d lookAt(vector3d scenePos):设置摄影机的旋转值,使其指向scenePos

  7. 方法vector3d lookAt(QtQuick3D::Node node):设置摄影机的旋转值,使其指向节点

  8. 方法vector3d mapFromViewport(vector3d viewportPos):将viewportPos从视口空间(viewPort Space)(2D)转换为全局场景空间(3D)。viewportPos的x和y值必须归一化,视口的左上角为[0,0],右下角为[1,1]。z值被解释为距截头体近剪裁平面的距离(clipNear)。如果viewportPos无法成功映射到场景中的某个位置,则返回[0,0,0]的位置。

  9. 方法vector3d mapToViewport(vector3d scenePos):将scenePos从全局场景空间(3D)转换到视口空间(2D)。返回的位置被归一化,视口的左上角为[0,0],右下角为[1,1]。返回的z值将包含从截头体的近剪裁平面(clipANear)到场景坐标中scenePos的距离。如果距离为负,则该点位于相机后面。如果scenePos无法成功映射到视口中的某个位置,则返回[0,0,0]的位置

Camera的实例代码

注意 代码中 “teapot.mesh” 这个网格,Qt 官方实例中有提供。

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick3D


//摄像机Demo
Item {
    id: root

    //场景需要 Model(mesh + Material),  Light, Camera, 3个元素
    Node{
        id: rootSceneNode                   //3D场景的根节点

        //平行光: 光源从无线远地方发射,类似于生活中太阳;平行光具有无限的范围,不会衰减;如果启用castsShadow,阴影将平行于灯光方向;
        //平行光实际上没有位置,因此移动它没有任何效果。光将始终沿光的Z轴方向发射。沿X或Y轴旋转灯光将改变发光方向。
        DirectionalLight {
            ambientColor: Qt.rgba(0.5, 0.5, 0.5, 1.0)
            brightness: 1.0
            eulerRotation.x: -25
        }

        Model {
            //Model 需要网格 + 材质
            source: "qrc:/qt/qml/text/3DDemo/teapot.mesh"
            y: -100
            scale: Qt.vector3d(50, 50, 50)
            materials: [
                PrincipledMaterial {
                    baseColor: "#41cd52"
                    metalness: 0.0
                    roughness: 0.1
                    opacity: 1.0
                }
            ]

            //沿着Y轴旋转,在xz所在平台旋转
            // PropertyAnimation on eulerRotation.y {
            //     loops: Animation.Infinite
            //     duration: 5000
            //     to: 0
            //     from: -360
            // }
        }

        //
        Node {
            //使用节点给摄像机设置动画。
            //Camera 做为Node 的子节点,可以通过Node节点的属性来定义相机的位置、旋转 之类属性;也会继承父节点的变换
            //透视投影:主要涉及 近平面(clipNear),远平面(clipFar),视野角(fiedOfView)
            id: idCamPNode
            PerspectiveCamera {
                id: cameraPerspectiveOne
                z: 600

                // onSceneRotationChanged: {
                //     console.log("onSceneRotationChanged = ",cameraPerspectiveOne.sceneRotation);
                // }

                // onScenePositionChanged: {
                //     console.log("onScenePositionChanged = ",cameraPerspectiveOne.scenePosition);
                // }

                // onSceneTransformChanged: {
                //     console.log("onSceneTransformChanged");
                // }
            }

            //
            PropertyAnimation on eulerRotation.y {
                loops: Animation.Infinite
                duration: 5000
                to: -360
                from: 0
            }

        }
    }


    View3D{
        id:idView3D
        anchors.fill: parent
        importScene: rootSceneNode
        camera: cameraPerspectiveOne


        MouseArea{
            anchors.fill: parent
            onClicked:(mouse)=> {
              var viewPos = Qt.vector3d(mouse.x /parent.width,mouse.y/parent.height,0);

            //同样的viewPos 因为Camera的位置在变化,造成映射到scene中值不一致
              var scenePos = cameraPerspectiveOne.mapFromViewport(viewPos);
              console.log("scenePos = ",scenePos, " viewPos = ",mouse.x,mouse.y);

            }
        }

    }
}

http://www.kler.cn/a/584837.html

相关文章:

  • 【2025前端高频面试题——系列三之vue生命周期:vue3】
  • 机器学习(李宏毅)——Explainable AI
  • 【UniApp跳转外部链接】实现方案
  • (全)2024下半年真题 系统架构设计师 综合知识 答案解析01
  • Ceph(2):Ceph简介
  • OpenText ETX 助力欧洲之翼航空公司远程工作升级
  • 98. 验证二叉搜索树
  • CSS—网格布局Grid
  • 浅谈交易暨百城联动线下技术交流会-南宁站圆满举行
  • 在 CentOS 7 上安装 PHP 7.3
  • [微服务设计]2_演化式架构
  • 微信小程序:实现多功能表格效果,例如滚动效果、宽度自定义、多选、行内编辑等功能
  • 从头开始开发基于虹软SDK的人脸识别考勤系统(python+RTSP开源)(五)完整源码已上传!
  • ALSA vs OSS:Linux 音频架构的演变与核心区别
  • 九点标定和十二点标定的区别
  • 【从零开始学习计算机科学】编程语言(二)名字、关键字、保留字 与 变量
  • 接口自动化入门 —— Jmeter实现在接口工具中关联接口处理方案
  • Ubuntu20.04安装运行DynaSLAM
  • 【实战篇】执行计划解析
  • 二叉树中堆的实现