diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfExportSettings.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfExportSettings.cs
index 6ab2be85e..b29f85d82 100644
--- a/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfExportSettings.cs
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/GltfExportSettings.cs
@@ -40,5 +40,10 @@ namespace UniGLTF
/// VRMC_materials_hdr_emissiveMultiplier
///
public bool UseEmissiveMultiplier;
+
+ ///
+ /// Keep VertexColor
+ ///
+ public bool KeepVertexColor;
}
}
diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportUtil.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportUtil.cs
index 2f888df29..b090f71ab 100644
--- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportUtil.cs
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExportUtil.cs
@@ -68,6 +68,7 @@ namespace UniGLTF
readonly List m_positions;
readonly List m_normals;
readonly List m_uv;
+ readonly List m_color;
readonly Func m_getJointIndex;
readonly List m_joints;
@@ -78,6 +79,7 @@ namespace UniGLTF
m_positions = new List(vertexCount);
m_normals = new List(vertexCount);
m_uv = new List();
+ m_color = new List();
m_getJointIndex = getJointIndex;
if (m_getJointIndex != null)
@@ -87,7 +89,7 @@ namespace UniGLTF
}
}
- public void Push(int index, Vector3 position, Vector3 normal, Vector2 uv)
+ public void PushVertex(int index, Vector3 position, Vector3 normal, Vector2 uv)
{
var newIndex = m_positions.Count;
m_vertexIndexMap.Add(index, newIndex);
@@ -97,7 +99,12 @@ namespace UniGLTF
m_uv.Add(uv);
}
- public void Push(BoneWeight boneWeight)
+ public void PushColor(Vector4 color)
+ {
+ m_color.Add(color);
+ }
+
+ public void PushBoneWeight(BoneWeight boneWeight)
{
m_joints.Add(new UShort4((ushort)boneWeight.boneIndex0, (ushort)boneWeight.boneIndex1, (ushort)boneWeight.boneIndex2, (ushort)boneWeight.boneIndex3));
m_weights.Add(new Vector4(boneWeight.weight0, boneWeight.weight1, boneWeight.weight2, boneWeight.weight3));
@@ -123,6 +130,12 @@ namespace UniGLTF
weightAccessorIndex = data.ExtendBufferAndGetAccessorIndex(m_weights.ToArray(), glBufferTarget.ARRAY_BUFFER);
}
+ int? vertexColorIndex = default;
+ if (m_color.Count == m_positions.Count)
+ {
+ vertexColorIndex = data.ExtendBufferAndGetAccessorIndex(m_color.ToArray(), glBufferTarget.ARRAY_BUFFER);
+ }
+
var primitive = new glTFPrimitives
{
indices = indicesAccessorIndex,
@@ -133,6 +146,7 @@ namespace UniGLTF
TEXCOORD_0 = uvAccessorIndex0,
JOINTS_0 = jointsAccessorIndex.GetValueOrDefault(-1),
WEIGHTS_0 = weightAccessorIndex.GetValueOrDefault(-1),
+ COLOR_0 = vertexColorIndex.GetValueOrDefault(-1),
},
material = materialIndex,
mode = 4,
diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_DividedVertexBuffer.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_DividedVertexBuffer.cs
index 9e3ce0588..f3b65e5f0 100644
--- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_DividedVertexBuffer.cs
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_DividedVertexBuffer.cs
@@ -34,6 +34,7 @@ namespace UniGLTF
var normals = mesh.normals;
var uv = mesh.uv;
var boneWeights = mesh.boneWeights;
+ var colors = mesh.colors;
Func getJointIndex = null;
if (boneWeights != null && boneWeights.Length == positions.Length)
@@ -44,25 +45,40 @@ namespace UniGLTF
Vector3[] blendShapePositions = new Vector3[mesh.vertexCount];
Vector3[] blendShapeNormals = new Vector3[mesh.vertexCount];
+ var vColorState = VertexColorUtility.DetectVertexColor(mesh, unityMaterials);
+ var exportVertexColor = (
+ (settings.KeepVertexColor && mesh.colors != null && mesh.colors.Length == mesh.vertexCount) // vertex color を残す設定
+ || vColorState == VertexColorState.ExistsAndIsUsed // VColor使っている
+ || vColorState == VertexColorState.ExistsAndMixed // VColorを使っているところと使っていないところが混在(とりあえずExportする)
+ );
+
var usedIndices = new List();
for (int i = 0; i < mesh.subMeshCount; ++i)
{
var indices = mesh.GetIndices(i);
var hash = new HashSet(indices);
- // aggrigate vertex attributes
+ // aggregate vertex attributes
var buffer = new MeshExportUtil.VertexBuffer(indices.Length, getJointIndex);
usedIndices.Clear();
for (int k = 0; k < positions.Length; ++k)
{
if (hash.Contains(k))
{
- // aggrigate indices
+ // aggregate indices
usedIndices.Add(k);
- buffer.Push(k, axisInverter.InvertVector3(positions[k]), axisInverter.InvertVector3(normals[k]), uv[k].ReverseUV());
+ buffer.PushVertex(k,
+ axisInverter.InvertVector3(positions[k]), // POSITION
+ axisInverter.InvertVector3(normals[k]), // NORMAL
+ uv[k].ReverseUV() // UV
+ );
if (getJointIndex != null)
{
- buffer.Push(boneWeights[k]);
+ buffer.PushBoneWeight(boneWeights[k]);
+ }
+ if (exportVertexColor)
+ {
+ buffer.PushColor(colors[k]);
}
}
}
diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_SharedVertexBuffer.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_SharedVertexBuffer.cs
index 4a9c89c78..4701dfdb0 100644
--- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_SharedVertexBuffer.cs
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshExporter_SharedVertexBuffer.cs
@@ -49,7 +49,8 @@ namespace UniGLTF
var colorAccessorIndex = -1;
var vColorState = VertexColorUtility.DetectVertexColor(mesh, materials);
- if (vColorState == VertexColorState.ExistsAndIsUsed // VColor使っている
+ if ((settings.KeepVertexColor && mesh.colors != null && mesh.colors.Length == mesh.vertexCount) // vertex color を残す設定
+ || vColorState == VertexColorState.ExistsAndIsUsed // VColor使っている
|| vColorState == VertexColorState.ExistsAndMixed // VColorを使っているところと使っていないところが混在(とりあえずExportする)
)
{
diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/VertexColorState.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/VertexColorState.cs
index 8ac9dfbfd..62403000b 100644
--- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/VertexColorState.cs
+++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/VertexColorState.cs
@@ -1,3 +1,4 @@
+using System.Collections.Generic;
using UnityEngine;
namespace UniGLTF
@@ -37,7 +38,7 @@ namespace UniGLTF
return true;
}
- public static VertexColorState DetectVertexColor(Mesh mesh, Material[] materials)
+ public static VertexColorState DetectVertexColor(Mesh mesh, IEnumerable materials)
{
if (mesh != null && mesh.colors != null && mesh.colors.Length == mesh.vertexCount)
{
diff --git a/Assets/VRM/Editor/Format/VRMExportOptions.cs b/Assets/VRM/Editor/Format/VRMExportOptions.cs
new file mode 100644
index 000000000..66d6b411a
--- /dev/null
+++ b/Assets/VRM/Editor/Format/VRMExportOptions.cs
@@ -0,0 +1,51 @@
+using UniGLTF.M17N;
+
+namespace VRM
+{
+ public enum VRMExportOptions
+ {
+ [LangMsg(Languages.ja, "エクスポート時に強制的にT-Pose化する。これを使わずに手動でT-Poseを作っても問題ありません")]
+ [LangMsg(Languages.en, "Force T-Pose before export. Manually making T-Pose for model without enabling this is ok")]
+ FORCE_T_POSE,
+
+ [LangMsg(Languages.ja, "エクスポート時に正規化(ヒエラルキーから回転と拡大縮小を取り除くためにベイク)する")]
+ [LangMsg(Languages.en, "Model's normalization (bake to remove roation and scaling from the hierarchy)")]
+ NORMALIZE,
+
+ [LangMsg(Languages.ja, "エクスポート時に新しいJsonSerializerを使う")]
+ [LangMsg(Languages.en, "The new version of JsonSerializer for model export")]
+ USE_GENERATED_SERIALIZER,
+
+ [LangMsg(Languages.ja, "BlendShapeの容量を GLTF の Sparse Accessor 機能で削減する。修正中: UniGLTF以外でロードできません")]
+ [LangMsg(Languages.en, "BlendShape size can be reduced by using Sparse Accessor")]
+ BLENDSHAPE_USE_SPARSE,
+
+ [LangMsg(Languages.ja, "BlendShapeClipのエクスポートに法線とTangentを含めない。UniVRM-0.53 以前ではロードがエラーになるのに注意してください")]
+ [LangMsg(Languages.en, "BlendShape's Normal and Tangent will not be exported. Be aware that errors may occur during import if the model is made by UniVRM-0.53 or earlier versions")]
+ BLENDSHAPE_EXCLUDE_NORMAL_AND_TANGENT,
+
+ [LangMsg(Languages.ja, "BlendShapeClipから参照されないBlendShapeをエクスポートに含めない")]
+ [LangMsg(Languages.en, "BlendShapes that are not referenced by BlendShapeClips will not be exported")]
+ BLENDSHAPE_ONLY_CLIP_USE,
+
+ [LangMsg(Languages.ja, "BlendShapeClip.Preset == Unknown のBlendShapeClipをエクスポートに含めない")]
+ [LangMsg(Languages.en, "BlendShapeClip will not be exported if BlendShapeClip.Preset == Unknown")]
+ BLENDSHAPE_EXCLUDE_UNKNOWN,
+
+ [LangMsg(Languages.ja, "エクスポートに頂点カラーを含めない")]
+ [LangMsg(Languages.en, "Vertex color will not be exported")]
+ REMOVE_VERTEX_COLOR,
+
+ [LangMsg(Languages.ja, "T-Pose にする")]
+ [LangMsg(Languages.en, "Make T-Pose")]
+ DO_TPOSE,
+
+ [LangMsg(Languages.ja, "頂点バッファをsubmeshで分割する。GLTF互換性のため。UniVRM-0.72 からロードできる。")]
+ [LangMsg(Languages.en, "Divide vertex buffer by submesh。For more gltf compatibility。UniVRM-0.72 or later can load.")]
+ DIVIDE_VERTEX_BUFFER,
+
+ [LangMsg(Languages.ja, "頂点カラーの自動削除をしない。")]
+ [LangMsg(Languages.en, "Do not automatically delete vertex colors.")]
+ KEEP_VERTEX_COLOR,
+ }
+}
diff --git a/Assets/VRM/Editor/Format/VRMExportOptions.cs.meta b/Assets/VRM/Editor/Format/VRMExportOptions.cs.meta
new file mode 100644
index 000000000..a232b6185
--- /dev/null
+++ b/Assets/VRM/Editor/Format/VRMExportOptions.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c00e4ca5b52c8c54bb0565edadf6c7f1
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/VRM/Editor/Format/VRMExportSettings.cs b/Assets/VRM/Editor/Format/VRMExportSettings.cs
index 3560f6808..e4922baea 100644
--- a/Assets/VRM/Editor/Format/VRMExportSettings.cs
+++ b/Assets/VRM/Editor/Format/VRMExportSettings.cs
@@ -7,7 +7,6 @@ namespace VRM
[Serializable]
public class VRMExportSettings : ScriptableObject
{
-
///
/// エクスポート時に強制的にT-Pose化する
///
@@ -50,11 +49,18 @@ namespace VRM
[Tooltip("Divide vertex buffer. For more gltf compatibility")]
public bool DivideVertexBuffer = false;
+ ///
+ /// Export時にVertexColorを落とさない。特別な用途で使えるように敢えて残す設定
+ ///
+ [Tooltip("Keep vertex color attribute")]
+ public bool KeepVertexColor = false;
+
public GltfExportSettings MeshExportSettings => new GltfExportSettings
{
UseSparseAccessorForMorphTarget = UseSparseAccessor,
ExportOnlyBlendShapePosition = OnlyBlendshapePosition,
DivideVertexBuffer = DivideVertexBuffer,
+ KeepVertexColor = KeepVertexColor,
};
public GameObject Root { get; set; }
diff --git a/Assets/VRM/Editor/Format/VRMExportSettingsEditor.cs b/Assets/VRM/Editor/Format/VRMExportSettingsEditor.cs
index a80219161..e411fe97c 100644
--- a/Assets/VRM/Editor/Format/VRMExportSettingsEditor.cs
+++ b/Assets/VRM/Editor/Format/VRMExportSettingsEditor.cs
@@ -3,6 +3,7 @@ using System;
using UnityEditor;
using UnityEngine;
using UniGLTF.M17N;
+using System.Collections.Generic;
namespace VRM
{
@@ -20,7 +21,7 @@ namespace VRM
Description = desc;
}
- public CheckBoxProp(SerializedProperty property, Options desc) : this(property, () => Msg(desc))
+ public CheckBoxProp(SerializedProperty property, VRMExportOptions desc) : this(property, () => Msg(desc))
{
}
@@ -36,69 +37,23 @@ namespace VRM
}
}
- CheckBoxProp m_poseFreeze;
- CheckBoxProp m_useSparseAccessor;
- CheckBoxProp m_onlyBlendShapePosition;
- CheckBoxProp m_reduceBlendShape;
- CheckBoxProp m_reduceBlendShapeClip;
- CheckBoxProp m_divideVertexBuffer;
+ List m_checkbox_list = new List();
- static string Msg(Options key)
+ static string Msg(VRMExportOptions key)
{
return LanguageGetter.Msg(key);
}
- public enum Options
- {
- [LangMsg(Languages.ja, "エクスポート時に強制的にT-Pose化する。これを使わずに手動でT-Poseを作っても問題ありません")]
- [LangMsg(Languages.en, "Force T-Pose before export. Manually making T-Pose for model without enabling this is ok")]
- FORCE_T_POSE,
-
- [LangMsg(Languages.ja, "エクスポート時に正規化(ヒエラルキーから回転と拡大縮小を取り除くためにベイク)する")]
- [LangMsg(Languages.en, "Model's normalization (bake to remove roation and scaling from the hierarchy)")]
- NORMALIZE,
-
- [LangMsg(Languages.ja, "エクスポート時に新しいJsonSerializerを使う")]
- [LangMsg(Languages.en, "The new version of JsonSerializer for model export")]
- USE_GENERATED_SERIALIZER,
-
- [LangMsg(Languages.ja, "BlendShapeの容量を GLTF の Sparse Accessor 機能で削減する。修正中: UniGLTF以外でロードできません")]
- [LangMsg(Languages.en, "BlendShape size can be reduced by using Sparse Accessor")]
- BLENDSHAPE_USE_SPARSE,
-
- [LangMsg(Languages.ja, "BlendShapeClipのエクスポートに法線とTangentを含めない。UniVRM-0.53 以前ではロードがエラーになるのに注意してください")]
- [LangMsg(Languages.en, "BlendShape's Normal and Tangent will not be exported. Be aware that errors may occur during import if the model is made by UniVRM-0.53 or earlier versions")]
- BLENDSHAPE_EXCLUDE_NORMAL_AND_TANGENT,
-
- [LangMsg(Languages.ja, "BlendShapeClipから参照されないBlendShapeをエクスポートに含めない")]
- [LangMsg(Languages.en, "BlendShapes that are not referenced by BlendShapeClips will not be exported")]
- BLENDSHAPE_ONLY_CLIP_USE,
-
- [LangMsg(Languages.ja, "BlendShapeClip.Preset == Unknown のBlendShapeClipをエクスポートに含めない")]
- [LangMsg(Languages.en, "BlendShapeClip will not be exported if BlendShapeClip.Preset == Unknown")]
- BLENDSHAPE_EXCLUDE_UNKNOWN,
-
- [LangMsg(Languages.ja, "エクスポートに頂点カラーを含めない")]
- [LangMsg(Languages.en, "Vertex color will not be exported")]
- REMOVE_VERTEX_COLOR,
-
- [LangMsg(Languages.ja, "T-Pose にする")]
- [LangMsg(Languages.en, "Make T-Pose")]
- DO_TPOSE,
-
- [LangMsg(Languages.ja, "頂点バッファをsubmeshで分割する。GLTF互換性のため。UniVRM-0.72 からロードできる。")]
- [LangMsg(Languages.en, "Divide vertex buffer by submesh。For more gltf compatibility。UniVRM-0.72 or later can load.")]
- DIVIDE_VERTEX_BUFFER,
- }
private void OnEnable()
{
- m_poseFreeze = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.PoseFreeze)), Options.NORMALIZE);
- m_useSparseAccessor = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.UseSparseAccessor)), Options.BLENDSHAPE_USE_SPARSE);
- m_onlyBlendShapePosition = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.OnlyBlendshapePosition)), Options.BLENDSHAPE_EXCLUDE_NORMAL_AND_TANGENT);
- m_reduceBlendShape = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.ReduceBlendshape)), Options.BLENDSHAPE_ONLY_CLIP_USE);
- m_reduceBlendShapeClip = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.ReduceBlendshapeClip)), Options.BLENDSHAPE_EXCLUDE_UNKNOWN);
- m_divideVertexBuffer = new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.DivideVertexBuffer)), Options.DIVIDE_VERTEX_BUFFER);
+ m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.PoseFreeze)), VRMExportOptions.NORMALIZE));
+ m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.UseSparseAccessor)), VRMExportOptions.BLENDSHAPE_USE_SPARSE));
+ m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.OnlyBlendshapePosition)), VRMExportOptions.BLENDSHAPE_EXCLUDE_NORMAL_AND_TANGENT));
+ m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.ReduceBlendshape)), VRMExportOptions.BLENDSHAPE_ONLY_CLIP_USE));
+ m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.ReduceBlendshapeClip)), VRMExportOptions.BLENDSHAPE_EXCLUDE_UNKNOWN));
+ m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.DivideVertexBuffer)), VRMExportOptions.DIVIDE_VERTEX_BUFFER));
+ m_checkbox_list.Add(new CheckBoxProp(serializedObject.FindProperty(nameof(VRMExportSettings.KeepVertexColor)), VRMExportOptions.KEEP_VERTEX_COLOR));
}
@@ -112,13 +67,10 @@ namespace VRM
EditorGUIUtility.labelWidth = 160;
serializedObject.Update();
- m_poseFreeze.Draw();
- m_useSparseAccessor.Draw();
- m_onlyBlendShapePosition.Draw();
- m_reduceBlendShape.Draw();
- m_reduceBlendShapeClip.Draw();
- m_divideVertexBuffer.Draw();
-
+ foreach (var checkbox in m_checkbox_list)
+ {
+ checkbox.Draw();
+ }
serializedObject.ApplyModifiedProperties();
}
}
diff --git a/Assets/VRM/Editor/Format/VRMExporterWizard.cs b/Assets/VRM/Editor/Format/VRMExporterWizard.cs
index c0de87363..8e1e94441 100644
--- a/Assets/VRM/Editor/Format/VRMExporterWizard.cs
+++ b/Assets/VRM/Editor/Format/VRMExporterWizard.cs
@@ -236,7 +236,7 @@ namespace VRM
//
// T-Pose
//
- if (GUILayout.Button(VRMExportSettingsEditor.Options.DO_TPOSE.Msg()))
+ if (GUILayout.Button(VRMExportOptions.DO_TPOSE.Msg()))
{
if (State.ExportRoot != null)
{
@@ -247,7 +247,7 @@ namespace VRM
}
}
- if (GUILayout.Button(VRMExportSettingsEditor.Options.DO_TPOSE.Msg() + "(unity internal)"))
+ if (GUILayout.Button(VRMExportOptions.DO_TPOSE.Msg() + "(unity internal)"))
{
if (State.ExportRoot != null)
{
diff --git a/Assets/VRM10/Runtime/IO/Model/MeshWriter.cs b/Assets/VRM10/Runtime/IO/Model/MeshWriter.cs
index bf16b16b6..2729bfd3a 100644
--- a/Assets/VRM10/Runtime/IO/Model/MeshWriter.cs
+++ b/Assets/VRM10/Runtime/IO/Model/MeshWriter.cs
@@ -100,7 +100,7 @@ namespace UniVRM10
{
// indices から参照される頂点だけを蓄える
usedIndices.Add(k);
- buffer.Push(k, positions[k], normals[k], uv[k]);
+ buffer.PushVertex(k, positions[k], normals[k], uv[k]);
if (getJointIndex != null)
{
var j = joints[k];
@@ -116,7 +116,7 @@ namespace UniVRM10
weight2 = w.z,
weight3 = w.w,
};
- buffer.Push(boneWeight);
+ buffer.PushBoneWeight(boneWeight);
}
}
}