protected virtual void BuildMeshAttributes(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[SemanticProperties.INDICES] = indexBuilder;
                }

                GLTFHelpers.BuildMeshAttributes(ref attributeAccessors);

                // Flip vectors and triangles to the Unity coordinate system.
                if (attributeAccessors.ContainsKey(SemanticProperties.POSITION))
                {
                    NumericArray resultArray = attributeAccessors[SemanticProperties.POSITION].AccessorContent;
                    resultArray.AsVertices = GLTFUnityHelpers.FlipVectorArrayHandedness(resultArray.AsVertices);
                    attributeAccessors[SemanticProperties.POSITION].AccessorContent = resultArray;
                }
                if (attributeAccessors.ContainsKey(SemanticProperties.INDICES))
                {
                    NumericArray resultArray = attributeAccessors[SemanticProperties.INDICES].AccessorContent;
                    resultArray.AsTriangles = GLTFUnityHelpers.FlipFaces(resultArray.AsTriangles);
                    attributeAccessors[SemanticProperties.INDICES].AccessorContent = resultArray;
                }
                if (attributeAccessors.ContainsKey(SemanticProperties.NORMAL))
                {
                    NumericArray resultArray = attributeAccessors[SemanticProperties.NORMAL].AccessorContent;
                    resultArray.AsNormals = GLTFUnityHelpers.FlipVectorArrayHandedness(resultArray.AsNormals);
                    attributeAccessors[SemanticProperties.NORMAL].AccessorContent = resultArray;
                }
                // TexCoord goes from 0 to 3 to match GLTFHelpers.BuildMeshAttributes
                for (int i = 0; i < 4; i++)
                {
                    if (attributeAccessors.ContainsKey(SemanticProperties.TexCoord(i)))
                    {
                        NumericArray resultArray = attributeAccessors[SemanticProperties.TexCoord(i)].AccessorContent;
                        resultArray.AsTexcoords = GLTFUnityHelpers.FlipTexCoordArrayV(resultArray.AsTexcoords);
                        attributeAccessors[SemanticProperties.TexCoord(i)].AccessorContent = resultArray;
                    }
                }
                if (attributeAccessors.ContainsKey(SemanticProperties.TANGENT))
                {
                    NumericArray resultArray = attributeAccessors[SemanticProperties.TANGENT].AccessorContent;
                    resultArray.AsTangents = GLTFUnityHelpers.FlipVectorArrayHandedness(resultArray.AsTangents);
                    attributeAccessors[SemanticProperties.TANGENT].AccessorContent = resultArray;
                }

                _assetCache.MeshCache[meshID][primitiveIndex].MeshAttributes = attributeAccessors;
            }
        }
Example #2
0
        // a mesh *might* decode to multiple prims if there are submeshes
        private MeshPrimitive[] ExportPrimitive(GameObject gameObject)
        {
            var filter  = gameObject.GetComponent <MeshFilter>();
            var meshObj = filter.sharedMesh;

            var renderer     = gameObject.GetComponent <MeshRenderer>();
            var materialsObj = renderer.sharedMaterials;

            var prims = new MeshPrimitive[meshObj.subMeshCount];

            // don't export any more accessors if this mesh is already exported
            MeshPrimitive[] primVariations;
            if (_meshToPrims.TryGetValue(meshObj, out primVariations) &&
                meshObj.subMeshCount == primVariations.Length)
            {
                for (var i = 0; i < primVariations.Length; i++)
                {
                    prims[i] = new MeshPrimitive(primVariations[i], _root)
                    {
                        Material = ExportMaterial(materialsObj[i])
                    };
                }

                return(prims);
            }

            AccessorId aPosition = null, aNormal = null, aTangent = null,
                       aTexcoord0 = null, aTexcoord1 = null, aColor0 = null;

            aPosition = ExportAccessor(GLTFUnityHelpers.FlipVectorArrayHandedness(meshObj.vertices));

            if (meshObj.normals.Length != 0)
            {
                aNormal = ExportAccessor(GLTFUnityHelpers.FlipVectorArrayHandedness(meshObj.normals));
            }

            if (meshObj.tangents.Length != 0)
            {
                aTangent = ExportAccessor(GLTFUnityHelpers.FlipVectorArrayHandedness(meshObj.tangents));
            }

            if (meshObj.uv.Length != 0)
            {
                aTexcoord0 = ExportAccessor(GLTFUnityHelpers.FlipTexCoordArrayV(meshObj.uv));
            }

            if (meshObj.uv2.Length != 0)
            {
                aTexcoord1 = ExportAccessor(GLTFUnityHelpers.FlipTexCoordArrayV(meshObj.uv2));
            }

            if (meshObj.colors.Length != 0)
            {
                aColor0 = ExportAccessor(meshObj.colors);
            }

            MaterialId lastMaterialId = null;

            for (var submesh = 0; submesh < meshObj.subMeshCount; submesh++)
            {
                var primitive = new MeshPrimitive();

                var triangles = meshObj.GetTriangles(submesh);
                primitive.Indices = ExportAccessor(GLTFUnityHelpers.FlipFaces(triangles), true);

                primitive.Attributes = new Dictionary <string, AccessorId>();
                primitive.Attributes.Add(SemanticProperties.POSITION, aPosition);

                if (aNormal != null)
                {
                    primitive.Attributes.Add(SemanticProperties.NORMAL, aNormal);
                }
                if (aTangent != null)
                {
                    primitive.Attributes.Add(SemanticProperties.TANGENT, aTangent);
                }
                if (aTexcoord0 != null)
                {
                    primitive.Attributes.Add(SemanticProperties.TexCoord(0), aTexcoord0);
                }
                if (aTexcoord1 != null)
                {
                    primitive.Attributes.Add(SemanticProperties.TexCoord(1), aTexcoord1);
                }
                if (aColor0 != null)
                {
                    primitive.Attributes.Add(SemanticProperties.Color(0), aColor0);
                }

                if (submesh < materialsObj.Length)
                {
                    primitive.Material = ExportMaterial(materialsObj[submesh]);
                    lastMaterialId     = primitive.Material;
                }
                else
                {
                    primitive.Material = lastMaterialId;
                }

                prims[submesh] = primitive;
            }

            _meshToPrims[meshObj] = prims;

            return(prims);
        }