implement BlendShapeExporter.Export

This commit is contained in:
ousttrue 2021-06-04 15:40:44 +09:00
parent 7e42a8bd12
commit 80abc5d7ce
4 changed files with 77 additions and 95 deletions

View File

@ -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
{

View File

@ -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);
}
}
}

View File

@ -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);
}

View File

@ -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];