Merge pull request #1798 from notargs/fix_1789

頂点レイアウト Issue #1789に対応
This commit is contained in:
ousttrue
2022-09-20 15:48:21 +09:00
committed by GitHub
24 changed files with 349 additions and 237 deletions

View File

@@ -10,25 +10,27 @@ namespace UniGLTF
{
internal class MeshData : IDisposable
{
private NativeArray<MeshVertex> _vertices;
public NativeArray<MeshVertex> Vertices => _vertices.GetSubArray(0, _currentVertexCount);
int _currentVertexCount = 0;
private NativeArray<SkinnedMeshVertex> _skinnedMeshVertices;
public NativeArray<SkinnedMeshVertex> SkinnedMeshVertices => _skinnedMeshVertices.GetSubArray(0, _currentSkinCount);
int _currentSkinCount = 0;
private int _currentVertexCount = 0;
private int _currentIndexCount = 0;
private NativeArray<int> _indices;
public NativeArray<int> Indices => _indices.GetSubArray(0, _currentIndexCount);
int _currentIndexCount = 0;
private NativeArray<MeshVertex0> _vertices0;
private NativeArray<MeshVertex1> _vertices1;
private NativeArray<MeshVertex2> _vertices2;
private readonly List<SubMeshDescriptor> _subMeshes = new List<SubMeshDescriptor>();
public IReadOnlyList<SubMeshDescriptor> SubMeshes => _subMeshes;
private readonly List<int> _materialIndices = new List<int>();
private readonly List<BlendShape> _blendShapes = new List<BlendShape>();
public NativeArray<MeshVertex0> Vertices0 => _vertices0.GetSubArray(0, _currentVertexCount);
public NativeArray<MeshVertex1> Vertices1 => _vertices1.GetSubArray(0, _currentVertexCount);
public NativeArray<MeshVertex2> Vertices2 => _vertices2.GetSubArray(0, _currentVertexCount);
public NativeArray<int> Indices => _indices.GetSubArray(0, _currentIndexCount);
public IReadOnlyList<SubMeshDescriptor> SubMeshes => _subMeshes;
public IReadOnlyList<int> MaterialIndices => _materialIndices;
private readonly List<BlendShape> _blendShapes = new List<BlendShape>();
public IReadOnlyList<BlendShape> BlendShapes => _blendShapes;
public bool HasNormal { get; private set; }
@@ -37,22 +39,23 @@ namespace UniGLTF
public MeshData(int vertexCapacity, int indexCapacity)
{
_vertices = new NativeArray<MeshVertex>(vertexCapacity, Allocator.Persistent);
_skinnedMeshVertices = new NativeArray<SkinnedMeshVertex>(vertexCapacity, Allocator.Persistent);
_vertices0 = new NativeArray<MeshVertex0>(vertexCapacity, Allocator.Persistent);
_vertices1 = new NativeArray<MeshVertex1>(vertexCapacity, Allocator.Persistent);
_vertices2 = new NativeArray<MeshVertex2>(vertexCapacity, Allocator.Persistent);
_indices = new NativeArray<int>(indexCapacity, Allocator.Persistent);
}
public void Dispose()
{
_vertices.Dispose();
_skinnedMeshVertices.Dispose();
_vertices0.Dispose();
_vertices1.Dispose();
_vertices2.Dispose();
_indices.Dispose();
}
void Clear()
{
_currentVertexCount = 0;
_currentSkinCount = 0;
_currentIndexCount = 0;
_subMeshes.Clear();
_materialIndices.Clear();
@@ -245,10 +248,6 @@ namespace UniGLTF
{
_currentVertexCount = maxIndex + 1;
}
if (maxIndex + 1 < _currentSkinCount)
{
_currentSkinCount = maxIndex + 1;
}
foreach (var blendShape in _blendShapes)
{
Truncate(blendShape.Positions, maxIndex);
@@ -282,18 +281,6 @@ namespace UniGLTF
}
}
private void AddVertex(MeshVertex vertex)
{
_vertices[_currentVertexCount] = vertex;
_currentVertexCount += 1;
}
private void AddSkin(SkinnedMeshVertex skin)
{
_skinnedMeshVertices[_currentSkinCount] = skin;
_currentSkinCount += 1;
}
/// <summary>
/// 各 primitive の attribute の要素が同じでない。=> uv が有るものと無いものが混在するなど
/// glTF 的にはありうる。
@@ -349,19 +336,22 @@ namespace UniGLTF
var texCoord1 = texCoords1 != null ? texCoords1.Value[i].ReverseUV() : Vector2.zero;
var color = colors != null ? colors.Value[i] : Color.white;
AddVertex(
new MeshVertex(
position,
normal,
texCoord0,
texCoord1,
color
));
_vertices0[_currentVertexCount] = new MeshVertex0(
position,
normal
);
_vertices1[_currentVertexCount] = new MeshVertex1(
texCoord0,
texCoord1,
color
);
var skin = skinning.GetSkinnedVertex(i);
if (skin.HasValue)
{
AddSkin(skin.Value);
_vertices2[_currentVertexCount] = skin.Value;
}
_currentVertexCount += 1;
}
// blendshape
@@ -481,19 +471,21 @@ namespace UniGLTF
var texCoord1 = texCoords1 != null ? texCoords1.Value[i].ReverseUV() : Vector2.zero;
var color = colors != null ? colors.Value[i] : Color.white;
AddVertex(
new MeshVertex(
position,
normal,
texCoord0,
texCoord1,
color));
var skin =
skinning.GetSkinnedVertex(i);
_vertices0[_currentVertexCount] = new MeshVertex0(
position,
normal
);
_vertices1[_currentVertexCount] = new MeshVertex1(
texCoord0,
texCoord1,
color
);
var skin = skinning.GetSkinnedVertex(i);
if (skin.HasValue)
{
AddSkin(skin.Value);
_vertices2[_currentVertexCount] = skin.Value;
}
_currentVertexCount += 1;
}
// blendshape

View File

@@ -17,27 +17,13 @@ namespace UniGLTF
/// </summary>
public static void UploadMeshVertices(MeshData data, Mesh mesh)
{
var vertexAttributeDescriptor = MeshVertex.GetVertexAttributeDescriptor();
MeshVertexUtility.SetVertexBufferParamsToMesh(mesh, data.Vertices0.Length, data.Vertices2.Length > 0);
// Weight情報等は存在しないパターンがあり、かつこの存在の有無によって内部的に条件分岐が走ってしまうため、
// Streamを分けて必要に応じてアップロードする
if (data.SkinnedMeshVertices.Length > 0)
mesh.SetVertexBufferData(data.Vertices0, 0, 0, data.Vertices0.Length);
mesh.SetVertexBufferData(data.Vertices1, 0, 0, data.Vertices0.Length, 1);
if (data.Vertices2.Length > 0)
{
vertexAttributeDescriptor = vertexAttributeDescriptor.Concat(SkinnedMeshVertex
.GetVertexAttributeDescriptor().Select(
attr =>
{
attr.stream = 1;
return attr;
})).ToArray();
}
mesh.SetVertexBufferParams(data.Vertices.Length, vertexAttributeDescriptor);
mesh.SetVertexBufferData(data.Vertices, 0, 0, data.Vertices.Length);
if (data.SkinnedMeshVertices.Length > 0)
{
mesh.SetVertexBufferData(data.SkinnedMeshVertices, 0, 0, data.SkinnedMeshVertices.Length, 1);
mesh.SetVertexBufferData(data.Vertices2, 0, 0, data.Vertices2.Length, 2);
}
}

View File

@@ -1,44 +0,0 @@
using System;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Rendering;
namespace UniGLTF
{
/// <summary>
/// インターリーブされたメッシュの頂点情報のうち、基本的なものを表す構造体
/// 必要に応じてSkinnedMeshVertexとあわせて
/// そのままGPUにアップロードされる
/// </summary>
[Serializable, StructLayout(LayoutKind.Sequential)]
internal readonly struct MeshVertex
{
private readonly Vector3 _position;
private readonly Vector3 _normal;
private readonly Color _color;
private readonly Vector2 _texCoord0;
private readonly Vector2 _texCoord1;
public MeshVertex(
Vector3 position,
Vector3 normal,
Vector2 texCoord0,
Vector2 texCoord1,
Color color)
{
_position = position;
_normal = normal;
_texCoord0 = texCoord0;
_texCoord1 = texCoord1;
_color = color;
}
public static VertexAttributeDescriptor[] GetVertexAttributeDescriptor() => new[] {
new VertexAttributeDescriptor(VertexAttribute.Position),
new VertexAttributeDescriptor(VertexAttribute.Normal),
new VertexAttributeDescriptor(VertexAttribute.Color, dimension: 4),
new VertexAttributeDescriptor(VertexAttribute.TexCoord0, dimension: 2),
new VertexAttributeDescriptor(VertexAttribute.TexCoord1, dimension: 2)
};
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Runtime.InteropServices;
using UnityEngine;
namespace UniGLTF
{
/// <summary>
/// Stream0用のインターリーブされたメッシュの頂点情報
/// そのままGPUにアップロードされる
/// </summary>
[Serializable, StructLayout(LayoutKind.Sequential)]
internal readonly struct MeshVertex0
{
private readonly Vector3 _position;
private readonly Vector3 _normal;
public MeshVertex0(
Vector3 position,
Vector3 normal)
{
_position = position;
_normal = normal;
}
}
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Runtime.InteropServices;
using UnityEngine;
namespace UniGLTF
{
/// <summary>
/// Stream1用のインターリーブされたメッシュの頂点情報
/// そのままGPUにアップロードされる
/// </summary>
[Serializable, StructLayout(LayoutKind.Sequential)]
internal readonly struct MeshVertex1
{
private readonly Color _color;
private readonly Vector2 _texCoord0;
private readonly Vector2 _texCoord1;
public MeshVertex1(
Vector2 texCoord0,
Vector2 texCoord1,
Color color)
{
_texCoord0 = texCoord0;
_texCoord1 = texCoord1;
_color = color;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 206d5584ba9a43079f9f09ad067c5c34
timeCreated: 1663145915

View File

@@ -1,15 +1,14 @@
using System;
using System.Runtime.InteropServices;
using UnityEngine.Rendering;
namespace UniGLTF
{
/// <summary>
/// インターリーブされたメッシュの頂点情報のうち、SkinnedMeshに関連した情報を表す構造体
/// Stream2用のインターリーブされたメッシュの頂点情報
/// そのままGPUにアップロードされる
/// </summary>
[Serializable, StructLayout(LayoutKind.Sequential)]
internal readonly struct SkinnedMeshVertex
internal readonly struct MeshVertex2
{
private readonly float _boneWeight0;
private readonly float _boneWeight1;
@@ -20,7 +19,7 @@ namespace UniGLTF
private readonly ushort _boneIndex2;
private readonly ushort _boneIndex3;
public SkinnedMeshVertex(
public MeshVertex2(
ushort boneIndex0,
ushort boneIndex1,
ushort boneIndex2,
@@ -39,10 +38,5 @@ namespace UniGLTF
_boneWeight2 = boneWeight2;
_boneWeight3 = boneWeight3;
}
public static VertexAttributeDescriptor[] GetVertexAttributeDescriptor() => new[] {
new VertexAttributeDescriptor(VertexAttribute.BlendWeight, dimension: 4),
new VertexAttributeDescriptor(VertexAttribute.BlendIndices, VertexAttributeFormat.UInt16, 4),
};
}
}

View File

@@ -0,0 +1,37 @@
using UnityEngine;
using UnityEngine.Rendering;
namespace UniGLTF
{
internal readonly struct MeshVertexUtility
{
public static void SetVertexBufferParamsToMesh(Mesh mesh, int length, bool useBlendWeight)
{
if (useBlendWeight)
{
mesh.SetVertexBufferParams(length, new VertexAttributeDescriptor[]
{
new VertexAttributeDescriptor(VertexAttribute.Position, stream: 0),
new VertexAttributeDescriptor(VertexAttribute.Normal, stream: 0),
new VertexAttributeDescriptor(VertexAttribute.Color, dimension: 4, stream: 1),
new VertexAttributeDescriptor(VertexAttribute.TexCoord0, dimension: 2, stream: 1),
new VertexAttributeDescriptor(VertexAttribute.TexCoord1, dimension: 2, stream: 1),
new VertexAttributeDescriptor(VertexAttribute.BlendWeight, dimension: 4, stream: 2),
new VertexAttributeDescriptor(VertexAttribute.BlendIndices, VertexAttributeFormat.UInt16, 4, 2),
});
}
else
{
mesh.SetVertexBufferParams(length, new VertexAttributeDescriptor[]
{
new VertexAttributeDescriptor(VertexAttribute.Position, stream: 0),
new VertexAttributeDescriptor(VertexAttribute.Normal, stream: 0),
new VertexAttributeDescriptor(VertexAttribute.Color, dimension: 4, stream: 1),
new VertexAttributeDescriptor(VertexAttribute.TexCoord0, dimension: 2, stream: 1),
new VertexAttributeDescriptor(VertexAttribute.TexCoord1, dimension: 2, stream: 1),
});
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6cf1507df80846d0aeb9ab663677881a
timeCreated: 1663146711

View File

@@ -87,7 +87,7 @@ namespace UniGLTF
return src;
}
public SkinnedMeshVertex? GetSkinnedVertex(int i)
public MeshVertex2? GetSkinnedVertex(int i)
{
if (Joints == null)
{
@@ -95,7 +95,7 @@ namespace UniGLTF
}
var joints = Joints?.Invoke(i) ?? (0, 0, 0, 0);
var weights = Weights != null ? NormalizeBoneWeight(Weights(i)) : (0, 0, 0, 0);
return new SkinnedMeshVertex(
return new MeshVertex2(
joints.x,
joints.y,
joints.z,

View File

@@ -19,7 +19,13 @@ namespace UniVRM10
internal struct InterleaveMeshVerticesJob : IJobParallelFor
{
[WriteOnly]
private NativeSlice<MeshVertex> _vertices;
private NativeSlice<MeshVertex0> _vertices0;
[WriteOnly]
private NativeSlice<MeshVertex1> _vertices1;
[WriteOnly]
private NativeSlice<MeshVertex2> _vertices2;
[ReadOnly]
private readonly NativeSlice<Vector3> _positions;
@@ -41,7 +47,9 @@ namespace UniVRM10
private readonly NativeSlice<SkinJoints> _joints;
public InterleaveMeshVerticesJob(
NativeSlice<MeshVertex> vertices,
NativeSlice<MeshVertex0> vertices0,
NativeSlice<MeshVertex1> vertices1,
NativeSlice<MeshVertex2> vertices2,
NativeSlice<Vector3> positions,
NativeSlice<Vector3> normals = default,
NativeSlice<Vector2> texCoords = default,
@@ -49,7 +57,9 @@ namespace UniVRM10
NativeSlice<Vector4> weights = default,
NativeSlice<SkinJoints> joints = default)
{
_vertices = vertices;
_vertices0 = vertices0;
_vertices1 = vertices1;
_vertices2 = vertices2;
_positions = positions;
_normals = normals;
_texCoords = texCoords;
@@ -60,11 +70,15 @@ namespace UniVRM10
public void Execute(int index)
{
_vertices[index] = new MeshVertex(
_vertices0[index] = new MeshVertex0(
_positions[index],
_normals.Length > 0 ? _normals[index] : Vector3.zero,
_normals.Length > 0 ? _normals[index] : Vector3.zero
);
_vertices1[index] = new MeshVertex1(
_texCoords.Length > 0 ? _texCoords[index] : Vector2.zero,
_colors.Length > 0 ? _colors[index] : Color.white,
_colors.Length > 0 ? _colors[index] : Color.white
);
_vertices2[index] = new MeshVertex2(
_joints.Length > 0 ? _joints[index].Joint0 : (ushort)0,
_joints.Length > 0 ? _joints[index].Joint1 : (ushort)0,
_joints.Length > 0 ? _joints[index].Joint2 : (ushort)0,

View File

@@ -246,8 +246,12 @@ namespace UniVRM10
var disposables = new List<IDisposable>();
// JobのSchedule
var vertices = new NativeArray<MeshVertex>(vertexCount, Allocator.TempJob);
disposables.Add(vertices);
var vertices0 = new NativeArray<MeshVertex0>(vertexCount, Allocator.TempJob);
var vertices1 = new NativeArray<MeshVertex1>(vertexCount, Allocator.TempJob);
var vertices2 = new NativeArray<MeshVertex2>(vertexCount, Allocator.TempJob);
disposables.Add(vertices0);
disposables.Add(vertices1);
disposables.Add(vertices2);
var indexOffset = 0;
JobHandle interleaveVertexJob = default;
@@ -261,7 +265,9 @@ namespace UniVRM10
var joints = mesh.VertexBuffer.Joints?.GetAsSkinJointsArray() ?? default;
interleaveVertexJob = new InterleaveMeshVerticesJob(
new NativeSlice<MeshVertex>(vertices, indexOffset, mesh.VertexBuffer.Count),
new NativeSlice<MeshVertex0>(vertices0, indexOffset, mesh.VertexBuffer.Count),
new NativeSlice<MeshVertex1>(vertices1, indexOffset, mesh.VertexBuffer.Count),
new NativeSlice<MeshVertex2>(vertices2, indexOffset, mesh.VertexBuffer.Count),
positions,
normals,
texCoords,
@@ -284,8 +290,10 @@ namespace UniVRM10
interleaveVertexJob.Complete();
// VertexBufferを設定
MeshVertex.SetVertexBufferParamsToMesh(resultMesh, vertices.Length);
resultMesh.SetVertexBufferData(vertices, 0, 0, vertices.Length);
MeshVertexUtility.SetVertexBufferParamsToMesh(resultMesh, vertexCount);
resultMesh.SetVertexBufferData(vertices0, 0, 0, vertexCount);
resultMesh.SetVertexBufferData(vertices1, 0, 0, vertexCount, 1);
resultMesh.SetVertexBufferData(vertices2, 0, 0, vertexCount, 2);
// 各種バッファを破棄
foreach (var disposable in disposables)

View File

@@ -30,13 +30,24 @@ namespace UniVRM10
var weights = src.VertexBuffer.Weights?.GetAsVector4Array() ?? default;
var joints = src.VertexBuffer.Joints?.GetAsSkinJointsArray() ?? default;
using (var vertices = new NativeArray<MeshVertex>(positions.Length, Allocator.TempJob))
using (var vertices0 = new NativeArray<MeshVertex0>(positions.Length, Allocator.TempJob))
using (var vertices1 = new NativeArray<MeshVertex1>(positions.Length, Allocator.TempJob))
using (var vertices2 = new NativeArray<MeshVertex2>(positions.Length, Allocator.TempJob))
{
// JobとBindPoseの更新を並行して行う
var jobHandle =
new InterleaveMeshVerticesJob(vertices, positions, normals, texCoords, colors, weights, joints)
.Schedule(vertices.Length, 1);
new InterleaveMeshVerticesJob(
vertices0,
vertices1,
vertices2,
positions,
normals,
texCoords,
colors,
weights,
joints
)
.Schedule(vertices0.Length, 1);
JobHandle.ScheduleBatchedJobs();
// BindPoseを更新
@@ -46,6 +57,7 @@ namespace UniVRM10
{
throw new ArgumentException();
}
if (skin != null)
{
mesh.bindposes = skin.InverseMatrices.GetSpan<Matrix4x4>().ToArray();
@@ -56,8 +68,10 @@ namespace UniVRM10
jobHandle.Complete();
// 頂点を更新
MeshVertex.SetVertexBufferParamsToMesh(mesh, vertices.Length);
mesh.SetVertexBufferData(vertices, 0, 0, vertices.Length);
MeshVertexUtility.SetVertexBufferParamsToMesh(mesh, vertices0.Length);
mesh.SetVertexBufferData(vertices0, 0, 0, vertices0.Length);
mesh.SetVertexBufferData(vertices1, 0, 0, vertices0.Length, 1);
mesh.SetVertexBufferData(vertices2, 0, 0, vertices0.Length, 2);
// 出力のNativeArrayを開放
}
@@ -66,26 +80,26 @@ namespace UniVRM10
switch (src.IndexBuffer.ComponentType)
{
case AccessorValueType.UNSIGNED_BYTE:
{
var intIndices = src.IndexBuffer.GetAsIntArray();
mesh.SetIndexBufferParams(intIndices.Length, IndexFormat.UInt32);
mesh.SetIndexBufferData(intIndices, 0, 0, intIndices.Length);
break;
}
{
var intIndices = src.IndexBuffer.GetAsIntArray();
mesh.SetIndexBufferParams(intIndices.Length, IndexFormat.UInt32);
mesh.SetIndexBufferData(intIndices, 0, 0, intIndices.Length);
break;
}
case AccessorValueType.UNSIGNED_SHORT:
{
var shortIndices = src.IndexBuffer.Bytes.Reinterpret<ushort>(1);
mesh.SetIndexBufferParams(shortIndices.Length, IndexFormat.UInt16);
mesh.SetIndexBufferData(shortIndices, 0, 0, shortIndices.Length);
break;
}
{
var shortIndices = src.IndexBuffer.Bytes.Reinterpret<ushort>(1);
mesh.SetIndexBufferParams(shortIndices.Length, IndexFormat.UInt16);
mesh.SetIndexBufferData(shortIndices, 0, 0, shortIndices.Length);
break;
}
case AccessorValueType.UNSIGNED_INT:
{
var intIndices = src.IndexBuffer.Bytes.Reinterpret<uint>(1);
mesh.SetIndexBufferParams(intIndices.Length, IndexFormat.UInt32);
mesh.SetIndexBufferData(intIndices, 0, 0, intIndices.Length);
break;
}
{
var intIndices = src.IndexBuffer.Bytes.Reinterpret<uint>(1);
mesh.SetIndexBufferParams(intIndices.Length, IndexFormat.UInt32);
mesh.SetIndexBufferData(intIndices, 0, 0, intIndices.Length);
break;
}
default:
throw new NotImplementedException();
}
@@ -102,9 +116,9 @@ namespace UniVRM10
foreach (var morphTarget in src.MorphTargets)
{
var morphTargetPositions =
morphTarget.VertexBuffer.Positions != null
? morphTarget.VertexBuffer.Positions.GetSpan<Vector3>().ToArray()
: new Vector3[mesh.vertexCount] // dummy
morphTarget.VertexBuffer.Positions != null
? morphTarget.VertexBuffer.Positions.GetSpan<Vector3>().ToArray()
: new Vector3[mesh.vertexCount] // dummy
;
mesh.AddBlendShapeFrame(morphTarget.Name, 100.0f, morphTargetPositions, null, null);
}
@@ -122,4 +136,4 @@ namespace UniVRM10
return mesh;
}
}
}
}

View File

@@ -1,70 +0,0 @@
using System;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Rendering;
namespace UniVRM10
{
/// <summary>
/// インターリーブされたメッシュの頂点情報を表す構造体
/// そのままGPUにアップロードされる
/// </summary>
[Serializable, StructLayout(LayoutKind.Sequential)]
internal readonly struct MeshVertex
{
private readonly Vector3 _position;
private readonly Vector3 _normal;
private readonly Color _color;
private readonly Vector2 _texCoord;
private readonly float _boneWeight0;
private readonly float _boneWeight1;
private readonly float _boneWeight2;
private readonly float _boneWeight3;
private readonly ushort _boneIndex0;
private readonly ushort _boneIndex1;
private readonly ushort _boneIndex2;
private readonly ushort _boneIndex3;
public MeshVertex(
Vector3 position,
Vector3 normal,
Vector2 texCoord,
Color color,
ushort boneIndex0,
ushort boneIndex1,
ushort boneIndex2,
ushort boneIndex3,
float boneWeight0,
float boneWeight1,
float boneWeight2,
float boneWeight3)
{
_position = position;
_normal = normal;
_texCoord = texCoord;
_color = color;
_boneIndex0 = boneIndex0;
_boneIndex1 = boneIndex1;
_boneIndex2 = boneIndex2;
_boneIndex3 = boneIndex3;
_boneWeight0 = boneWeight0;
_boneWeight1 = boneWeight1;
_boneWeight2 = boneWeight2;
_boneWeight3 = boneWeight3;
}
private static readonly VertexAttributeDescriptor[] vertexAttributeDescriptor = {
new VertexAttributeDescriptor(VertexAttribute.Position),
new VertexAttributeDescriptor(VertexAttribute.Normal),
new VertexAttributeDescriptor(VertexAttribute.Color, dimension: 4),
new VertexAttributeDescriptor(VertexAttribute.TexCoord0, dimension: 2),
new VertexAttributeDescriptor(VertexAttribute.BlendWeight, dimension: 4),
new VertexAttributeDescriptor(VertexAttribute.BlendIndices, VertexAttributeFormat.UInt16, 4),
};
public static void SetVertexBufferParamsToMesh(Mesh mesh, int length)
{
mesh.SetVertexBufferParams(length, vertexAttributeDescriptor);
}
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Runtime.InteropServices;
using UnityEngine;
namespace UniVRM10
{
/// <summary>
/// Stream0用のインターリーブされたメッシュの頂点情報を表す構造体
/// そのままGPUにアップロードされる
/// </summary>
[Serializable, StructLayout(LayoutKind.Sequential)]
internal readonly struct MeshVertex0
{
private readonly Vector3 _position;
private readonly Vector3 _normal;
public MeshVertex0(
Vector3 position,
Vector3 normal)
{
_position = position;
_normal = normal;
}
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Runtime.InteropServices;
using UnityEngine;
namespace UniVRM10
{
/// <summary>
/// Stream1用のインターリーブされたメッシュの頂点情報を表す構造体
/// そのままGPUにアップロードされる
/// </summary>
[Serializable, StructLayout(LayoutKind.Sequential)]
internal readonly struct MeshVertex1
{
private readonly Color _color;
private readonly Vector2 _texCoord;
public MeshVertex1(
Vector2 texCoord,
Color color)
{
_texCoord = texCoord;
_color = color;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0ec609c13465473984b73fc5fed0ab17
timeCreated: 1663140746

View File

@@ -0,0 +1,42 @@
using System;
using System.Runtime.InteropServices;
namespace UniVRM10
{
/// <summary>
/// Stream2用のインターリーブされたメッシュの頂点情報を表す構造体
/// そのままGPUにアップロードされる
/// </summary>
[Serializable, StructLayout(LayoutKind.Sequential)]
internal readonly struct MeshVertex2
{
private readonly float _boneWeight0;
private readonly float _boneWeight1;
private readonly float _boneWeight2;
private readonly float _boneWeight3;
private readonly ushort _boneIndex0;
private readonly ushort _boneIndex1;
private readonly ushort _boneIndex2;
private readonly ushort _boneIndex3;
public MeshVertex2(
ushort boneIndex0,
ushort boneIndex1,
ushort boneIndex2,
ushort boneIndex3,
float boneWeight0,
float boneWeight1,
float boneWeight2,
float boneWeight3)
{
_boneIndex0 = boneIndex0;
_boneIndex1 = boneIndex1;
_boneIndex2 = boneIndex2;
_boneIndex3 = boneIndex3;
_boneWeight0 = boneWeight0;
_boneWeight1 = boneWeight1;
_boneWeight2 = boneWeight2;
_boneWeight3 = boneWeight3;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9f359472cfd14db28982f4db837a7aaf
timeCreated: 1663140985

View File

@@ -0,0 +1,21 @@
using UnityEngine;
using UnityEngine.Rendering;
namespace UniVRM10
{
internal static class MeshVertexUtility
{
public static void SetVertexBufferParamsToMesh(Mesh mesh, int length)
{
mesh.SetVertexBufferParams(length, new VertexAttributeDescriptor[]
{
new VertexAttributeDescriptor(VertexAttribute.Position, stream: 0),
new VertexAttributeDescriptor(VertexAttribute.Normal, stream: 0),
new VertexAttributeDescriptor(VertexAttribute.Color, dimension: 4, stream: 1),
new VertexAttributeDescriptor(VertexAttribute.TexCoord0, dimension: 2, stream: 1),
new VertexAttributeDescriptor(VertexAttribute.BlendWeight, dimension: 4, stream: 2),
new VertexAttributeDescriptor(VertexAttribute.BlendIndices, VertexAttributeFormat.UInt16, 4, 2),
});
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d041a5d5b4c5412896a316b98ae1677c
timeCreated: 1663143719