# vr_range.py - joint travel check (left side; the right is its mirror). Each joint is turned # from the rest pose through its range in steps; every step runs vr_check.check(). # Axes are the bones' own: Y along the bone, Z = the roll axis (outward / back of hand), # X = forward for arms and legs. Flexion is about Z, abduction about X. import bpy, math from mathutils import Euler TESTS = [ # bone, axis index (0 X, 1 Y, 2 Z), angles in degrees ("thigh_l", 2, (-90, -60, -30, 20)), # hip: flex forward 90, back 20 ("thigh_l", 0, (-8, 30)), # hip: in (to the other leg) / out ("calf_l", 2, (30, 60, 90, 110)), # knee ("foot_l", 2, (-25, 30)), # ankle ("upperarm_l", 2, (-90, -45, 30)), # shoulder: forward / back ("upperarm_l", 0, (-20, 40)), # shoulder: down (to 80 deg, the wide hips stop more) / up ("lowerarm_l", 2, (-40, -80, -110)), # elbow ("hand_l", 2, (-50, 50)), # wrist: flex / extend ("hand_l", 0, (-30, 30)), # wrist: side to side ("neck_01", 2, (-25, 25)), ("neck_01", 0, (-20, 20)), ("head", 1, (-60, 60)), ("head", 0, (-20, 20)), ("spine_02", 2, (-25, 20)), ] def run(ck, tests=None, fist=True): rig = bpy.data.objects["VR_Rig"] out = [] for bone, ax, angles in tests or TESTS: for a in angles: for pb in rig.pose.bones: pb.rotation_mode = 'XYZ'; pb.rotation_euler = (0, 0, 0); pb.location = (0, 0, 0) e = [0, 0, 0]; e[ax] = math.radians(a) rig.pose.bones[bone].rotation_euler = e bpy.context.view_layer.update() c = ck["check"]()["clashes"] out.append((bone, "XYZ"[ax], a, [(x, y) for x, y, n in c])) if fist: for pb in rig.pose.bones: pb.rotation_euler = (0, 0, 0) if pb.name.endswith("_l") and pb.name.split("_")[0] in ("index", "middle", "ring", "pinky", "thumb"): pb.rotation_euler = (math.radians(-80 if not pb.name.startswith("thumb") else -50), 0, 0) bpy.context.view_layer.update() out.append(("fingers_l", "X", -80, [(x, y) for x, y, n in ck["check"]()["clashes"]])) for pb in rig.pose.bones: pb.rotation_euler = (0, 0, 0) bpy.context.view_layer.update() return out