clean up stale test_level files (project uses LevelRuntime now)
This commit is contained in:
+11
-33
@@ -1,5 +1,5 @@
|
||||
import bpy
|
||||
import os
|
||||
import math
|
||||
|
||||
# Clear scene
|
||||
bpy.ops.object.select_all(action='SELECT')
|
||||
@@ -19,18 +19,13 @@ if not armatures:
|
||||
exit(1)
|
||||
|
||||
armature = armatures[0]
|
||||
print(f"ARMature: {armature.name}, bones: {len(armature.data.bones)}")
|
||||
|
||||
# The key: we need to bake the animation with HIGH FPS and LARGE motion
|
||||
# so the optimizer can't strip it.
|
||||
print(f"Armature: {armature.name}, bones: {len(armature.data.bones)}")
|
||||
|
||||
# Switch to pose mode
|
||||
bpy.context.view_layer.objects.active = armature
|
||||
bpy.ops.object.mode_set(mode='POSE')
|
||||
|
||||
# Function to create an animation with PER-FRAME keyframes (can't be optimized away)
|
||||
def create_anim_dense(name, bone_rotations_func, length_frames=60):
|
||||
"""bone_rotations_func: callable(frame) -> dict of bone_name -> euler_tuple
|
||||
Creates keyframes on EVERY frame to prevent Blender from optimizing."""
|
||||
action = bpy.data.actions.new(name=name)
|
||||
armature.animation_data.action = action
|
||||
action.use_fake_user = True
|
||||
@@ -47,8 +42,6 @@ def create_anim_dense(name, bone_rotations_func, length_frames=60):
|
||||
|
||||
return action
|
||||
|
||||
import math
|
||||
|
||||
# WALK: Per-frame keyframes (60 frames, 1 second)
|
||||
def walk_fn(frame, length):
|
||||
t = frame / length * math.pi * 2
|
||||
@@ -61,7 +54,7 @@ def walk_fn(frame, length):
|
||||
}
|
||||
|
||||
create_anim_dense("Walk", walk_fn, 60)
|
||||
print("Walk created (dense per-frame keyframes)")
|
||||
print("Walk created")
|
||||
|
||||
# RUN: Faster (40 frames)
|
||||
def run_fn(frame, length):
|
||||
@@ -80,14 +73,14 @@ print("Run created")
|
||||
# JUMP: Single jump cycle (40 frames)
|
||||
def jump_fn(frame, length):
|
||||
t = frame / length
|
||||
peak = max(0.0, 1.0 - abs(t - 0.5) * 3.0) # Sharp peak
|
||||
peak = max(0.0, 1.0 - abs(t - 0.5) * 3.0)
|
||||
return {
|
||||
"LeftUpperArm": (-2.5 * peak, 0, -0.3 * peak),
|
||||
"RightUpperArm": (-2.5 * peak, 0, 0.3 * peak),
|
||||
"LeftUpperLeg": (-0.5 * peak, 0, 0),
|
||||
"RightUpperLeg": (-0.5 * peak, 0, 0),
|
||||
"Spine": (0.15 * peak, 0, 0),
|
||||
"Hips": (0, 0.3 * peak, 0), # Bounce up
|
||||
"Hips": (0, 0.3 * peak, 0),
|
||||
}
|
||||
|
||||
create_anim_dense("Jump", jump_fn, 40)
|
||||
@@ -107,10 +100,10 @@ def idle_fn(frame, length):
|
||||
create_anim_dense("Idle", idle_fn, 60)
|
||||
print("Idle created")
|
||||
|
||||
# Remove all C_001 duplicates and original stripped actions
|
||||
# Remove original stripped actions, keep only our custom ones
|
||||
for action in list(bpy.data.actions):
|
||||
if action.use_fake_user:
|
||||
# Rename to clean names
|
||||
# Rename Blender's auto-suffixed names
|
||||
if action.name == "Walk.001":
|
||||
action.name = "Walk"
|
||||
elif action.name == "Run.001":
|
||||
@@ -122,10 +115,11 @@ for action in list(bpy.data.actions):
|
||||
else:
|
||||
bpy.data.actions.remove(action)
|
||||
|
||||
print(f"Actions: {[a.name for a in bpy.data.actions if a.use_fake_user]}")
|
||||
print(f"Final actions: {[a.name for a in bpy.data.actions if a.use_fake_user]}")
|
||||
|
||||
# CRITICAL: Export with animation sampling at high rate to prevent optimization
|
||||
# Export
|
||||
bpy.context.scene.render.fps = 60
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
bpy.ops.export_scene.gltf(
|
||||
filepath=output_path,
|
||||
@@ -139,20 +133,4 @@ bpy.ops.export_scene.gltf(
|
||||
)
|
||||
|
||||
print(f"\nExported to {output_path}")
|
||||
|
||||
# Verify
|
||||
bpy.ops.import_scene.gltf(filepath=output_path)
|
||||
new_armatures = [obj for obj in bpy.data.objects if obj.type == 'ARMATURE']
|
||||
if new_armatures:
|
||||
new_ap = new_armatures[0]
|
||||
new_ap.animation_data_create()
|
||||
for action in bpy.data.actions:
|
||||
if action.use_fake_user:
|
||||
new_ap.animation_data.action = action
|
||||
# Check motion
|
||||
max_delta = max((action.frame_range[1] - action.frame_range[0]), 1)
|
||||
# Check track count
|
||||
track_count = len(action.fcurves) if hasattr(action, 'fcurves') else 0
|
||||
print(f" {action.name}: {track_count} fcurves, {max_delta:.0f} frames")
|
||||
|
||||
print("Done!")
|
||||
|
||||
Reference in New Issue
Block a user