mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-04-25 07:28:51 -05:00
implement BlendShapeExporter.Export
This commit is contained in:
parent
7e42a8bd12
commit
80abc5d7ce
|
|
@ -21,15 +21,58 @@ namespace UniGLTF
|
|||
{
|
||||
public static gltfMorphTarget Export(glTF gltf, int gltfBuffer, Vector3[] positions, Vector3[] normals, SparseBase? sparseBase)
|
||||
{
|
||||
var accessorCount = positions.Length;
|
||||
if (normals != null && positions.Length != normals.Length)
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
bool useSparse = sparseBase.HasValue;
|
||||
if (sparseBase.HasValue)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var sparseIndices = Enumerable.Range(0, positions.Length).Where(x => positions[x] != Vector3.zero).ToArray();
|
||||
if (sparseIndices.Length == 0)
|
||||
{
|
||||
useSparse = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (useSparse)
|
||||
{
|
||||
// positions
|
||||
var positionAccessorIndex = -1;
|
||||
var sparseIndices = Enumerable.Range(0, positions.Length).Where(x => positions[x] != Vector3.zero).ToArray();
|
||||
if (sparseIndices.Length > 0)
|
||||
{
|
||||
Debug.LogFormat("Sparse {0}/{1}", sparseIndices.Length, positions.Length);
|
||||
var sparseIndicesViewIndex = gltf.ExtendBufferAndGetViewIndex(gltfBuffer, sparseIndices);
|
||||
positionAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(gltfBuffer, accessorCount, positions, sparseIndices, sparseIndicesViewIndex, glBufferTarget.NONE);
|
||||
}
|
||||
|
||||
// normals
|
||||
var normalAccessorIndex = -1;
|
||||
if (normals != null)
|
||||
{
|
||||
var sparseNormalIndices = Enumerable.Range(0, positions.Length).Where(x => normals[x] != Vector3.zero).ToArray();
|
||||
if (sparseNormalIndices.Length > 0)
|
||||
{
|
||||
var sparseNormalIndicesViewIndex = gltf.ExtendBufferAndGetViewIndex(gltfBuffer, sparseNormalIndices);
|
||||
normalAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(gltfBuffer, accessorCount, normals, sparseNormalIndices, sparseNormalIndicesViewIndex, glBufferTarget.NONE);
|
||||
}
|
||||
}
|
||||
|
||||
return new gltfMorphTarget
|
||||
{
|
||||
POSITION = positionAccessorIndex,
|
||||
NORMAL = normalAccessorIndex,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
// position
|
||||
var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(gltfBuffer, positions, glBufferTarget.ARRAY_BUFFER);
|
||||
gltf.accessors[positionAccessorIndex].min = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Min(a.x, b.x), Math.Min(a.y, b.y), Mathf.Min(a.z, b.z))).ToArray();
|
||||
gltf.accessors[positionAccessorIndex].max = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Max(a.x, b.x), Math.Max(a.y, b.y), Mathf.Max(a.z, b.z))).ToArray();
|
||||
|
||||
// normal
|
||||
var normalAccessorIndex = -1;
|
||||
|
|
@ -37,7 +80,6 @@ namespace UniGLTF
|
|||
{
|
||||
normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(gltfBuffer, normals, glBufferTarget.ARRAY_BUFFER);
|
||||
}
|
||||
gltf.accessors[positionAccessorIndex].max = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Max(a.x, b.x), Math.Max(a.y, b.y), Mathf.Max(a.z, b.z))).ToArray();
|
||||
|
||||
return new gltfMorphTarget
|
||||
{
|
||||
|
|
|
|||
|
|
@ -213,106 +213,38 @@ namespace UniGLTF
|
|||
var useNormal = usePosition && blendShapeNormals != null && blendShapeNormals.Length == blendShapeVertices.Length;
|
||||
// var useNormal = usePosition && blendShapeNormals != null && blendShapeNormals.Length == blendShapeVertices.Length && !exportOnlyBlendShapePosition;
|
||||
|
||||
var blendShapeTangents = mesh.tangents.Select(y => (Vector3)y).ToArray();
|
||||
//var useTangent = usePosition && blendShapeTangents != null && blendShapeTangents.Length == blendShapeVertices.Length;
|
||||
var useTangent = false;
|
||||
// var blendShapeTangents = mesh.tangents.Select(y => (Vector3)y).ToArray();
|
||||
// //var useTangent = usePosition && blendShapeTangents != null && blendShapeTangents.Length == blendShapeVertices.Length;
|
||||
// var useTangent = false;
|
||||
|
||||
var frameCount = mesh.GetBlendShapeFrameCount(blendShapeIndex);
|
||||
mesh.GetBlendShapeFrameVertices(blendShapeIndex, frameCount - 1, blendShapeVertices, blendShapeNormals, null);
|
||||
|
||||
var blendShapePositionAccessorIndex = -1;
|
||||
var blendShapeNormalAccessorIndex = -1;
|
||||
var blendShapeTangentAccessorIndex = -1;
|
||||
if (useSparseAccessorForMorphTarget)
|
||||
//
|
||||
// invert axis
|
||||
//
|
||||
for (int i = 0; i < blendShapeVertices.Length; ++i)
|
||||
{
|
||||
var accessorCount = blendShapeVertices.Length;
|
||||
var sparseIndices = Enumerable.Range(0, blendShapeVertices.Length)
|
||||
.Where(x => UseSparse(
|
||||
usePosition, blendShapeVertices[x],
|
||||
useNormal, blendShapeNormals[x],
|
||||
useTangent, blendShapeTangents[x]))
|
||||
.ToArray()
|
||||
;
|
||||
|
||||
if (sparseIndices.Length == 0)
|
||||
{
|
||||
usePosition = false;
|
||||
useNormal = false;
|
||||
useTangent = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogFormat("Sparse {0}/{1}", sparseIndices.Length, mesh.vertexCount);
|
||||
}
|
||||
|
||||
var sparseIndicesViewIndex = -1;
|
||||
if (usePosition)
|
||||
{
|
||||
sparseIndicesViewIndex = gltf.ExtendBufferAndGetViewIndex(bufferIndex, sparseIndices);
|
||||
|
||||
blendShapeVertices = sparseIndices.Select(x => axisInverter.InvertVector3(blendShapeVertices[x])).ToArray();
|
||||
blendShapePositionAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(bufferIndex, accessorCount,
|
||||
blendShapeVertices,
|
||||
sparseIndices, sparseIndicesViewIndex,
|
||||
glBufferTarget.NONE);
|
||||
}
|
||||
|
||||
if (useNormal)
|
||||
{
|
||||
blendShapeNormals = sparseIndices.Select(x => axisInverter.InvertVector3(blendShapeNormals[x])).ToArray();
|
||||
blendShapeNormalAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(bufferIndex, accessorCount,
|
||||
blendShapeNormals,
|
||||
sparseIndices, sparseIndicesViewIndex,
|
||||
glBufferTarget.NONE);
|
||||
}
|
||||
|
||||
if (useTangent)
|
||||
{
|
||||
blendShapeTangents = sparseIndices.Select(x => axisInverter.InvertVector3(blendShapeTangents[x])).ToArray();
|
||||
blendShapeTangentAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(bufferIndex, accessorCount,
|
||||
blendShapeTangents, sparseIndices, sparseIndicesViewIndex,
|
||||
glBufferTarget.NONE);
|
||||
}
|
||||
blendShapeVertices[i] = axisInverter.InvertVector3(blendShapeVertices[i]);
|
||||
}
|
||||
else
|
||||
for (int i = 0; i < blendShapeNormals.Length; ++i)
|
||||
{
|
||||
for (int i = 0; i < blendShapeVertices.Length; ++i) blendShapeVertices[i] = axisInverter.InvertVector3(blendShapeVertices[i]);
|
||||
if (usePosition)
|
||||
{
|
||||
blendShapePositionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex,
|
||||
blendShapeVertices,
|
||||
glBufferTarget.ARRAY_BUFFER);
|
||||
}
|
||||
|
||||
if (useNormal)
|
||||
{
|
||||
for (int i = 0; i < blendShapeNormals.Length; ++i) blendShapeNormals[i] = axisInverter.InvertVector3(blendShapeNormals[i]);
|
||||
blendShapeNormalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex,
|
||||
blendShapeNormals,
|
||||
glBufferTarget.ARRAY_BUFFER);
|
||||
}
|
||||
|
||||
if (useTangent)
|
||||
{
|
||||
for (int i = 0; i < blendShapeTangents.Length; ++i) blendShapeTangents[i] = axisInverter.InvertVector3(blendShapeTangents[i]);
|
||||
blendShapeTangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex,
|
||||
blendShapeTangents,
|
||||
glBufferTarget.ARRAY_BUFFER);
|
||||
}
|
||||
blendShapeNormals[i] = axisInverter.InvertVector3(blendShapeNormals[i]);
|
||||
}
|
||||
var sparseBase = new SparseBase(mesh.vertices, mesh.normals);
|
||||
for (int i = 0; i < sparseBase.Positions.Length; ++i)
|
||||
{
|
||||
sparseBase.Positions[i] = axisInverter.InvertVector3(sparseBase.Positions[i]);
|
||||
}
|
||||
for (int i = 0; i < sparseBase.Normals.Length; ++i)
|
||||
{
|
||||
sparseBase.Normals[i] = axisInverter.InvertVector3(sparseBase.Normals[i]);
|
||||
}
|
||||
|
||||
if (blendShapePositionAccessorIndex != -1)
|
||||
{
|
||||
gltf.accessors[blendShapePositionAccessorIndex].min = blendShapeVertices.Aggregate(blendShapeVertices[0], (a, b) => new Vector3(Mathf.Min(a.x, b.x), Math.Min(a.y, b.y), Mathf.Min(a.z, b.z))).ToArray();
|
||||
gltf.accessors[blendShapePositionAccessorIndex].max = blendShapeVertices.Aggregate(blendShapeVertices[0], (a, b) => new Vector3(Mathf.Max(a.x, b.x), Math.Max(a.y, b.y), Mathf.Max(a.z, b.z))).ToArray();
|
||||
}
|
||||
|
||||
return new gltfMorphTarget
|
||||
{
|
||||
POSITION = blendShapePositionAccessorIndex,
|
||||
NORMAL = blendShapeNormalAccessorIndex,
|
||||
TANGENT = blendShapeTangentAccessorIndex,
|
||||
};
|
||||
return BlendShapeExporter.Export(gltf, bufferIndex,
|
||||
blendShapeVertices,
|
||||
exportOnlyBlendShapePosition && useNormal ? null : blendShapeNormals,
|
||||
useSparseAccessorForMorphTarget ? sparseBase : default);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,15 @@ namespace UniVRM10
|
|||
{
|
||||
var morphTarget = src.Meshes[meshIndex].MorphTargets[i];
|
||||
positions.AddRange(morphTarget.VertexBuffer.Positions.GetSpan<Vector3>());
|
||||
normals.AddRange(morphTarget.VertexBuffer.Normals.GetSpan<Vector3>());
|
||||
if (morphTarget.VertexBuffer.Normals != null)
|
||||
{
|
||||
normals.AddRange(morphTarget.VertexBuffer.Normals.GetSpan<Vector3>());
|
||||
}
|
||||
else
|
||||
{
|
||||
// fill zero
|
||||
normals.AddRange(Enumerable.Range(0, morphTarget.VertexBuffer.Count).Select(x => Vector3.zero));
|
||||
}
|
||||
}
|
||||
dst.AddBlendShapeFrame(name, 100.0f, positions.ToArray(), normals.ToArray(), null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ namespace UniVRM10
|
|||
// blendShape
|
||||
for (int j = 0; j < mesh.MorphTargets.Count; ++j)
|
||||
{
|
||||
var blendShape = new MeshExportUtil.BlendShapeBuffer(indices.Length);
|
||||
var blendShape = new MeshExportUtil.BlendShapeBuffer(usedIndices.Count);
|
||||
|
||||
// index の順に attributes を蓄える
|
||||
var morph = mesh.MorphTargets[j];
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user