Beispiel #1
0
 public static async Awaitable <Material> CreateAsync(glTF gltf, int i, GetTextureAsyncFunc getTexture, bool hasVertexColor)
 {
     if (getTexture == null)
     {
         getTexture = (_x, _y) => Awaitable.FromResult <Texture2D>(default);
        public static IEnumerable <(Mesh, glTFMesh, Dictionary <int, int>)> ExportMeshes(glTF gltf, int bufferIndex,
                                                                                         List <MeshWithRenderer> unityMeshes, List <Material> unityMaterials,
                                                                                         MeshExportSettings settings)
        {
            foreach (var unityMesh in unityMeshes)
            {
                var gltfMesh = ExportPrimitives(gltf, bufferIndex,
                                                unityMesh, unityMaterials);

                var targetNames = new List <string>();

                var blendShapeIndexMap = new Dictionary <int, int>();
                int exportBlendShapes  = 0;
                for (int j = 0; j < unityMesh.Mesh.blendShapeCount; ++j)
                {
                    var morphTarget = ExportMorphTarget(gltf, bufferIndex,
                                                        unityMesh.Mesh, j,
                                                        settings.UseSparseAccessorForMorphTarget,
                                                        settings.ExportOnlyBlendShapePosition);
                    if (morphTarget.POSITION < 0 && morphTarget.NORMAL < 0 && morphTarget.TANGENT < 0)
                    {
                        continue;
                    }

                    // maybe skip
                    var blendShapeName = unityMesh.Mesh.GetBlendShapeName(j);
                    blendShapeIndexMap.Add(j, exportBlendShapes++);
                    targetNames.Add(blendShapeName);

                    //
                    // all primitive has same blendShape
                    //
                    for (int k = 0; k < gltfMesh.primitives.Count; ++k)
                    {
                        gltfMesh.primitives[k].targets.Add(morphTarget);
                    }
                }

                gltf_mesh_extras_targetNames.Serialize(gltfMesh, targetNames);

                yield return(unityMesh.Mesh, gltfMesh, blendShapeIndexMap);
            }
        }
Beispiel #3
0
        static glTFMesh ExportPrimitives(glTF gltf, int bufferIndex,
                                         Mesh mesh, Material[] materials,
                                         List <Material> unityMaterials)
        {
            var positions             = mesh.vertices.Select(y => y.ReverseZ()).ToArray();
            var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, 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();

            var normalAccessorIndex  = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.normals.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER);
            var tangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.tangents.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER);
            var uvAccessorIndex      = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.uv.Select(y => y.ReverseY()).ToArray(), glBufferTarget.ARRAY_BUFFER);
            var colorAccessorIndex   = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.colors, glBufferTarget.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(), glBufferTarget.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(), glBufferTarget.ARRAY_BUFFER);

            var attributes = new glTFAttributes
            {
                POSITION = positionAccessorIndex,
            };

            if (normalAccessorIndex != -1)
            {
                attributes.NORMAL = normalAccessorIndex;
            }
            if (tangentAccessorIndex != -1)
            {
                attributes.TANGENT = tangentAccessorIndex;
            }
            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 = TriangleUtil.FlipTriangle(mesh.GetIndices(j)).Select(y => (uint)y).ToArray();
                var indicesAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, indices, glBufferTarget.ELEMENT_ARRAY_BUFFER);

                gltfMesh.primitives.Add(new glTFPrimitives
                {
                    attributes = attributes,
                    indices    = indicesAccessorIndex,
                    mode       = 4, // triangels ?
                    material   = unityMaterials.IndexOf(materials[j])
                });
            }
            return(gltfMesh);
        }
Beispiel #4
0
        public static Exported FromGameObject(glTF gltf, GameObject go)
        {
            var bytesBuffer = new ArrayByteBuffer();
            var bufferIndex = gltf.AddBuffer(bytesBuffer);

            var unityNodes = go.transform.Traverse()
                             .Skip(1) // exclude root object for the symmetry with the importer
                             .ToList();

            #region Material
            var unityMaterials = unityNodes.SelectMany(x => x.GetSharedMaterials()).Where(x => x != null).Distinct().ToList();
            var unityTextures  = unityMaterials.SelectMany(x => x.GetTextures()).Where(x => x != null).Distinct().ToList();

            for (int i = 0; i < unityTextures.Count; ++i)
            {
                var texture = unityTextures[i];

                var bytesWithPath = new BytesWithPath(texture);;

                // add view
                var view      = gltf.buffers[bufferIndex].Storage.Extend(bytesWithPath.Bytes, glBufferTarget.NONE);
                var viewIndex = gltf.AddBufferView(view);

                // add image
                var imageIndex = gltf.images.Count;
                gltf.images.Add(new glTFImage
                {
                    bufferView = viewIndex,
                    mimeType   = bytesWithPath.Mime,
                });

                // add sampler
                var filter = default(glFilter);
                switch (texture.filterMode)
                {
                case FilterMode.Point:
                    filter = glFilter.NEAREST;
                    break;

                default:
                    filter = glFilter.LINEAR;
                    break;
                }
                var wrap = default(glWrap);

                switch (texture.wrapMode)
                {
                case TextureWrapMode.Clamp:
                    wrap = glWrap.CLAMP_TO_EDGE;
                    break;

                case TextureWrapMode.Repeat:
                    wrap = glWrap.REPEAT;
                    break;

#if UNITY_2017_OR_NEWER
                case TextureWrapMode.Mirror:
                    wrap = glWrap.MIRRORED_REPEAT;
                    break;
#endif

                default:
                    throw new NotImplementedException();
                }

                var samplerIndex = gltf.samplers.Count;
                gltf.samplers.Add(new glTFTextureSampler
                {
                    magFilter = filter,
                    minFilter = filter,
                    wrapS     = wrap,
                    wrapT     = wrap,
                });

                // add texture
                gltf.textures.Add(new glTFTexture
                {
                    sampler = samplerIndex,
                    source  = imageIndex,
                });
            }

            gltf.materials = unityMaterials.Select(x => ExportMaterial(x, unityTextures)).ToList();
            #endregion

            #region Meshes
            var unityMeshes = unityNodes
                              .Select(x => new MeshWithRenderer
            {
                Mesh       = x.GetSharedMesh(),
                Rendererer = x.GetComponent <Renderer>(),
            })
                              .Where(x => x.Mesh != null)
                              .ToList();
            for (int i = 0; i < unityMeshes.Count; ++i)
            {
                var x         = unityMeshes[i];
                var mesh      = x.Mesh;
                var materials = x.Rendererer.sharedMaterials;

                var positions             = mesh.vertices.Select(y => y.ReverseZ()).ToArray();
                var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, 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();

                var normalAccessorIndex  = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.normals.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER);
                var tangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.tangents.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER);
                var colorAccessorIndex   = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.colors.Select(y => (Vector4)y).ToArray(), glBufferTarget.ARRAY_BUFFER);
                var uvAccessorIndex      = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.uv.Select(y => y.ReverseY()).ToArray(), glBufferTarget.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(), glBufferTarget.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(), glBufferTarget.ARRAY_BUFFER);

                var attributes = new glTFAttributes
                {
                    POSITION = positionAccessorIndex,
                };
                if (normalAccessorIndex != -1)
                {
                    attributes.NORMAL = normalAccessorIndex;
                }
                if (tangentAccessorIndex != -1)
                {
                    attributes.TANGENT = tangentAccessorIndex;
                }
                if (colorAccessorIndex != -1)
                {
                    attributes.COLOR_0 = colorAccessorIndex;
                }
                if (uvAccessorIndex != -1)
                {
                    attributes.TEXCOORD_0 = uvAccessorIndex;
                }
                if (weightAccessorIndex != -1)
                {
                    attributes.WEIGHTS_0 = weightAccessorIndex;
                }
                if (jointsAccessorIndex != -1)
                {
                    attributes.JOINTS_0 = jointsAccessorIndex;
                }

                gltf.meshes.Add(new glTFMesh(mesh.name));

                for (int j = 0; j < mesh.subMeshCount; ++j)
                {
                    var indices = TriangleUtil.FlipTriangle(mesh.GetIndices(j)).Select(y => (uint)y).ToArray();
                    var indicesAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, indices, glBufferTarget.ELEMENT_ARRAY_BUFFER);

                    gltf.meshes.Last().primitives.Add(new glTFPrimitives
                    {
                        attributes = attributes,
                        indices    = indicesAccessorIndex,
                        mode       = 4,                                 // triangels ?
                        //material = unityMaterials.IndexOf(materials[j])
                        material = unityMaterials.IndexOf(materials[0]) // JIA change for Maquette image entity
                    });
                }

                if (mesh.blendShapeCount > 0)
                {
                    for (int j = 0; j < mesh.blendShapeCount; ++j)
                    {
                        var blendShapeVertices = mesh.vertices;
                        var blendShpaeNormals  = mesh.normals;
                        var blendShapeTangents = mesh.tangents.Select(y => (Vector3)y).ToArray();
                        var blendShapeColors   = mesh.colors.Select(y => (Vector4)y).ToArray();
                        var k = mesh.GetBlendShapeFrameCount(j);
                        mesh.GetBlendShapeFrameVertices(j, k - 1, blendShapeVertices, blendShpaeNormals, null);

                        var blendShapePositionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex,
                                                                                                   blendShapeVertices.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER);
                        var blendShapeNormalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex,
                                                                                                 blendShpaeNormals.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER);
                        var blendShapeTangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex,
                                                                                                  blendShapeTangents.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER);
                        var blendShapeColorAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex,
                                                                                                blendShapeColors.ToArray(), glBufferTarget.ARRAY_BUFFER);
                        //
                        // first primitive has whole blendShape
                        //
                        gltf.meshes.Last().primitives[0].targets.Add(new glTFAttributes
                        {
                            POSITION = blendShapePositionAccessorIndex,
                            NORMAL   = blendShapeNormalAccessorIndex,
                            TANGENT  = blendShapeTangentAccessorIndex,
                            COLOR_0  = blendShapeColorAccessorIndex,
                        });
                    }
                }
            }
            #endregion

            #region Skins
            var unitySkins = unityNodes
                             .Select(x => x.GetComponent <SkinnedMeshRenderer>()).Where(x => x != null)
                             .ToList();
            gltf.nodes  = unityNodes.Select(x => ExportNode(x, unityNodes, unityMeshes.Select(y => y.Mesh).ToList(), unitySkins)).ToList();
            gltf.scenes = new List <gltfScene>
            {
                new gltfScene
                {
                    nodes = go.transform.GetChildren().Select(x => unityNodes.IndexOf(x)).ToArray(),
                }
            };

            foreach (var x in unitySkins)
            {
                var matrices = x.sharedMesh.bindposes.Select(y => y.ReverseZ()).ToArray();
                var accessor = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, matrices, glBufferTarget.NONE);

                var skin = new glTFSkin
                {
                    inverseBindMatrices = accessor,
                    joints   = x.bones.Select(y => unityNodes.IndexOf(y)).ToArray(),
                    skeleton = unityNodes.IndexOf(x.rootBone),
                };
                var skinIndex = gltf.skins.Count;
                gltf.skins.Add(skin);

                foreach (var z in unityNodes.Where(y => y.Has(x)))
                {
                    var nodeIndex = unityNodes.IndexOf(z);
                    gltf.nodes[nodeIndex].skin = skinIndex;
                }
            }
            #endregion

#if UNITY_EDITOR
            #region Animations
            var animation = go.GetComponent <Animation>();
            if (animation != null)
            {
                foreach (AnimationState state in animation)
                {
                    var animationWithCurve = ExportAnimation(state.clip, go.transform, unityNodes);

                    foreach (var kv in animationWithCurve.SamplerMap)
                    {
                        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;

                        // 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 3:
                            outputAccessor.type   = "VEC3";
                            outputAccessor.count /= 3;
                            break;

                        case 4:
                            outputAccessor.type   = "VEC4";
                            outputAccessor.count /= 4;
                            break;

                        default:
                            throw new NotImplementedException();
                        }
                    }

                    gltf.animations.Add(animationWithCurve.Animation);
                }
            }
            #endregion
#endif

            // glb buffer
            gltf.buffers[bufferIndex].UpdateByteLength();

            return(new Exported
            {
                Meshes = unityMeshes,
                Nodes = unityNodes.Select(x => x.transform).ToList(),
                Materials = unityMaterials,
                Textures = unityTextures,
            });
        }
        static gltfMorphTarget ExportMorphTarget(glTF gltf, int bufferIndex,
                                                 Mesh mesh, int j,
                                                 bool useSparseAccessorForMorphTarget,
                                                 bool exportOnlyBlendShapePosition)
        {
            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 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 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,
                                                                                                 glBufferTarget.NONE);
                }

                if (useNormal)
                {
                    blendShapeNormals             = sparseIndices.Select(x => blendShapeNormals[x].ReverseZ()).ToArray();
                    blendShapeNormalAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(bufferIndex, accessorCount,
                                                                                               blendShapeNormals,
                                                                                               sparseIndices, sparseIndicesViewIndex,
                                                                                               glBufferTarget.NONE);
                }

                if (useTangent)
                {
                    blendShapeTangents             = sparseIndices.Select(x => blendShapeTangents[x].ReverseZ()).ToArray();
                    blendShapeTangentAccessorIndex = gltf.ExtendSparseBufferAndGetAccessorIndex(bufferIndex, accessorCount,
                                                                                                blendShapeTangents, sparseIndices, sparseIndicesViewIndex,
                                                                                                glBufferTarget.NONE);
                }
            }
            else
            {
                for (int i = 0; i < blendShapeVertices.Length; ++i)
                {
                    blendShapeVertices[i] = blendShapeVertices[i].ReverseZ();
                }
                if (usePosition)
                {
                    blendShapePositionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex,
                                                                                           blendShapeVertices,
                                                                                           glBufferTarget.ARRAY_BUFFER);
                }

                if (useNormal)
                {
                    for (int i = 0; i < blendShapeNormals.Length; ++i)
                    {
                        blendShapeNormals[i] = blendShapeNormals[i].ReverseZ();
                    }
                    blendShapeNormalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex,
                                                                                         blendShapeNormals,
                                                                                         glBufferTarget.ARRAY_BUFFER);
                }

                if (useTangent)
                {
                    for (int i = 0; i < blendShapeTangents.Length; ++i)
                    {
                        blendShapeTangents[i] = blendShapeTangents[i].ReverseZ();
                    }
                    blendShapeTangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex,
                                                                                          blendShapeTangents,
                                                                                          glBufferTarget.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,
            });
        }
Beispiel #6
0
        public void ProcessOnAnyThread(glTF gltf, IStorage storage)
        {
            var imageIndex = gltf.GetImageIndexFromTextureIndex(m_textureIndex);

            m_segments = gltf.GetImageBytes(storage, imageIndex, out m_textureName);
        }
Beispiel #7
0
        public void GlTFToJsonTest()
        {
            var gltf = new glTF();

            using (var exporter = new gltfExporter(gltf))
            {
                exporter.Prepare(CreateSimpleScene());
                exporter.Export(MeshExportSettings.Default, AssetTextureUtil.IsTextureEditorAsset, AssetTextureUtil.GetTextureBytesWithMime);
            }

            var expected = gltf.ToJson().ParseAsJson();

            expected.AddKey(Utf8String.From("meshes"));
            expected.AddValue(default(ArraySegment <byte>), ValueNodeType.Array);
            expected["meshes"].AddValue(default(ArraySegment <byte>), ValueNodeType.Object);

            var mesh = expected["meshes"][0];

            mesh.AddKey(Utf8String.From("name"));
            mesh.AddValue(Utf8String.From(JsonString.Quote("test")).Bytes, ValueNodeType.String);
            mesh.AddKey(Utf8String.From("primitives"));
            mesh.AddValue(default(ArraySegment <byte>), ValueNodeType.Array);
            mesh["primitives"].AddValue(default(ArraySegment <byte>), ValueNodeType.Object);

            var primitive = mesh["primitives"][0];

            primitive.AddKey(Utf8String.From("mode"));
            primitive.AddValue(Utf8String.From("0").Bytes, ValueNodeType.Integer);
            primitive.AddKey(Utf8String.From("indices"));
            primitive.AddValue(Utf8String.From("0").Bytes, ValueNodeType.Integer);
            primitive.AddKey(Utf8String.From("material"));
            primitive.AddValue(Utf8String.From("0").Bytes, ValueNodeType.Integer);
            primitive.AddKey(Utf8String.From("attributes"));
            primitive.AddValue(default(ArraySegment <byte>), ValueNodeType.Object);
            primitive["attributes"].AddKey(Utf8String.From("POSITION"));
            primitive["attributes"].AddValue(Utf8String.From("0").Bytes, ValueNodeType.Integer);
            primitive.AddKey(Utf8String.From("targets"));
            primitive.AddValue(default(ArraySegment <byte>), ValueNodeType.Array);
            primitive["targets"].AddValue(default(ArraySegment <byte>), ValueNodeType.Object);
            primitive["targets"][0].AddKey(Utf8String.From("POSITION"));
            primitive["targets"][0].AddValue(Utf8String.From("1").Bytes, ValueNodeType.Integer);
            primitive["targets"].AddValue(default(ArraySegment <byte>), ValueNodeType.Object);
            primitive["targets"][1].AddKey(Utf8String.From("POSITION"));
            primitive["targets"][1].AddValue(Utf8String.From("2").Bytes, ValueNodeType.Integer);
            primitive["targets"][1].AddKey(Utf8String.From("TANGENT"));
            primitive["targets"][1].AddValue(Utf8String.From("0").Bytes, ValueNodeType.Integer);

            gltf.meshes.Add(new glTFMesh("test")
            {
                primitives = new List <glTFPrimitives>
                {
                    new glTFPrimitives
                    {
                        indices    = 0,
                        attributes = new glTFAttributes
                        {
                            POSITION = 0,
                            TANGENT  = -1 // should be removed
                        },
                        targets = new List <gltfMorphTarget>
                        {
                            new gltfMorphTarget
                            {
                                POSITION = 1,
                                TANGENT  = -1 // should be removed
                            },
                            new gltfMorphTarget
                            {
                                POSITION = 2,
                                TANGENT  = 0
                            }
                        }
                    }
                }
            });
            var actual = gltf.ToJson().ParseAsJson();

            Assert.AreEqual(expected, actual);
        }
Beispiel #8
0
        public static Exported FromGameObject(glTF gltf, GameObject go, bool useSparseAccessorForMorphTarget = false)
        {
            var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]);
            var bufferIndex = gltf.AddBuffer(bytesBuffer);

            if (go.transform.childCount == 0)
            {
                throw new UniGLTFException("empty root GameObject required");
            }

            var unityNodes = go.transform.Traverse()
                             .Skip(1) // exclude root object for the symmetry with the importer
                             .ToList();

            #region Materials and Textures
            var unityMaterials = unityNodes.SelectMany(x => x.GetSharedMaterials()).Where(x => x != null).Distinct().ToList();
            var unityTextures  = unityMaterials.SelectMany(x => x.GetTextures()).Where(x => x != null).Distinct().ToList();

            for (int i = 0; i < unityTextures.Count; ++i)
            {
                var texture = unityTextures[i];
                TextureIO.ExportTexture(gltf, bufferIndex, texture);
            }

            gltf.materials = unityMaterials.Select(x => MaterialIO.ExportMaterial(x, unityTextures)).ToList();
            #endregion

            #region Meshes
            var unityMeshes = unityNodes
                              .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();
            ExportMeshes(gltf, bufferIndex, unityMeshes, unityMaterials, useSparseAccessorForMorphTarget);
            #endregion

            #region Skins
            var unitySkins = unityNodes
                             .Select(x => x.GetComponent <SkinnedMeshRenderer>()).Where(x => x != null)
                             .ToList();
            gltf.nodes  = unityNodes.Select(x => ExportNode(x, unityNodes, unityMeshes.Select(y => y.Mesh).ToList(), unitySkins)).ToList();
            gltf.scenes = new List <gltfScene>
            {
                new gltfScene
                {
                    nodes = go.transform.GetChildren().Select(x => unityNodes.IndexOf(x)).ToArray(),
                }
            };

            foreach (var x in unitySkins)
            {
                var matrices = x.sharedMesh.bindposes.Select(y => y.ReverseZ()).ToArray();
                var accessor = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, matrices, glBufferTarget.NONE);

                var skin = new glTFSkin
                {
                    inverseBindMatrices = accessor,
                    joints   = x.bones.Select(y => unityNodes.IndexOf(y)).ToArray(),
                    skeleton = unityNodes.IndexOf(x.rootBone),
                };
                var skinIndex = gltf.skins.Count;
                gltf.skins.Add(skin);

                foreach (var z in unityNodes.Where(y => y.Has(x)))
                {
                    var nodeIndex = unityNodes.IndexOf(z);
                    var node      = gltf.nodes[nodeIndex];
                    node.skin = skinIndex;
                }
            }
            #endregion

#if UNITY_EDITOR
            #region Animations
            var animation = go.GetComponent <Animation>();
            if (animation != null)
            {
                foreach (AnimationState state in animation)
                {
                    var animationWithCurve = ExportAnimation(state.clip, go.transform, unityNodes);

                    foreach (var kv in animationWithCurve.SamplerMap)
                    {
                        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;

                        // 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 3:
                            outputAccessor.type   = "VEC3";
                            outputAccessor.count /= 3;
                            break;

                        case 4:
                            outputAccessor.type   = "VEC4";
                            outputAccessor.count /= 4;
                            break;

                        default:
                            throw new NotImplementedException();
                        }
                    }

                    gltf.animations.Add(animationWithCurve.Animation);
                }
            }
            #endregion
#endif

            return(new Exported
            {
                Meshes = unityMeshes,
                Nodes = unityNodes.Select(x => x.transform).ToList(),
                Materials = unityMaterials,
                Textures = unityTextures,
            });
        }
Beispiel #9
0
 public static GetTextureParam BaseColorTexture(glTF gltf, glTFMaterial src)
 {
     return(GetTextureParam.CreateSRGB(gltf, src.pbrMetallicRoughness.baseColorTexture.index));
 }
Beispiel #10
0
        static glTFMesh ExportPrimitives(glTF 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, 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();

            var normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.normals.Select(y => y.normalized.ReverseZ()).ToArray(), glBufferTarget.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(), glBufferTarget.ARRAY_BUFFER);

            var colorAccessorIndex = -1;

            var vColorState = MeshExportInfo.DetectVertexColor(mesh, materials);
            if (vColorState == MeshExportInfo.VertexColorState.ExistsAndIsUsed || // VColor使っている
                vColorState == MeshExportInfo.VertexColorState.ExistsAndMixed // VColorを使っているところと使っていないところが混在(とりあえずExportする)
                )
            {
                // UniUnlit で Multiply 設定になっている
                colorAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.colors, glBufferTarget.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(), glBufferTarget.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(), glBufferTarget.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 = TriangleUtil.FlipTriangle(mesh.GetIndices(j)).Select(y => (uint)y).ToArray();
                var indicesAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, indices, glBufferTarget.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, // triangles ?
                    material   = unityMaterials.IndexOf(materials[j])
                });
            }
            return(gltfMesh);
        }
Beispiel #11
0
        public static IEnumerable <(Mesh, glTFMesh, Dictionary <int, int>)> ExportMeshes(glTF gltf, int bufferIndex,
                                                                                         List <MeshWithRenderer> unityMeshes, List <Material> unityMaterials,
                                                                                         MeshExportSettings settings)
        {
            for (int i = 0; i < unityMeshes.Count; ++i)
            {
                var x         = unityMeshes[i];
                var mesh      = x.Mesh;
                var materials = x.Renderer.sharedMaterials;

                var gltfMesh = ExportPrimitives(gltf, bufferIndex,
                                                x.Renderer.name,
                                                mesh, materials, unityMaterials);

                var blendShapeIndexMap = new Dictionary <int, int>();
                int exportBlendShapes  = 0;
                for (int j = 0; j < mesh.blendShapeCount; ++j)
                {
                    var morphTarget = ExportMorphTarget(gltf, bufferIndex,
                                                        mesh, j,
                                                        settings.UseSparseAccessorForMorphTarget,
                                                        settings.ExportOnlyBlendShapePosition);
                    if (morphTarget.POSITION < 0 && morphTarget.NORMAL < 0 && morphTarget.TANGENT < 0)
                    {
                        continue;
                    }

                    // maybe skip
                    blendShapeIndexMap.Add(j, exportBlendShapes++);

                    //
                    // all primitive has same blendShape
                    //
                    for (int k = 0; k < gltfMesh.primitives.Count; ++k)
                    {
                        gltfMesh.primitives[k].targets.Add(morphTarget);
                        gltfMesh.primitives[k].extras.targetNames.Add(mesh.GetBlendShapeName(j));
                    }
                }

                yield return(mesh, gltfMesh, blendShapeIndexMap);
            }
        }
        public static glTFMesh Export(glTF gltf, int bufferIndex,
            MeshWithRenderer unityMesh, List<Material> unityMaterials,
            IAxisInverter axisInverter, MeshExportSettings settings)
        {
            var mesh = unityMesh.Mesh;
            var gltfMesh = new glTFMesh(mesh.name);

            if (settings.ExportTangents)
            {
                // support しない
                throw new NotImplementedException();
            }

            var positions = mesh.vertices;
            var normals = mesh.normals;
            var uv = mesh.uv;
            var boneWeights = mesh.boneWeights;

            Func<int, int> getJointIndex = null;
            if (boneWeights != null && boneWeights.Length == positions.Length)
            {
                getJointIndex = unityMesh.GetJointIndex;
            }

            Vector3[] blendShapePositions = new Vector3[mesh.vertexCount];
            Vector3[] blendShapeNormals = new Vector3[mesh.vertexCount];

            var usedIndices = new List<int>();
            for (int i = 0; i < mesh.subMeshCount; ++i)
            {
                var indices = mesh.GetIndices(i);

                // mesh
                // index の順に attributes を蓄える                
                var buffer = new MeshExportUtil.VertexBuffer(indices.Length, getJointIndex);
                usedIndices.Clear();
                for (int k = 0; k < positions.Length; ++k)
                {
                    if (indices.Contains(k))
                    {
                        // indices から参照される頂点だけを蓄える
                        usedIndices.Add(k);
                        buffer.Push(k, axisInverter.InvertVector3(positions[k]), axisInverter.InvertVector3(normals[k]), uv[k].ReverseUV());
                        if (getJointIndex != null)
                        {
                            buffer.Push(boneWeights[k]);
                        }
                    }
                }

                var material = unityMesh.Renderer.sharedMaterials[i];
                var materialIndex = -1;
                if (material != null)
                {
                    materialIndex = unityMaterials.IndexOf(material);
                }

                var flipped = new List<int>();
                for (int j = 0; j < indices.Length; j += 3)
                {
                    var t0 = indices[j];
                    var t1 = indices[j + 1];
                    var t2 = indices[j + 2];
                    flipped.Add(t2);
                    flipped.Add(t1);
                    flipped.Add(t0);
                }
                var gltfPrimitive = buffer.ToGltfPrimitive(gltf, bufferIndex, materialIndex, flipped);

                // blendShape
                for (int j = 0; j < mesh.blendShapeCount; ++j)
                {
                    var blendShape = new MeshExportUtil.BlendShapeBuffer(indices.Length);

                    // index の順に attributes を蓄える                
                    mesh.GetBlendShapeFrameVertices(j, 0, blendShapePositions, blendShapeNormals, null);
                    foreach (var k in usedIndices)
                    {
                        blendShape.Push(
                            axisInverter.InvertVector3(blendShapePositions[k]),
                            axisInverter.InvertVector3(blendShapeNormals[k]));
                    }

                    gltfPrimitive.targets.Add(blendShape.ToGltf(gltf, bufferIndex, !settings.ExportOnlyBlendShapePosition));
                }

                gltfMesh.primitives.Add(gltfPrimitive);
            }

            var targetNames = Enumerable.Range(0, mesh.blendShapeCount).Select(x => mesh.GetBlendShapeName(x)).ToArray();
            gltf_mesh_extras_targetNames.Serialize(gltfMesh, targetNames);

            return gltfMesh;
        }
        public static (glTFMesh gltfMesh, Dictionary <int, int> blendShapeIndexMap) ExportMesh(glTF gltf, int bufferIndex, Mesh mesh, Renderer renderer, List <Material> exportedMaterials, MeshExportSettings meshExportSettings, IAxisInverter axisInverter)
        {
            var meshMaterials = default(Material[]);

            if (renderer != null)
            {
                meshMaterials = renderer.sharedMaterials;
            }

            var boneWeights   = default(BoneWeight[]);
            var jointIndexMap = default(int[]);

            if (renderer is SkinnedMeshRenderer skin)
            {
                var bones       = skin.bones;
                var uniqueBones = bones.Distinct().ToArray();
                jointIndexMap = new int[bones.Length];
                for (var i = 0; i < bones.Length; i++)
                {
                    jointIndexMap[i] = Array.IndexOf(uniqueBones, bones[i]);
                }

                boneWeights = mesh.boneWeights;
            }

            var gltfMesh = ExportPrimitives(gltf, bufferIndex, mesh, meshMaterials, boneWeights, jointIndexMap, exportedMaterials);

            var targetNames = new List <string>();

            var blendShapeIndexMap = new Dictionary <int, int>();
            int exportBlendShapes  = 0;

            for (int j = 0; j < mesh.blendShapeCount; ++j)
            {
                var morphTarget = ExportMorphTarget(gltf, bufferIndex,
                                                    mesh, j,
                                                    meshExportSettings.UseSparseAccessorForMorphTarget,
                                                    meshExportSettings.ExportOnlyBlendShapePosition, axisInverter);
                if (morphTarget.POSITION < 0 && morphTarget.NORMAL < 0 && morphTarget.TANGENT < 0)
                {
                    continue;
                }

                // maybe skip
                var blendShapeName = mesh.GetBlendShapeName(j);
                blendShapeIndexMap.Add(j, exportBlendShapes++);
                targetNames.Add(blendShapeName);

                //
                // all primitive has same blendShape
                //
                for (int k = 0; k < gltfMesh.primitives.Count; ++k)
                {
                    gltfMesh.primitives[k].targets.Add(morphTarget);
                }
            }

            gltf_mesh_extras_targetNames.Serialize(gltfMesh, targetNames);

            return(gltfMesh, blendShapeIndexMap);
        }
Beispiel #14
0
        public static AnimationClip ConvertAnimationClip(glTF gltf, glTFAnimation animation, AxisInverter inverter, glTFNode root = null)
        {
            var clip = new AnimationClip();

            clip.ClearCurves();
            clip.legacy   = true;
            clip.name     = animation.name;
            clip.wrapMode = WrapMode.Loop;

            foreach (var channel in animation.channels)
            {
                var relativePath = RelativePathFrom(gltf.nodes, root, gltf.nodes[channel.target.node]);
                switch (channel.target.path)
                {
                case glTFAnimationTarget.PATH_TRANSLATION:
                {
                    var sampler = animation.samplers[channel.sampler];
                    var input   = gltf.GetArrayFromAccessor <float>(sampler.input);
                    var output  = gltf.FlatternFloatArrayFromAccessor(sampler.output);

                    AnimationImporterUtil.SetAnimationCurve(
                        clip,
                        relativePath,
                        new string[] { "localPosition.x", "localPosition.y", "localPosition.z" },
                        input,
                        output,
                        sampler.interpolation,
                        typeof(Transform),
                        (values, last) =>
                        {
                            Vector3 temp = new Vector3(values[0], values[1], values[2]);
                            return(inverter.InvertVector3(temp).ToArray());
                        }
                        );
                }
                break;

                case glTFAnimationTarget.PATH_ROTATION:
                {
                    var sampler = animation.samplers[channel.sampler];
                    var input   = gltf.GetArrayFromAccessor <float>(sampler.input);
                    var output  = gltf.FlatternFloatArrayFromAccessor(sampler.output);

                    AnimationImporterUtil.SetAnimationCurve(
                        clip,
                        relativePath,
                        new string[] { "localRotation.x", "localRotation.y", "localRotation.z", "localRotation.w" },
                        input,
                        output,
                        sampler.interpolation,
                        typeof(Transform),
                        (values, last) =>
                        {
                            Quaternion currentQuaternion = new Quaternion(values[0], values[1], values[2], values[3]);
                            Quaternion lastQuaternion    = new Quaternion(last[0], last[1], last[2], last[3]);
                            return(AnimationImporterUtil.GetShortest(lastQuaternion, inverter.InvertQuaternion(currentQuaternion)).ToArray());
                        }
                        );

                    clip.EnsureQuaternionContinuity();
                }
                break;

                case glTFAnimationTarget.PATH_SCALE:
                {
                    var sampler = animation.samplers[channel.sampler];
                    var input   = gltf.GetArrayFromAccessor <float>(sampler.input);
                    var output  = gltf.FlatternFloatArrayFromAccessor(sampler.output);

                    AnimationImporterUtil.SetAnimationCurve(
                        clip,
                        relativePath,
                        new string[] { "localScale.x", "localScale.y", "localScale.z" },
                        input,
                        output,
                        sampler.interpolation,
                        typeof(Transform),
                        (values, last) => values);
                }
                break;

                case glTFAnimationTarget.PATH_WEIGHT:
                {
                    var node      = gltf.nodes[channel.target.node];
                    var mesh      = gltf.meshes[node.mesh];
                    var primitive = mesh.primitives.FirstOrDefault();
                    var targets   = primitive.targets;

                    if (!gltf_mesh_extras_targetNames.TryGet(mesh, out List <string> targetNames))
                    {
                        throw new Exception("glTF BlendShape Animation. targetNames invalid.");
                    }

                    var keyNames = targetNames
                                   .Where(x => !string.IsNullOrEmpty(x))
                                   .Select(x => "blendShape." + x)
                                   .ToArray();

                    var sampler = animation.samplers[channel.sampler];
                    var input   = gltf.GetArrayFromAccessor <float>(sampler.input);
                    var output  = gltf.GetArrayFromAccessor <float>(sampler.output);
                    AnimationImporterUtil.SetAnimationCurve(
                        clip,
                        relativePath,
                        keyNames,
                        input,
                        output,
                        sampler.interpolation,
                        typeof(SkinnedMeshRenderer),
                        (values, last) =>
                        {
                            for (int j = 0; j < values.Length; j++)
                            {
                                values[j] *= 100.0f;
                            }
                            return(values);
                        });
                }
                break;

                default:
                    Debug.LogWarningFormat("unknown path: {0}", channel.target.path);
                    break;
                }
            }
            return(clip);
        }
 public static int ExtendBufferAndGetViewIndex <T>(this glTF gltf, int bufferIndex,
                                                   T[] array,
                                                   glBufferTarget target = glBufferTarget.NONE) where T : struct
 {
     return(ExtendBufferAndGetViewIndex(gltf, bufferIndex, new ArraySegment <T>(array), target));
 }
Beispiel #16
0
 public static GetTextureParam NormalTexture(glTF gltf, glTFMaterial src)
 {
     return(GetTextureParam.CreateNormal(gltf, src.normalTexture.index));
 }
Beispiel #17
0
        public static void Serialize(JsonFormatter f, glTF value)
        {
            f.BeginMap();


            if (value.asset != null)
            {
                f.Key("asset");
                Serialize_gltf_asset(f, value.asset);
            }

            if (value.buffers != null && value.buffers.Count >= 1)
            {
                f.Key("buffers");
                Serialize_gltf_buffers(f, value.buffers);
            }

            if (value.bufferViews != null && value.bufferViews.Count >= 1)
            {
                f.Key("bufferViews");
                Serialize_gltf_bufferViews(f, value.bufferViews);
            }

            if (value.accessors != null && value.accessors.Count >= 1)
            {
                f.Key("accessors");
                Serialize_gltf_accessors(f, value.accessors);
            }

            if (value.textures != null && value.textures.Count >= 1)
            {
                f.Key("textures");
                Serialize_gltf_textures(f, value.textures);
            }

            if (value.samplers != null && value.samplers.Count >= 1)
            {
                f.Key("samplers");
                Serialize_gltf_samplers(f, value.samplers);
            }

            if (value.images != null && value.images.Count >= 1)
            {
                f.Key("images");
                Serialize_gltf_images(f, value.images);
            }

            if (value.materials != null && value.materials.Count >= 1)
            {
                f.Key("materials");
                Serialize_gltf_materials(f, value.materials);
            }

            if (value.meshes != null && value.meshes.Count >= 1)
            {
                f.Key("meshes");
                Serialize_gltf_meshes(f, value.meshes);
            }

            if (value.nodes != null && value.nodes.Count >= 1)
            {
                f.Key("nodes");
                Serialize_gltf_nodes(f, value.nodes);
            }

            if (value.skins != null && value.skins.Count >= 1)
            {
                f.Key("skins");
                Serialize_gltf_skins(f, value.skins);
            }

            if (value.scene >= 0)
            {
                f.Key("scene");
                f.Value(value.scene);
            }

            if (value.scenes != null && value.scenes.Count >= 1)
            {
                f.Key("scenes");
                Serialize_gltf_scenes(f, value.scenes);
            }

            if (value.animations != null && value.animations.Count >= 1)
            {
                f.Key("animations");
                Serialize_gltf_animations(f, value.animations);
            }

            if (value.cameras != null && value.cameras.Count >= 1)
            {
                f.Key("cameras");
                Serialize_gltf_cameras(f, value.cameras);
            }

            if (value.extensionsUsed != null && value.extensionsUsed.Count >= 1)
            {
                f.Key("extensionsUsed");
                Serialize_gltf_extensionsUsed(f, value.extensionsUsed);
            }

            if (value.extensionsRequired != null && value.extensionsRequired.Count >= 1)
            {
                f.Key("extensionsRequired");
                Serialize_gltf_extensionsRequired(f, value.extensionsRequired);
            }

            if (value.extensions != null)
            {
                f.Key("extensions");
                value.extensions.Serialize(f);
            }

            if (value.extras != null)
            {
                f.Key("extras");
                value.extras.Serialize(f);
            }

            f.EndMap();
        }
Beispiel #18
0
        public static async Task <Material> CreateAsync(IAwaitCaller awaitCaller, glTF gltf, int i, GetTextureAsyncFunc getTexture)
        {
            if (getTexture == null)
            {
                getTexture = (IAwaitCaller _awaitCaller, glTF _gltf, GetTextureParam _param) => Task.FromResult <Texture2D>(null);
            }

            if (i < 0 || i >= gltf.materials.Count)
            {
                return(MaterialFactory.CreateMaterial(i, null, ShaderName));
            }

            var src           = gltf.materials[i];
            var material      = MaterialFactory.CreateMaterial(i, src, ShaderName);
            var standardParam = default(GetTextureParam);

            if (src.pbrMetallicRoughness != null || src.occlusionTexture != null)
            {
                if (src.pbrMetallicRoughness.metallicRoughnessTexture != null || src.occlusionTexture != null)
                {
                    standardParam = StandardTexture(gltf, src);
                }
                if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4)
                {
                    var color = src.pbrMetallicRoughness.baseColorFactor;
                    material.color = (new Color(color[0], color[1], color[2], color[3])).gamma;
                }

                if (src.pbrMetallicRoughness.baseColorTexture != null && src.pbrMetallicRoughness.baseColorTexture.index != -1)
                {
                    material.mainTexture = await getTexture(awaitCaller, gltf, BaseColorTexture(gltf, src));

                    // Texture Offset and Scale
                    MaterialFactory.SetTextureOffsetAndScale(material, src.pbrMetallicRoughness.baseColorTexture, "_MainTex");
                }

                if (src.pbrMetallicRoughness.metallicRoughnessTexture != null && src.pbrMetallicRoughness.metallicRoughnessTexture.index != -1)
                {
                    material.EnableKeyword("_METALLICGLOSSMAP");

                    var texture = await getTexture(awaitCaller, gltf, standardParam);

                    if (texture != null)
                    {
                        material.SetTexture(GetTextureParam.METALLIC_GLOSS_PROP, texture);
                    }

                    material.SetFloat("_Metallic", 1.0f);
                    // Set 1.0f as hard-coded. See: https://github.com/dwango/UniVRM/issues/212.
                    material.SetFloat("_GlossMapScale", 1.0f);

                    // Texture Offset and Scale
                    MaterialFactory.SetTextureOffsetAndScale(material, src.pbrMetallicRoughness.metallicRoughnessTexture, "_MetallicGlossMap");
                }
                else
                {
                    material.SetFloat("_Metallic", src.pbrMetallicRoughness.metallicFactor);
                    material.SetFloat("_Glossiness", 1.0f - src.pbrMetallicRoughness.roughnessFactor);
                }
            }

            if (src.normalTexture != null && src.normalTexture.index != -1)
            {
                material.EnableKeyword("_NORMALMAP");
                var texture = await getTexture(awaitCaller, gltf, NormalTexture(gltf, src));

                if (texture != null)
                {
                    material.SetTexture(GetTextureParam.NORMAL_PROP, texture);
                    material.SetFloat("_BumpScale", src.normalTexture.scale);
                }

                // Texture Offset and Scale
                MaterialFactory.SetTextureOffsetAndScale(material, src.normalTexture, "_BumpMap");
            }

            if (src.occlusionTexture != null && src.occlusionTexture.index != -1)
            {
                var texture = await getTexture(awaitCaller, gltf, standardParam);

                if (texture != null)
                {
                    material.SetTexture(GetTextureParam.OCCLUSION_PROP, texture);
                    material.SetFloat("_OcclusionStrength", src.occlusionTexture.strength);
                }

                // Texture Offset and Scale
                MaterialFactory.SetTextureOffsetAndScale(material, src.occlusionTexture, "_OcclusionMap");
            }

            if (src.emissiveFactor != null ||
                (src.emissiveTexture != null && src.emissiveTexture.index != -1))
            {
                material.EnableKeyword("_EMISSION");
                material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;

                if (src.emissiveFactor != null && src.emissiveFactor.Length == 3)
                {
                    material.SetColor("_EmissionColor", new Color(src.emissiveFactor[0], src.emissiveFactor[1], src.emissiveFactor[2]));
                }

                if (src.emissiveTexture != null && src.emissiveTexture.index != -1)
                {
                    var texture = await getTexture(awaitCaller, gltf, GetTextureParam.CreateSRGB(gltf, src.emissiveTexture.index));

                    if (texture != null)
                    {
                        material.SetTexture("_EmissionMap", texture);
                    }

                    // Texture Offset and Scale
                    MaterialFactory.SetTextureOffsetAndScale(material, src.emissiveTexture, "_EmissionMap");
                }
            }

            BlendMode blendMode = BlendMode.Opaque;

            // https://forum.unity.com/threads/standard-material-shader-ignoring-setfloat-property-_mode.344557/#post-2229980
            switch (src.alphaMode)
            {
            case "BLEND":
                blendMode = BlendMode.Fade;
                material.SetOverrideTag("RenderType", "Transparent");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                material.SetInt("_ZWrite", 0);
                material.DisableKeyword("_ALPHATEST_ON");
                material.EnableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 3000;
                break;

            case "MASK":
                blendMode = BlendMode.Cutout;
                material.SetOverrideTag("RenderType", "TransparentCutout");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                material.SetInt("_ZWrite", 1);
                material.SetFloat("_Cutoff", src.alphaCutoff);
                material.EnableKeyword("_ALPHATEST_ON");
                material.DisableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = 2450;

                break;

            default:     // OPAQUE
                blendMode = BlendMode.Opaque;
                material.SetOverrideTag("RenderType", "");
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                material.SetInt("_ZWrite", 1);
                material.DisableKeyword("_ALPHATEST_ON");
                material.DisableKeyword("_ALPHABLEND_ON");
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                material.renderQueue = -1;
                break;
            }

            material.SetFloat("_Mode", (float)blendMode);

            return(material);
        }
Beispiel #19
0
 public void ProcessOnAnyThread(glTF gltf, IStorage storage)
 {
 }
Beispiel #20
0
        void FromGameObject(glTF gltf, GameObject go, bool useSparseAccessorForMorphTarget = false)
        {
            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
            {
                Nodes = go.transform.Traverse()
                        .Skip(1) // exclude root object for the symmetry with the importer
                        .ToList();

                #region Materials and Textures
                Materials = Nodes.SelectMany(x => x.GetSharedMaterials()).Where(x => x != null).Distinct().ToList();
                var unityTextures = Materials.SelectMany(x => TextureIO.GetTextures(x)).Where(x => x.Texture != null).Distinct().ToList();

                TextureManager = new TextureExportManager(unityTextures.Select(x => x.Texture));

                var materialExporter = CreateMaterialExporter();
                gltf.materials = Materials.Select(x => materialExporter.ExportMaterial(x, TextureManager)).ToList();

                for (int i = 0; i < unityTextures.Count; ++i)
                {
                    var unityTexture = unityTextures[i];
                    TextureIO.ExportTexture(gltf, bufferIndex, TextureManager.GetExportTexture(i), unityTexture.TextureType);
                }
                #endregion


                #region Meshes
                var unityMeshes = Nodes
                                  .Select(x => new MeshWithRenderer
                {
                    Mesh     = x.GetSharedMesh(),
                    Renderer = x.GetComponent <Renderer>(),
                })
                                  .Where(x =>
                {
                    if (x.Mesh == null)
                    {
                        return(false);
                    }
                    if (x.Renderer.sharedMaterials == null ||
                        x.Renderer.sharedMaterials.Length == 0)
                    {
                        return(false);
                    }

                    return(true);
                })
                                  .ToList();
                MeshExporter.ExportMeshes(gltf, bufferIndex, unityMeshes, Materials, useSparseAccessorForMorphTarget);
                Meshes = unityMeshes.Select(x => x.Mesh).ToList();
                #endregion

                #region Nodes and 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.Renderer).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, glBufferTarget.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.Has(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())
                {
                    foreach (AnimationClip clip in clips)
                    {
                        var animationWithCurve = AnimationExporter.Export(clip, go.transform, Nodes);

                        foreach (var kv in animationWithCurve.SamplerMap)
                        {
                            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;

                            // 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);
                    }
                }
            }
        }
Beispiel #21
0
        public void SameMeshButDifferentMaterialExport()
        {
            var go = new GameObject("same_mesh");

            try
            {
                var shader = Shader.Find("Unlit/Color");

                var cubeA = GameObject.CreatePrimitive(PrimitiveType.Cube);
                {
                    cubeA.transform.SetParent(go.transform);
                    var material = new Material(shader);
                    material.name  = "red";
                    material.color = Color.red;
                    cubeA.GetComponent <Renderer>().sharedMaterial = material;
                }

                {
                    var cubeB = GameObject.Instantiate(cubeA);
                    cubeB.transform.SetParent(go.transform);
                    var material = new Material(shader);
                    material.color = Color.blue;
                    material.name  = "blue";
                    cubeB.GetComponent <Renderer>().sharedMaterial = material;

                    Assert.AreEqual(cubeB.GetComponent <MeshFilter>().sharedMesh, cubeA.GetComponent <MeshFilter>().sharedMesh);
                }

                // export
                var gltf = new glTF();
                var json = default(string);
                using (var exporter = new gltfExporter(gltf))
                {
                    exporter.Prepare(go);
                    exporter.Export(UniGLTF.MeshExportSettings.Default, AssetTextureUtil.IsTextureEditorAsset, AssetTextureUtil.GetTextureBytesWithMime);

                    json = gltf.ToJson();
                }

                Assert.AreEqual(2, gltf.meshes.Count);

                var red = gltf.materials[gltf.meshes[0].primitives[0].material];
                Assert.AreEqual(new float[] { 1, 0, 0, 1 }, red.pbrMetallicRoughness.baseColorFactor);

                var blue = gltf.materials[gltf.meshes[1].primitives[0].material];
                Assert.AreEqual(new float[] { 0, 0, 1, 1 }, blue.pbrMetallicRoughness.baseColorFactor);

                Assert.AreEqual(2, gltf.nodes.Count);

                Assert.AreNotEqual(gltf.nodes[0].mesh, gltf.nodes[1].mesh);

                // import
                {
                    var parser = new GltfParser();
                    parser.ParseJson(json, new SimpleStorage(new ArraySegment <byte>(new byte[1024 * 1024])));

                    using (var context = new ImporterContext(parser))
                    {
                        //Debug.LogFormat("{0}", context.Json);
                        context.Load();

                        var importedRed         = context.Root.transform.GetChild(0);
                        var importedRedMaterial = importedRed.GetComponent <Renderer>().sharedMaterial;
                        Assert.AreEqual("red", importedRedMaterial.name);
                        Assert.AreEqual(Color.red, importedRedMaterial.color);

                        var importedBlue         = context.Root.transform.GetChild(1);
                        var importedBlueMaterial = importedBlue.GetComponent <Renderer>().sharedMaterial;
                        Assert.AreEqual("blue", importedBlueMaterial.name);
                        Assert.AreEqual(Color.blue, importedBlueMaterial.color);
                    }
                }

                // import new version
                {
                    var parser = new GltfParser();
                    parser.ParseJson(json, new SimpleStorage(new ArraySegment <byte>(new byte[1024 * 1024])));
                    //Debug.LogFormat("{0}", context.Json);
                    using (var context = new ImporterContext(parser))
                    {
                        context.Load();

                        var importedRed         = context.Root.transform.GetChild(0);
                        var importedRedMaterial = importedRed.GetComponent <Renderer>().sharedMaterial;
                        Assert.AreEqual("red", importedRedMaterial.name);
                        Assert.AreEqual(Color.red, importedRedMaterial.color);

                        var importedBlue         = context.Root.transform.GetChild(1);
                        var importedBlueMaterial = importedBlue.GetComponent <Renderer>().sharedMaterial;
                        Assert.AreEqual("blue", importedBlueMaterial.name);
                        Assert.AreEqual(Color.blue, importedBlueMaterial.color);
                    }
                }
            }
            finally
            {
                GameObject.DestroyImmediate(go);
            }
        }
Beispiel #22
0
 static T[] GetAttrib <T>(this glTF self, glTFAccessor accessor, glTFBufferView view) where T : struct
 {
     return(self.GetAttrib <T>(accessor.count, accessor.byteOffset, view));
 }
Beispiel #23
0
 public static async Task <Material> CreateAsync(IAwaitCaller awaitCaller, glTF gltf, int i, GetTextureAsyncFunc getTexture, bool hasVertexColor)
 {
     if (getTexture == null)
     {
         getTexture = (_x, _y, _z) => Task.FromResult <Texture2D>(default);
Beispiel #24
0
 public void SetSampler(glTF gltf)
 {
     SetSampler(Texture, gltf.GetSamplerFromTextureIndex(m_textureIndex));
 }
        static glTFMesh ExportPrimitives(glTF gltf, int bufferIndex,
                                         MeshWithRenderer unityMesh, List <Material> unityMaterials)
        {
            var mesh                  = unityMesh.Mesh;
            var materials             = unityMesh.Renderer.sharedMaterials;
            var positions             = mesh.vertices.Select(y => y.ReverseZ()).ToArray();
            var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, 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();

            var normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.normals.Select(y => y.normalized.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER);

#if GLTF_EXPORT_TANGENTS
            var tangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.tangents.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER);
#endif
            var uvAccessorIndex0 = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.uv.Select(y => y.ReverseUV()).ToArray(), glBufferTarget.ARRAY_BUFFER);
            var uvAccessorIndex1 = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.uv2.Select(y => y.ReverseUV()).ToArray(), glBufferTarget.ARRAY_BUFFER);

            var colorAccessorIndex = -1;

            var vColorState = MeshExportInfo.DetectVertexColor(mesh, materials);
            if (vColorState == MeshExportInfo.VertexColorState.ExistsAndIsUsed || // VColor使っている
                vColorState == MeshExportInfo.VertexColorState.ExistsAndMixed // VColorを使っているところと使っていないところが混在(とりあえずExportする)
                )
            {
                // UniUnlit で Multiply 設定になっている
                colorAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.colors, glBufferTarget.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(), glBufferTarget.ARRAY_BUFFER);
            var jointsAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, boneweights.Select(y =>
                                                                                                           new UShort4(
                                                                                                               (ushort)unityMesh.GetJointIndex(y.boneIndex0),
                                                                                                               (ushort)unityMesh.GetJointIndex(y.boneIndex1),
                                                                                                               (ushort)unityMesh.GetJointIndex(y.boneIndex2),
                                                                                                               (ushort)unityMesh.GetJointIndex(y.boneIndex3))
                                                                                                           ).ToArray(), glBufferTarget.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 (uvAccessorIndex0 != -1)
            {
                attributes.TEXCOORD_0 = uvAccessorIndex0;
            }
            if (uvAccessorIndex1 != -1)
            {
                attributes.TEXCOORD_1 = uvAccessorIndex1;
            }
            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);
            var indices  = new List <uint>();
            for (int j = 0; j < mesh.subMeshCount; ++j)
            {
                indices.Clear();

                var triangles = mesh.GetIndices(j);
                if (triangles.Length == 0)
                {
                    // https://github.com/vrm-c/UniVRM/issues/664
                    continue;
                }

                for (int i = 0; i < triangles.Length; i += 3)
                {
                    var i0 = triangles[i];
                    var i1 = triangles[i + 1];
                    var i2 = triangles[i + 2];

                    // flip triangle
                    indices.Add((uint)i2);
                    indices.Add((uint)i1);
                    indices.Add((uint)i0);
                }

                var indicesAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, indices.ToArray(), glBufferTarget.ELEMENT_ARRAY_BUFFER);
                if (indicesAccessorIndex < 0)
                {
                    // https://github.com/vrm-c/UniVRM/issues/664
                    throw new Exception();
                }

                if (j >= materials.Length)
                {
                    Debug.LogWarningFormat("{0}.materials is not enough", unityMesh.Renderer.name);
                    break;
                }

                gltfMesh.primitives.Add(new glTFPrimitives
                {
                    attributes = attributes,
                    indices    = indicesAccessorIndex,
                    mode       = 4, // triangles ?
                    material   = unityMaterials.IndexOf(materials[j])
                });
            }
            return(gltfMesh);
        }
Beispiel #26
0
 public void Process(glTF gltf, IStorage storage)
 {
     ProcessOnAnyThread(gltf, storage);
     ProcessOnMainThread(gltf);
 }
Beispiel #27
0
        public static int ExportTexture(glTF gltf, int bufferIndex, Texture texture)
        {
            var bytesWithPath = new BytesWithPath(texture);;

            // add view
            var view      = gltf.buffers[bufferIndex].Append(bytesWithPath.Bytes, glBufferTarget.NONE);
            var viewIndex = gltf.AddBufferView(view);

            // add image
            var imageIndex = gltf.images.Count;

            gltf.images.Add(new glTFImage
            {
                name       = texture.name,
                bufferView = viewIndex,
                mimeType   = bytesWithPath.Mime,
            });

            // add sampler
            var filter = default(glFilter);

            switch (texture.filterMode)
            {
            case FilterMode.Point:
                filter = glFilter.NEAREST;
                break;

            default:
                filter = glFilter.LINEAR;
                break;
            }
            var wrap = default(glWrap);

            switch (texture.wrapMode)
            {
            case TextureWrapMode.Clamp:
                wrap = glWrap.CLAMP_TO_EDGE;
                break;

            case TextureWrapMode.Repeat:
                wrap = glWrap.REPEAT;
                break;

#if UNITY_2017_OR_NEWER
            case TextureWrapMode.Mirror:
                wrap = glWrap.MIRRORED_REPEAT;
                break;
#endif

            default:
                throw new NotImplementedException();
            }

            var samplerIndex = gltf.samplers.Count;
            gltf.samplers.Add(new glTFTextureSampler
            {
                magFilter = filter,
                minFilter = filter,
                wrapS     = wrap,
                wrapT     = wrap,
            });

            // add texture
            gltf.textures.Add(new glTFTexture
            {
                sampler = samplerIndex,
                source  = imageIndex,
            });

            return(imageIndex);
        }
Beispiel #28
0
 public void ProcessOnMainThread(glTF gltf)
 {
     GetOrCreateTexture();
     SetSampler(gltf);
 }
 void OnExported(UniGLTF.glTF vrm)
 {
     Debug.LogFormat("exported");
 }
Beispiel #30
0
 public MaterialFactory(glTF gltf, IStorage storage,
                        IEnumerable <(string, UnityEngine.Object)> externalMap)