GLB 또는 GLTF 파일에서 애니메이션을 평가하면 장면을 렌더링하지 않고도 3D 객체가 시간에 따라 어떻게 이동하고, 회전하고, 스케일되는지 확인할 수 있습니다. 이 접근 방식을 사용하여 애니메이션 데이터를 분석하고, 움직임을 검증하거나, 추가 처리를 위해 변환을 내보낼 수 있습니다. 이 튜토리얼에서는 애니메이션이 적용된 GLB 모델을 로드하고, 클립을 검사하며, 다섯 개의 타임스탬프를 평가하고, 노드 변환을 CSV로 내보냅니다.

Python에서 GLB 애니메이션 로드 및 평가

애니메이션 클립은 씬과 연결된 애니메이션 데이터를 포함합니다. 시작 시간과 종료 시간은 평가할 수 있는 기간을 정의합니다. 워크플로는 모델을 로드하고, 애니메이션 클립을 선택한 다음, 특정 시간에 적용하고, 씬 노드를 검사하며, 그들의 변환을 내보내는 것입니다.

Aspose.3D for Python via .NET 설치

설치 Aspose.3D for Python via .NET, 여기에서 사용되는 애니메이션 평가 API를 제공합니다:

pip install aspose-3d==26.10.0

자세한 내용은 설치 문서를 참조하십시오.

애니메이션을 평가하고 노드 변환을 내보내기

다음 코드 예제는 첫 번째 애니메이션 클립을 다섯 개의 균등한 타임스탬프에서 평가하고 각 노드의 로컬 변환(translation, rotation, scaling)을 animation_transforms.csv에 저장합니다.

import csv
import aspose.threed as a3d

INPUT_FILE = "animated_model.glb"
OUTPUT_FILE = "animation_transforms.csv"
FRAME_COUNT = 5

def get_nodes(root):
    """Recursively collect all nodes in the scene."""
    nodes = [root]

for child in root.child_nodes:
        nodes.extend(get_nodes(child))

return nodes

# Load the animated model
scene = a3d.Scene.from_file(INPUT_FILE)

# Retrieve animation clips
clips = list(scene.animation_clips)

if not clips:
    raise RuntimeError("No animation clips found.")

print(f"Found {len(clips)} animation clip(s).")

for i, item in enumerate(clips):
    print(
        f"{i}: {item.name} "
        f"({item.start:.3f} to {item.stop:.3f} seconds)"
    )

# Select the first clip and collect scene nodes
clip = clips[0]
nodes = get_nodes(scene.root_node)

print(f"\nEvaluating: {clip.name}")
print(f"Scene nodes: {len(nodes)}")

records = []

for i in range(FRAME_COUNT):
    time = float(
        clip.start +
        (clip.stop - clip.start) * i / (FRAME_COUNT - 1)
    )

# Apply animation at the requested time
    clip.apply_to(time)

print(f"\nTimestamp: {time:.3f}s")

for index, node in enumerate(nodes):
        transform = node.transform

translation = str(transform.translation)
        rotation = str(transform.rotation)
        scaling = str(transform.scaling)

records.append([
            time,
            index,
            node.name or "(unnamed)",
            translation,
            rotation,
            scaling
        ])

print(
            f"  {node.name or '(unnamed)'}: "
            f"position={translation}, "
            f"rotation={rotation}"
        )

# Write evaluated transformations to CSV
with open(
    OUTPUT_FILE, "w", newline="", encoding="utf-8"
) as file:
    writer = csv.writer(file)

writer.writerow([
        "Time",
        "Node Index",
        "Node Name",
        "Translation",
        "Rotation",
        "Scaling"
    ])

writer.writerows(records)

print(f"\nSaved animation data to {OUTPUT_FILE}")

애니메이션 평가 작동 방식

GLB 씬을 로드하고 클립을 가져오기

Scene.from_file()는 GLB 또는 GLTF 모델을 로드합니다. scene.animation_clips 컬렉션은 사용 가능한 클립을 제공합니다:

scene = a3d.Scene.from_file("animated_model.glb")
clips = list(scene.animation_clips)

각 클립은 name, start, stop을 통해 이름과 초 단위의 시간 범위를 노출합니다. AnimationClip API 참조.

특정 타임스탬프에 애니메이션 적용

핵심 작업은 clip.apply_to(time)입니다. 지속 시간이 약 3.708초인 샘플 클립의 경우, 다섯 개의 타임스탬프는 다음과 같습니다:

샘플시간 (초)
10.000
20.927
31.854
42.781
53.708

더 많은 샘플을 수집하려면 FRAME_COUNT를 변경할 수 있습니다. 이 샘플들은 렌더링된 이미지 프레임이 아니라 평가된 애니메이션 상태입니다.

변환, 회전 및 스케일 읽기

클립을 적용한 후, 스크립트는 모든 씬 노드를 순회하며 읽습니다:

  • transform.translation: 노드의 로컬 위치.
  • transform.rotation: 노드의 로컬 회전.
  • transform.scaling: 노드의 로컬 스케일.

이들은 로컬 변환이며, 반드시 월드 공간 좌표는 아닙니다. 부모 노드 변환도 씬에서 노드의 최종 위치에 영향을 줍니다. 애니메이션이 없는 노드는 모든 타임스탬프에서 동일한 값을 유지할 수 있습니다.

애니메이션의 CSV 출력

스크립트는 animation_transforms.csv 파일을 생성합니다. 제공된 샘플의 경우, 콘솔은 다음과 같이 시작됩니다:

Found 1 animation clip(s).
0: Animation_1 (0.000 to 3.708 seconds)

Evaluating: Animation_1

CSV 파일은 각 샘플링된 타임스탬프마다 씬 노드당 한 행을 포함하며 다음과 같은 열이 있습니다:

열설명
시간초 단위 평가 타임스탬프
노드 인덱스재귀 순회에서 노드의 인덱스
노드 이름씬 노드의 이름
이동해당 타임스탬프의 로컬 위치
회전해당 타임스탬프의 로컬 회전
스케일해당 타임스탬프의 로컬 스케일

CSV 파일을 스프레드시트 애플리케이션에서 열거나 Python으로 분석하여 클립 전체의 변환을 비교할 수 있습니다.

애니메이션 평가 시 확인할 사항

Multiple clips. 이 예제는 clips[0]을 평가합니다. 다른 애니메이션을 평가하려면 다른 인덱스를 선택하거나 scene.get_animation_clip(name)을 사용하여 이름으로 클립을 가져옵니다.

샘플링 해상도. 다섯 개의 타임스탬프는 기본 개요를 제공하지만 빠른 움직임을 놓칠 수 있습니다. FRAME_COUNT를 늘리거나 특정 시간을 선택하여 더 자세히 검사하십시오.

스켈레톤 및 모프 타깃. 모든 애니메이션 효과가 노드의 로컬 변환, 회전 또는 스케일링 변화로 나타나는 것은 아닙니다. 이 CSV 워크플로는 모든 종류의 스켈레톤 또는 모프-타깃 변형을 포착하지 못합니다.

GLTF 종속성. 텍스트 기반 .gltf 파일은 외부 버퍼와 텍스처를 참조할 수 있습니다. 이러한 파일을 예상되는 상대 경로에 두세요.

GLB 애니메이션을 평가하려면 GPU가 필요합니까?

이 예제는 Scene.render() 또는 Vulkan 렌더링 백엔드를 호출하지 않습니다. 애니메이션 속성을 평가하고 이미지를 생성하는 대신 CSV 데이터를 기록합니다. Aspose.3D 렌더링에는 별도의 하드웨어 요구 사항이 있으며, 이 예제의 CSV 전용 워크플로에는 적용되지 않습니다.

무료 임시 라이선스 받기

무료 30일 임시 라이선스를 요청하여 Aspose.3D for Python via .NET를 평가 제한 없이 평가할 수 있습니다. Python 애플리케이션에 라이선스를 적용하려면 Aspose.3D 라이선스 가이드를 따라 주세요.

무료 학습 자료

Aspose.3D for Python via .NET를 사용하여 3D 모델, 애니메이션 및 지원되는 파일 형식 작업에 대해 자세히 알아보려면 다음 리소스를 확인하십시오:

결론

Aspose.3D for Python via .NET 26.10을 사용하면 AnimationClip.apply_to()를 통해 선택한 시간에 GLB 및 GLTF 애니메이션 클립을 평가할 수 있습니다. 각 평가 후 노드 변환을 읽어 모델을 렌더링하지 않고도 움직임을 확인하고 구조화된 애니메이션 데이터를 내보낼 수 있습니다. 예제를 수정하여 추가 클립을 평가하거나 샘플링 빈도를 높이거나 선택된 노드를 분석하세요.

더 읽기