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 static void MergeAccessorsBufferViewsAndBuffers(GLTFRoot mergeToRoot, GLTFRoot mergeFromRoot, PreviousGLTFSizes previousGLTFSizes) { if (mergeFromRoot.Buffers != null) { if (mergeToRoot.Buffers == null) { mergeToRoot.Buffers = new List <Buffer>(mergeFromRoot.Buffers.Count); } mergeToRoot.Buffers.AddRange(mergeFromRoot.Buffers); } if (mergeFromRoot.BufferViews != null) { if (mergeToRoot.BufferViews == null) { mergeToRoot.BufferViews = new List <BufferView>(mergeFromRoot.BufferViews.Count); } mergeToRoot.BufferViews.AddRange(mergeFromRoot.BufferViews); for (int i = previousGLTFSizes.PreviousBufferViewCount; i < mergeToRoot.BufferViews.Count; ++i) { GLTFId <Buffer> bufferId = mergeToRoot.BufferViews[i].Buffer; bufferId.Id += previousGLTFSizes.PreviousBufferCount; bufferId.Root = mergeToRoot; } } if (mergeFromRoot.Accessors != null) { if (mergeToRoot.Accessors == null) { mergeToRoot.Accessors = new List <Accessor>(mergeFromRoot.Accessors.Count); } mergeToRoot.Accessors.AddRange(mergeFromRoot.Accessors); for (int i = previousGLTFSizes.PreviousAccessorCount; i < mergeToRoot.Accessors.Count; ++i) { Accessor accessor = mergeToRoot.Accessors[i]; if (accessor.BufferView != null) { BufferViewId bufferViewId = accessor.BufferView; bufferViewId.Id += previousGLTFSizes.PreviousBufferViewCount; bufferViewId.Root = mergeToRoot; } AccessorSparse accessorSparse = accessor.Sparse; if (accessorSparse != null) { BufferViewId indicesId = accessorSparse.Indices.BufferView; indicesId.Id += previousGLTFSizes.PreviousBufferViewCount; indicesId.Root = mergeToRoot; BufferViewId valuesId = accessorSparse.Values.BufferView; valuesId.Id += previousGLTFSizes.PreviousBufferViewCount; valuesId.Root = mergeToRoot; } } } }
private static void MergeMaterialsImagesTexturesAndSamplers(GLTFRoot mergeToRoot, GLTFRoot mergeFromRoot, PreviousGLTFSizes previousGLTFSizes) { if (mergeFromRoot.Samplers != null) { if (mergeToRoot.Samplers == null) { mergeToRoot.Samplers = new List <Sampler>(mergeFromRoot.Samplers.Count); } mergeToRoot.Samplers.AddRange(mergeFromRoot.Samplers); } if (mergeFromRoot.Images != null) { if (mergeToRoot.Images == null) { mergeToRoot.Images = new List <Image>(mergeFromRoot.Images.Count); } mergeToRoot.Images.AddRange(mergeFromRoot.Images); for (int i = previousGLTFSizes.PreviousImageCount; i < mergeToRoot.Images.Count; ++i) { Image image = mergeToRoot.Images[i]; if (image.BufferView != null) { BufferViewId bufferViewId = image.BufferView; bufferViewId.Id += previousGLTFSizes.PreviousBufferViewCount; bufferViewId.Root = mergeToRoot; } } } if (mergeFromRoot.Textures != null) { if (mergeToRoot.Textures == null) { mergeToRoot.Textures = new List <Texture>(mergeFromRoot.Textures.Count); } mergeToRoot.Textures.AddRange(mergeFromRoot.Textures); for (int i = previousGLTFSizes.PreviousTextureCount; i < mergeToRoot.Textures.Count; ++i) { Texture texture = mergeToRoot.Textures[i]; if (texture.Sampler != null) { SamplerId samplerId = texture.Sampler; samplerId.Id += previousGLTFSizes.PreviousSamplerCount; samplerId.Root = mergeToRoot; } if (texture.Source != null) { ImageId samplerId = texture.Source; samplerId.Id += previousGLTFSizes.PreviousImageCount; samplerId.Root = mergeToRoot; } } } if (mergeFromRoot.Materials != null) { if (mergeToRoot.Materials == null) { mergeToRoot.Materials = new List <Material>(mergeFromRoot.Materials.Count); } mergeToRoot.Materials.AddRange(mergeFromRoot.Materials); for (int i = previousGLTFSizes.PreviousMaterialCount; i < mergeToRoot.Materials.Count; ++i) { Material material = mergeToRoot.Materials[i]; PbrMetallicRoughness pbrMetallicRoughness = material.PbrMetallicRoughness; if (pbrMetallicRoughness != null) { if (pbrMetallicRoughness.BaseColorTexture != null) { TextureId textureId = pbrMetallicRoughness.BaseColorTexture.Index; textureId.Id += previousGLTFSizes.PreviousTextureCount; textureId.Root = mergeToRoot; } if (pbrMetallicRoughness.MetallicRoughnessTexture != null) { TextureId textureId = pbrMetallicRoughness.MetallicRoughnessTexture.Index; textureId.Id += previousGLTFSizes.PreviousTextureCount; textureId.Root = mergeToRoot; } } MaterialCommonConstant commonConstant = material.CommonConstant; if (commonConstant?.LightmapTexture != null) { TextureId textureId = material.CommonConstant.LightmapTexture.Index; textureId.Id += previousGLTFSizes.PreviousTextureCount; textureId.Root = mergeToRoot; } if (material.EmissiveTexture != null) { TextureId textureId = material.EmissiveTexture.Index; material.EmissiveTexture.Index.Id += previousGLTFSizes.PreviousTextureCount; textureId.Root = mergeToRoot; } if (material.NormalTexture != null) { TextureId textureId = material.NormalTexture.Index; textureId.Id += previousGLTFSizes.PreviousTextureCount; textureId.Root = mergeToRoot; } if (material.OcclusionTexture != null) { TextureId textureId = material.OcclusionTexture.Index; textureId.Id += previousGLTFSizes.PreviousTextureCount; textureId.Root = mergeToRoot; } } } }
private static void MergeAccessorsBufferViewsAndBuffers(GLTFRoot mergeToRoot, GLTFRoot mergeFromRoot, PreviousGLTFSizes previousGLTFSizes) { bool isGLB = false; if (mergeFromRoot.Buffers != null) { if (mergeToRoot.Buffers == null) { mergeToRoot.Buffers = new List <GLTFBuffer>(mergeFromRoot.Buffers.Count); } foreach (GLTFBuffer buffer in mergeFromRoot.Buffers) { if (buffer.Uri != null) { mergeToRoot.Buffers.Add(buffer); } else { isGLB = true; // assume glb is a uri is null } } } if (mergeFromRoot.BufferViews != null) { if (mergeToRoot.BufferViews == null) { mergeToRoot.BufferViews = new List <BufferView>(mergeFromRoot.BufferViews.Count); } mergeToRoot.BufferViews.AddRange(mergeFromRoot.BufferViews); for (int i = previousGLTFSizes.PreviousBufferViewCount; i < mergeToRoot.BufferViews.Count; ++i) { GLTFId <GLTFBuffer> bufferId = mergeToRoot.BufferViews[i].Buffer; if (!(isGLB && bufferId.Id == 0)) // if it is pointing a the special glb buffer (index 0 of a glb) then we dont want to adjust the buffer view, otherwise we do { // adjusting bufferview id based on merge amount bufferId.Id += previousGLTFSizes.PreviousBufferCount; bufferId.Root = mergeToRoot; } } } if (mergeFromRoot.Accessors != null) { if (mergeToRoot.Accessors == null) { mergeToRoot.Accessors = new List <Accessor>(mergeFromRoot.Accessors.Count); } mergeToRoot.Accessors.AddRange(mergeFromRoot.Accessors); for (int i = previousGLTFSizes.PreviousAccessorCount; i < mergeToRoot.Accessors.Count; ++i) { Accessor accessor = mergeToRoot.Accessors[i]; if (accessor.BufferView != null) { BufferViewId bufferViewId = accessor.BufferView; bufferViewId.Id += previousGLTFSizes.PreviousBufferViewCount; bufferViewId.Root = mergeToRoot; } AccessorSparse accessorSparse = accessor.Sparse; if (accessorSparse != null) { BufferViewId indicesId = accessorSparse.Indices.BufferView; indicesId.Id += previousGLTFSizes.PreviousBufferViewCount; indicesId.Root = mergeToRoot; BufferViewId valuesId = accessorSparse.Values.BufferView; valuesId.Id += previousGLTFSizes.PreviousBufferViewCount; valuesId.Root = mergeToRoot; } } } }
public GLTFObject(GLTFRoot root) { Root = root; }
public static GLTFRoot ParseString(string gltfContent) { var stringReader = new StringReader(gltfContent); return(GLTFRoot.Deserialize(new JsonTextReader(stringReader))); }
/// <summary> /// Removes references to indexes that do not exist. /// </summary> /// <param name="root">The node to clean</param> public static void RemoveUndefinedReferences(GLTFRoot root) { int accessorCount = root.Accessors?.Count ?? 0; int bufferCount = root.Buffers?.Count ?? 0; int bufferViewCount = root.BufferViews?.Count ?? 0; int cameraCount = root.Cameras?.Count ?? 0; int meshCount = root.Meshes?.Count ?? 0; int nodeCount = root.Nodes?.Count ?? 0; int samplersCount = root.Samplers?.Count ?? 0; int skinCount = root.Skins?.Count ?? 0; int textureCount = root.Textures?.Count ?? 0; if (root.Accessors != null) { foreach (Accessor accessor in root.Accessors) { if (accessor.BufferView != null && accessor.BufferView.Id >= bufferViewCount) { accessor.BufferView = null; } } } if (root.Animations != null) { foreach (GLTFAnimation animation in root.Animations) { if (animation.Samplers != null) { foreach (AnimationSampler animationSampler in animation.Samplers) { if (animationSampler.Input != null && animationSampler.Input.Id >= accessorCount) { animationSampler.Input = null; } if (animationSampler.Output != null && animationSampler.Output.Id >= accessorCount) { animationSampler.Output = null; } } } } } if (root.BufferViews != null) { foreach (BufferView bufferView in root.BufferViews) { if (bufferView.Buffer != null && bufferView.Buffer.Id >= bufferCount) { bufferView.Buffer = null; } } } if (root.Images != null) { foreach (GLTFImage image in root.Images) { if (image.BufferView != null && image.BufferView.Id >= bufferViewCount) { image.BufferView = null; } } } if (root.Materials != null) { foreach (GLTFMaterial material in root.Materials) { if (material.EmissiveTexture?.Index != null && material.EmissiveTexture.Index.Id >= textureCount) { material.EmissiveTexture.Index = null; } if (material.NormalTexture?.Index != null && material.NormalTexture.Index.Id >= textureCount) { material.NormalTexture.Index = null; } if (material.OcclusionTexture?.Index != null && material.OcclusionTexture.Index.Id >= textureCount) { material.OcclusionTexture.Index = null; } if (material.OcclusionTexture?.Index != null && material.OcclusionTexture.Index.Id >= textureCount) { material.OcclusionTexture.Index = null; } if (material.PbrMetallicRoughness != null) { if (material.PbrMetallicRoughness.BaseColorTexture?.Index != null && material.PbrMetallicRoughness.BaseColorTexture.Index.Id >= textureCount) { material.PbrMetallicRoughness.BaseColorTexture.Index = null; } if (material.PbrMetallicRoughness.MetallicRoughnessTexture?.Index != null && material.PbrMetallicRoughness.MetallicRoughnessTexture.Index.Id >= textureCount) { material.PbrMetallicRoughness.MetallicRoughnessTexture.Index = null; } } } } if (root.Meshes != null) { foreach (GLTFMesh mesh in root.Meshes) { if (mesh.Primitives != null) { foreach (MeshPrimitive primitive in mesh.Primitives) { if (primitive.Indices != null && primitive.Indices.Id >= accessorCount) { primitive.Indices = null; } if (primitive.Material != null && primitive.Material.Id >= accessorCount) { primitive.Material = null; } } } } } if (root.Nodes != null) { foreach (Node node in root.Nodes) { if (node.Camera != null && node.Camera.Id >= cameraCount) { node.Camera = null; } if (node.Children != null) { for (int i = node.Children.Count - 1; i > 0; i--) { if (node.Children[i].Id >= nodeCount) { node.Children.RemoveAt(i); } } } if (node.Mesh != null && node.Mesh.Id >= meshCount) { node.Mesh = null; } if (node.Skin != null && node.Skin.Id >= skinCount) { node.Skin = null; } } } if (root.Scenes != null) { foreach (GLTFScene scene in root.Scenes) { if (scene.Nodes != null) { for (int i = scene.Nodes.Count - 1; i > 0; i--) { if (scene.Nodes[i].Id >= nodeCount) { scene.Nodes.RemoveAt(i); } } } } } if (root.Skins != null) { foreach (Skin skin in root.Skins) { if (skin.Joints != null) { for (int i = skin.Joints.Count - 1; i > 0; i--) { if (skin.Joints[i].Id >= nodeCount) { skin.Joints.RemoveAt(i); } } } if (skin.Skeleton != null && skin.Skeleton.Id >= nodeCount) { skin.Skeleton = null; } } } if (root.Textures != null) { foreach (GLTFTexture texture in root.Textures) { if (texture.Sampler != null && texture.Sampler.Id >= samplersCount) { texture.Sampler = null; } } } }
public static NodeId FindCommonAncestor(IEnumerable <NodeId> nodes) { // build parentage GLTFRoot root = nodes.First().Root; Dictionary <int, int> childToParent = new Dictionary <int, int>(root.Nodes.Count); for (int i = 0; i < root.Nodes.Count; i++) { if (root.Nodes[i].Children == null) { continue; } foreach (NodeId child in root.Nodes[i].Children) { childToParent[child.Id] = i; } } // scan for common ancestor int?commonAncestorIndex = nodes .Select(n => n.Id) .Aggregate((int?)null, (elder, node) => FindCommonAncestor(elder, node)); return(commonAncestorIndex != null ? new NodeId() { Id = commonAncestorIndex.Value, Root = root } : null); int?FindCommonAncestor(int?a, int?b) { // trivial cases if (a == null && b == null) { return(null); } else if (a != null) { return(a); } else if (b != null) { return(b); } else if (AncestorOf(a.Value, b.Value)) { return(a); } else { return(FindCommonAncestor(childToParent[a.Value], b.Value)); } } bool AncestorOf(int ancestor, int descendant) { while (childToParent.ContainsKey(descendant)) { if (childToParent[descendant] == ancestor) { return(true); } descendant = childToParent[descendant]; } return(false); } }
public static Node Deserialize(GLTFRoot root, JsonReader reader) { var node = new Node(); while (reader.Read() && reader.TokenType == JsonToken.PropertyName) { var curProp = reader.Value.ToString(); switch (curProp) { case "camera": node.Camera = CameraId.Deserialize(root, reader); break; case "children": node.Children = NodeId.ReadList(root, reader); break; case "skin": node.Skin = SkinId.Deserialize(root, reader); break; case "matrix": var list = reader.ReadDoubleList(); var mat = new Matrix4x4(); for (var i = 0; i < 16; i++) { mat[i] = (float)list[i]; } node.Matrix = mat; break; case "mesh": node.Mesh = MeshId.Deserialize(root, reader); break; case "rotation": node._useTRS = true; node.Rotation = reader.ReadAsQuaternion(); break; case "scale": node._useTRS = true; node.Scale = reader.ReadAsVector3(); break; case "translation": node._useTRS = true; node.Translation = reader.ReadAsVector3(); break; case "weights": node.Weights = reader.ReadDoubleList(); break; default: node.DefaultPropertyDeserializer(root, reader); break; } } return(node); }
private static GLTFRoot ParseString(string gltfContent) { var stringReader = new StringReader(gltfContent); return(GLTFRoot.Deserialize(stringReader)); }
public static GLTFRoot Deserialize(JsonReader reader) { var root = new GLTFRoot(); if (reader.Read() && reader.TokenType != JsonToken.StartObject) { throw new Exception("glTF JSON must be an object"); } while (reader.Read() && reader.TokenType == JsonToken.PropertyName) { var curProp = reader.Value.ToString(); switch (curProp) { case "extensionsUsed": root.ExtensionsUsed = reader.ReadStringList(); break; case "extensionsRequired": root.ExtensionsRequired = reader.ReadStringList(); break; case "accessors": root.Accessors = reader.ReadList(() => Accessor.Deserialize(root, reader)); break; case "animations": root.Animations = reader.ReadList(() => GLTFAnimation.Deserialize(root, reader)); break; case "asset": root.Asset = Asset.Deserialize(root, reader); break; case "buffers": root.Buffers = reader.ReadList(() => Buffer.Deserialize(root, reader)); break; case "bufferViews": root.BufferViews = reader.ReadList(() => BufferView.Deserialize(root, reader)); break; case "cameras": root.Cameras = reader.ReadList(() => GLTFCamera.Deserialize(root, reader)); break; case "images": root.Images = reader.ReadList(() => Image.Deserialize(root, reader)); break; case "materials": root.Materials = reader.ReadList(() => Material.Deserialize(root, reader)); break; case "meshes": root.Meshes = reader.ReadList(() => Mesh.Deserialize(root, reader)); break; case "nodes": root.Nodes = reader.ReadList(() => Node.Deserialize(root, reader)); break; case "samplers": root.Samplers = reader.ReadList(() => Sampler.Deserialize(root, reader)); break; case "scene": root.Scene = SceneId.Deserialize(root, reader); break; case "scenes": root.Scenes = reader.ReadList(() => GLTF.Scene.Deserialize(root, reader)); break; case "skins": root.Skins = reader.ReadList(() => Skin.Deserialize(root, reader)); break; case "textures": root.Textures = reader.ReadList(() => Texture.Deserialize(root, reader)); break; default: root.DefaultPropertyDeserializer(root, reader); break; } } return(root); }
public abstract GLTFExtension Deserialize(GLTFRoot root, JsonReader reader);