public static AnimationSampler Deserialize(GLTFRoot root, JsonReader reader) { var animationSampler = new AnimationSampler(); while (reader.Read() && reader.TokenType == JsonToken.PropertyName) { var curProp = reader.Value.ToString(); switch (curProp) { case "input": animationSampler.Input = AccessorId.Deserialize(root, reader); break; case "interpolation": animationSampler.Interpolation = reader.ReadStringEnum <InterpolationType>(); break; case "output": animationSampler.Output = AccessorId.Deserialize(root, reader); break; default: animationSampler.DefaultPropertyDeserializer(root, reader); break; } } return(animationSampler); }
public static Skin Deserialize(GLTFRoot root, JsonReader reader) { var skin = new Skin(); while (reader.Read() && reader.TokenType == JsonToken.PropertyName) { var curProp = reader.Value.ToString(); switch (curProp) { case "inverseBindMatrices": skin.InverseBindMatrices = AccessorId.Deserialize(root, reader); break; case "skeleton": skin.Skeleton = NodeId.Deserialize(root, reader); break; case "joints": skin.Joints = reader.ReadList(() => NodeId.Deserialize(root, reader)); break; default: skin.DefaultPropertyDeserializer(root, reader); break; } } return(skin); }
private static void MergeMeshes(GLTFRoot mergeToRoot, GLTFRoot mergeFromRoot, PreviousGLTFSizes previousGLTFSizes) { if (mergeFromRoot.Meshes == null) { return; } if (mergeToRoot.Meshes == null) { mergeToRoot.Meshes = new List <Mesh>(mergeFromRoot.Meshes.Count); } mergeToRoot.Meshes.AddRange(mergeFromRoot.Meshes); for (int i = previousGLTFSizes.PreviousMeshCount; i < mergeToRoot.Meshes.Count; ++i) { Mesh mesh = mergeToRoot.Meshes[i]; if (mesh.Primitives != null) { foreach (MeshPrimitive primitive in mesh.Primitives) { foreach (var attributeAccessorPair in primitive.Attributes) { AccessorId accessorId = attributeAccessorPair.Value; accessorId.Id += previousGLTFSizes.PreviousAccessorCount; accessorId.Root = mergeToRoot; } if (primitive.Indices != null) { AccessorId accessorId = primitive.Indices; accessorId.Id += previousGLTFSizes.PreviousAccessorCount; accessorId.Root = mergeToRoot; } if (primitive.Material != null) { MaterialId materialId = primitive.Material; materialId.Id += previousGLTFSizes.PreviousMaterialCount; materialId.Root = mergeToRoot; } if (primitive.Targets != null) { foreach (Dictionary <string, AccessorId> targetsDictionary in primitive.Targets) { foreach (var targetsPair in targetsDictionary) { AccessorId accessorId = targetsPair.Value; accessorId.Id += previousGLTFSizes.PreviousAccessorCount; accessorId.Root = mergeToRoot; } } } } } } }
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 })); }); break; default: primitive.DefaultPropertyDeserializer(root, reader); break; } } return(primitive); }
private static void MergeAnimationsAndSkins(GLTFRoot mergeToRoot, GLTFRoot mergeFromRoot, PreviousGLTFSizes previousGLTFSizes) { if (mergeFromRoot.Skins != null) { if (mergeToRoot.Skins == null) { mergeToRoot.Skins = new List <Skin>(mergeFromRoot.Skins.Count); } mergeToRoot.Skins.AddRange(mergeFromRoot.Skins); for (int i = previousGLTFSizes.PreviousSkinCount; i < mergeToRoot.Skins.Count; ++i) { Skin skin = mergeToRoot.Skins[i]; if (skin.InverseBindMatrices != null) { skin.InverseBindMatrices.Id += previousGLTFSizes.PreviousAccessorCount; } if (skin.Skeleton != null) { skin.Skeleton.Id += previousGLTFSizes.PreviousNodeCount; } if (skin.Joints != null) { foreach (NodeId joint in skin.Joints) { joint.Id += previousGLTFSizes.PreviousNodeCount; } } } } if (mergeFromRoot.Animations != null) { if (mergeToRoot.Animations == null) { mergeToRoot.Animations = new List <Animation>(mergeFromRoot.Animations.Count); } mergeToRoot.Animations.AddRange(mergeFromRoot.Animations); for (int i = previousGLTFSizes.PreviousAnimationCount; i < mergeToRoot.Animations.Count; ++i) { Animation animation = mergeToRoot.Animations[i]; foreach (AnimationSampler sampler in animation.Samplers) { AccessorId inputId = sampler.Input; inputId.Id += previousGLTFSizes.PreviousAccessorCount; inputId.Root = mergeToRoot; AccessorId outputId = sampler.Output; outputId.Id += previousGLTFSizes.PreviousAccessorCount; outputId.Root = mergeToRoot; } foreach (AnimationChannel channel in animation.Channels) { SamplerId samplerId = channel.Sampler; samplerId.Id += previousGLTFSizes.PreviousSamplerCount; samplerId.Root = mergeToRoot; NodeId nodeId = channel.Target.Node; nodeId.Id += previousGLTFSizes.PreviousNodeCount; nodeId.Root = mergeToRoot; } } } }
private AccessorId ExportAccessor(Vector3[] arr) { var count = arr.Length; if (count == 0) { throw new Exception("Accessors can not have a count of 0."); } var accessor = new Accessor(); accessor.ComponentType = GLTFComponentType.Float; accessor.Count = count; accessor.Type = GLTFAccessorAttributeType.VEC3; float minX = arr[0].x; float minY = arr[0].y; float minZ = arr[0].z; float maxX = arr[0].x; float maxY = arr[0].y; float maxZ = arr[0].z; for (var i = 1; i < count; i++) { var cur = arr[i]; if (cur.x < minX) { minX = cur.x; } if (cur.y < minY) { minY = cur.y; } if (cur.z < minZ) { minZ = cur.z; } if (cur.x > maxX) { maxX = cur.x; } if (cur.y > maxY) { maxY = cur.y; } if (cur.z > maxZ) { maxZ = cur.z; } } accessor.Min = new List <double> { minX, minY, minZ }; accessor.Max = new List <double> { maxX, maxY, maxZ }; var byteOffset = _bufferWriter.BaseStream.Position; foreach (var vec in arr) { _bufferWriter.Write(vec.x); _bufferWriter.Write(vec.y); _bufferWriter.Write(vec.z); } var byteLength = _bufferWriter.BaseStream.Position - byteOffset; accessor.BufferView = ExportBufferView((int)byteOffset, (int)byteLength); var id = new AccessorId { Id = _root.Accessors.Count, Root = _root }; _root.Accessors.Add(accessor); return(id); }
private AccessorId ExportAccessor(int[] arr) { var count = arr.Length; if (count == 0) { throw new Exception("Accessors can not have a count of 0."); } var accessor = new Accessor(); accessor.Count = count; accessor.Type = GLTFAccessorAttributeType.SCALAR; int min = arr[0]; int max = arr[0]; for (var i = 1; i < count; i++) { var cur = arr[i]; if (cur < min) { min = cur; } if (cur > max) { max = cur; } } var byteOffset = _bufferWriter.BaseStream.Position; if (max < byte.MaxValue && min > byte.MinValue) { accessor.ComponentType = GLTFComponentType.UnsignedByte; foreach (var v in arr) { _bufferWriter.Write((byte)v); } } else if (max < sbyte.MaxValue && min > sbyte.MinValue) { accessor.ComponentType = GLTFComponentType.Byte; foreach (var v in arr) { _bufferWriter.Write((sbyte)v); } } else if (max < short.MaxValue && min > short.MinValue) { accessor.ComponentType = GLTFComponentType.Short; foreach (var v in arr) { _bufferWriter.Write((short)v); } } else if (max < ushort.MaxValue && min > ushort.MinValue) { accessor.ComponentType = GLTFComponentType.UnsignedShort; foreach (var v in arr) { _bufferWriter.Write((ushort)v); } } else if (min > uint.MinValue) { accessor.ComponentType = GLTFComponentType.UnsignedInt; foreach (var v in arr) { _bufferWriter.Write((uint)v); } } else { accessor.ComponentType = GLTFComponentType.Float; foreach (var v in arr) { _bufferWriter.Write((float)v); } } accessor.Min = new List <double> { min }; accessor.Max = new List <double> { max }; var byteLength = _bufferWriter.BaseStream.Position - byteOffset; accessor.BufferView = ExportBufferView((int)byteOffset, (int)byteLength); var id = new AccessorId { Id = _root.Accessors.Count, Root = _root }; _root.Accessors.Add(accessor); return(id); }
// 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] = primVariations[i].Clone(); prims[i].Material = ExportMaterial(materialsObj[i]); } return(prims); } AccessorId aPosition = null, aNormal = null, aTangent = null, aTexcoord0 = null, aTexcoord1 = null, aColor0 = null; aPosition = ExportAccessor(InvertZ(meshObj.vertices)); if (meshObj.normals.Length != 0) { aNormal = ExportAccessor(InvertZ(meshObj.normals)); } if (meshObj.tangents.Length != 0) { aTangent = ExportAccessor(InvertW(meshObj.tangents)); } if (meshObj.uv.Length != 0) { aTexcoord0 = ExportAccessor(InvertY(meshObj.uv)); } if (meshObj.uv2.Length != 0) { aTexcoord1 = ExportAccessor(InvertY(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(); primitive.Contents = meshObj; var triangles = meshObj.GetTriangles(submesh); primitive.Indices = ExportAccessor(FlipFaces(triangles)); 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); }
private AccessorId ExportAccessor(Color[] arr) { var count = arr.Length; if (count == 0) { throw new Exception("Accessors can not have a count of 0."); } var accessor = new Accessor(); accessor.ComponentType = GLTFComponentType.Float; accessor.Count = count; accessor.Type = GLTFAccessorAttributeType.VEC4; float minR = arr[0].r; float minG = arr[0].g; float minB = arr[0].b; float minA = arr[0].a; float maxR = arr[0].r; float maxG = arr[0].g; float maxB = arr[0].b; float maxA = arr[0].a; for (var i = 1; i < count; i++) { var cur = arr[i]; if (cur.r < minR) { minR = cur.r; } if (cur.g < minG) { minG = cur.g; } if (cur.b < minB) { minB = cur.b; } if (cur.a < minA) { minA = cur.a; } if (cur.r > maxR) { maxR = cur.r; } if (cur.g > maxG) { maxG = cur.g; } if (cur.b > maxB) { maxB = cur.b; } if (cur.a > maxA) { maxA = cur.a; } } accessor.Min = new List <double> { minR, minG, minB, minA }; accessor.Max = new List <double> { maxR, maxG, maxB, maxA }; var byteOffset = _bufferWriter.BaseStream.Position; foreach (var color in arr) { _bufferWriter.Write(color.r); _bufferWriter.Write(color.g); _bufferWriter.Write(color.b); _bufferWriter.Write(color.a); } var byteLength = _bufferWriter.BaseStream.Position - byteOffset; accessor.BufferView = ExportBufferView((int)byteOffset, (int)byteLength); var id = new AccessorId { Id = _root.Accessors.Count, Root = _root }; _root.Accessors.Add(accessor); return(id); }