mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-07-27 21:18:00 -05:00
Merge pull request #2685 from notargs/use_materials
MaterialValueBindingMergerについて、sharedMaterialsではなくmaterialsを使用するように変更
This commit is contained in:
commit
cff9aa75b7
|
|
@ -61,7 +61,7 @@ namespace UniGLTF
|
|||
context.AddObjectToAsset(k.Name, o);
|
||||
});
|
||||
var root = loaded.Root;
|
||||
GameObject.DestroyImmediate(loaded);
|
||||
DestroyImmediate(loaded);
|
||||
|
||||
context.AddObjectToAsset(root.name, root);
|
||||
context.SetMainObject(root);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ namespace UniGLTF
|
|||
/// ImporterContext の Load 結果の GltfModel
|
||||
///
|
||||
/// Runtime でモデルを Destory したときに関連リソース(Texture, Material...などの UnityEngine.Object)を自動的に Destroy する。
|
||||
///
|
||||
/// TODO: Editor Importの場合でも一瞬だけこのクラスのインスタンスが生じるが、すぐDestroyImmediateされるため、それらを区別する用途に使うことができる
|
||||
/// Editorでも利用されている以上、名前・責務が良くないので見直したい。
|
||||
///
|
||||
/// </summary>
|
||||
public class RuntimeGltfInstance : MonoBehaviour, IResponsibilityForDestroyObjects
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
|
|
@ -8,7 +9,7 @@ namespace UniVRM10
|
|||
/// <summary>
|
||||
/// ブレンドシェイプを蓄えてまとめて適用するクラス
|
||||
/// </summary>
|
||||
internal sealed class ExpressionMerger
|
||||
internal sealed class ExpressionMerger : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Key から Expression を得る
|
||||
|
|
@ -24,7 +25,7 @@ namespace UniVRM10
|
|||
MaterialValueBindingMerger m_materialValueBindingMerger;
|
||||
|
||||
|
||||
public ExpressionMerger(VRM10ObjectExpression expressions, Transform root)
|
||||
public ExpressionMerger(VRM10ObjectExpression expressions, Transform root, bool isPrefabInstance)
|
||||
{
|
||||
m_clipMap = expressions.Clips.ToDictionary(
|
||||
x => expressions.CreateKey(x.Clip),
|
||||
|
|
@ -33,7 +34,7 @@ namespace UniVRM10
|
|||
);
|
||||
m_valueMap = new Dictionary<ExpressionKey, float>(ExpressionKey.Comparer);
|
||||
m_morphTargetBindingMerger = new MorphTargetBindingMerger(m_clipMap, root);
|
||||
m_materialValueBindingMerger = new MaterialValueBindingMerger(m_clipMap, root);
|
||||
m_materialValueBindingMerger = new MaterialValueBindingMerger(m_clipMap, root, isPrefabInstance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -74,5 +75,10 @@ namespace UniVRM10
|
|||
{
|
||||
m_materialValueBindingMerger.RestoreMaterialInitialValues();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
m_materialValueBindingMerger.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,14 @@ using System.Collections.Generic;
|
|||
using UniGLTF.Extensions.VRMC_vrm;
|
||||
using UnityEngine;
|
||||
using VRM10.MToon10;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace UniVRM10
|
||||
{
|
||||
///
|
||||
/// Base + (A.Target - Base) * A.Weight + (B.Target - Base) * B.Weight ...
|
||||
///
|
||||
internal sealed class MaterialValueBindingMerger
|
||||
internal sealed class MaterialValueBindingMerger : IDisposable
|
||||
{
|
||||
private static readonly string COLOR_PROPERTY = MToon10Prop.BaseColorFactor.ToUnityShaderLabName();
|
||||
private static readonly string EMISSION_COLOR_PROPERTY = MToon10Prop.EmissiveFactor.ToUnityShaderLabName();
|
||||
|
|
@ -18,6 +19,8 @@ namespace UniVRM10
|
|||
private static readonly string SHADE_COLOR_PROPERTY = MToon10Prop.ShadeColorFactor.ToUnityShaderLabName();
|
||||
private static readonly string MATCAP_COLOR_PROPERTY = MToon10Prop.MatcapColorFactor.ToUnityShaderLabName();
|
||||
|
||||
private readonly HashSet<Material> _clonedMaterials = new();
|
||||
|
||||
public static string GetProperty(MaterialColorType bindType)
|
||||
{
|
||||
switch (bindType)
|
||||
|
|
@ -50,16 +53,44 @@ namespace UniVRM10
|
|||
/// </summary>
|
||||
Dictionary<string, PreviewMaterialItem> m_materialMap = new Dictionary<string, PreviewMaterialItem>();
|
||||
|
||||
void InitializeMaterialMap(Dictionary<ExpressionKey, VRM10Expression> clipMap, Transform root)
|
||||
void InitializeMaterialMap(Dictionary<ExpressionKey, VRM10Expression> clipMap, Transform root, bool isPrefabInstance)
|
||||
{
|
||||
Dictionary<string, Material> materialNameMap = new Dictionary<string, Material>();
|
||||
var materialNameMap = new Dictionary<string, Material>();
|
||||
foreach (var renderer in root.GetComponentsInChildren<Renderer>())
|
||||
{
|
||||
foreach (var material in renderer.sharedMaterials)
|
||||
// VFXRendererなど、Materialが設定できないRendererが存在する
|
||||
if (renderer is not SkinnedMeshRenderer && renderer is not MeshRenderer) continue;
|
||||
|
||||
if (isPrefabInstance)
|
||||
{
|
||||
if (material != null && !materialNameMap.ContainsKey(material.name))
|
||||
// EditorImportされたPrefabのInstanceとして生成されている場合、Materialを複製する
|
||||
var sharedMaterials = renderer.sharedMaterials;
|
||||
var materials = renderer.materials;
|
||||
for (var i = 0; i < materials.Length; i++)
|
||||
{
|
||||
materialNameMap.Add(material.name, material);
|
||||
var sharedMaterial = sharedMaterials[i];
|
||||
var material = materials[i];
|
||||
|
||||
if (!sharedMaterial || !material) continue;
|
||||
|
||||
// 複製されたマテリアルはこのクラス内で破棄
|
||||
if (sharedMaterial != material) _clonedMaterials.Add(material);
|
||||
|
||||
// 複製前の名前に揃え、それを記録しておく
|
||||
// なお、Vrm10Runtimeのインスタンスが作られるより先にユーザーによってMaterialが複製されるパターンは想定しない
|
||||
material.name = sharedMaterial.name;
|
||||
materialNameMap.TryAdd(sharedMaterial.name, material);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// PrefabのInstanceでない(RuntimeImportされている)ならMaterialは複製しない
|
||||
foreach (var material in renderer.sharedMaterials)
|
||||
{
|
||||
if (material)
|
||||
{
|
||||
materialNameMap.TryAdd(material.name, material);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -284,9 +315,18 @@ namespace UniVRM10
|
|||
}
|
||||
#endregion
|
||||
|
||||
public MaterialValueBindingMerger(Dictionary<ExpressionKey, VRM10Expression> clipMap, Transform root)
|
||||
public MaterialValueBindingMerger(Dictionary<ExpressionKey, VRM10Expression> clipMap, Transform root, bool isPrefabInstance)
|
||||
{
|
||||
InitializeMaterialMap(clipMap, root);
|
||||
InitializeMaterialMap(clipMap, root, isPrefabInstance);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var clonedMaterial in _clonedMaterials)
|
||||
{
|
||||
Object.Destroy(clonedMaterial);
|
||||
}
|
||||
_clonedMaterials.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,8 +141,11 @@ namespace UniVRM10
|
|||
}
|
||||
|
||||
var initPose = RuntimeGltfInstance.SafeGetInitialPose(transform);
|
||||
|
||||
// NOTE: RuntimeGltfInstanceがないかどうかでPrefabのインスタンスであるか(EditorImportされているか)が判別できる
|
||||
var isPrefabInstance = !GetComponent<RuntimeGltfInstance>();
|
||||
|
||||
return new Vrm10Runtime(this, useControlRig, m_springBoneRuntime, initPose);
|
||||
return new Vrm10Runtime(this, useControlRig, m_springBoneRuntime, initPose, isPrefabInstance);
|
||||
}
|
||||
|
||||
public Vrm10Runtime Runtime
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ namespace UniVRM10
|
|||
IReadOnlyDictionary<Transform, TransformState> _initPose;
|
||||
|
||||
public Vrm10Runtime(Vrm10Instance instance, bool useControlRig, IVrm10SpringBoneRuntime springBoneRuntime,
|
||||
IReadOnlyDictionary<Transform, TransformState> initPose)
|
||||
IReadOnlyDictionary<Transform, TransformState> initPose, bool isPrefabInstance)
|
||||
{
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
|
|
@ -77,7 +77,7 @@ namespace UniVRM10
|
|||
}
|
||||
Constraints = instance.GetComponentsInChildren<IVrm10Constraint>();
|
||||
LookAt = new Vrm10RuntimeLookAt(instance, instance.Humanoid, ControlRig);
|
||||
Expression = new Vrm10RuntimeExpression(instance, LookAt.EyeDirectionApplicable);
|
||||
Expression = new Vrm10RuntimeExpression(instance, LookAt.EyeDirectionApplicable, isPrefabInstance);
|
||||
SpringBone = springBoneRuntime;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ namespace UniVRM10
|
|||
public float LookAtOverrideRate { get; private set; }
|
||||
public float MouthOverrideRate { get; private set; }
|
||||
|
||||
internal Vrm10RuntimeExpression(Vrm10Instance target, ILookAtEyeDirectionApplicable eyeDirectionApplicable)
|
||||
internal Vrm10RuntimeExpression(Vrm10Instance target, ILookAtEyeDirectionApplicable eyeDirectionApplicable, bool isPrefabInstance)
|
||||
{
|
||||
_merger = new ExpressionMerger(target.Vrm.Expression, target.transform);
|
||||
_merger = new ExpressionMerger(target.Vrm.Expression, target.transform, isPrefabInstance);
|
||||
_keys = target.Vrm.Expression.Clips
|
||||
.Select(x => target.Vrm.Expression.CreateKey(x.Clip))
|
||||
.ToList();
|
||||
|
|
@ -56,6 +56,9 @@ namespace UniVRM10
|
|||
|
||||
_eyeDirectionApplicable?.Restore();
|
||||
_eyeDirectionApplicable = null;
|
||||
|
||||
_merger?.Dispose();
|
||||
_merger = null;
|
||||
}
|
||||
|
||||
internal void Process(LookAtEyeDirection inputEyeDirection)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user