教程 9:如何使用 v2 中的新数据类型

教程 9:如何使用 v2 中的新数据类型视频介绍了使用 QMatrix4x4 和 QVector3D 的数学运算示例。

下载示例脚本

跳转到脚本示例

下载教程 PDF

视频字幕:大家好,欢迎学习面向 VRED Pro 的下一个 Python 教程。我叫 Christopher,今天我将介绍 API v2 中的新数据类型、讨论其背景并展示如何使用它们。

当我们回顾 Python API v1,会发现实际上没有任何数据类型可用。所有参数都以单个值或列表形式传递,例如矢量或颜色分量。此外,大多数情况下,函数返回值为单个值、元组或列表。

从 Python 的角度来看,这没有问题。这称为 Pythonic,也就是 Python 中的处理方式。但是,这种处理方式存在缺点。例如,当我们使用矢量时,我们总是必须将 Pythonic 表示方式转换为更方便的表示方式,才能执行数学运算。

因此,Python API v2 引入了可解决上述问题的新数据类型。它引入了面向对象的数据处理方式。这意味着,像矢量分量这样的值会组合到单个对象中,而不是单独处理。例如,处理矢量的几何函数的输入参数和返回值现在使用新数据类型。这些数据类型是从 VRED 内部使用的 Qt 框架借用的,每种数据类型都有完全可以处理它的对应函数。对于三维图形编程,我们提供了新类型“QVector2D”、“QVector3D”和“QVector4D”,以及矩阵数据类型。我们提供了新的颜色类型,可以根据十六进制值、RGB 或其他颜色格式创建颜色。此外,我们还提供了一些可以帮助我们构建图形用户界面的类型,例如 QIcon、QSize 或 QImage。

当您想使用这些类型时,不必手动导入它们。VRED 已经为您添加了这些类型,您只需在“脚本编辑器”中键入大写的 Q,在按住 Ctrl 键的同时按空格键,即可获得所有可用的新数据类型的列表。接下来,我们来看一看使用新数据类型可以执行的一些操作。在第一个示例中,我们创建一个新标注并设置其颜色。为此,我们可以使用新的“QColor”类型,使用此类型可以根据 RGB 值创建颜色,也可以根据 HSV 或其他颜色空间创建颜色。在下一步中,我们可以将标注移高一点,将其放置在汽车引擎盖上。为此,我们只需创建一个新的三维矢量并将其放在标注的“setPosition”方法中。

在下一个示例中,我们要计算一个从当前摄影机指向右侧的矢量。实际上,我们想要由摄影机查看方向和“至”矢量的叉积描述的矢量。计算“叉积”或“点积”是进行三维编程时的基本运算,但是通过使用新数据类型,现在可以很轻松地完成此运算。

在脚本中,我们首先从当前摄影机获取“至”、“来源”和“位于”值,这些值基本描述“至”方向、摄影机从其查看的“来源”方向和摄影机查看的“位于”方向。使用这些值,我们基本上可以通过计算从摄影机到目标的矢量和“至”矢量,在一行中计算叉积。最后,我们只需将结果规格化,至此就完成了。这是这些新数据类型的优势。我们拥有所有功能,不必导入任何外部模块,也不必实现自己的类型。

另一个示例:我们要计算从摄影机到原点的距离以及从摄影机到坐标系 Z 轴的距离。这也非常简单,因为矢量类已经提供了此类方法。在本例中,就是我们在此处使用的“distanceToPoint”和“distanceToLine”方法。因此,您会发现,实际上不需要使用外部库,也不需要编写自己的矢量实现。这些数据类型应包含进行三维编程时所需的大多数函数。

还有很多值得讨论的有用数据类型,例如,用于测量时间的“QTime”数据类型或用于表示面积的“QSize”数据类型,但矢量类型肯定是最有用的类型。要了解所有其他类型,强烈建议查看官方 Qt 文档。文档中还有一些很好的示例。只需记住,在“脚本编辑器”中按住 Ctrl 键的同时按空格键可使用自动完成功能(这会显示可用的函数和类型),以及使用在线搜索查找有关 Qt 类型的文档。

好了。关于 VRED 中的所有新数据类型的介绍,今天就到这里。希望您喜欢。感谢您参加本课程,下次见!


Python 代码示例

下面是教程 9:如何使用 v2 中的新数据类型视频随附的 Python 脚本示例。

提示:

要下载这些压缩文件,请单击此处

math_operations.py

# Calculating with QtVectors
camera = vrCameraService.getActiveCamera()
cameraTranslation = camera.getTranslation()

print("Distance to origin: ", cameraTranslation.length())
print("Distance to origin (point): ", cameraTranslation.distanceToPoint(QVector3D(0,0,0)))

distanceToZAxis = cameraTranslation.distanceToLine(QVector3D(0,0,0), QVector3D(0,0,1))
print("Distance to z-axis", distanceToZAxis)

# Example 2.0
# Using vrMathService
boxPtr = vrNodeUtils.createBox(1000, 1000, 1000, 1, 1, 1, 1, 1, 1)
boxPtr.setName("Box")
boxPtr.setTranslation(100, 200, 300)
boxPtr.setRotation(23, 34, 45)
boxPtr.setScale(1.2, 1.3, 1.3)

box = vrNodeService.findNode("Box")
transform = box.getWorldTransform()

translation = vrMathService.getTranslation(transform)
rotation = vrMathService.getRotation(transform)
scale = vrMathService.getScaleFactor(transform)
scaleOrientation = vrMathService.getScaleOrientation(transform)

print("Translation", translation)
print("Rotation", rotation.toEulerAngles())
print("Scale", scale)
print("Scale Orientation", scaleOrientation.toEulerAngles())

new_data_types.py

# Example 1
# QColor:
colorRed = QColor(255, 0, 0)
colorBlue = QColor(0, 255, 0)
colorGreen = QColor(0, 0, 255)

fontcolor = QColor.fromRgb(127, 24, 78)
backgroundColor = QColor.fromHsv(180, 255, 255)

annotation = vrAnnotationService.createAnnotation("New Annotation")
annotation.setFontColor(fontcolor)
annotation.setBackgroundColor(backgroundColor)
annotation.setText("I like it!")

x = 0
y = 0
z = 300
position = QVector3D(x, y, z)
matAnnotation = vrAnnotationService.findAnnotation("MaterialAnnotation")
matAnnotation.setPosition(position)

# Example 2:
# QVector4D, QVector3D, QVector2D    

# QVector4D
camera = vrCameraService.getActiveCamera()
viewFrustum = camera.getFrustum()
print("Frustum as QVector4D:", viewFrustum)

# QVector3D
camera = vrCameraService.getActiveCamera()
fromAtUp = vrCameraService.getActiveCamera().getFromAtUp()
fromVector = fromAtUp.getFrom()
atVector = fromAtUp.getAt()
upVector = fromAtUp.getUp()

print("From Vector:", fromVector)
print("At Vector:", atVector)
print("Up Vector:", upVector)

cameraTangent = QVector3D.crossProduct((atVector - fromVector), upVector)
cameraTangent.normalize()
print("Cross product", cameraTangent)

x = 0
y = 0
z = -300
position = QVector3D(x, y, z)
matAnnotation = vrAnnotationService.findAnnotation("MaterialAnnotation")
matAnnotation.setPosition(position)

# QVector2D
camera = vrCameraService.getActiveCamera()
camera.setSensorSize(QVector2D(10, 10))
camera.updateFromPerspectiveMatch()

#Example 3:
# QMatrix4x4
camera = vrCameraService.getActiveCamera()
projectionMat = camera.getCustomProjectionMatrix()
print(projectionMat)

# Example:
# Math operations

old_data_types.py

# Example 1
# Color
blue = 127
red = 255
green = 127

vrRenderSettings.setRenderBackgroundColor(blue, red, green)
renderBackground = vrRenderSettings.getRenderBackgroundColor()
print(type(renderBackground), renderBackground.x(), renderBackground.y(), renderBackground.z())

# Example 2
# Vectors
camera = vrCamera.getActiveCameraNode()
cameraPosition = camera.getTranslation()
print(type(cameraPosition), cameraPosition)


# Example 3
# Math operations on vectors
v1 = vr