// SPDX-FileCopyrightText: 2023 Unity Technologies and the glTFast authors // SPDX-License-Identifier: Apache-2.0 namespace GLTFast.Schema { /// [System.Serializable] public class Node : NodeBase { } /// /// Node extensions type [System.Serializable] public abstract class NodeBase : NodeBase where TExtensions : NodeExtensions { /// public TExtensions extensions; /// public override NodeExtensions Extensions => extensions; /// internal override void UnsetExtensions() { extensions = null; } } /// /// An object defining the hierarchy relations and the local transform of /// its content. /// [System.Serializable] public abstract class NodeBase : NamedObject { /// /// The indices of this node's children. /// public uint[] children; /// /// The index of the mesh in this node. /// public int mesh = -1; /// /// A floating-point 4x4 transformation matrix stored in column-major order. /// public float[] matrix; /// /// The node's unit quaternion rotation in the order (x, y, z, w), /// where w is the scalar. /// public float[] rotation; /// /// The node's non-uniform scale. /// public float[] scale; /// /// The node's translation. /// public float[] translation; /// /// The weights of the instantiated Morph Target. /// Number of elements must match number of Morph Targets of used mesh. /// public float[] weights; /// /// The index of the skin (in referenced by this node. /// public int skin = -1; /// /// Camera index /// public int camera = -1; /// public abstract NodeExtensions Extensions { get; } /// /// Sets to null. /// internal abstract void UnsetExtensions(); internal void GltfSerialize(JsonWriter writer) { writer.AddObject(); GltfSerializeName(writer); if (children != null) { writer.AddArrayProperty("children", children); } if (mesh >= 0) { writer.AddProperty("mesh", mesh); } if (translation != null) { writer.AddArrayProperty("translation", translation); } if (rotation != null) { writer.AddArrayProperty("rotation", rotation); } if (scale != null) { writer.AddArrayProperty("scale", scale); } if (matrix != null) { writer.AddArrayProperty("matrix", matrix); } if (weights != null) { writer.AddArrayProperty("weights", weights); } if (skin >= 0) { writer.AddProperty("skin", skin); } if (camera >= 0) { writer.AddProperty("camera", camera); } if (Extensions != null) { writer.AddProperty("extensions"); Extensions.GltfSerialize(writer); } writer.Close(); } /// /// Cleans up invalid parsing artifacts created by . /// If you inherit a custom Node class (for use with /// /// ) you can override this method to perform sanity checks on the deserialized, custom properties. /// public virtual void JsonUtilityCleanup() { var e = Extensions; if (e != null) { // Check if GPU instancing extension is valid if (e.EXT_mesh_gpu_instancing?.attributes == null) { e.EXT_mesh_gpu_instancing = null; } // Check if Lights extension is valid if ((e.KHR_lights_punctual?.light ?? -1) < 0) { e.KHR_lights_punctual = null; } // Unset `extension` if none of them was valid if (e.EXT_mesh_gpu_instancing == null && e.KHR_lights_punctual == null) { UnsetExtensions(); } } } } /// /// Node extensions /// [System.Serializable] public class NodeExtensions { // Names are identical to glTF specified properties, that's why // inconsistent names are ignored. // ReSharper disable InconsistentNaming /// public MeshGpuInstancing EXT_mesh_gpu_instancing; /// public NodeLightsPunctual KHR_lights_punctual; // Whenever an extension is added, the JsonParser // (specifically step four of JsonParser.ParseJson) // needs to be updated! // ReSharper restore InconsistentNaming internal void GltfSerialize(JsonWriter writer) { writer.AddObject(); if (EXT_mesh_gpu_instancing != null) { writer.AddProperty("EXT_mesh_gpu_instancing"); EXT_mesh_gpu_instancing.GltfSerialize(writer); } if (KHR_lights_punctual != null) { writer.AddProperty("KHR_lights_punctual"); KHR_lights_punctual.GltfSerialize(writer); } writer.Close(); } } }