Qt组件推荐:
- QtitanRibbon: 遵循Microsoft Ribbon UI Paradigm for Qt技术的Ribbon UI组件,致力于为Windows、Linux和Mac OS X提供功能完整的Ribbon组件。
- QtitanChart:是一个C ++库,代表一组控件,这些控件使您可以快速地为应用程序提供漂亮而丰富的图表。并且支持所有主要的桌面
文末附下载
Qt 3D:行星 QML 示例
Qt官方最新版免费下载试用,历史版本下载,在线文档和帮助文件下载-慧都网
演示结合 Qt 3D 渲染和 Qt Quick 2 元素。
本文演示了如何实现将 Qt 3D 渲染与 Qt Quick 2D 元素结合使用的应用程序。该示例显示了太阳系的八颗行星与太阳。
行星纹理贴图由 James Hastings-Trew 版权所有 (c)
http://planetpixelemporium.com/planets.html经许可使用。
行星在给定时间根据它们的轨道围绕太阳旋转。轮换从 2000 Jan 0.0 UT 开始。行星位置是根据此处找到的公式计算的:http :
//www.stjarnhimlen.se/comp/ppcomp.html和
http://www.davidcolarusso.com/astro/。
运行示例
要从Qt Creator运行示例,请打开welcome模式并从Examples选择示例。有关更多信息,请访问构建和运行示例。
Qt 快速二维实现
planets-qml/PlanetsMain.qml示例中的 Qt Quick Implementation使用Scene3D类型呈现 3D 内容。
Scene3D {
anchors.fill: parent
aspects: ["render", "logic", "input"]
SolarSystem { id: solarsystem }
}
行星相关信息存储在一个ListModel. 行星的选择按钮和信息表是基于模型创建的。2D 元素、选择按钮和滑块在
planets-qml/PlanetsMain.qml.
选择按钮会更改 的focusedPlanet属性mainview。随着属性的变化,行星信息会更新,并且相机会动画到新的位置。
onFocusedPlanetChanged: {
if (focusedPlanet == 100) {
info.opacity = 0
updatePlanetInfo()
} else {
updatePlanetInfo()
info.opacity = 1
}
solarsystem.changePlanetFocus(oldPlanet, focusedPlanet)
oldPlanet = focusedPlanet
}
相机位置和相机观察点根据 中动画的值更新
planets-qml/SolarSystem.qml,由changePlanetFocus()函数触发。
QQ2.NumberAnimation {
id: lookAtOffsetAnimation
target: sceneRoot
properties: "xLookAtOffset, yLookAtOffset, zLookAtOffset"
to: 0
easing.type: Easing.InOutQuint
duration: 1250
}
QQ2.NumberAnimation {
id: cameraOffsetAnimation
target: sceneRoot
properties: "xCameraOffset, yCameraOffset, zCameraOffset"
to: 0
easing.type: Easing.InOutQuint
duration: 2500
}
滑块用于调整旋转速度、行星大小和观看距离。当滑块值发生变化时,
planets-qml/SolarSystem.qml会调用一个 JavaScript 函数来调整给定的属性。例如,更改观看距离滑块的值会调用该changeCameraDistance()方法。
onValueChanged: solarsystem.changeCameraDistance(value)
Qt 3D 实现
实现的主要部分,包括行星的运动和旋转数学,在
planets-qml/SolarSystem.qml.
首先,添加 a Camera、 aLight和 a Configuration,然后是Effects 代表行星Materials,最后是行星本身。例如,地球的构造如下:
Entity {
id: earthEntity
Planet {
id: earth
tilt: planetData[Planets.EARTH].tilt
}
PlanetMaterial {
id: materialEarth
effect: effectDSB
ambientLight: ambientStrengthPlanet
diffuseMap: "qrc:/images/solarsystemscope/earthmap2k.jpg"
specularMap: "qrc:/images/solarsystemscope/earthspec2k.jpg"
normalMap: "qrc:/images/solarsystemscope/earthnormal2k.jpg"
shininess: shininessSpecularMap
}
property Transform transformEarth: Transform {
matrix: {
var m = Qt.matrix4x4()
m.translate(Qt.vector3d(earth.x, earth.y, earth.z))
m.rotate(earth.tilt, tiltAxis)
m.rotate(earth.roll, rollAxis)
m.scale(earth.r)
return m
}
}
components: [ earth, materialEarth, transformEarth ]
}
移动和旋转计算等所需的行星数据是planets-qml/planets.js通过loadPlanetData()在组件完成时调用的JavaScript 来构建的。其他初始化,例如将行星插入数组以便于处理,计算土星环和天王星环的环半径,以及设置默认比例、速度和相机偏移,也已完成:
QQ2.Component.onCompleted: {
planetData = Planets.loadPlanetData()
// Push in the correct order
planets.push(sun)
planets.push(mercury)
planets.push(venus)
planets.push(earth)
planets.push(mars)
planets.push(jupiter)
planets.push(saturn)
planets.push(uranus)
planets.push(neptune)
planets.push(moon)
// TODO: Once support for creating meshes from arrays is implemented take these into use
//saturnRing.makeRing()
//uranusRing.makeRing()
saturnRingOuterRadius = planetData[Planets.SATURN].radius + Planets.saturnOuterRadius
saturnRingInnerRadius = planetData[Planets.SATURN].radius + 0.006630
uranusRingOuterRadius = planetData[Planets.URANUS].radius + Planets.uranusOuterRadius
uranusRingInnerRadius = planetData[Planets.URANUS].radius + 0.002
ready = true
changeScale(1200)
changeSpeed(0.2)
setLookAtOffset(Planets.SUN)
}
场景通过调用该animate()函数进行动画处理。这也是时间提前的地方,计算所有行星的新位置。行星positionPlanet()根据它们的轴向倾斜和它们的恒星自转周期在函数中旋转。最后,在updateCamera()函数中计算新的相机位置。
function animate(focusedPlanet) {
if (!ready)
return
advanceTime(focusedPlanet)
for (var i = 0; i <= Planets.NUM_SELECTABLE_PLANETS; i++)
positionPlanet(i)
updateCamera(focusedPlanet)
}