mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-05-11 21:14:19 -05:00
Merge pull request #581 from ousttrue/feature/gltf_export
Add gltf export and fix morphTarget sparse
This commit is contained in:
commit
216ed90161
|
|
@ -500,5 +500,26 @@ namespace UniGLTF
|
|||
|
||||
return Glb.ToBytes(json, buffers[0].GetBytes());
|
||||
}
|
||||
|
||||
public (string, List<glTFBuffer>) ToGltf(string gltfPath)
|
||||
{
|
||||
var f = new JsonFormatter();
|
||||
|
||||
// fix buffer path
|
||||
if (buffers.Count == 1)
|
||||
{
|
||||
var withoutExt = Path.GetFileNameWithoutExtension(gltfPath);
|
||||
buffers[0].uri = $"{withoutExt}.bin";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
f.GenSerialize(this);
|
||||
var json = f.ToString().ParseAsJson().ToString(" ");
|
||||
RemoveUnusedExtensions(json);
|
||||
return (json, buffers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -306,7 +306,7 @@ namespace UniGLTF
|
|||
blendShapePositionAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(bufferIndex, accessorCount,
|
||||
blendShapeVertices,
|
||||
sparseIndices, sparseIndicesViewIndex,
|
||||
glBufferTarget.ARRAY_BUFFER);
|
||||
glBufferTarget.NONE);
|
||||
}
|
||||
|
||||
if (useNormal)
|
||||
|
|
@ -315,7 +315,7 @@ namespace UniGLTF
|
|||
blendShapeNormalAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(bufferIndex, accessorCount,
|
||||
blendShapeNormals,
|
||||
sparseIndices, sparseIndicesViewIndex,
|
||||
glBufferTarget.ARRAY_BUFFER);
|
||||
glBufferTarget.NONE);
|
||||
}
|
||||
|
||||
if (useTangent)
|
||||
|
|
@ -323,7 +323,7 @@ namespace UniGLTF
|
|||
blendShapeTangents = sparseIndices.Select(x => blendShapeTangents[x].ReverseZ()).ToArray();
|
||||
blendShapeTangentAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(bufferIndex, accessorCount,
|
||||
blendShapeTangents, sparseIndices, sparseIndicesViewIndex,
|
||||
glBufferTarget.ARRAY_BUFFER);
|
||||
glBufferTarget.NONE);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -380,6 +380,10 @@ namespace UniGLTF
|
|||
var gltfMesh = ExportPrimitives(gltf, bufferIndex,
|
||||
x.Renderer.name,
|
||||
mesh, materials, unityMaterials);
|
||||
if (gltfMesh.extras == null)
|
||||
{
|
||||
gltfMesh.extras = new glTFMesh_extras();
|
||||
}
|
||||
|
||||
var blendShapeIndexMap = new Dictionary<int, int>();
|
||||
int exportBlendShapes = 0;
|
||||
|
|
@ -395,7 +399,9 @@ namespace UniGLTF
|
|||
}
|
||||
|
||||
// maybe skip
|
||||
var blendShapeName = mesh.GetBlendShapeName(j);
|
||||
blendShapeIndexMap.Add(j, exportBlendShapes++);
|
||||
gltfMesh.extras.targetNames.Add(blendShapeName);
|
||||
|
||||
//
|
||||
// all primitive has same blendShape
|
||||
|
|
@ -403,7 +409,7 @@ namespace UniGLTF
|
|||
for (int k = 0; k < gltfMesh.primitives.Count; ++k)
|
||||
{
|
||||
gltfMesh.primitives[k].targets.Add(morphTarget);
|
||||
gltfMesh.primitives[k].extras.targetNames.Add(mesh.GetBlendShapeName(j));
|
||||
gltfMesh.primitives[k].extras.targetNames.Add(blendShapeName);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,26 +12,45 @@ namespace UniGLTF
|
|||
{
|
||||
public class gltfExporter : IDisposable
|
||||
{
|
||||
const string CONVERT_HUMANOID_KEY = UniGLTFVersion.MENU + "/Export";
|
||||
const string MENU_EXPORT_GLB_KEY = UniGLTFVersion.MENU + "/Export(glb)";
|
||||
const string MENU_EXPORT_GLTF_KEY = UniGLTFVersion.MENU + "/Export(gltf)";
|
||||
|
||||
#if UNITY_EDITOR
|
||||
[MenuItem(CONVERT_HUMANOID_KEY, true, 1)]
|
||||
[MenuItem(MENU_EXPORT_GLTF_KEY, true, 1)]
|
||||
[MenuItem(MENU_EXPORT_GLB_KEY, true, 1)]
|
||||
private static bool ExportValidate()
|
||||
{
|
||||
return Selection.activeObject != null && Selection.activeObject is GameObject;
|
||||
}
|
||||
|
||||
[MenuItem(CONVERT_HUMANOID_KEY, false, 1)]
|
||||
private static void ExportFromMenu()
|
||||
[MenuItem(MENU_EXPORT_GLTF_KEY, false, 1)]
|
||||
private static void ExportGltfFromMenu()
|
||||
{
|
||||
ExportFromMenu(false, new MeshExportSettings
|
||||
{
|
||||
ExportOnlyBlendShapePosition = false,
|
||||
UseSparseAccessorForMorphTarget = true,
|
||||
});
|
||||
}
|
||||
|
||||
[MenuItem(MENU_EXPORT_GLB_KEY, false, 1)]
|
||||
private static void ExportGlbFromMenu()
|
||||
{
|
||||
ExportFromMenu(true, MeshExportSettings.Default);
|
||||
}
|
||||
|
||||
private static void ExportFromMenu(bool isGlb, MeshExportSettings settings)
|
||||
{
|
||||
var go = Selection.activeObject as GameObject;
|
||||
|
||||
var ext = isGlb ? "glb" : "gltf";
|
||||
|
||||
if (go.transform.position == Vector3.zero &&
|
||||
go.transform.rotation == Quaternion.identity &&
|
||||
go.transform.localScale == Vector3.one)
|
||||
{
|
||||
var path = EditorUtility.SaveFilePanel(
|
||||
"Save glb", "", go.name + ".glb", "glb");
|
||||
$"Save {ext}", "", go.name + $".{ext}", $"{ext}");
|
||||
if (string.IsNullOrEmpty(path))
|
||||
{
|
||||
return;
|
||||
|
|
@ -41,10 +60,28 @@ namespace UniGLTF
|
|||
using (var exporter = new gltfExporter(gltf))
|
||||
{
|
||||
exporter.Prepare(go);
|
||||
exporter.Export(MeshExportSettings.Default);
|
||||
exporter.Export(settings);
|
||||
}
|
||||
|
||||
if (isGlb)
|
||||
{
|
||||
var bytes = gltf.ToGlbBytes();
|
||||
File.WriteAllBytes(path, bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
var (json, buffers) = gltf.ToGltf(path);
|
||||
// without BOM
|
||||
var encoding = new System.Text.UTF8Encoding(false);
|
||||
File.WriteAllText(path, json, encoding);
|
||||
// write to local folder
|
||||
var dir = Path.GetDirectoryName(path);
|
||||
foreach (var b in buffers)
|
||||
{
|
||||
var bufferPath = Path.Combine(dir, b.uri);
|
||||
File.WriteAllBytes(bufferPath, b.GetBytes().ToArray());
|
||||
}
|
||||
}
|
||||
var bytes = gltf.ToGlbBytes();
|
||||
File.WriteAllBytes(path, bytes);
|
||||
|
||||
if (path.StartsWithUnityAssetPath())
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user