mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-28 05:44:48 -05:00
CreateErasedMeshAsync
This commit is contained in:
@@ -131,7 +131,7 @@ namespace UniGLTF.MeshUtility
|
||||
/// <param name="boneWeights"></param>
|
||||
/// <param name="eraseBoneIndices"></param>
|
||||
/// <returns></returns>
|
||||
public static int[] GetExcludedIndices(int[] indices, BoneWeight[] boneWeights, int[] eraseBoneIndices)
|
||||
static int[] GetExcludedIndices(int[] indices, BoneWeight[] boneWeights, int[] eraseBoneIndices)
|
||||
{
|
||||
var count = ExcludeTriangles(indices, boneWeights, eraseBoneIndices);
|
||||
var dst = new int[count];
|
||||
|
||||
@@ -165,6 +165,12 @@ namespace UniGLTF.MeshUtility
|
||||
|
||||
public void Push(SkinnedMeshRenderer renderer)
|
||||
{
|
||||
if (renderer == null)
|
||||
{
|
||||
// Debug.LogWarningFormat("{0} was destroyed", renderer);
|
||||
return;
|
||||
}
|
||||
|
||||
var mesh = renderer.sharedMesh;
|
||||
if (mesh == null)
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace UniVRM10
|
||||
}
|
||||
}
|
||||
|
||||
public static int[] GetBonesThatHasAncestor(SkinnedMeshRenderer smr, Transform ancestor)
|
||||
static int[] GetBonesThatHasAncestor(SkinnedMeshRenderer smr, Transform ancestor)
|
||||
{
|
||||
var eraseBones = smr.bones
|
||||
.Where(x => x.Ancestor().Any(y => y == ancestor))
|
||||
@@ -38,24 +38,46 @@ namespace UniVRM10
|
||||
return eraseBones;
|
||||
}
|
||||
|
||||
public static async Task<Mesh> CreateErasedMeshAsync(SkinnedMeshRenderer smr,
|
||||
Transform firstPersonBone,
|
||||
IAwaitCaller awaitCaller)
|
||||
{
|
||||
var eraseBones = GetBonesThatHasAncestor(smr, firstPersonBone);
|
||||
if (eraseBones.Any())
|
||||
{
|
||||
return await BoneMeshEraser.CreateErasedMeshAsync(smr.sharedMesh, eraseBones, awaitCaller);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// <summary>
|
||||
// 頭部を取り除いたモデルを複製する
|
||||
// </summary>
|
||||
// <parameter>renderer: 元になるSkinnedMeshRenderer</parameter>
|
||||
// <parameter>eraseBones: 削除対象になるボーンのindex</parameter>
|
||||
private async static Task<SkinnedMeshRenderer> CreateHeadlessMeshAsync(SkinnedMeshRenderer renderer, int[] eraseBones, IAwaitCaller awaitCaller)
|
||||
public async static Task<SkinnedMeshRenderer> CreateHeadlessMeshAsync(SkinnedMeshRenderer renderer,
|
||||
Transform firstPersonBone, IAwaitCaller awaitCaller)
|
||||
{
|
||||
var mesh = await BoneMeshEraser.CreateErasedMeshAsync(renderer.sharedMesh, eraseBones, awaitCaller);
|
||||
|
||||
var go = new GameObject("_headless_" + renderer.name);
|
||||
var erased = go.AddComponent<SkinnedMeshRenderer>();
|
||||
erased.enabled = false; // hide
|
||||
erased.sharedMesh = mesh;
|
||||
erased.sharedMaterials = renderer.sharedMaterials;
|
||||
erased.bones = renderer.bones;
|
||||
erased.rootBone = renderer.rootBone;
|
||||
|
||||
return erased;
|
||||
var mesh = await CreateErasedMeshAsync(renderer, firstPersonBone, awaitCaller);
|
||||
if (mesh != null)
|
||||
{
|
||||
var go = new GameObject("_headless_" + renderer.name);
|
||||
var erased = go.AddComponent<SkinnedMeshRenderer>();
|
||||
erased.enabled = false; // hide
|
||||
erased.sharedMesh = mesh;
|
||||
erased.sharedMaterials = renderer.sharedMaterials;
|
||||
erased.bones = renderer.bones;
|
||||
erased.rootBone = renderer.rootBone;
|
||||
return erased;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 削除対象が含まれないので何もしない
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
bool m_done;
|
||||
@@ -70,14 +92,13 @@ namespace UniVRM10
|
||||
{
|
||||
if (x.GetRenderer(go.transform) is SkinnedMeshRenderer smr)
|
||||
{
|
||||
var eraseBones = GetBonesThatHasAncestor(smr, firstPersonBone);
|
||||
if (eraseBones.Any())
|
||||
{
|
||||
// オリジナルのモデルを3人称用にする
|
||||
smr.gameObject.layer = layer.ThirdPersonOnly;
|
||||
// オリジナルのモデルを3人称用にする
|
||||
smr.gameObject.layer = layer.ThirdPersonOnly;
|
||||
|
||||
// 頭を取り除いた複製モデルを作成し、1人称用にする
|
||||
var headless = await CreateHeadlessMeshAsync(smr, eraseBones, awaitCaller);
|
||||
// 頭を取り除いた複製モデルを作成し、1人称用にする
|
||||
var headless = await CreateHeadlessMeshAsync(smr, firstPersonBone, awaitCaller);
|
||||
if (headless != null)
|
||||
{
|
||||
headless.gameObject.layer = layer.FirstPersonOnly;
|
||||
headless.transform.SetParent(smr.transform, false);
|
||||
if (runtime != null)
|
||||
@@ -85,10 +106,6 @@ namespace UniVRM10
|
||||
runtime.AddRenderer(headless);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 削除対象が含まれないので何もしない
|
||||
}
|
||||
}
|
||||
else if (x.GetRenderer(go.transform) is MeshRenderer mr)
|
||||
{
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UniGLTF;
|
||||
using UniGLTF.Extensions.VRMC_vrm;
|
||||
using UniGLTF.MeshUtility;
|
||||
using UniHumanoid;
|
||||
using UnityEngine;
|
||||
@@ -122,6 +120,10 @@ namespace UniVRM10
|
||||
|
||||
void RemoveComponent<T>(T c) where T : Component
|
||||
{
|
||||
if (c == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var t = c.transform;
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
@@ -225,12 +227,40 @@ namespace UniVRM10
|
||||
|
||||
{
|
||||
// TODO: UNDO
|
||||
var results = new List<MeshIntegrationResult>();
|
||||
foreach (var group in copy)
|
||||
{
|
||||
var result = MeshIntegrator.Integrate(group, SplitByBlendShape
|
||||
? MeshIntegrator.BlendShapeOperation.Split
|
||||
: MeshIntegrator.BlendShapeOperation.None);
|
||||
results.Add(result);
|
||||
|
||||
result.AddIntegratedRendererTo(go);
|
||||
|
||||
if (generateFirstPerson && group.Name == "auto")
|
||||
{
|
||||
Debug.Log("generateFirstPerson");
|
||||
var firstPersonBone = vrmInstance.Humanoid.Head;
|
||||
var task = VRM10ObjectFirstPerson.CreateErasedMeshAsync(
|
||||
result.IntegratedRenderer,
|
||||
firstPersonBone,
|
||||
new ImmediateCaller());
|
||||
task.Wait();
|
||||
|
||||
if (task.Result != null)
|
||||
{
|
||||
result.IntegratedRenderer.sharedMesh = task.Result;
|
||||
result.IntegratedRenderer.name = "auto.headless";
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("no result");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var result in results)
|
||||
{
|
||||
foreach (var r in result.SourceMeshRenderers)
|
||||
{
|
||||
RemoveComponent(r);
|
||||
@@ -239,27 +269,6 @@ namespace UniVRM10
|
||||
{
|
||||
RemoveComponent(r);
|
||||
}
|
||||
|
||||
result.AddIntegratedRendererTo(go);
|
||||
|
||||
if (generateFirstPerson && group.Name == "auto")
|
||||
{
|
||||
var firstPersonBone = vrmInstance.Humanoid.Head;
|
||||
var eraseBones = VRM10ObjectFirstPerson.GetBonesThatHasAncestor(
|
||||
result.IntegratedRenderer, firstPersonBone);
|
||||
var task = BoneMeshEraser.CreateErasedMeshAsync(result.MeshMap.Integrated, eraseBones,
|
||||
new ImmediateCaller());
|
||||
task.Wait();
|
||||
|
||||
if (task.Result.vertexCount > 0)
|
||||
{
|
||||
var headless = new GameObject("auto.headless");
|
||||
var smr = headless.AddComponent<SkinnedMeshRenderer>();
|
||||
smr.sharedMesh = task.Result;
|
||||
|
||||
headless.transform.SetParent(go.transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user