示例#1
0
        // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#meshes

        int ExportIndices(int[] indices)
        {
            // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#primitiveindices

            indices = CoordUtils.FlipIndices(indices).ToArray();

            // Scalar | UNSIGNED_BYTE
            //        | UNSIGNED_SHORT
            //        | UNSIGNED_INT! (TODO: optimize kind...)

            byte[] buffer    = PrimitiveExporter.Marshal(indices);
            var    viewIndex = BufferBuilder.AddView(
                new ArraySegment <byte>(buffer),
                null,
                Types.BufferView.TargetEnum.ELEMENT_ARRAY_BUFFER);

            var viewComponentType = Types.Accessor.ComponentTypeEnum.UNSIGNED_INT;

            var accessor = new Types.Accessor
            {
                BufferView    = viewIndex,
                ByteOffset    = 0,
                ComponentType = viewComponentType,
                Count         = indices.Length,
                Type          = Types.Accessor.TypeEnum.Scalar,
            };

            return(Types.GltfExtensions.AddAccessor(Gltf, accessor));
        }
示例#2
0
        void CreateGameObjects(int nodeIndex, Dictionary <int, GameObject> gameObjects)
        {
            var gltf     = Container.Gltf;
            var gltfNode = gltf.Nodes[nodeIndex];

            var go = new GameObject();

            go.name = gltfNode.Name;

            var matrix = PrimitiveImporter.AsMatrix4x4(gltfNode.Matrix);

            if (!matrix.isIdentity)
            {
                throw new NotImplementedException("matrix is not implemented");
            }
            else
            {
                var t = PrimitiveImporter.AsVector3(gltfNode.Translation);
                var r = PrimitiveImporter.AsQuaternion(gltfNode.Rotation);
                var s = PrimitiveImporter.AsVector3(gltfNode.Scale);
                go.transform.localPosition = CoordUtils.ConvertSpace(t);
                go.transform.localRotation = CoordUtils.ConvertSpace(r);
                go.transform.localScale    = s;
            }

            gameObjects.Add(nodeIndex, go);

            if (gltfNode.Children != null)
            {
                foreach (var childIndex in gltfNode.Children)
                {
                    if (gameObjects.ContainsKey(childIndex))
                    {
                        throw new NotImplementedException("Node duplication"); // TODO:
                    }
                    CreateGameObjects(childIndex, gameObjects);

                    var childGo = gameObjects[childIndex];
                    childGo.transform.SetParent(go.transform, false);
                }
            }
        }
示例#3
0
        public IndexedResource <Transform> ForceExport(Transform trans)
        {
            var go = trans.gameObject;

            IndexedResource <Mesh> meshResource = null;
            int?skinIndex = null;
            var mr        = go.GetComponent <MeshRenderer>();
            var smr       = go.GetComponent <SkinnedMeshRenderer>();

            if (mr != null)
            {
                var meshFilter = mr.gameObject.GetComponent <MeshFilter>();
                var sharedMesh = meshFilter.sharedMesh;

                meshResource = Meshes.Export(mr, sharedMesh);
            }
            else if (smr != null)
            {
                var sharedMesh = smr.sharedMesh;
                meshResource = Meshes.Export(smr, sharedMesh);

                if (smr.bones.Length > 0)
                {
                    skinIndex = ExportSkin(smr, sharedMesh).Index;
                }
            }

            var t        = CoordUtils.ConvertSpace(go.transform.localPosition);
            var r        = CoordUtils.ConvertSpace(go.transform.localRotation);
            var s        = go.transform.localScale;
            var gltfNode = new Types.Node
            {
                Name = go.name,

                Mesh = meshResource != null ? (int?)meshResource.Index : null,
                Skin = skinIndex,

                Matrix      = null,
                Translation = new float[] { t.x, t.y, t.z },
                Rotation    = new float[] { r.x, r.y, r.z, r.w },
                Scale       = new float[] { s.x, s.y, s.z },
            };

            var nodesIndices = new List <int>();

            for (int i = 0; i < go.transform.childCount; ++i)
            {
                var c            = go.transform.GetChild(i);
                var nodeResource = Export(c.gameObject);
                nodesIndices.Add(nodeResource.Index);
            }
            if (nodesIndices.Count > 0)
            {
                gltfNode.Children = nodesIndices.ToArray();
            }

            foreach (var h in Hooks)
            {
                h.PostHook(this, trans, gltfNode);
            }

            return(new IndexedResource <Transform>
            {
                Index = Types.GltfExtensions.AddNode(Gltf, gltfNode),
                Value = trans,
            });
        }
示例#4
0
        public IndexedResource <Mesh> ForceImport(int meshIndex, GameObject go)
        {
            var gltf     = Container.Gltf;
            var gltfMesh = gltf.Meshes[meshIndex];

            var mesh = new Mesh();

            mesh.name         = gltfMesh.Name;
            mesh.subMeshCount = gltfMesh.Primitives.Count;

            var prims = gltfMesh.Primitives.Select(p => {
                var gltfAttr = p.Attributes;
                var res      = new Primitive();

                {
                    int index;
                    if (!gltfAttr.TryGetValue(Types.Mesh.PrimitiveType.AttributeName.POSITION, out index))
                    {
                        throw new NotImplementedException(""); // TODO: fix
                    }
                    res.Position = index;
                }

                {
                    int index;
                    if (gltfAttr.TryGetValue(Types.Mesh.PrimitiveType.AttributeName.NORMAL, out index))
                    {
                        res.Normal = index;
                    }
                }

                {
                    int index;
                    if (gltfAttr.TryGetValue(Types.Mesh.PrimitiveType.AttributeName.TANGENT, out index))
                    {
                        res.Tangent = index;
                    }
                }

                {
                    int index;
                    if (gltfAttr.TryGetValue(Types.Mesh.PrimitiveType.AttributeName.TEXCOORD_0, out index))
                    {
                        res.TexCoord0 = index;
                    }
                }

                {
                    int index;
                    if (gltfAttr.TryGetValue(Types.Mesh.PrimitiveType.AttributeName.TEXCOORD_1, out index))
                    {
                        res.TexCoord1 = index;
                    }
                }

                {
                    int index;
                    if (gltfAttr.TryGetValue(Types.Mesh.PrimitiveType.AttributeName.COLOR_0, out index))
                    {
                        res.Color = index;
                    }
                }

                {
                    int index;
                    if (gltfAttr.TryGetValue(Types.Mesh.PrimitiveType.AttributeName.WEIGHTS_0, out index))
                    {
                        res.Weight = index;
                    }
                }

                {
                    int index;
                    if (gltfAttr.TryGetValue(Types.Mesh.PrimitiveType.AttributeName.JOINTS_0, out index))
                    {
                        res.Joint = index;
                    }
                }

                if (res.Weight != null || res.Joint != null)
                {
                    if (res.Weight == null || res.Joint == null)
                    {
                        throw new NotImplementedException(""); // TODO: fix
                    }
                }

                if (p.Targets != null)
                {
                    var targets = new List <Target>();
                    foreach (var t in p.Targets)
                    {
                        var target = new Target();
                        {
                            int index;
                            if (!t.TryGetValue(Types.Mesh.PrimitiveType.AttributeName.POSITION, out index))
                            {
                                throw new NotImplementedException(""); // TODO: fix
                            }
                            target.Position = index;
                        }

                        {
                            int index;
                            if (t.TryGetValue(Types.Mesh.PrimitiveType.AttributeName.NORMAL, out index))
                            {
                                target.Normal = index;
                            }
                        }

                        {
                            int index;
                            if (t.TryGetValue(Types.Mesh.PrimitiveType.AttributeName.TANGENT, out index))
                            {
                                target.Tangent = index;
                            }
                        }

                        targets.Add(target);
                    }

                    res.Targets = targets;
                }

                if (p.Indices == null)
                {
                    throw new NotImplementedException(""); // TODO: fix
                }
                res.Indices = p.Indices.Value;

                if (p.Material == null)
                {
                    throw new NotImplementedException(""); // TODO: fix
                }
                res.Material = p.Material.Value;

                return(res);
            }).ToArray();

            var b = prims[0];
            var fullClonedMode = false;
            var skinedMesh     = b.Weight != null;

            foreach (var p in prims.Skip(1))
            {
                if (!(b.Position == p.Position &&
                      EqualityComparer <int?> .Default.Equals(b.Normal, p.Normal) &&
                      EqualityComparer <int?> .Default.Equals(b.Tangent, p.Tangent) &&
                      EqualityComparer <int?> .Default.Equals(b.TexCoord0, p.TexCoord0) &&
                      EqualityComparer <int?> .Default.Equals(b.TexCoord1, p.TexCoord1) &&
                      EqualityComparer <int?> .Default.Equals(b.Color, p.Color) &&
                      EqualityComparer <int?> .Default.Equals(b.Weight, p.Weight) &&
                      EqualityComparer <int?> .Default.Equals(b.Joint, p.Joint) &&
                      ((b.Targets == null && p.Targets == null) || (b.Targets != null && p.Targets != null && b.Targets.SequenceEqual(p.Targets)))))
                {
                    fullClonedMode = true;
                    break;
                }

                if (skinedMesh != (p.Weight != null))
                {
                    throw new NotImplementedException(); // Renderer is mixed
                }
            }

            var materials = new List <Material>();

            if (fullClonedMode)
            {
                throw new NotImplementedException("Not supported");

                IEnumerable <Vector3> vertices = new Vector3[] { };
                IEnumerable <Vector3> normals  = new Vector3[] { };

                var currentOffset = 0;
                foreach (var p in prims)
                {
                    var positionBuf = BufferView.GetOrLoadTypedBufferByAccessorIndex(p.Position);
                    var pVertices   = positionBuf.GetEntity <Vector3>().GetEnumerable().Select(CoordUtils.ConvertSpace).ToArray();
                }
            }
            else
            {
                {
                    mesh.vertices = ImportPositions(b.Position);
                }

                if (b.Normal != null)
                {
                    mesh.normals = ImportNormals(b.Normal.Value);
                }

                if (b.Tangent != null)
                {
                    mesh.tangents = ImportTangents(b.Tangent.Value);
                }

                if (b.TexCoord0 != null)
                {
                    mesh.uv = ImportUV(b.TexCoord0.Value);
                }

                if (b.TexCoord1 != null)
                {
                    mesh.uv2 = ImportUV(b.TexCoord1.Value);
                }

                if (b.Color != null)
                {
                    mesh.colors = ImportColors(b.Color.Value);
                }

                if (b.Joint != null && b.Weight != null)
                {
                    var joints  = ImportJoints(b.Joint.Value);
                    var weights = ImportWeights(b.Weight.Value);
                    if (joints.Length != weights.Length)
                    {
                        throw new NotImplementedException(); // TODO
                    }

                    mesh.boneWeights = joints.Zip(weights, (j, w) => {
                        var bw        = new BoneWeight();
                        bw.boneIndex0 = j.x;
                        bw.boneIndex1 = j.y;
                        bw.boneIndex2 = j.z;
                        bw.boneIndex3 = j.w;
                        bw.weight0    = w.x;
                        bw.weight1    = w.y;
                        bw.weight2    = w.z;
                        bw.weight3    = w.w;
                        return(bw);
                    }).ToArray();
                }

                if (b.Targets != null)
                {
                    // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#morph-targets
                    var extras         = gltfMesh.Extras as Dictionary <string, object>;
                    var targetNamesObj = default(object);
                    var targetNames    = default(string[]);
                    if (extras != null && extras.TryGetValue("targetNames", out targetNamesObj))
                    {
                        var objs = targetNamesObj as object[];
                        if (objs != null)
                        {
                            targetNames = objs
                                          .Select(o => o as string)
                                          .Where(s => s != null)
                                          .ToArray();
                        }
                    }

                    var i = 0;
                    foreach (var t in b.Targets)
                    {
                        var deltaVertices = ImportPositions(t.Position);

                        var deltaNormals = default(Vector3[]);
                        if (t.Normal != null)
                        {
                            deltaNormals = ImportNormals(t.Normal.Value);
                        }

                        var deltaTangents = default(Vector3[]);
                        if (t.Tangent != null)
                        {
                            // TODO: read Tangents as Vector3[] (NOT Vector4[])
                            //mesh.tangents = ImportTangents(t.Tangent.Value);
                        }

                        var name = (targetNames != null && i < targetNames.Length)
                            ? targetNames[i]
                            : string.Format("BlendShape.{0}", i);
                        mesh.AddBlendShapeFrame(name, 100.0f, deltaVertices, deltaNormals, deltaTangents);

                        ++i;
                    }
                }

                int submesh = 0;
                foreach (var p in prims)
                {
                    var indicesBuf = BufferView.GetOrLoadTypedBufferByAccessorIndex(p.Indices);
                    var indices    = CoordUtils.FlipIndices(indicesBuf.GetPrimitivesAsCasted <int>().ToArray()).ToArray();
                    mesh.SetIndices(indices, MeshTopology.Triangles, submesh);
                    ++submesh;

                    var matResource = Materials.Import(p.Material);
                    materials.Add(matResource.Value);
                }
            }

            mesh.RecalculateBounds();
            mesh.RecalculateTangents();

            Renderer r = null;

            if (skinedMesh)
            {
                var smr = go.AddComponent <SkinnedMeshRenderer>();
                smr.sharedMesh = mesh;

                // Default blend shape weight
                if (gltfMesh.Weights != null)
                {
                    var i = 0;
                    foreach (var w in gltfMesh.Weights)
                    {
                        // gltf[0, 1] -> Unity[0, 100]
                        smr.SetBlendShapeWeight(i, w * 100.0f);
                        ++i;
                    }
                }

                r = smr;
            }
            else
            {
                var mf = go.AddComponent <MeshFilter>();
                mf.sharedMesh = mesh;

                var mr = go.AddComponent <MeshRenderer>();
                r = mr;
            }

            r.sharedMaterials = materials.ToArray();

            return(new IndexedResource <Mesh>
            {
                Index = meshIndex,
                Value = mesh,
            });
        }