Ejemplo n.º 1
0
        protected virtual void BuildMeshAttributes(GLTF.Schema.MeshPrimitive primitive, int meshID, int primitiveIndex)
        {
            if (_assetCache.MeshCache[meshID][primitiveIndex].MeshAttributes.Count == 0)
            {
                Dictionary <string, AttributeAccessor> attributeAccessors = new Dictionary <string, AttributeAccessor>(primitive.Attributes.Count + 1);
                foreach (var attributePair in primitive.Attributes)
                {
                    AttributeAccessor AttributeAccessor = new AttributeAccessor()
                    {
                        AccessorId = attributePair.Value,
                        Buffer     = _assetCache.BufferCache[attributePair.Value.Value.BufferView.Value.Buffer.Id]
                    };

                    attributeAccessors[attributePair.Key] = AttributeAccessor;
                }

                if (primitive.Indices != null)
                {
                    AttributeAccessor indexBuilder = new AttributeAccessor()
                    {
                        AccessorId = primitive.Indices,
                        Buffer     = _assetCache.BufferCache[primitive.Indices.Value.BufferView.Value.Buffer.Id]
                    };

                    attributeAccessors[GLTF.Schema.SemanticProperties.INDICES] = indexBuilder;
                }

                GLTFHelpers.BuildMeshAttributes(ref attributeAccessors);
                _assetCache.MeshCache[meshID][primitiveIndex].MeshAttributes = attributeAccessors;
            }
        }
        private void parseAttribute(ref GLTF.Schema.MeshPrimitive prim, string property, ref Vector4[] values)
        {
            byte[]       bufferData = _assetCache.BufferCache[prim.Attributes[property].Value.BufferView.Value.Buffer.Id];
            NumericArray num        = new NumericArray();

            GLTF.Math.Vector4[] gltfValues = prim.Attributes[property].Value.AsVector4Array(ref num, bufferData);
            values = new Vector4[gltfValues.Length];

            for (int i = 0; i < gltfValues.Length; ++i)
            {
                values[i] = gltfValues[i].ToUnityVector4();
            }
        }
        protected virtual void LoadSkinnedMeshAttributes(int meshIndex, int primitiveIndex, ref Vector4[] boneIndexes, ref Vector4[] weights)
        {
            GLTF.Schema.MeshPrimitive prim = _root.Meshes[meshIndex].Primitives[primitiveIndex];
            if (!prim.Attributes.ContainsKey(SemanticProperties.JOINT) || !prim.Attributes.ContainsKey(SemanticProperties.WEIGHT))
            {
                return;
            }

            parseAttribute(ref prim, SemanticProperties.JOINT, ref boneIndexes);
            parseAttribute(ref prim, SemanticProperties.WEIGHT, ref weights);
            foreach (Vector4 wei in weights)
            {
                wei.Normalize();
            }
        }
Ejemplo n.º 4
0
        // Taken from: http://answers.unity3d.com/comments/190515/view.html
        // Official support for Mesh.RecalculateTangents should be coming in 5.6
        // https://feedback.unity3d.com/suggestions/recalculatetangents

        /*private MeshPrimitiveAttributes CalculateAndSetTangents(MeshPrimitiveAttributes attributes)
         * {
         *      var triangleCount = attributes.Triangles.Length;
         *      var vertexCount = attributes.Vertices.Length;
         *
         *      var tan1 = new Vector3[vertexCount];
         *      var tan2 = new Vector3[vertexCount];
         *
         *      attributes.Tangents = new Vector4[vertexCount];
         *
         *      for (long a = 0; a < triangleCount; a += 3)
         *      {
         *              long i1 = attributes.Triangles[a + 0];
         *              long i2 = attributes.Triangles[a + 1];
         *              long i3 = attributes.Triangles[a + 2];
         *
         *              var v1 = attributes.Vertices[i1];
         *              var v2 = attributes.Vertices[i2];
         *              var v3 = attributes.Vertices[i3];
         *
         *              var w1 = attributes.Uv[i1];
         *              var w2 = attributes.Uv[i2];
         *              var w3 = attributes.Uv[i3];
         *
         *              var x1 = v2.X - v1.X;
         *              var x2 = v3.X - v1.X;
         *              var y1 = v2.Y - v1.Y;
         *              var y2 = v3.Y - v1.Y;
         *              var z1 = v2.Z - v1.Z;
         *              var z2 = v3.Z - v1.Z;
         *
         *              var s1 = w2.X - w1.X;
         *              var s2 = w3.X - w1.X;
         *              var t1 = w2.Y - w1.Y;
         *              var t2 = w3.Y - w1.Y;
         *
         *              var r = 1.0f / (s1 * t2 - s2 * t1);
         *
         *              var sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
         *              var tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
         *
         *              tan1[i1] += sdir;
         *              tan1[i2] += sdir;
         *              tan1[i3] += sdir;
         *
         *              tan2[i1] += tdir;
         *              tan2[i2] += tdir;
         *              tan2[i3] += tdir;
         *      }
         *
         *
         *      for (long a = 0; a < vertexCount; ++a)
         *      {
         *              var n = attributes.Normals[a];
         *              var t = tan1[a];
         *
         *              Vector3.OrthoNormalize(ref n, ref t);
         *
         *              attributes.Tangents[a].X = t.X;
         *              attributes.Tangents[a].Y = t.Y;
         *              attributes.Tangents[a].Z = t.Z;
         *
         *              attributes.Tangents[a].W = (Vector3.Dot(Vector3.Cross(n, t), tan2[a]) < 0.0f) ? -1.0f : 1.0f;
         *      }
         *
         *      return attributes;
         * }*/

        public static MeshPrimitive Deserialize(GLTFRoot root, JsonReader reader)
        {
            var primitive = new MeshPrimitive();

            while (reader.Read() && reader.TokenType == JsonToken.PropertyName)
            {
                var curProp = reader.Value.ToString();

                switch (curProp)
                {
                case "attributes":
                    primitive.Attributes = reader.ReadAsDictionary(() => new AccessorId
                    {
                        Id   = reader.ReadAsInt32().Value,
                        Root = root
                    });
                    break;

                case "indices":
                    primitive.Indices = AccessorId.Deserialize(root, reader);
                    break;

                case "material":
                    primitive.Material = MaterialId.Deserialize(root, reader);
                    break;

                case "mode":
                    primitive.Mode = (DrawMode)reader.ReadAsInt32().Value;
                    break;

                case "targets":
                    primitive.Targets = reader.ReadList(() =>
                    {
                        return(reader.ReadAsDictionary(() => new AccessorId
                        {
                            Id = reader.ReadAsInt32().Value,
                            Root = root
                        },
                                                       skipStartObjectRead: true));
                    });
                    break;

                case "extras":
                    // GLTF does not support morph target names, serialize in extras for now
                    // https://github.com/KhronosGroup/glTF/issues/1036
                    if (reader.Read() && reader.TokenType == JsonToken.StartObject)
                    {
                        while (reader.Read() && reader.TokenType == JsonToken.PropertyName)
                        {
                            var extraProperty = reader.Value.ToString();
                            switch (extraProperty)
                            {
                            case "targetNames":
                                primitive.TargetNames = reader.ReadStringList();
                                break;
                            }
                        }
                    }

                    break;

                default:
                    primitive.DefaultPropertyDeserializer(root, reader);
                    break;
                }
            }

            return(primitive);
        }
Ejemplo n.º 5
0
        protected virtual GameObject CreateMeshPrimitive(GLTF.Schema.MeshPrimitive primitive, int meshID, int primitiveIndex)
        {
            var primitiveObj = new GameObject("Primitive");

            var meshFilter = primitiveObj.AddComponent <MeshFilter>();

            if (_assetCache.MeshCache[meshID][primitiveIndex] == null)
            {
                _assetCache.MeshCache[meshID][primitiveIndex] = new MeshCacheData();
            }
            if (_assetCache.MeshCache[meshID][primitiveIndex].LoadedMesh == null)
            {
                if (_assetCache.MeshCache[meshID][primitiveIndex].MeshAttributes.Count == 0)
                {
                    BuildMeshAttributes(primitive, meshID, primitiveIndex);
                }
                var meshAttributes = _assetCache.MeshCache[meshID][primitiveIndex].MeshAttributes;
                var vertexCount    = primitive.Attributes[GLTF.Schema.SemanticProperties.POSITION].Value.Count;

                // todo optimize: There are multiple copies being performed to turn the buffer data into mesh data. Look into reducing them
                UnityEngine.Mesh mesh = new UnityEngine.Mesh
                {
                    vertices = primitive.Attributes.ContainsKey(GLTF.Schema.SemanticProperties.POSITION)
                                                ? meshAttributes[GLTF.Schema.SemanticProperties.POSITION].AccessorContent.AsVertices.ToUnityVector3()
                                                : null,
                    normals = primitive.Attributes.ContainsKey(GLTF.Schema.SemanticProperties.NORMAL)
                                                ? meshAttributes[GLTF.Schema.SemanticProperties.NORMAL].AccessorContent.AsNormals.ToUnityVector3()
                                                : null,

                    uv = primitive.Attributes.ContainsKey(GLTF.Schema.SemanticProperties.TexCoord(0))
                                                ? meshAttributes[GLTF.Schema.SemanticProperties.TexCoord(0)].AccessorContent.AsTexcoords.ToUnityVector2()
                                                : null,

                    uv2 = primitive.Attributes.ContainsKey(GLTF.Schema.SemanticProperties.TexCoord(1))
                                                ? meshAttributes[GLTF.Schema.SemanticProperties.TexCoord(1)].AccessorContent.AsTexcoords.ToUnityVector2()
                                                : null,

                    uv3 = primitive.Attributes.ContainsKey(GLTF.Schema.SemanticProperties.TexCoord(2))
                                                ? meshAttributes[GLTF.Schema.SemanticProperties.TexCoord(2)].AccessorContent.AsTexcoords.ToUnityVector2()
                                                : null,

                    uv4 = primitive.Attributes.ContainsKey(GLTF.Schema.SemanticProperties.TexCoord(3))
                                                ? meshAttributes[GLTF.Schema.SemanticProperties.TexCoord(3)].AccessorContent.AsTexcoords.ToUnityVector2()
                                                : null,

                    colors = primitive.Attributes.ContainsKey(GLTF.Schema.SemanticProperties.Color(0))
                                                ? meshAttributes[GLTF.Schema.SemanticProperties.Color(0)].AccessorContent.AsColors.ToUnityColor()
                                                : null,

                    triangles = primitive.Indices != null
                                                ? meshAttributes[GLTF.Schema.SemanticProperties.INDICES].AccessorContent.AsTriangles
                                                : GLTF.Schema.MeshPrimitive.GenerateTriangles(vertexCount),

                    tangents = primitive.Attributes.ContainsKey(GLTF.Schema.SemanticProperties.TANGENT)
                                                ? meshAttributes[GLTF.Schema.SemanticProperties.TANGENT].AccessorContent.AsTangents.ToUnityVector4()
                                                : null
                };

                _assetCache.MeshCache[meshID][primitiveIndex].LoadedMesh = mesh;
            }

            meshFilter.sharedMesh = _assetCache.MeshCache[meshID][primitiveIndex].LoadedMesh;

            var materialWrapper = CreateMaterial(
                primitive.Material != null ? primitive.Material.Value : DefaultMaterial,
                primitive.Material != null ? primitive.Material.Id : -1
                );

            var meshRenderer = primitiveObj.AddComponent <MeshRenderer>();

            meshRenderer.material = materialWrapper.GetContents(primitive.Attributes.ContainsKey(GLTF.Schema.SemanticProperties.Color(0)));

            if (_addColliders)
            {
                var meshCollider = primitiveObj.AddComponent <MeshCollider>();
                meshCollider.sharedMesh = meshFilter.mesh;
            }

            return(primitiveObj);
        }