private void WriteMember(object memberValue, AttributeAccessor attribute, TypeDesc memberTypeDesc, object parent) { if (memberTypeDesc.IsAbstract) { return; } if (memberTypeDesc.IsArrayLike) { var sb = new StringBuilder(); TypeDesc arrayElementTypeDesc = memberTypeDesc.ArrayElementTypeDesc; bool canOptimizeWriteListSequence = CanOptimizeWriteListSequence(arrayElementTypeDesc); if (attribute.IsList) { if (canOptimizeWriteListSequence) { Writer.WriteStartAttribute(null, attribute.Name, attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : String.Empty); } } if (memberValue != null) { var a = (IEnumerable)memberValue; IEnumerator e = a.GetEnumerator(); bool shouldAppendWhitespace = false; if (e != null) { while (e.MoveNext()) { object ai = e.Current; if (attribute.IsList) { string stringValue; if (attribute.Mapping is EnumMapping) { stringValue = WriteEnumMethod((EnumMapping)attribute.Mapping, ai); } else { if (!WritePrimitiveValue(arrayElementTypeDesc, ai, true, out stringValue)) { // #10593: Add More Tests for Serialization Code Debug.Assert(ai is byte[]); } } // check to see if we can write values of the attribute sequentially if (canOptimizeWriteListSequence) { if (shouldAppendWhitespace) { Writer.WriteString(" "); } if (ai is byte[]) { WriteValue((byte[])ai); } else { WriteValue(stringValue); } } else { if (shouldAppendWhitespace) { sb.Append(" "); } sb.Append(stringValue); } } else { WriteAttribute(ai, attribute, parent); } shouldAppendWhitespace = true; } if (attribute.IsList) { // check to see if we can write values of the attribute sequentially if (canOptimizeWriteListSequence) { Writer.WriteEndAttribute(); } else { if (sb.Length != 0) { string ns = attribute.Form == XmlSchemaForm.Qualified ? attribute.Namespace : String.Empty; WriteAttribute(attribute.Name, ns, sb.ToString()); } } } } } } else { WriteAttribute(memberValue, attribute, parent); } }
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; } }