Skip to content

Commit

Permalink
Merge pull request #390 from anatawa12/undo-clear-endpoint-position
Browse files Browse the repository at this point in the history
Undo clear endpoint position
  • Loading branch information
anatawa12 authored Aug 28, 2023
2 parents a15bab4 + 42fe681 commit 01f9cda
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 15 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG-PRERELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ The format is based on [Keep a Changelog].
### Removed

### Fixed
- Clear Endpoint Position may not work well with ignore transforms `#390`
- Clear Endpoint Position doesn't support Undo `#390`

### Security

Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ The format is based on [Keep a Changelog].
### Fixed
- MergeBone not working well with non-restpose bones `#379`
- Unclear Error with Mesh with Read/Write off `#386`
- Clear Endpoint Position may not work well with ignore transforms `#390`
- Clear Endpoint Position doesn't support Undo `#390`

### Security

Expand Down
17 changes: 15 additions & 2 deletions Editor/ClearEndpointPositionEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,21 @@ protected override void OnInspectorGUIInner()
{
if (GUILayout.Button(CL4EE.Tr("ClearEndpointPosition:button:Apply and Remove Component")))
{
ClearEndpointPositionProcessor.Process(((Component)target).GetComponent<VRCPhysBoneBase>());
DestroyImmediate(target);
var pb = ((Component)target).GetComponent<VRCPhysBoneBase>();
Undo.SetCurrentGroupName("Clear Endpoint Position");
ClearEndpointPositionProcessor.CreateEndBones(pb, (name, parent, localPosition) =>
{
var gameObject = new GameObject(name);
Undo.RegisterCreatedObjectUndo(gameObject, $"Create EndBone: {name}");
Undo.SetTransformParent(gameObject.transform, parent, $"Set EndBone Parent: {name}");
Undo.RecordObject(gameObject.transform, $"Set Position of EndBone: {name}");
gameObject.transform.localPosition = localPosition;
PrefabUtility.RecordPrefabInstancePropertyModifications(gameObject.transform);
});
Undo.RecordObject(pb, "Set Endpoint Position to Zero");
pb.endpointPosition = Vector3.zero;
PrefabUtility.RecordPrefabInstancePropertyModifications(pb);
Undo.DestroyObjectImmediate(target);
}
}
}
Expand Down
36 changes: 23 additions & 13 deletions Editor/Processors/ClearEndpointPositionProcessor.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using Anatawa12.AvatarOptimizer.ErrorReporting;
using UnityEditor;
using UnityEngine;
Expand All @@ -12,28 +13,37 @@ public void Process(OptimizerSession session)
BuildReport.ReportingObjects(session.GetComponents<ClearEndpointPosition>(),
component => BuildReport.ReportingObjects(component.GetComponents<VRCPhysBoneBase>(), Process));
}

public static void Process(VRCPhysBoneBase pb)
{
if (pb.endpointPosition == Vector3.zero) return;
WalkChildrenAndSetEndpoint(pb.GetTarget(), pb);
CreateEndBones(pb, (name, parent, localPosition) =>
{
new GameObject(name) { transform = { localPosition = localPosition } }
.transform.SetParent(parent, worldPositionStays: false);
});
pb.endpointPosition = Vector3.zero;
EditorUtility.SetDirty(pb);
}

internal static void WalkChildrenAndSetEndpoint(Transform target, VRCPhysBoneBase physBone)
public static void CreateEndBones(VRCPhysBoneBase pb, Action<string, Transform, Vector3> createEndBone)
{
if (pb.endpointPosition == Vector3.zero) return;
WalkChildrenAndSetEndpoint(pb.GetTarget(), pb, createEndBone);
}

internal static bool WalkChildrenAndSetEndpoint(Transform target, VRCPhysBoneBase physBone,
Action<string, Transform, Vector3> createEndBone)
{
if (physBone.ignoreTransforms.Contains(target))
return;
if (target.childCount == 0)
{
var go = new GameObject($"{target.name}_EndPhysBone");
go.transform.parent = target;
go.transform.localPosition = physBone.endpointPosition;
return;
}
return false;
var childCount = 0;
for (var i = 0; i < target.childCount; i++)
WalkChildrenAndSetEndpoint(target.GetChild(i), physBone);
if (WalkChildrenAndSetEndpoint(target.GetChild(i), physBone, createEndBone))
childCount++;
if (childCount == 0)
createEndBone($"{target.name}_EndPhysBone", target, physBone.endpointPosition);

return true;
}
}
}

0 comments on commit 01f9cda

Please sign in to comment.