教程 6:如何借助服务和对象使用 V2 界面视频介绍了 VR 中的摄影机、视点和场景板的相关示例。
视频字幕:大家好,欢迎学习这一面向 VRED Pro 的新 Python 教程。我叫 Christopher,今天我将介绍新的 API v2、为什么其工作方式不同,以及如何使用它。
随着 API v2 的发布,Autodesk 引入了一个新的对象模型,旨在更轻松地在 VRED 中使用 Python 界面。它引入了关键功能(即所谓的服务类),并提供了更多面向对象的数据类型供您使用。要理解为什么这是一件好事,我们首先必须讨论之前 API 的缺点。
我们来看看以下示例。版本 1 API 通常使用单独的值作为参数。举例来说,当您只想使用单个矢量的 X、Y 和 Z 值时,这没问题。但是,当一个函数需要多个矢量或矢量分量时,这会变得非常混乱。一个更好的方法是,将这些参数封装在一个对象中,该对象清楚地描述它应该是什么,比如矢量。对于返回值也是如此。
在 API v1 中,如果返回值是矢量的分量,我们会看到函数返回单个值或值列表。开发人员必须知道函数的返回值类型,才能知道这个返回值列表应该是什么。当函数返回单个对象(例如矢量)时,可以立即识别它。
API v1 的另一个缺点是它基于 Python 2.7。并不是 Python 2.7 版本不好,但使用 Python 3,提供完全静态类型的 API 要容易得多。虽然动态类型有吸引人之处,但是使用静态类型构建一致的 API 会更加容易。
在我看来,API v2 在很多方面都进行了改进。首先,它引入了多个专门的服务类,现在用作与 VRED 交互的主要方式。vrNodeService
或 vrSessionService
等服务将针对该特定主题的所有功能合并在一起。例如,会话服务包含管理协作会话的功能。摄影机服务使您能够管理摄影机和视点。这样可以更轻松地找到正确的函数,举例来说,所有与摄影机相关的功能现在都位于 vrCameraService
以及新的摄影机类型 vrdCameraNode
和 vrdCameraBaseNode
中。
新 API 引入了一系列数据类型,这些数据类型封装了一段数据的功能。这些新类型都带有前缀“vrd”。例如,如我刚才所说,vrdCameraNode
包含有关场景中摄影机的所有信息。同样,vrdSessionUser
类型的对象包含协作会话中特定用户的所有相关信息。
每个新类型都包含添加或更改对象数据的函数。因此,如果要更改摄影机的设置(如其焦距),首先应从 vrCameraService
获取 vrdCameraNode
类型的对象,然后使用函数 setFocalLength
更改设置。VRED 中还有许多其他新类型的各种数据,我们在这里只是简单地介绍一二。例如,vrdPointLightNode
,它提供了在场景中操纵点光源所需的功能。
另一个优点是,新 API v2 附带的其他支持数据类型的范围。我已经提到了矢量数据类型。它们组合了现在已明确标记为矢量的单独数字。这样,您的代码更具可读性,更容易理解。每个开发人员立即知道此函数需要一个矢量作为输入,而另一个函数返回一个矢量。另一个优势是,这些新数据类型附带数学运算,您可以直观地使用它们。下面我们来看几个例子。
首先,我想介绍新服务的基本用法。使用它们并没有什么困难。在此示例中,我们要了解如何使用 vrCameraService
来操作摄影机。首先,我们在场景中创建一个新摄影机。我们使用 vrCameraService
中的 createCamera
函数并为其提供一个名称。此函数的返回值是我们指定给变量的 vrdCameraNode
。
现在,我们可以使用此摄影机节点对象来创建新的摄影机轨迹。这也可以通过 vrCameraService
和函数 createCameraTrack
来完成。这次,返回值是 vrdCameraTrack
对象,我们也将其存储在变量中。
我们可以进一步旋转它,并在此摄影机轨迹上创建新视点。我们只需使用 vrCameraService 中的 createViewpoint
函数,并将摄影机轨迹对象用作输入参数。当我们查看摄影机编辑器时,可以看到我们创建的所有对象。
在下一个示例中,我们要在场景中创建一些光源。同样,我们可以使用 vrLightService
及其函数 createLight
。这次,我们必须提供名称和灯光类型作为输入参数。
API v2 还包含带有某种类型的类。在此示例中,我们需要的 vrLightType
为点灯光。请不要将这些类型与我们之前在本视频中讨论的数据类型混淆。在新 API 中以“type”结尾的所有类都定义了一组不同的内容,或者说,类型。例如,灯光可以是点灯光、聚光灯、平行光等类型。使用此灯光类型,我们可以告知灯光服务要创建哪种灯光。
在摄影机示例中,我们已经接触了一些新的“vrd 对象”。当回到这个示例时,我们不仅可以使用摄影机服务创建新对象,还可以更改摄影机、摄影机轨迹和我们创建的视点。
首先,我想更改摄影机的位置。这可以通过定义摄影机应该位于的位置、摄影机的视点以及指示场景中“向上”的方向来完成。我们通过使用 fromAtUp
数据类型(用我们定义的矢量馈送)来设置这些值。这会将摄影机对准场景的中心。之后,我们激活摄影机以立即查看结果。
当然,我们可以用类似的方式更改其他对象。例如,我们可以使用函数 createPreview()
更新视点的预览。这将创建当前场景中视点的新预览。
在最后一个示例中,我想介绍新的数据类型如何让您的工作更轻松。我们在即将发布的视频中提供了更详细的教程,因此我现在不会讲得太深。只需注意我们如何使用新的矢量类型来封装矢量分量,并使整个脚本更具可读性且更短。
在右侧,我们创建几个几何体,并设置其在三维空间中的位置。在左侧,是使用 API v1 中的函数编写脚本的同一个示例。至少对我来说,它更具可读性,也更容易理解。您还可以看到,我们可以使用矢量类型提供的数学运算来使脚本更短。
有关文档的最后一点说明。在文档中,您可以看到版本 1 中已被版本 2 替换的所有函数。这些函数称为“已弃用”。这基本上意味着,它们仍然可用,但将来可能被移除或替换。
例如,在版本 2 中,几乎所有包含在 vrCamera
中的函数都被现在包含在 vrCameraService
、vrdCameraNode
或 vrdCameraBaseNode
中的函数所替换。在编写新脚本时,您应避免使用已弃用的函数。它们仍然起作用,但使用新的 API,您会更加安全。当您查看页面顶部时,还会看到一个指向版本 2 中现在包含此功能的类的链接。
在 API v2 中,Autodesk 为 VRED Python 界面引入了令人兴奋的新变化。当您熟悉编写脚本后,使用新的类和数据类型应该没有问题。当您刚开始时,我希望能帮助您快速入门。今天就到这里。希望您喜欢此视频,下次见。
下面是教程 6:如何借助服务和对象使用 V2 界面视频随附的 Python 脚本示例。
要下载这些压缩文件,请单击此处。
camera.py
import math
# Example 1.0
# Get active camera with vrCameraService
camera = vrCameraService.getActiveCamera()
# Set Focal Length
camera.setFocalLength(35)
# Example 2.0
# Creating a camera using API v1 and settings its fov to 35
vrCamera.selectCamera("Perspective")
camera_v1 = vrCamera.getActiveCameraNode()
# read field of view mode (0 := vertical, 1 := horizontal)
fov_mode = camera_v1.fields().getUInt32("fovMode")
sensor_size = camera_v1.fields().getVec("sensorSize", 2)
# calculate fov based on sensor size
fov = vrOSGWidget.getFov()
focal_length = 35
if fov_mode is 0:
fov = 2 * math.degrees(math.atan((sensor_size[1] / 2) / focal_length))
else:
fov = 2 * math.degrees(math.atan((sensor_size[0] / 2) / focal_length))
vrOSGWidget.setFov(fov)
# Example 3.0
# Creating a camera using API v2 and calculating the fov manually
camera_v2_1 = vrCameraService.createCamera("Camera v2_1")
# read field of view mode (vertical or horizontal)
fov_mode = camera_v2_1.getFovMode()
# read sensor size as QtVector2D
sensor_size = camera_v2_1.getSensorSize()
# calculate fov based on sensor size
fov = camera_v2_1.getFov()
focal_length = 50
if fov_mode is vrCameraTypes.FovMode.Vertical:
fov = 2 * math.degrees(math.atan((sensor_size.y() / 2) / focal_length))
else:
fov = 2 * math.degrees(math.atan((sensor_size.x() / 2) / focal_length))
camera_v2_1.setFov(fov)
light.py
# Example 1
# Get vrdPointLightNode with the vrLightService
myPointLight = vrLightService.findLight("MyPointLight")
# Set the ground shadow intensity
myPointLight.setGroundShadowIntensity(0.5)
service.py
#Example 1
# Get the active camera from the camera service
camera = vrCameraService.createCamera("My New Camera")
# Create a new camera track on the camera object
cameraTrack = vrCameraService.createCameraTrack("My New Camera Track", camera)
# Create a new viewpoint on the camera track
viewpoint = vrCameraService.createViewpoint("My New Viewpoint", cameraTrack)
#Example 2
# Create a new pointlight with the vrLightService
newPointLight = vrLightService.createLight(
"My New PointLight",
vrLightTypes.LightType.Point
)
# Set the translation of this pointlight
newPointLight.setTranslation(QVector3D(0,0,1000))
#Example 3
# Create a new camera with the vrCameraService
camera = vrCameraService.createCamera("New Camera")
# Create vectors that define the location and look-at point of the camera
cameraFrom = QVector3D(5000, 8000, 3000)
cameraAt = QVector3D(0, 0, 0)
cameraUp = QVector3D(0, 0, 1)
# Set the camera parameters
fromAtUp = vrCameraFromAtUp(cameraFrom, cameraAt, cameraUp)
camera.setFromAtUp(fromAtUp)
# Activate the camera
camera.activate()
# Create a new camera track on the camera object
cameraTrack = vrCameraService.createCameraTrack("My New Camera Track", camera)
# Create a new viewpoint on the camera track
viewpoint = vrCameraService.createViewpoint("My New Viewpoint", cameraTrack)
viewpoint.createPreview(True)