튜토리얼 7: VRED 2021.3에서 도입된 새로운 vrdTransformNode를 사용하여 장면 객체 변환을 스크립팅하는 방법

튜토리얼 7: VRED 2021.3에 도입된 새로운 vrdTransformNode를 사용하여 장면 객체 변환을 스크립팅하는 방법 동영상에서는 VR의 장면 플레이트뿐만 아니라 카메라 및 뷰포인트가 포함된 예제를 다룹니다.

예제 스크립트 다운로드

스크립트 예제로 이동

튜토리얼의 PDF 다운로드

동영상 캡션: 안녕하세요. VRED Pro를 위한 Python 튜토리얼에 오신 것을 환영합니다. 저는 크리스토퍼라고 하며, 오늘은 새로운 vrdTransformNode를 사용하여 객체 변환을 스크립팅하는 방법을 소개하겠습니다.

VRED 버전 13.3의 최신 릴리즈까지는, API 버전 2에 이 동영상에서 설명하려는 vrdTransformNode 클래스가 포함되지 않았습니다. vrdTransformNode 클래스는 형상 노드를 조작할 수 있는 모든 변환 작업을 결합합니다. 이전 VRED 버전에서는 setTranslation, setRotation 등의 vrNodePtr 클래스에서 제공된 함수를 사용하여 변환을 수행했습니다. 새로운 vrdTransformNode 자체의 기능은 이전 vrNodePtr에 비해 크게 바뀌지 않았습니다. 하지만 이러한 기능을 사용하는 방식에 차이가 있습니다.

이전의 변환 작업을 살펴보면 모든 매개변수를 단일 값으로 전달해야 함을 알 수 있습니다. 따라서 벡터의 X, Y, Z 구성요소를 함수에 별도로 전달합니다. 반환 값은 벡터 구성요소의 목록입니다.

현재 예제에서는 두 점을 만들고 그 사이의 중심점을 계산하는 간단한 스크립트를 보여 줍니다. 각 벡터 구성요소를 개별적으로 처리하고 이동 함수로 전달해야 합니다. 두 위치 사이의 중심점 계산과 같은 벡터 수학 연산을 일부 수행할 때까지는 모두 좋습니다. 이 작업을 수행하려면 이러한 값을 적절한 벡터 표현으로 변환하거나 수학 함수를 직접 작성해야 합니다. 여기서는 값을 직접 계산하겠습니다.

이 문제를 해결하기 위해 모든 변환 작업은 이제 vrdTransformNode의 일부가 되며 새로운 Qt 데이터 유형이 사용됩니다. 이 데이터 유형은 개별 X, Y, Z 구성요소를 단일 벡터로 결합하고 벡터 수학 연산에서 직접 사용할 수 있는 기능을 제공합니다. 이전과 동일한 예제를 살펴보면, 중심점을 직접 계산할 필요가 없다는 것을 알 수 있습니다. 두 벡터를 직접 더하고, 2로 나누고, 결과 벡터를 이동 함수의 입력으로 사용할 수 있습니다. 따라서 외부 라이브러리를 가져오거나 자체 벡터 작업을 작성할 필요가 없습니다. 이렇게 하면 코드를 훨씬 더 읽기 쉬우며 유지 관리하기도 쉬워집니다.

또 다른 예제를 살펴보겠습니다. 선을 따라 나선형으로 움직이는 여러 개의 상자를 생성하려고 합니다. 이러한 상자는 서로에 대해 회전하여 위치에 따라 배율이 변경되어야 합니다. 이는 일부 변환 작업이 작동하는 방식을 보여 주는 좋은 예제입니다. 물론 이전의 API를 사용하여 이를 수행할 수도 있지만 새로운 변환 노드는 실제로 수학 연산에 도움이 됩니다.

상자가 될 그룹 노드를 만드는 것부터 시작하겠습니다. 나선형 상자의 동작을 제어할 몇 가지 변수를 정의합니다. 다음 단계에서 루프에 상자를 만들고 그룹 노드에 추가한 다음 x축을 따라 이동합니다. createBox 함수는 이전 API에서 노드 포인터를 반환하므로 getNodeFromId 함수를 사용하여 vrdTransformNode로 변환해야 합니다. 그런 다음, 변환을 유지하는 단순한 벡터를 만들어 상자의 setTranslation 함수에 배치합니다. 루프의 "I" 매개변수는 x축을 따라 각 상자를 약간 더 이동하는 역할을 합니다.

다음으로 x축을 따라 상자의 배율을 변경하려고 합니다. 이렇게 하려면 먼저 상자의 현재 배율을 가져와 루프 증분에 따라 증가하는 작은 인자를 곱합니다. 결과 벡터를 setScale의 입력 매개변수로 사용하여 이제 상자가 더 커지는 것을 확인합니다.

마지막 단계로 중앙선을 중심으로 상자를 나선형으로 만들려고 합니다. 또한 이를 위해서 저를 조금 믿어 주셔야 합니다. 먼저, 회전을 위해 오일러 각도를 유지하는 회전 벡터를 만든 다음 이 상자의 회전을 설정합니다. 이렇게 하면 각 상자에 멋진 회전이 만들어집니다. 이제 0 벡터를 사용하여 setWorldRotatePivot 함수를 호출하고 회전 피벗의 위치를 지정하는 벡터를 사용하여 setRotatePivotTranslation을 호출합니다. 기본적으로 회전 축을 상자에서 멀리 이동시키면 회전 변환이 이동되고 멋진 나선형 효과가 나타납니다. 회전은 더 이상 상자 중심이 아니라 상자 위의 x축에 적용됩니다.

앞서 설명한 것처럼 이전 API를 사용해도 동일한 결과를 얻을 수 있지만 새로운 변환 노드를 사용하면 훨씬 더 쉽게 결과를 얻을 수 있습니다. Qt 프레임워크 설명서에서 Python QT 벡터를 검색하면 이러한 새로운 데이터 유형에 대한 설명서를 찾을 수 있습니다. 예를 들어 Qt 벡터 설명서에서 이 데이터 유형을 사용하여 수행할 수 있는 기본 연산 더하기 및 빼기와 같은 모든 수학 함수 또는 벡터 정규화와 같은 함수를 찾을 수 있습니다. 또한 VRED의 새로운 데이터 유형에 대해 자세히 다루는 별도의 튜토리얼이 있습니다.

오늘은 이것으로 마치겠습니다. 즐거운 시간이 되셨기를 바랍니다. 시청해 주셔서 감사합니다. 다음 튜토리얼에서 뵙겠습니다.


샘플 Python 코드

튜토리얼 7: VRED 2021.3에 도입된 새로운 vrdTransformNode를 사용하여 장면 객체 변환을 스크립팅하는 방법 동영상과 함께 제공되는 예제 Python 스크립트입니다.

팁:

이러한 파일을 압축하여 다운로드하려면 여기를 클릭하십시오.

old_vs_new_transformation.py

# Old API transformations

# Create a point p1
x1 = -500
y1 = 0
z1 = 1500

p1 = vrNodeUtils.createSphere(1, 100, 1, 1, 1)
p1.`setTranslation`(x1, y1, z1)
p1.setName("p1")

# Create a point p2
x2 = 500
y2 = 0
z2 = 500

p2 = vrNodeUtils.createSphere(1, 100, 1, 1, 1)
p2.`setTranslation`(x2, y2, z2)
p2.setName("p2")

# Create a point p_center at the geometrical center between p1 and p2
x_c = (x1 + x2) / 2
y_c = (y1 + y2) / 2
z_c = (z1 + z2) / 2

p_center = vrNodeUtils.createSphere(1, 100, 1, 1, 1)
p_center.`setTranslation`(x_c, y_c, z_c)
p_center.setName("p_center")


# NEW API transformations

# Create a point p1
v1 = QVector3D(-500, 500, 1500)
p1 = vrNodeUtils.createSphere(1, 100, 1, 1, 1)
vrNodeService.getNodeFromId(p1.getID()).`setTranslation`(v1)
p1.setName("p1")

# Create a point p2
v2 = QVector3D(500, 500, 500)
p2 = vrNodeUtils.createSphere(1, 100, 1, 1, 1)
vrNodeService.getNodeFromId(p2.getID()).`setTranslation`(v2)
p2.setName("p2")

# Create a point p_center at the geometrical center between p1 and p2
v_center = (v1 + v2) / 2
p_center = vrNodeUtils.createSphere(1, 100, 1, 1, 1)
vrNodeService.getNodeFromId(p_center.getID()).`setTranslation`(v_center)
p_center.setName("p_center")

vrdTransformNode.py

groupNode = vrNodeService.findNode("Group")
deleteNode(groupNode)

numberOfBoxes = 50
boxSize = 50
xStep = 125
xRotationStep = 20
z = 500
radius = 400

boxGroup = createNode("Group")

for i in range(0, numberOfBoxes):
    box = vrNodeUtils.createBox(boxSize, boxSize, boxSize, 1, 1, 1, 0, 0, 0)
    box.setName("box {}".format(i))
    boxGroup.addChild(box)

    # Get the vrdNode object of the box
    boxNode = vrNodeService.getNodeFromId(box.getID())

    boxTranslation = QVector3D(xStep * i, 0 ,z)
    boxNode.`setTranslation`(boxTranslation)

    boxScale = boxNode.getScale() * (1 + (i * 0.01))
    boxNode.setScale(boxScale)

    boxLocalRotation = QVector3D(xRotationStep, 0, 0) * i
    boxNode.`setRotation`AsEuler(boxLocalRotation)

    boxNode.`setWorldRotatePivot`(QVector3D(0, 0, 0))
    boxNode.`setRotatePivotTranslation`(QVector3D(0, 0, z + radius))