Skip to content

Commit

Permalink
Merge pull request #218 from anatawa12/merge-0.4
Browse files Browse the repository at this point in the history
Merge 0.4
  • Loading branch information
anatawa12 authored Jun 10, 2023
2 parents 8f052ff + 415dc9e commit 11405af
Show file tree
Hide file tree
Showing 26 changed files with 306 additions and 350 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified .docs/content/docs/tutorial/basic-usage/add-merge-skinned-mesh.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified .docs/content/docs/tutorial/basic-usage/drag-and-drop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 15 additions & 12 deletions .docs/content/docs/tutorial/basic-usage/index.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,50 +25,51 @@ SkinnedMeshを結合するとメッシュを変形させる処理の回数が減

まず初めにマージ先のGameObjectを作りましょう。
アバターのGameObjectを右クリックから `Create Empty` をクリックして新たなGameObjectを作ります。
そしたらわかりやすい名前に変えておいてください。この記事では`MergedMesh`とします
そしたらわかりやすい名前に変えておいてください。この記事では`Anon_Merged`とします

![create-empty.png](./create-empty.png)

そしたら`Merged Mesh``Merge Skinned Mesh`を追加しましょう。
そしたら`Anon_Merged``Merge Skinned Mesh`を追加しましょう。

![add-merge-skinned-mesh.png](./add-merge-skinned-mesh.png)

すると`Merge Skinned Mesh``Skinned Mesh Renderer`が追加されます。

この`Merge Skinned Mesh`コンポーネントは、指定された`Skinned Mesh Renderer`を一緒についている`Skinned Mesh Renderer`にマージするコンポーネントです
マージを機能させるために`Merge Skinned Mesh`にマージする`Skinned Mesh Renderer`を指定しましょう
この`Merge Skinned Mesh`は、指定されたメッシュ[^mesh]を一緒についているメッシュにマージします
マージを機能させるために`Merge Skinned Mesh`にマージするメッシュを指定しましょう

指定を楽にするために、`MergedMesh`を選択した状態でinspectorをロックしましょう。
こうすることで複数のS`Skinned Mesh Renderer`をまとめてドラックアンドドロップできるようになります[^tip-lock-inspector]
指定を楽にするために、`Anon_Merged`を選択した状態でinspectorをロックしましょう。
こうすることで複数のメッシュをまとめてドラックアンドドロップできるようになります[^tip-lock-inspector]

![lock-inspector.png](./lock-inspector.png)

それではHierarchyで顔のメッシュであるBody以外の`Skinned Mesh Renderer`を選択してドラックアンドドロップでSkinned Renderersに指定しましょう!
それではHierarchyで顔のメッシュであるBody以外のメッシュを選択してドラックアンドドロップでSkinned Renderersに指定しましょう!

![drag-and-drop.png](./drag-and-drop.png)

{{< hint info >}}

**なせ顔のメッシュを結合しないの?**

BlendShapeは頂点数とBlendShape数の積に比例して重くなる処理です
BlendShape(シェイプキー)[^blend-shape]は頂点数とBlendShape数の積に比例して重くなる処理です
そのため、BlendShapeの数が多い顔のメッシュを頂点数の多い体のメッシュと結合するとかえって重くなってしまうため、顔は別のままにするのを推奨しています

{{< /hint >}}

続いて、`MergedMesh``Skinned Mesh Renderer`の設定をしましょう!
続いて、`Anon_Merged`の設定をしましょう!

`Merge Skinned Mesh`は諸事情[^merge-skinned-mesh]によりボーン、メッシュ、マテリアル以外の設定を自動的には行いません。
そのため、Bounds, Root Bone, Anchor Override等を手動で設定してください。
Anchor Overrideは素体のを、Root BoneはHipsを指定するとうまくいくことが多いと思います。

[^tip-lock-inspector]: PhysBoneに複数のコライダーを指定するのにも使えたり、色んなところで使えるので覚えておくと便利だと思います。
[^merge-skinned-mesh]: Boundsは大きな箱にすることで今後対応予定、Root Bone/Anchor Overrideは等しくないとマージできないため対応予定がないです。もし良いアルゴリズムを教えてください。
[^mesh]: この記事ではメッシュはUnityのMesh assetではなくSkinnedMeshRendererの意味で使用しています。

BlendShapeを固定する {#freeze-blendshape}
---

また、Avatar Optimizerを使用すると簡単にBlendShapeを固定することができます
また、Avatar Optimizerを使用すると簡単にBlendShape(シェイプキー)[^blend-shape]を固定することができます

{{< hint info >}}

Expand All @@ -83,15 +84,17 @@ BlendShapeを固定する {#freeze-blendshape}

それでは使わない素体や服のの体型変更用のBlendShapeを結合してみましょう!

頂点数が増えたメッシュである先程の`MergedMesh``Freeze BlendShapes`を追加しましょう!
頂点数が増えたメッシュである先程の`Anon_Merged``Freeze BlendShapes`を追加しましょう!

![add-freeze-blendshape.png](add-freeze-blendshape.png)

`Freeze BlendShape`は一緒についている`Skinned Mesh Renderer`のBlendShapeを固定するコンポーネントです
`Freeze BlendShape`は一緒についているメッシュのBlendShapeを固定します

マージを機能させるために固定するBlendShapeを指定しましょう!
チェックボックスにチェックするとそのBlendShapeは固定されます。

![freeze-blendshape.png](freeze-blendshape.png)

これでBlendShapeの固定の設定は終わりです!

[^blend-shape]: BlendShapeはUnity上のシェイプキーの名前です。UnityやMayaではBlend Shape、BlenderではShape Key、MetasequoiaやMMDではモーフと呼ばれます。
Binary file modified .docs/content/docs/tutorial/basic-usage/lock-inspector.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 18 additions & 1 deletion CHANGELOG-PRERELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ The format is based on [Keep a Changelog].
[Keep a Changelog]: https://keepachangelog.com/en/1.1.0/

## [Unreleased]
**If you're using v0.3.x or older, Please upgrade to v0.4.x before upgrading v1.x.x!**

**もし v0.3.x 以前を使用しているのであれば, v1.x.xに更新する前に v0.4.x に更新してください!**

### Added
- Merged changes in 0.4.5 and 0.4.6 `#218`

### Changed

Expand All @@ -19,6 +24,14 @@ The format is based on [Keep a Changelog].

### Security

## [0.4.6] - 2023-06-10
### Changed
- Improve ErrorReport window on build error [`#216`](https://github.com/anatawa12/AvatarOptimizer/pull/216)

## [0.4.5] - 2023-06-06
### Fixed
- Error in MergeSkinnedMeshProcessor with RecordMoveProperty [`#214`](https://github.com/anatawa12/AvatarOptimizer/pull/214)

## [1.0.0-beta.1] - 2023-06-05
**If you're using v0.3.x or older, Please upgrade to v0.4.x before upgrading v1.x.x!**

Expand All @@ -29,6 +42,7 @@ The format is based on [Keep a Changelog].
- We no longer see save data in format of v0.3.x or older.
- Please migrate to v0.4.x format before installing v1.0.0.

## [0.4.5-beta.1] - 2023-06-05
## [0.4.4] - 2023-06-04
## [0.4.4-rc.1] - 2023-06-04
### Changed
Expand Down Expand Up @@ -402,7 +416,10 @@ The format is based on [Keep a Changelog].
- Clear Endpoint Position

[Unreleased]: https://github.com/anatawa12/AvatarOptimizer/compare/v1.0.0-beta.1...HEAD
[1.0.0-beta.1]: https://github.com/anatawa12/AvatarOptimizer/compare/v0.4.4...v1.0.0-beta.1
[1.0.0-beta.1]: https://github.com/anatawa12/AvatarOptimizer/compare/v0.4.6...v1.0.0-beta.1
[0.4.6]: https://github.com/anatawa12/AvatarOptimizer/compare/v0.4.5...v0.4.6
[0.4.5]: https://github.com/anatawa12/AvatarOptimizer/compare/v0.4.5-beta.1...v0.4.5
[0.4.5-beta.1]: https://github.com/anatawa12/AvatarOptimizer/compare/v0.4.4...v0.4.5-beta.1
[0.4.4]: https://github.com/anatawa12/AvatarOptimizer/compare/v0.4.4-rc.1...v0.4.4
[0.4.4-rc.1]: https://github.com/anatawa12/AvatarOptimizer/compare/v0.4.3...v0.4.4-rc.1
[0.4.3]: https://github.com/anatawa12/AvatarOptimizer/compare/v0.4.2...v0.4.3
Expand Down
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ The format is based on [Keep a Changelog].

### Security

## [0.4.6] - 2023-06-10
### Changed
- Improve ErrorReport window on build error [`#216`](https://github.com/anatawa12/AvatarOptimizer/pull/216)

## [0.4.5] - 2023-06-06
### Fixed
- Error in MergeSkinnedMeshProcessor with RecordMoveProperty [`#214`](https://github.com/anatawa12/AvatarOptimizer/pull/214)

## [0.4.4] - 2023-06-04
### Changed
- Make `Remove Empty Renderer Object` enabled by default [`#208`](https://github.com/anatawa12/AvatarOptimizer/pull/208)
Expand Down Expand Up @@ -315,7 +323,9 @@ The format is based on [Keep a Changelog].
- Merge Bone
- Clear Endpoint Position

[Unreleased]: https://github.com/anatawa12/AvatarOptimizer/compare/v0.4.4...HEAD
[Unreleased]: https://github.com/anatawa12/AvatarOptimizer/compare/v0.4.6...HEAD
[0.4.6]: https://github.com/anatawa12/AvatarOptimizer/compare/v0.4.5...v0.4.6
[0.4.5]: https://github.com/anatawa12/AvatarOptimizer/compare/v0.4.4...v0.4.5
[0.4.4]: https://github.com/anatawa12/AvatarOptimizer/compare/v0.4.3...v0.4.4
[0.4.3]: https://github.com/anatawa12/AvatarOptimizer/compare/v0.4.2...v0.4.3
[0.4.2]: https://github.com/anatawa12/AvatarOptimizer/compare/v0.4.1...v0.4.2
Expand Down
4 changes: 2 additions & 2 deletions Editor/MergePhysBoneEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ private static List<ErrorLog> Validate(MergePhysBone mergePhysBone)
{
var list = new List<ErrorLog>();
if (mergePhysBone.makeParent && mergePhysBone.transform.childCount != 0)
list.Add(ErrorLog.Validation("MergePhysBone:error:makeParentWithChildren", mergePhysBone));
list.Add(ErrorLog.Validation("MergePhysBone:error:makeParentWithChildren").WithContext(mergePhysBone));

new MergePhysBoneValidator(list, mergePhysBone).DoProcess();

Expand All @@ -525,7 +525,7 @@ protected override void EndPbConfig() {
if (_differProps.Count != 0)
{
_errorLogs.Add(ErrorLog.Validation("MergePhysBone:error:differValues",
new[] { string.Join(", ", _differProps) }));
string.Join(", ", _differProps)));
}
}

Expand Down
50 changes: 36 additions & 14 deletions Editor/ObjectMapping/ObjectMappingBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,11 @@ public ObjectMappingBuilder([NotNull] GameObject rootObject)
public void RecordMergeComponent<T>(T from, T mergeTo) where T: Component =>
GetComponentInfo(from).MergedTo(GetComponentInfo(mergeTo));

public void RecordMoveProperties(Component from, params (string old, string @new)[] props) =>
GetComponentInfo(from).MoveProperties(props);

public void RecordMoveProperty(Component from, string oldProp, string newProp) =>
GetComponentInfo(from).MoveProperty(oldProp, newProp);
GetComponentInfo(from).MoveProperties((oldProp, newProp));

public void RecordRemoveProperty(Component from, string oldProp) =>
GetComponentInfo(from).RemoveProperty(oldProp);
Expand Down Expand Up @@ -96,26 +99,45 @@ public void MergedTo([NotNull] BuildingComponentInfo mergeTo)
_mergedInto = mergeTo;
}

public void MoveProperty(string oldProp, string newProp)
public void MoveProperties(params (string old, string @new)[] props)
{
foreach (var mergeSource in MergeSources) mergeSource.MoveProperty(oldProp, newProp);
foreach (var mergeSource in MergeSources) mergeSource.MoveProperties(props);

var propertyIds = new int[props.Length];
for (var i = 0; i < props.Length; i++)
{
var (oldProp, newProp) = props[i];
if (_afterPropertyIds.TryGetValue(oldProp, out var propId))
{
propertyIds[i] = propId;
}
else
{
if (!_beforePropertyIds.ContainsKey(oldProp))
{
if (_afterPropertyIds.ContainsKey(newProp) && props.All(x => x.old != newProp))
throw new InvalidOperationException("Merging property");
propertyIds[i] = _nextPropertyId++;
}
}
}

if (_afterPropertyIds.TryGetValue(oldProp, out var propId))
for (var i = 0; i < propertyIds.Length; i++)
{
var propId = propertyIds[i];
var (oldProp, _) = props[i];
if (propId == 0) continue;
_afterPropertyIds.Remove(oldProp);
_afterPropertyIds[newProp] = propId;
if (!_beforePropertyIds.ContainsKey(oldProp))
_beforePropertyIds.Add(oldProp, propId);
}
else

for (var i = 0; i < propertyIds.Length; i++)
{
var propId = propertyIds[i];
var (oldProp, newProp) = props[i];
if (propId == 0) continue;
_afterPropertyIds[newProp] = propId;
if (!_beforePropertyIds.ContainsKey(oldProp))
{
if (_afterPropertyIds.ContainsKey(newProp))
throw new InvalidOperationException("Merging property");
_beforePropertyIds.Add(oldProp, propId = _nextPropertyId++);
_afterPropertyIds.Add(newProp, propId);
}
_beforePropertyIds.Add(oldProp, propId);
}
}

Expand Down
10 changes: 8 additions & 2 deletions Editor/Processors/SkinnedMeshes/MergeSkinnedMeshProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public override void Process(OptimizerSession session, MeshInfo2 target, MeshInf
TexCoordStatus TexCoordStatusMax(TexCoordStatus x, TexCoordStatus y) =>
(TexCoordStatus)Math.Max((int)x, (int)y);

var mappings = new List<(string, string)>();

for (var i = 0; i < meshInfos.Length; i++)
{
var meshInfo = meshInfos[i];
Expand All @@ -47,6 +49,8 @@ TexCoordStatus TexCoordStatusMax(TexCoordStatus x, TexCoordStatus y) =>
for (var j = 0; j < meshInfo.SubMeshes.Count; j++)
target.SubMeshes[subMeshIndexMap[i][j]].Triangles.AddRange(meshInfo.SubMeshes[j].Triangles);

mappings.Clear();

// add blend shape if not defined by name
for (var sourceI = 0; sourceI < meshInfo.BlendShapes.Count; sourceI++)
{
Expand All @@ -58,10 +62,12 @@ TexCoordStatus TexCoordStatusMax(TexCoordStatus x, TexCoordStatus y) =>
target.BlendShapes.Add((name, weight));
}

session.MappingBuilder.RecordMoveProperty(meshInfo.SourceRenderer,
VProp.BlendShapeIndex(sourceI), VProp.BlendShapeIndex(newIndex));
// this can cause merge prop error.
mappings.Add((VProp.BlendShapeIndex(sourceI), VProp.BlendShapeIndex(newIndex)));
}

session.MappingBuilder.RecordMoveProperties(meshInfo.SourceRenderer, mappings.ToArray());

target.Bones.AddRange(meshInfo.Bones);

target.HasColor |= meshInfo.HasColor;
Expand Down
21 changes: 0 additions & 21 deletions Internal/ErrorReporter/Editor/.generate.ts

This file was deleted.

30 changes: 19 additions & 11 deletions Internal/ErrorReporter/Editor/BuildReport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using JetBrains.Annotations;
using UnityEditor;
using UnityEngine;
using VRC.SDK3.Avatars.Components;
Expand Down Expand Up @@ -63,7 +64,7 @@ private static BuildReport LoadReport()
var data = File.ReadAllText(Path);
return JsonUtility.FromJson<BuildReport>(data);
}
catch (Exception e)
catch (Exception)
{
return null;
}
Expand All @@ -76,17 +77,21 @@ internal static void SaveReport()

File.WriteAllText(Path, json);

ErrorReportUI.reloadErrorReport();
ErrorReportUI.ReloadErrorReport();
}

private class AvatarReportScope : IDisposable
{
public void Dispose()
{
var successful = CurrentReport.CurrentAvatar.successful;
var avatar = CurrentReport.CurrentAvatar;
CurrentReport.CurrentAvatar = null;
var successful = avatar.successful;
BuildReport.SaveReport();
ErrorReportUI.MaybeOpenErrorReportUI();
if (avatar.logs.Any())
ErrorReportUI.OpenErrorReportUIFor(avatar);
else
ErrorReportUI.MaybeOpenErrorReportUI();
if (!successful) throw new Exception("Avatar processing failed");
}
}
Expand Down Expand Up @@ -121,24 +126,26 @@ internal AvatarReport Initialize(VRCAvatarDescriptor descriptor)
return report;
}

internal static void Log(ReportLevel level, string code, object[] strings, params Object[] objects)
[CanBeNull]
internal static ErrorLog Log(ReportLevel level, string code, object[] strings)
{
ErrorLog errorLog =
new ErrorLog(level, code, strings: strings.Select(s => s.ToString()).ToArray(), objects);
var errorLog = new ErrorLog(level, code, strings: strings.Select(s => s.ToString()).ToArray());

var avatarReport = CurrentReport.CurrentAvatar;
if (avatarReport == null)
{
Debug.LogWarning("Error logged when not processing an avatar: " + errorLog);
return;
return null;
}

avatarReport.logs.Add(errorLog);
return errorLog;
}

internal static void LogFatal(string code, object[] strings, params Object[] objects)
[CanBeNull]
internal static ErrorLog LogFatal(string code, object[] strings)
{
Log(ReportLevel.Error, code, strings: strings, objects: objects);
var log = Log(ReportLevel.Error, code, strings: strings);
if (CurrentReport.CurrentAvatar != null)
{
CurrentReport.CurrentAvatar.successful = false;
Expand All @@ -147,6 +154,7 @@ internal static void LogFatal(string code, object[] strings, params Object[] obj
{
throw new Exception("Fatal error without error reporting scope");
}
return log;
}

internal static void LogException(Exception e, string additionalStackTrace = "")
Expand Down Expand Up @@ -227,7 +235,7 @@ public static void RemapPaths(string original, string cloned)
}
}

ErrorReportUI.reloadErrorReport();
ErrorReportUI.ReloadErrorReport();
}
}
}
Loading

0 comments on commit 11405af

Please sign in to comment.