// public void Process(glTF gltf, IStorage storage) // { // ProcessOnAnyThread(gltf, storage); // ProcessOnMainThreadCoroutine(gltf).CoroutinetoEnd(); // } public IEnumerator ProcessCoroutine(GLTFRoot gltf, IStorage storage) { ProcessOnAnyThread(gltf, storage); yield return(ProcessOnMainThreadCoroutine(gltf)); }
public void ProcessOnAnyThread(GLTFRoot gltf, IStorage storage) { _textureLoader.ProcessOnAnyThread(gltf, storage); }
private GLTFMorphTarget ExportMorphTarget(GLTFRoot gltf, int bufferIndex, Mesh mesh, int j, bool useSparseAccessorForMorphTarget) { var blendShapeVertices = mesh.vertices; var usePosition = blendShapeVertices != null && blendShapeVertices.Length > 0; var blendShapeNormals = mesh.normals; var useNormal = usePosition && blendShapeNormals != null && blendShapeNormals.Length == blendShapeVertices.Length; 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(j); mesh.GetBlendShapeFrameVertices(j, frameCount - 1, blendShapeVertices, blendShapeNormals, null); var blendShapePositionAccessorIndex = -1; var blendShapeNormalAccessorIndex = -1; var blendShapeTangentAccessorIndex = -1; if (useSparseAccessorForMorphTarget) { 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 vertexSize = 12; * if (useNormal) vertexSize += 12; * if (useTangent) vertexSize += 24; * var sparseBytes = (4 + vertexSize) * sparseIndices.Length; * var fullBytes = (vertexSize) * blendShapeVertices.Length; * Debug.LogFormat("Export sparse: {0}/{1}bytes({2}%)", * sparseBytes, fullBytes, (int)((float)sparseBytes / fullBytes) * ); */ var sparseIndicesViewIndex = -1; if (usePosition) { sparseIndicesViewIndex = gltf.ExtendBufferAndGetViewIndex(bufferIndex, sparseIndices); blendShapeVertices = sparseIndices.Select(x => blendShapeVertices[x].ReverseZ()).ToArray(); blendShapePositionAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(bufferIndex, accessorCount, blendShapeVertices, sparseIndices, sparseIndicesViewIndex, GLTFBufferTarget.ARRAY_BUFFER); } if (useNormal) { blendShapeNormals = sparseIndices.Select(x => blendShapeNormals[x].ReverseZ()).ToArray(); blendShapeNormalAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(bufferIndex, accessorCount, blendShapeNormals, sparseIndices, sparseIndicesViewIndex, GLTFBufferTarget.ARRAY_BUFFER); } if (useTangent) { blendShapeTangents = sparseIndices.Select(x => blendShapeTangents[x].ReverseZ()).ToArray(); blendShapeTangentAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(bufferIndex, accessorCount, blendShapeTangents, sparseIndices, sparseIndicesViewIndex, GLTFBufferTarget.ARRAY_BUFFER); } } else { for (int i = 0; i < blendShapeVertices.Length; ++i) { blendShapeVertices[i] = blendShapeVertices[i].ReverseZ(); } if (usePosition) { blendShapePositionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, blendShapeVertices, GLTFBufferTarget.ARRAY_BUFFER); } if (useNormal) { for (int i = 0; i < blendShapeNormals.Length; ++i) { blendShapeNormals[i] = blendShapeNormals[i].ReverseZ(); } blendShapeNormalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, blendShapeNormals, GLTFBufferTarget.ARRAY_BUFFER); } if (useTangent) { for (int i = 0; i < blendShapeTangents.Length; ++i) { blendShapeTangents[i] = blendShapeTangents[i].ReverseZ(); } blendShapeTangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, blendShapeTangents, GLTFBufferTarget.ARRAY_BUFFER); } } 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, }); }
private GLTFMesh ExportPrimitives(GLTFRoot gltf, int bufferIndex, string rendererName, Mesh mesh, Material[] materials, List <Material> unityMaterials) { var positions = mesh.vertices.Select(y => y.ReverseZ()).ToArray(); var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, positions, GLTFBufferTarget.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(); var normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.normals.Select(y => y.ReverseZ()).ToArray(), GLTFBufferTarget.ARRAY_BUFFER); #if GLTF_EXPORT_TANGENTS var tangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.tangents.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER); #endif var uvAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.uv.Select(y => y.ReverseUV()).ToArray(), GLTFBufferTarget.ARRAY_BUFFER); var colorAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.colors, GLTFBufferTarget.ARRAY_BUFFER); var boneweights = mesh.boneWeights; var weightAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, boneweights.Select(y => new Vector4(y.weight0, y.weight1, y.weight2, y.weight3)).ToArray(), GLTFBufferTarget.ARRAY_BUFFER); var jointsAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, boneweights.Select(y => new UShort4((ushort)y.boneIndex0, (ushort)y.boneIndex1, (ushort)y.boneIndex2, (ushort)y.boneIndex3)).ToArray(), GLTFBufferTarget.ARRAY_BUFFER); var attributes = new GLTFAttributes { POSITION = positionAccessorIndex, }; if (normalAccessorIndex != -1) { attributes.NORMAL = normalAccessorIndex; } #if GLTF_EXPORT_TANGENTS if (tangentAccessorIndex != -1) { attributes.TANGENT = tangentAccessorIndex; } #endif if (uvAccessorIndex != -1) { attributes.TEXCOORD_0 = uvAccessorIndex; } if (colorAccessorIndex != -1) { attributes.COLOR_0 = colorAccessorIndex; } if (weightAccessorIndex != -1) { attributes.WEIGHTS_0 = weightAccessorIndex; } if (jointsAccessorIndex != -1) { attributes.JOINTS_0 = jointsAccessorIndex; } var gltfMesh = new GLTFMesh(mesh.name); for (int j = 0; j < mesh.subMeshCount; ++j) { var indices = mesh.GetIndices(j).FlipTriangle().Select(y => (uint)y).ToArray(); var indicesAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, indices, GLTFBufferTarget.ELEMENT_ARRAY_BUFFER); if (j >= materials.Length) { Debug.LogWarningFormat("{0}.materials is not enough", rendererName); break; } gltfMesh.primitives.Add(new GLTFPrimitives { attributes = attributes, indices = indicesAccessorIndex, mode = 4, // triangels ? material = unityMaterials.IndexOf(materials[j]) }); } return(gltfMesh); }
public void ProcessOnAnyThread(GLTFRoot gltf, IStorage storage) { }
public void ProcessOnAnyThread(GLTFRoot gltf, IStorage storage) { var imageIndex = gltf.GetImageIndexFromTextureIndex(m_textureIndex); m_segments = gltf.GetImageBytes(storage, imageIndex, out m_textureName, out url); }
public GLTFExporter(GLTFRoot gltf) : this(gltf, null, null, null) { }
void FromGameObject(GLTFRoot gltf, GameObject go, bool useSparseAccessorForMorphTarget = false, int textureFormat = 0) { var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]); var bufferIndex = gltf.AddBuffer(bytesBuffer); GameObject tmpParent = null; if (go.transform.childCount == 0) { tmpParent = new GameObject("tmpParent"); go.transform.SetParent(tmpParent.transform, true); go = tmpParent; } try { // exclude root object for the symmetry with the importer nodes = go.transform.Traverse().Skip(1).ToList(); #region Materials and Textures materials = nodes.SelectMany(x => x.GetSharedMaterials()).Where(x => x != null).Distinct().ToList(); var unityTextures = materials.SelectMany(x => x.GetTextures()).Where(x => x.Texture != null).Distinct().ToList(); textureManager = new TextureExportManager(unityTextures); gltf.materials = materials.Select(x => _materialExporter.ExportMaterial(x, textureManager)).ToList(); Debug.Log("image count = " + unityTextures.Count); for (int i = 0; i < unityTextures.Count; ++i) { gltf.ExportTexture(bufferIndex, textureManager.GetExportTexture(i), unityTextures[i].TextureType, textureFormat); } #endregion #region Meshes var unityMeshes = nodes .Select(x => new MeshWithRenderer { mesh = x.GetSharedMesh(), rendererer = x.GetComponent <Renderer>(), }) .Where(x => { if (x.mesh == null) { return(false); } if (x.rendererer.sharedMaterials == null || x.rendererer.sharedMaterials.Length == 0) { return(false); } return(true); }) .ToList(); Debug.Log("unityMesher...." + unityMeshes.Count); _meshExporter.Export(gltf, bufferIndex, unityMeshes, materials, useSparseAccessorForMorphTarget); meshes = unityMeshes.Select(x => x.mesh).ToList(); #endregion #region Skins var unitySkins = nodes .Select(x => x.GetComponent <SkinnedMeshRenderer>()).Where(x => x != null && x.bones != null && x.bones.Length > 0) .ToList(); gltf.nodes = nodes.Select(x => ExportNode(x, nodes, unityMeshes.Select(y => y.mesh).ToList(), unitySkins)).ToList(); gltf.scenes = new List <GLTFScene> { new GLTFScene { nodes = go.transform.GetChildren().Select(x => nodes.IndexOf(x)).ToArray(), } }; foreach (var x in unitySkins) { var matrices = x.sharedMesh.bindposes.Select(y => y.ReverseZ()).ToArray(); var accessor = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, matrices, GLTFBufferTarget.NONE); var skin = new GLTFSkin { inverseBindMatrices = accessor, joints = x.bones.Select(y => nodes.IndexOf(y)).ToArray(), skeleton = nodes.IndexOf(x.rootBone), }; var skinIndex = gltf.skins.Count; gltf.skins.Add(skin); foreach (var z in nodes.Where(y => y.HasComponent(x))) { var nodeIndex = nodes.IndexOf(z); var node = gltf.nodes[nodeIndex]; node.skin = skinIndex; } } #endregion #if UNITY_EDITOR #region Animations var clips = new List <AnimationClip>(); var animator = go.GetComponent <Animator>(); var animation = go.GetComponent <Animation>(); if (animator != null) { clips = _animationExporter.GetAnimationClips(animator); } else if (animation != null) { clips = _animationExporter.GetAnimationClips(animation); } if (clips.Any()) { Debug.Log("export clips.." + clips.Count); foreach (AnimationClip clip in clips) { var animationWithCurve = _animationExporter.Export(clip, go.transform, nodes); foreach (var kv in animationWithCurve.samplers) { var sampler = animationWithCurve.animation.samplers[kv.Key]; var inputAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.input); sampler.input = inputAccessorIndex; var outputAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.output); sampler.output = outputAccessorIndex; Debug.Log(sampler.interpolation + ">>" + string.Join(",", kv.Value.output)); // modify accessors var outputAccessor = gltf.accessors[outputAccessorIndex]; var channel = animationWithCurve.animation.channels.First(x => x.sampler == kv.Key); switch (GLTFAnimationTarget.GetElementCount(channel.target.path)) { case 1: outputAccessor.type = "SCALAR"; //outputAccessor.count = ; break; case 3: outputAccessor.type = "VEC3"; outputAccessor.count /= 3; break; case 4: outputAccessor.type = "VEC4"; outputAccessor.count /= 4; break; default: throw new NotImplementedException(); } } animationWithCurve.animation.name = clip.name; gltf.animations.Add(animationWithCurve.animation); } } #endregion #endif } finally { if (tmpParent != null) { tmpParent.transform.GetChild(0).SetParent(null); if (Application.isPlaying) { GameObject.Destroy(tmpParent); } else { GameObject.DestroyImmediate(tmpParent); } } } }
public static int ExtendBufferAndGetViewIndex <T>(this GLTFRoot gltf, int bufferIndex, T[] array, GLTFBufferTarget target = GLTFBufferTarget.NONE) where T : struct { return(ExtendBufferAndGetViewIndex(gltf, bufferIndex, new ArraySegment <T>(array), target)); }