Merge pull request #14 from dwango/work_v039

Work v039
This commit is contained in:
ousttrue
2018-07-18 20:10:49 +09:00
committed by GitHub
14 changed files with 318 additions and 136 deletions

View File

@@ -25,7 +25,7 @@ namespace VRM
[SerializeField]
float m_closeSeconds = 0.1f;
Coroutine m_coroutine;
protected Coroutine m_coroutine;
//static readonly string BLINK_NAME = BlendShapePreset.Blink.ToString();
@@ -45,7 +45,7 @@ namespace VRM
}
}
IEnumerator BlinkRoutine()
protected IEnumerator BlinkRoutine()
{
while (true)
{

View File

@@ -84,7 +84,7 @@ namespace VRM
{
if (m_scene != null)
{
Debug.Log("Bake");
//Debug.Log("Bake");
m_scene.Bake(values, materialValues, weight);
}
}

View File

@@ -59,7 +59,7 @@ public class VRMTest
exporter.Export();
// import
context.Json = gltf.ToJson();
context.ParseJson<glTF_VRM>(gltf.ToJson(), new SimpleStorage());
Debug.LogFormat("{0}", context.Json);
gltfImporter.Import<glTF>(context);

View File

@@ -100,7 +100,7 @@ namespace VRM
}).ToArray();
}
foreach (var src in secondary.GetComponents<VRMSpringBone>())
foreach (var src in go.transform.Traverse().SelectMany(x => x.GetComponents<VRMSpringBone>()))
{
var dst = dstSecondary.gameObject.AddComponent<VRMSpringBone>();
dst.m_comment = src.m_comment;

View File

@@ -6,6 +6,7 @@ using UnityEditor;
namespace VRM
{
#if !VRM_STOP_ASSETPOSTPROCESSOR
public class vrmAssetPostprocessor : AssetPostprocessor
{
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
@@ -59,4 +60,5 @@ namespace VRM
}
}
}
#endif
}

View File

@@ -16,7 +16,13 @@ namespace VRM
{
var gltf = new glTF_VRM();
gltf.asset.generator = string.Format("UniVRM-{0}.{1}", VRMVersion.MAJOR, VRMVersion.MINOR);
using (var exporter = new VRMExporter(gltf))
using (var exporter = new VRMExporter(gltf)
{
#if VRM_EXPORTER_USE_SPARSE
// experimental
UseSparseAccessorForBlendShape=true
#endif
})
{
_Export(gltf, exporter, go);
@@ -99,60 +105,10 @@ namespace VRM
}
// secondary
var secondary = exporter.Copy.transform.Find("secondary");
if (secondary == null)
{
secondary = exporter.Copy.transform;
}
var colliders = new List<VRMSpringBoneColliderGroup>();
foreach (var vrmColliderGroup in exporter.Copy.transform.Traverse().Select(x => x.GetComponent<VRMSpringBoneColliderGroup>()).Where(x => x != null))
{
colliders.Add(vrmColliderGroup);
var colliderGroup = new glTF_VRM_SecondaryAnimationColliderGroup
{
node = exporter.Nodes.IndexOf(vrmColliderGroup.transform)
};
colliderGroup.colliders = vrmColliderGroup.Colliders.Select(x =>
{
return new glTF_VRM_SecondaryAnimationCollider
{
offset = x.Offset,
radius = x.Radius,
};
}).ToList();
gltf.extensions.VRM.secondaryAnimation.colliderGroups.Add(colliderGroup);
}
foreach (var spring in secondary.GetComponents<VRMSpringBone>())
{
gltf.extensions.VRM.secondaryAnimation.boneGroups.Add(new glTF_VRM_SecondaryAnimationGroup
{
comment = spring.m_comment,
center = exporter.Nodes.IndexOf(spring.m_center),
dragForce = spring.m_dragForce,
gravityDir = spring.m_gravityDir,
gravityPower = spring.m_gravityPower,
stiffiness = spring.m_stiffnessForce,
hitRadius = spring.m_hitRadius,
colliderGroups = spring.ColliderGroups
.Select(x =>
{
var index = colliders.IndexOf(x);
if (index == -1)
{
throw new IndexOutOfRangeException();
}
return index;
})
.ToArray(),
bones = spring.RootBones.Select(x => exporter.Nodes.IndexOf(x)).ToArray(),
});
}
VRMSpringUtility.ExportSecondary(exporter.Copy.transform, exporter.Nodes,
x => gltf.extensions.VRM.secondaryAnimation.colliderGroups.Add(x),
x => gltf.extensions.VRM.secondaryAnimation.boneGroups.Add(x)
);
// meta(obsolete)
{

View File

@@ -78,8 +78,8 @@ namespace VRM
public static CreateMaterialFunc GetMaterialFunc(List<glTF_VRM_Material> materials)
{
var CreateDefault = gltfImporter.CreateMaterialFuncFromShader(Shader.Find("VRM/UnlitTexture"));
var CreateZWrite = gltfImporter.CreateMaterialFuncFromShader(Shader.Find("VRM/UnlitTransparentZWrite"));
var CreateDefault = gltfImporter.CreateMaterialFuncFromShader(new ShaderStore("VRM/UnlitTexture"));
var CreateZWrite = gltfImporter.CreateMaterialFuncFromShader(new ShaderStore("VRM/UnlitTransparentZWrite"));
CreateMaterialFunc fallback = (ctx, i) =>
{
var vrm = ctx.GLTF as glTF_VRM;
@@ -183,7 +183,8 @@ namespace VRM
}
LoadBlendShapeMaster(context);
LoadSecondaryMotions(context);
VRMSpringUtility.LoadSecondary(context.Root.transform, context.Nodes,
context.VRM.extensions.VRM.secondaryAnimation);
LoadFirstPerson(context);
return Unit.Default;
@@ -230,59 +231,6 @@ namespace VRM
lookAtHead.OnImported(context);
}
static void LoadSecondaryMotions(VRMImporterContext context)
{
var secondary = context.Root.transform.Find("secondary");
if (secondary == null)
{
secondary = new GameObject("secondary").transform;
secondary.SetParent(context.Root.transform, false);
}
var secondaryAnimation = context.VRM.extensions.VRM.secondaryAnimation;
var colliders = new List<VRMSpringBoneColliderGroup>();
foreach (var colliderGroup in secondaryAnimation.colliderGroups)
{
var vrmGroup = context.Nodes[colliderGroup.node].gameObject.AddComponent<VRMSpringBoneColliderGroup>();
vrmGroup.Colliders = colliderGroup.colliders.Select(x =>
{
return new VRMSpringBoneColliderGroup.SphereCollider
{
Offset = x.offset,
Radius = x.radius
};
}).ToArray();
colliders.Add(vrmGroup);
}
if (secondaryAnimation.boneGroups.Count > 0)
{
foreach (var boneGroup in secondaryAnimation.boneGroups)
{
var vrmBoneGroup = secondary.gameObject.AddComponent<VRMSpringBone>();
if (boneGroup.center != -1)
{
vrmBoneGroup.m_center = context.Nodes[boneGroup.center];
}
vrmBoneGroup.m_comment = boneGroup.comment;
vrmBoneGroup.m_dragForce = boneGroup.dragForce;
vrmBoneGroup.m_gravityDir = boneGroup.gravityDir;
vrmBoneGroup.m_gravityPower = boneGroup.gravityPower;
vrmBoneGroup.m_hitRadius = boneGroup.hitRadius;
vrmBoneGroup.m_stiffnessForce = boneGroup.stiffiness;
if (boneGroup.colliderGroups != null && boneGroup.colliderGroups.Any())
{
vrmBoneGroup.ColliderGroups = boneGroup.colliderGroups.Select(x => colliders[x]).ToArray();
}
vrmBoneGroup.RootBones = boneGroup.bones.Select(x => context.Nodes[x]).ToList();
}
}
else
{
secondary.gameObject.AddComponent<VRMSpringBone>();
}
}
static void LoadBlendShapeMaster(VRMImporterContext context)
{
context.BlendShapeAvatar = ScriptableObject.CreateInstance<BlendShapeAvatar>();
@@ -457,12 +405,12 @@ namespace VRM
#endregion
#region LoadVrmAsync
static IEnumerator LoadTextures(VRMImporterContext context)
static IEnumerator LoadTextures(VRMImporterContext context, IStorage storage)
{
for(int i=0; i<context.GLTF.textures.Count; ++i)
for (int i = 0; i < context.GLTF.textures.Count; ++i)
{
var x = new TextureItem(context.GLTF, i);
x.Process();
x.Process(context.GLTF, storage);
context.Textures.Add(x);
yield return null;
}
@@ -561,24 +509,28 @@ namespace VRM
}
#endif
public static void LoadVrmAsync(string path, Action<GameObject> onLoaded)
public static void LoadVrmAsync(string path, Action<GameObject> onLoaded, Action<Exception> onError = null)
{
var context = new VRMImporterContext(path);
context.ParseVrm(File.ReadAllBytes(path));
LoadVrmAsync(context, onLoaded);
LoadVrmAsync(context, onLoaded, onError);
}
public static void LoadVrmAsync(Byte[] bytes, Action<GameObject> onLoaded)
public static void LoadVrmAsync(Byte[] bytes, Action<GameObject> onLoaded, Action<Exception> onError = null)
{
var context = new VRMImporterContext();
context.ParseVrm(bytes);
LoadVrmAsync(context, onLoaded);
LoadVrmAsync(context, onLoaded, onError);
}
public static void LoadVrmAsync(VRMImporterContext ctx, Action<GameObject> onLoaded)
public static void LoadVrmAsync(VRMImporterContext ctx, Action<GameObject> onLoaded, Action<Exception> onError = null)
{
if (onError == null)
{
onError = Debug.LogError;
}
LoadVrmAsyncInternal(ctx)
.Subscribe(Scheduler.MainThread, onLoaded, Debug.LogError);
.Subscribe(Scheduler.MainThread, onLoaded, onError);
}
private static Schedulable<GameObject> LoadVrmAsyncInternal(VRMImporterContext ctx)
@@ -610,7 +562,7 @@ namespace VRM
() =>
{
var texture = new TextureItem(ctx.GLTF, index);
texture.Process();
texture.Process(ctx.GLTF, ctx.Storage);
return texture;
})
.ContinueWith(Scheduler.ThreadPool, x => ctx.Textures.Add(x));

View File

@@ -58,7 +58,7 @@ namespace VRM
if(gltfMeta.texture >= 0 && gltfMeta.texture < VRM.textures.Count)
{
var t = new TextureItem(VRM, gltfMeta.texture);
t.Process();
t.Process(VRM, Storage);
meta.Thumbnail=t.Texture;
}
}

View File

@@ -4,11 +4,11 @@ namespace VRM
public static partial class VRMVersion
{
public const int MAJOR = 0;
public const int MINOR = 38;
public const int MINOR = 39;
public const string VERSION = "0.38";
public const string VERSION = "0.39";
public const string DecrementMenuName = "VRM/Version(0.38) Decrement";
public const string IncrementMenuName = "VRM/Version(0.38) Increment";
public const string DecrementMenuName = "VRM/Version(0.39) Decrement";
public const string IncrementMenuName = "VRM/Version(0.39) Increment";
}
}

View File

@@ -10,6 +10,7 @@ using UnityEditor;
namespace VRM
{
[Serializable]
public class glTF_VRM_Material : UniGLTF.JsonSerializableBase
{
public string name;
@@ -98,7 +99,7 @@ namespace VRM
return materials;
}
public static glTF_VRM_Material CreateFromMaterial(Material m, List<Texture2D> textures)
public static glTF_VRM_Material CreateFromMaterial(Material m, List<Texture> textures)
{
var material = new glTF_VRM_Material
{
@@ -131,7 +132,7 @@ namespace VRM
case ShaderUtil.ShaderPropertyType.TexEnv:
{
var texture = m.GetTexture(name) as Texture2D;
var texture = m.GetTexture(name);
if (texture != null)
{
var value = textures.IndexOf(texture);

View File

@@ -170,7 +170,30 @@ namespace VRM
{
mesh.SetIndices(srcMesh.GetIndices(i), srcMesh.GetTopology(i), i);
}
mesh.boneWeights = srcMesh.boneWeights;
// boneweights
var bones = srcRenderer.bones.Select(x => boneMap[x]).ToArray();
if (bones.Length > 0)
{
mesh.boneWeights = srcMesh.boneWeights;
}
else
{
Debug.LogFormat("no weight: {0}", srcMesh.name);
bones = new[] { boneMap[srcRenderer.transform] };
var bw = new BoneWeight
{
boneIndex0 = 0,
boneIndex1 = 0,
boneIndex2 = 0,
boneIndex3 = 0,
weight0 = 1.0f,
weight1 = 0.0f,
weight2 = 0.0f,
weight3 = 0.0f,
};
mesh.boneWeights = Enumerable.Range(0, srcMesh.vertexCount).Select(x => bw).ToArray();
}
var meshVertices = mesh.vertices;
var meshNormals = mesh.normals;
@@ -270,7 +293,6 @@ namespace VRM
}
// recalc bindposes
var bones = srcRenderer.bones.Select(x => boneMap[x]).ToArray();
mesh.bindposes = bones.Select(x =>
x.worldToLocalMatrix * dst.transform.localToWorldMatrix).ToArray();

View File

@@ -0,0 +1,237 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UniGLTF;
using UnityEngine;
using System.IO;
using System.Text;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace VRM
{
public static class VRMSpringUtility
{
#if UNITY_EDITOR
#region save
[MenuItem("VRM/SaveSpringBoneToJSON", validate = true)]
static bool SaveSpringBoneToJSONIsEnable()
{
var root = Selection.activeObject as GameObject;
if (root == null)
{
return false;
}
var animator = root.GetComponent<Animator>();
if (animator == null)
{
return false;
}
return true;
}
[MenuItem("VRM/SaveSpringBoneToJSON")]
static void SaveSpringBoneToJSON()
{
var path = EditorUtility.SaveFilePanel(
"Save spring to json",
null,
"VRMSpring.json",
"json");
if (string.IsNullOrEmpty(path))
{
return;
}
var go = Selection.activeObject as GameObject;
var root = go.transform;
var nodes = root.Traverse().Skip(1).ToList();
var spring = new glTF_VRM_SecondaryAnimation();
ExportSecondary(root, nodes,
spring.colliderGroups.Add,
spring.boneGroups.Add
);
File.WriteAllText(path, spring.ToJson(), Encoding.UTF8);
}
#endregion
#region load
[MenuItem("VRM/LoadSpringBoneFromJSON", true)]
static bool LoadSpringBoneFromJSONIsEnable()
{
var root = Selection.activeObject as GameObject;
if (root == null)
{
return false;
}
var animator = root.GetComponent<Animator>();
if (animator == null)
{
return false;
}
return true;
}
[MenuItem("VRM/LoadSpringBoneFromJSON")]
static void LoadSpringBoneFromJSON()
{
var path = EditorUtility.OpenFilePanel(
"Load spring from json",
null,
"json");
if (string.IsNullOrEmpty(path))
{
return;
}
var json = File.ReadAllText(path, Encoding.UTF8);
var spring = JsonUtility.FromJson<glTF_VRM_SecondaryAnimation>(json);
var go = Selection.activeObject as GameObject;
var root = go.transform;
var nodes = root.Traverse().Skip(1).ToList();
LoadSecondary(root, nodes, spring);
}
#endregion
#endif
public static void ExportSecondary(Transform root, List<Transform> nodes,
Action<glTF_VRM_SecondaryAnimationColliderGroup> addSecondaryColliderGroup,
Action<glTF_VRM_SecondaryAnimationGroup> addSecondaryGroup)
{
var colliders = new List<VRMSpringBoneColliderGroup>();
foreach (var vrmColliderGroup in root.Traverse()
.Select(x => x.GetComponent<VRMSpringBoneColliderGroup>())
.Where(x => x != null))
{
colliders.Add(vrmColliderGroup);
var colliderGroup = new glTF_VRM_SecondaryAnimationColliderGroup
{
node = nodes.IndexOf(vrmColliderGroup.transform)
};
colliderGroup.colliders = vrmColliderGroup.Colliders.Select(x =>
{
return new glTF_VRM_SecondaryAnimationCollider
{
offset = x.Offset,
radius = x.Radius,
};
}).ToList();
addSecondaryColliderGroup(colliderGroup);
}
foreach (var spring in root.Traverse()
.SelectMany(x => x.GetComponents<VRMSpringBone>())
.Where(x => x != null))
{
addSecondaryGroup(new glTF_VRM_SecondaryAnimationGroup
{
comment = spring.m_comment,
center = nodes.IndexOf(spring.m_center),
dragForce = spring.m_dragForce,
gravityDir = spring.m_gravityDir,
gravityPower = spring.m_gravityPower,
stiffiness = spring.m_stiffnessForce,
hitRadius = spring.m_hitRadius,
colliderGroups = spring.ColliderGroups
.Select(x =>
{
var index = colliders.IndexOf(x);
if (index == -1)
{
throw new IndexOutOfRangeException();
}
return index;
})
.ToArray(),
bones = spring.RootBones.Select(x => nodes.IndexOf(x)).ToArray(),
});
}
}
public static void LoadSecondary(Transform root, List<Transform> nodes,
glTF_VRM_SecondaryAnimation secondaryAnimation)
{
var secondary = root.Find("secondary");
if (secondary == null)
{
secondary = new GameObject("secondary").transform;
secondary.SetParent(root, false);
}
// clear components
var remove = root.Traverse()
.SelectMany(x => x.GetComponents<Component>())
.Where(x => x is VRMSpringBone || x is VRMSpringBoneColliderGroup)
.ToArray();
foreach(var x in remove)
{
if (Application.isPlaying)
{
GameObject.Destroy(x);
}
else
{
GameObject.DestroyImmediate(x);
}
}
//var secondaryAnimation = context.VRM.extensions.VRM.secondaryAnimation;
var colliders = new List<VRMSpringBoneColliderGroup>();
foreach (var colliderGroup in secondaryAnimation.colliderGroups)
{
var vrmGroup = nodes[colliderGroup.node].gameObject.AddComponent<VRMSpringBoneColliderGroup>();
vrmGroup.Colliders = colliderGroup.colliders.Select(x =>
{
return new VRMSpringBoneColliderGroup.SphereCollider
{
Offset = x.offset,
Radius = x.radius
};
}).ToArray();
colliders.Add(vrmGroup);
}
if (secondaryAnimation.boneGroups.Count > 0)
{
foreach (var boneGroup in secondaryAnimation.boneGroups)
{
var vrmBoneGroup = secondary.gameObject.AddComponent<VRMSpringBone>();
if (boneGroup.center != -1)
{
vrmBoneGroup.m_center = nodes[boneGroup.center];
}
vrmBoneGroup.m_comment = boneGroup.comment;
vrmBoneGroup.m_dragForce = boneGroup.dragForce;
vrmBoneGroup.m_gravityDir = boneGroup.gravityDir;
vrmBoneGroup.m_gravityPower = boneGroup.gravityPower;
vrmBoneGroup.m_hitRadius = boneGroup.hitRadius;
vrmBoneGroup.m_stiffnessForce = boneGroup.stiffiness;
if (boneGroup.colliderGroups != null && boneGroup.colliderGroups.Any())
{
vrmBoneGroup.ColliderGroups = boneGroup.colliderGroups.Select(x => colliders[x]).ToArray();
}
vrmBoneGroup.RootBones = boneGroup.bones.Select(x => nodes[x]).ToList();
}
}
else
{
secondary.gameObject.AddComponent<VRMSpringBone>();
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 42564d357aca11d4882ab504d7f99166
timeCreated: 1528358605
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Submodule UniGLTF updated: c8b19d3b83...1d41ff08c2