mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-09-08 11:59:26 -05:00
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
};
|
||||
}
|
||||
}
|
||||
25
Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshVertex0.cs
Normal file
25
Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshVertex0.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
28
Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshVertex1.cs
Normal file
28
Assets/UniGLTF/Runtime/UniGLTF/IO/MeshIO/MeshVertex1.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 206d5584ba9a43079f9f09ad067c5c34
|
||||
timeCreated: 1663145915
|
||||
@@ -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),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6cf1507df80846d0aeb9ab663677881a
|
||||
timeCreated: 1663146711
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Assets/VRM10/Runtime/IO/Model/MeshVertex0.cs
Normal file
25
Assets/VRM10/Runtime/IO/Model/MeshVertex0.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Assets/VRM10/Runtime/IO/Model/MeshVertex1.cs
Normal file
25
Assets/VRM10/Runtime/IO/Model/MeshVertex1.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/VRM10/Runtime/IO/Model/MeshVertex1.cs.meta
Normal file
3
Assets/VRM10/Runtime/IO/Model/MeshVertex1.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ec609c13465473984b73fc5fed0ab17
|
||||
timeCreated: 1663140746
|
||||
42
Assets/VRM10/Runtime/IO/Model/MeshVertex2.cs
Normal file
42
Assets/VRM10/Runtime/IO/Model/MeshVertex2.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/VRM10/Runtime/IO/Model/MeshVertex2.cs.meta
Normal file
3
Assets/VRM10/Runtime/IO/Model/MeshVertex2.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f359472cfd14db28982f4db837a7aaf
|
||||
timeCreated: 1663140985
|
||||
21
Assets/VRM10/Runtime/IO/Model/MeshVertexUtility.cs
Normal file
21
Assets/VRM10/Runtime/IO/Model/MeshVertexUtility.cs
Normal 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),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/VRM10/Runtime/IO/Model/MeshVertexUtility.cs.meta
Normal file
3
Assets/VRM10/Runtime/IO/Model/MeshVertexUtility.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d041a5d5b4c5412896a316b98ae1677c
|
||||
timeCreated: 1663143719
|
||||
Reference in New Issue
Block a user