{
    "$id": "https://schemas.3d.si.edu/voyager/document.schema.json",
    "$schema": "http://json-schema.org/draft-07/schema#",

    "title": "Smithsonian 3D Document",
    "description": "Describes a 3D document containing a scene with 3D models.",

    "definitions": {
        "scene": {
            "$id": "#scene",
            "type": "object",
            "properties": {
                "nodes": {
                    "type": "array",
                    "description": "The indices of the scene's root nodes.",
                    "items": {
                        "type": "integer",
                        "minimum": 0
                    },
                    "uniqueItems": true,
                    "minItems": 1
                },
                "setup": {
                    "description": "The index of the scene's setup.",
                    "type": "integer",
                    "minimum": 0
                }
            }
        },
        "node": {
            "$id": "#node",
            "type": "object",
            "properties": {
                "name": {
                    "type": "string"
                },
                "children": {
                    "type": "array",
                    "description": "The indices of this node's children.",
                    "items": {
                        "type": "integer",
                        "minimum": 0
                    },
                    "uniqueItems": true,
                    "minItems": 1
                },

                "matrix": {
                    "description": "A floating-point 4x4 transformation matrix stored in column-major order.",
                    "type": "array",
                    "items": {
                        "type": "number"
                    },
                    "minItems": 16,
                    "maxItems": 16,
                    "default": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ]
                },
                "translation": {
                    "description": "The node's translation along the x, y, and z axes.",
                    "type": "array",
                    "items": {
                        "type": "number"
                    },
                    "minItems": 3,
                    "maxItems": 3,
                    "default": [ 0.0, 0.0, 0.0 ]
                },
                "rotation": {
                    "description": "The node's unit quaternion rotation in the order (x, y, z, w), where w is the scalar.",
                    "type": "array",
                    "items": {
                        "type": "number",
                        "minimum": -1.0,
                        "maximum": 1.0
                    },
                    "minItems": 4,
                    "maxItems": 4,
                    "default": [ 0.0, 0.0, 0.0, 1.0 ]
                },
                "scale": {
                    "description": "The node's non-uniform scale, given as the scaling factors along the x, y, and z axes.",
                    "type": "array",
                    "items": {
                        "type": "number"
                    },
                    "minItems": 3,
                    "maxItems": 3,
                    "default": [ 1.0, 1.0, 1.0 ]
                },

                "camera": {
                    "description": "The index of the camera component of this node.",
                    "type": "integer",
                    "minimum": 0
                },
                "light": {
                    "description": "The index of the light component of this node.",
                    "type": "integer",
                    "minimum": 0
                },
                "meta": {
                    "description": "The index of the meta data component of this node.",
                    "type": "integer",
                    "minimum": 0
                },
                "model": {
                    "description": "The index of the model component of this node.",
                    "type": "integer",
                    "minimum": 0
                }
            },
            "not": {
                "anyOf": [
                    { "required": [ "matrix", "translation" ] },
                    { "required": [ "matrix", "rotation" ] },
                    { "required": [ "matrix", "scale" ] }
                ]
            }
        },

        "camera": {
            "$id": "#camera",
            "type": "object",
            "properties": {
                "type": {
                    "description": "Specifies if the camera uses a perspective or orthographic projection.",
                    "type": "string",
                    "enum": [
                        "perspective",
                        "orthographic"
                    ]
                },
                "perspective": {
                    "description": "A perspective camera containing properties to create a perspective projection matrix.",
                    "type": "object",
                    "properties": {
                        "yfov": {
                            "type": "number",
                            "description": "The floating-point vertical field of view in radians.",
                            "exclusiveMinimum": 0.0
                        },
                        "aspectRatio": {
                            "type": "number",
                            "description": "The floating-point aspect ratio of the field of view.",
                            "exclusiveMinimum": 0.0
                        },
                        "znear": {
                            "type": "number",
                            "description": "The floating-point distance to the near clipping plane.",
                            "exclusiveMinimum": 0.0
                        },
                        "zfar": {
                            "type": "number",
                            "description": "The floating-point distance to the far clipping plane.",
                            "exclusiveMinimum": 0.0
                        }
                    },
                    "required": [
                        "yfov",
                        "znear"
                    ]
                },
                "orthographic": {
                    "description": "An orthographic camera containing properties to create an orthographic projection matrix.",
                    "type": "object",
                    "properties": {
                        "xmag": {
                            "type": "number",
                            "description": "The floating-point horizontal magnification of the view. Must not be zero."
                        },
                        "ymag": {
                            "type": "number",
                            "description": "The floating-point vertical magnification of the view. Must not be zero."
                        },
                        "znear": {
                            "type": "number",
                            "description": "The floating-point distance to the near clipping plane.",
                            "exclusiveMinimum": 0.0
                        },
                        "zfar": {
                            "type": "number",
                            "description": "The floating-point distance to the far clipping plane. `zfar` must be greater than `znear`.",
                            "exclusiveMinimum": 0.0
                        }
                    },
                    "required": [
                        "ymag",
                        "znear",
                        "zfar"
                    ]
                },
                "autoNearFar": {
                    "type": "boolean",
                    "default": true
                }
            },
            "required": [
                "type"
            ],
            "not": {
                "required": [ "perspective", "orthographic", "autoNearFar" ]
            }
        },

        "light": {
            "$id": "#light",
            "type": "object",
            "properties": {
                "type": {
                    "description": "Specifies the type of the light source.",
                    "type": "string",
                    "enum": [
                        "ambient",
                        "directional",
                        "point",
                        "spot",
                        "hemisphere",
                        "rect",
                        "environment",
                        "sun"
                    ]
                },
                "color": {
                    "$ref": "#/definitions/colorRGB"
                },
                "tags": {
                    "type": "string"
                },
                "intensity": {
                    "type": "number",
                    "minimum": 0,
                    "default": 1
                },
                "castShadow": {
                    "type": "boolean",
                    "default": false
                },
                "point": {
                    "type": "object",
                    "properties": {
                        "distance": {
                            "type": "number",
                            "minimum": 0
                        },
                        "decay": {
                            "type": "number",
                            "minimum": 0
                        }
                    }
                },
                "spot": {
                    "type": "object",
                    "properties": {
                        "distance": {
                            "type": "number",
                            "minimum": 0
                        },
                        "decay": {
                            "type": "number",
                            "minimum": 0
                        },
                        "angle": {
                            "type": "number",
                            "minimum": 0
                        },
                        "penumbra": {
                            "type": "number",
                            "minimum": 0
                        }
                    }
                },
                "hemisphere": {
                    "type": "object",
                    "properties": {
                        "groundColor": {
                            "$ref": "#/definitions/colorRGB"
                        }
                    }
                }
            },
            "required": [
                "type"
            ],
            "not": {
                "required": [ "point", "spot", "hemisphere" ]
            }
        },

        "colorRGB": {
            "$id": "#colorRGB",
            "type": "array",
            "items": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
            },
            "minItems": 3,
            "maxItems": 3,
            "default": [ 1.0, 1.0, 1.0 ]
        }
    },

    "type": "object",
    "properties": {
        "asset": {
            "type": "object",
            "properties": {
                "type": {
                    "type": "string",
                    "const": "application/si-dpo-3d.document+json"
                },
                "version": {
                    "description": "Version of this presentation description.",
                    "type": "string",
                    "minLength": 1
                },
                "copyright": {
                    "description": "A copyright message to credit the content creator.",
                    "type": "string",
                    "minLength": 0
                },
                "generator": {
                    "description": "Tool that generated this presentation description.",
                    "type": "string",
                    "minLength": 1
                }
            },
            "required": [
                "type",
                "version"
            ]
        },
        "scene": {
            "description": "Index of the root scene of the document.",
            "type": "integer",
            "minimum": 0
        },
        "scenes": {
            "description": "An array of scenes.",
            "type": "array",
            "items": {
                "$ref": "#/definitions/scene"
            }
        },
        "nodes": {
            "description": "An array of nodes.",
            "type": "array",
            "items": {
                "$ref": "#/definitions/node"
            },
            "minItems": 1
        },
        "metas": {
            "description": "An array of meta data components.",
            "type": "array",
            "items": {
                "$ref": "./meta.schema.json"
            }
        },
        "setups": {
            "description": "An array of setup components.",
            "type": "array",
            "items": {
                "$ref": "./setup.schema.json"
            },
            "minItems": 1
        },
        "cameras": {
            "description": "An array of camera components.",
            "type": "array",
            "items": {
                "$ref": "#/definitions/camera"
            },
            "minItems": 1
        },
        "lights": {
            "description": "An array of light components.",
            "type": "array",
            "items": {
                "$ref": "#/definitions/light"
            },
            "minItems": 1
        },
        "models": {
            "description": "An array of model components.",
            "type": "array",
            "items": {
                "$ref": "./model.schema.json"
            },
            "minItems": 1
        }
    },
    "required": [
        "asset",
        "scene",
        "scenes"
    ],
    "additionalProperties": false
}