Skip to content

Commit 812a9e9

Browse files
committed
revert: character bone normalization
1 parent f4b3d30 commit 812a9e9

File tree

2 files changed

+2
-115
lines changed

2 files changed

+2
-115
lines changed

Warudo/Scripts/Warudo/Editor/SetupCharacterWindow.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
using UnityEditor;
1212
using UnityEngine;
1313
using VRM;
14-
using UniVRM10;
1514
using Warudo.Plugins.Core.Assets.Character;
1615

1716
namespace Warudo.Editor {
@@ -105,9 +104,9 @@ public void SetupCharacter() {
105104
selectedCharacter.transform.rotation = Quaternion.identity;
106105

107106
var colliderGroups = selectedCharacter.GetComponentsInChildren<VRMSpringBoneColliderGroup>();
108-
var colliderGroupCenters = colliderGroups.ToDictionary(it => it, it =>
107+
var colliderGroupCenters = colliderGroups.ToDictionary(it => it, it =>
109108
it.Colliders.Select(c => it.transform.TransformPoint(c.Offset)).ToArray());
110-
109+
111110
if (!normalizedBones) {
112111
var animator = selectedCharacter.GetComponent<Animator>();
113112
BoneNormalization.Apply(selectedCharacter.gameObject, animator);

Warudo/Scripts/Warudo/Plugins/Core/Assets/Character/BoneNormalization.cs

Lines changed: 0 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -13,119 +13,7 @@
1313
namespace Warudo.Plugins.Core.Assets.Character {
1414
// Much of the code here is brought from UniVRM. Thanks!
1515
public static class BoneNormalization {
16-
/// <summary>
17-
/// Apply hierarchical bone normalization by storing non-standardized rotations in HumanBones
18-
/// and propagating inverse rotations to children to maintain their world positions.
19-
/// </summary>
2016
public static void Apply(GameObject go, Animator animator) {
21-
ApplyHierarchicalNormalization(go, animator);
22-
}
23-
24-
/// <summary>
25-
/// Normalizes bones hierarchically by:
26-
/// 1. Storing the non-identity rotation of each HumanBone
27-
/// 2. Setting the HumanBone's local rotation to identity
28-
/// 3. Applying the inverse rotation to children to preserve their world positions
29-
/// 4. Recursively processing HumanBone children
30-
/// </summary>
31-
private static void ApplyHierarchicalNormalization(GameObject go, Animator animator) {
32-
// Build a HashSet of all HumanBone transforms for quick lookup
33-
var humanBoneSet = new HashSet<Transform>();
34-
for (var i = 0; i < (int)HumanBodyBones.LastBone; i++) {
35-
var bone = animator.GetBoneTransform((HumanBodyBones)i);
36-
if (bone != null) {
37-
humanBoneSet.Add(bone);
38-
}
39-
}
40-
41-
// Collect all HumanBone transforms in hierarchy order (parent to child)
42-
var humanBones = new List<(HumanBodyBones boneType, Transform transform)>();
43-
for (var i = 0; i < (int)HumanBodyBones.LastBone; i++) {
44-
var bone = animator.GetBoneTransform((HumanBodyBones)i);
45-
if (bone != null) {
46-
humanBones.Add(((HumanBodyBones)i, bone));
47-
}
48-
}
49-
50-
// Sort by hierarchy depth to process parents before children
51-
humanBones.Sort((a, b) => GetHierarchyDepth(a.transform).CompareTo(GetHierarchyDepth(b.transform)));
52-
53-
Debug.Log($"Normalizing {humanBones.Count} humanoid bones hierarchically...");
54-
55-
foreach (var (boneType, boneTransform) in humanBones) {
56-
if (boneTransform.localRotation == Quaternion.identity) {
57-
continue; // Already normalized
58-
}
59-
60-
var nonStandardRotation = boneTransform.localRotation;
61-
Debug.Log($"Normalizing bone {boneTransform.name} ({boneType}): {nonStandardRotation.eulerAngles}");
62-
63-
// Store the non-standard rotation (we could save this somewhere if needed)
64-
// For now, we just apply the normalization
65-
66-
// Apply inverse rotation to all children to preserve their world positions
67-
NormalizeBoneAndChildren(boneTransform, humanBoneSet);
68-
}
69-
70-
Debug.Log("Bone normalization complete.");
71-
}
72-
73-
/// <summary>
74-
/// Normalizes a bone and recursively updates its children to preserve world positions.
75-
/// </summary>
76-
private static void NormalizeBoneAndChildren(Transform boneTransform, HashSet<Transform> humanBoneSet) {
77-
var originalRotation = boneTransform.localRotation;
78-
79-
// If the bone is already normalized, no need to process
80-
if (originalRotation == Quaternion.identity) {
81-
return;
82-
}
83-
84-
// First, recursively process all HumanBone children first (bottom-up approach)
85-
var humanBoneChildren = new List<Transform>();
86-
foreach (Transform child in boneTransform) {
87-
if (humanBoneSet.Contains(child)) {
88-
humanBoneChildren.Add(child);
89-
}
90-
}
91-
92-
// Process HumanBone children first
93-
foreach (var child in humanBoneChildren) {
94-
NormalizeBoneAndChildren(child, humanBoneSet);
95-
}
96-
97-
// Calculate the inverse rotation that will be applied to children
98-
var inverseRotation = Quaternion.Inverse(originalRotation);
99-
100-
// Now normalize this bone
101-
boneTransform.localRotation = Quaternion.identity;
102-
103-
// Apply inverse rotation to all direct children (both HumanBones and non-HumanBones)
104-
// to preserve their world positions
105-
foreach (Transform child in boneTransform) {
106-
if (!humanBoneChildren.Contains(child)) {
107-
// For non-HumanBone children, apply the inverse rotation
108-
child.localRotation = inverseRotation * child.localRotation;
109-
}
110-
// HumanBone children were already processed recursively
111-
}
112-
}
113-
114-
/// <summary>
115-
/// Gets the hierarchy depth of a transform (root = 0).
116-
/// </summary>
117-
private static int GetHierarchyDepth(Transform transform) {
118-
var depth = 0;
119-
var current = transform;
120-
while (current.parent != null) {
121-
depth++;
122-
current = current.parent;
123-
}
124-
return depth;
125-
}
126-
127-
// Legacy method for reference (original implementation)
128-
private static void ApplyLegacy(GameObject go, Animator animator) {
12917
var (normalized, boneMap) = NormalizeHierarchy(go, animator);
13018

13119
foreach (var src in go.transform.Traverse()) {

0 commit comments

Comments
 (0)