{
  "$id": "schema2e",

  "$defs": {
    "cylindricalprojection": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "const": "CylindricalProjection",
          "default": "CylindricalProjection",
          "readOnly": true
        },
        "quality": {
          "$ref": "sgct.schema.json#/$defs/projectionquality"
        },
        "heightOffset": {
          "type": "number",
          "title": "Height Offset",
          "description": "Offsets the height from which the cylindrical projection is generated. This is, in general, only necessary if the user position is offset and you want to counter that offset to continue producing a “standard” cylindrical projection"
        }
      },
      "required": [ "type" ],
      "additionalProperties": false,
      "description": "This projection method renders the scene into a view that can be mapped on the inside or outside of a cylinder. This projection method is support by some live media curation tools. The forward-facing direction will be at the left border of the image unless changed via the rotation option"
    },
  
    "fisheyeprojection": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "const": "FisheyeProjection",
          "default": "FisheyeProjection",
          "readOnly": true
        },
        "quality": {
          "$ref": "sgct.schema.json#/$defs/projectionquality"
        }
      },
      "required": [ "type" ],
      "additionalProperties": false,
      "description": "Describes a fisheye projection that is used to render into its parent Viewport. This uses a default of 180 degrees field of view and has a 1:1 aspect ratio. This projection type counts as a non-linear projection, which requires 4-6 render passes of the application, meaning that the application might render slower when using these kind of projections than a flat projection. In either case, the application does not need to be aware of the projection as this abstract is handled internally and the applications draw method is only called multiple times per frame with different projection methods that are used to create the full fisheye projection"
    },
  
    "planarprojection": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "const": "PlanarProjection",
          "default": "PlanarProjection",
          "readOnly": true
        },
        "fov": {
          "$ref": "sgct.schema.json#/$defs/fovhorizontalvertical",
          "title": "Camera Field-of-View",
          "description": "This element describes the field of view used the camera in this planar projection"
        }
      },
      "additionalProperties": false,
      "description": "Describes a projection for the Viewport that is a flat projection described by simple frustum, which may be asymmetric"
    },
  
    "sphericalmirrorprojection": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "const": "SphericalMirrorProjection",
          "default": "SphericalMirrorProjection",
          "readOnly": true
        },
        "quality": {
          "$ref": "sgct.schema.json#/$defs/projectionquality"
        }
      },
      "required": [ "type" ],
      "additionalProperties": false,
      "description": "Used to create a projection used for Paul Bourke's spherical mirror setup (see here), which makes it possible to use an off-the-shelf projector to create a planetarium-like environment by bouncing the image of a shiny metal mirror. Please note that this is not the only way to produce these kind of images. Depending on your setup and availability of warping meshes, it might suffice to use the FisheyeProjection node type instead and add a single mesh to the parent Viewport instead. The config folder in SGCT contains an example of this using a default 16x9 warping mesh. This projection type specifically deals with the case where you have four different meshes, one for the bottom, top, left, and right parts of the distorted image"
    },
  
    "spoutoutputprojection": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "const": "SpoutOutputProjection",
          "default": "SpoutOutputProjection",
          "readOnly": true
        },
        "quality": {
          "$ref": "sgct.schema.json#/$defs/projectionquality"
        },
        "mapping": {
          "type": "string",
          "enum": [ "fisheye", "equirectangular" ],
          "title": "Mapping",
          "description": "Determines the type of sharing that occurs with this projection and thus how many and which texture is shared via Spout. For the “fisheye” and “equirectangular”, only the single, final reprojected image is shared, for the “cubemap” method, all selected cubemaps will be provided through the Spout interface. The default value is “cubemap”"
        },
        "mappingspoutname": {
          "type": "string",
          "title": "Mapping Spout Name",
          "description": "Sets the name of the texture if the mapping type is 'fisheye' or 'equirectangular'. If the mapping is 'cubemap', this value is ignored"
        }
      },
      "required": [ "type", "mapping" ],
      "additionalProperties": false,
      "description": "Provides the ability to share a fully reprojected image using the Spout library. This library only supports the Windows operating system, so this projection will only work on Windows machines. Spout's functionality is the abilty to shared textures between different applications on the same machine, making it possible to render images using SGCT and making them available to other real-time applications on the same machine for further processing. Spout uses a textual name for accessing which texture should be used for sharing. The SpoutOutputProjection has three different output types, outputting each cube map face, sharing a fisheye image, or sharing an equirectangular projection, as determined by the mapping attribute"
    },
  
    "projection": {
      "oneOf": [
        {
          "$ref": "#/$defs/planarprojection",
          "title": "Planar Projection"
        },
        {
          "$ref": "#/$defs/fisheyeprojection",
          "title": "Fisheye Projection"
        },
        {
          "$ref": "#/$defs/sphericalmirrorprojection",
          "title": "Spherical Mirror Projection"
        },
        {
          "$ref": "#/$defs/spoutoutputprojection",
          "title": "Spout Output Projection"
        },
        {
          "$ref": "#/$defs/cylindricalprojection",
          "title": "Cylindrical Projection"
        },
        {
          "$ref": "sgct.schema.json#/$defs/equirectangularprojection",
          "title": "Equirectangular Projection"
        }
      ],
      "title": "Projection"
    },
  
    "node": {
      "type": "object",
      "properties": {
        "address": {
          "$ref": "sgct.schema.json#/$defs/address"
        },
        "port": {
          "$ref": "sgct.schema.json#/$defs/port"
        },
        "windows": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "border": {
                "$ref": "sgct.schema.json#/$defs/windowborder"
              },
              "draw2d": {
                "$ref": "sgct.schema.json#/$defs/draw2d"
              },
              "draw3d": {
                "$ref": "sgct.schema.json#/$defs/draw3d"
              },
              "monitor": {
                "$ref": "sgct.schema.json#/$defs/monitor"
              },
              "id": {
                "$ref": "sgct.schema.json#/$defs/id"
              },
              "name": {
                "$ref": "sgct.schema.json#/$defs/windowname"
              },
              "pos": {
                "$ref": "sgct.schema.json#/$defs/windowpos"
              },
              "size": {
                "$ref": "sgct.schema.json#/$defs/windowsize"
              },
              "tags": {
                "$ref": "sgct.schema.json#/$defs/tags"
              },
              "viewports": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "pos": {
                      "$ref": "sgct.schema.json#/$defs/viewportpos"
                    },
                    "size": {
                      "$ref": "sgct.schema.json#/$defs/viewportsize"
                    },
                    "projection": {
                      "$ref": "sgct.schema.json#/$defs/projection"
                    },
                    "tracked": {
                      "$ref": "sgct.schema.json#/$defs/tracked"
                    }
                  }
                },
                "title": "Viewports"
              }
            },
	    "required": [ "pos", "size", "viewports" ]
  	},
          "title": "Windows",
          "description": "Specifies a single window that is used to render content into. There can be an arbitrary(-ish) number of windows for each node and they all will be created and initialized at start time. Each window has at least one Viewport that specifies exactly where in the window the rendering occurs with which parameters"
        }
      },
      "required": [ "address", "port", "windows" ],
      "additionalProperties": false,
      "description": "Defines a single computing node that is contained in the described cluster. In general this corresponds to a single computer, but it is also possible to create multiple nodes on a local machine by using the 127.0.0.x IP address with x from 0 to 255. It is not possible to create multiple nodes on the same remote computer, however"
    },
  
    "scene": {
      "type": "object",
      "properties": {
        "orientation": {
          "$ref": "sgct.schema.json#/$defs/quat",
          "title": "Orientation",
          "description": "Describes a fixed orientation of the global scene"
        }
      },
      "required": [ "orientation" ],
      "additionalProperties": false,
      "description": "Determines an overall orientation of the scene. It consists only of an Orientation, which is included in the projection matrix that is passed to the rendering function callback of the specific application. This node can be used to customize the rendering for a specific rendering window. A common use-case in planetariums, for example, is to account for a tilt in the display system by providing an Orientation with the same pitch as the planetarium surface. This makes it possible to reuse the same application between the planetarium dome and fixed setups without the need for special care"
    },
  
    "display": {
      "type": "object",
      "properties": {
        "swapinterval": {
          "type": "integer",
          "minimum": 0,
          "title": "Swap Interval",
          "description": "Determines the swap interval for the application. This determines the amount of V-Sync that should occur for the application. The two most common values for this are 0 for disabling V-Sync and 1 for regular V-Sync. The number provided determines the number of screen updates to wait before swapping the backbuffers and returning. For example on a 60Hz monitor, swapinterval=\"1\" would lead to a maximum of 60Hz frame rate, swapinterval=\"2\" would lead to a maximum of 30Hz frame rate. Using the same values for a 144Hz monitor would be a refresh rate of 144 and 72 respectively. The default value is 0, meaning that V-Sync is disabled"
        }
      },
      "title": "Display",
      "additionalProperties": false,
      "description": "Settings specific for the handling of display-related settings for the whole application"
    },
  
    "settings": {
      "type": "object",
      "properties": {
        "display": {
          "$ref": "#/$defs/display"
        }
      },
      "additionalProperties": false,
      "description": "Controls global settings that affect the overall behavior of the SGCT library that are not limited just to a single window"
    },

    "user": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "title": "Name",
          "description": "Specifies the name of this user. Each user needs to have a unique name, but there also has to be exactly one user present that has an empty name (or without a name attribute) which is used as the default user"
        },
        "eyeseparation": {
          "type": "number",
          "minimum": 0.0,
          "title": "Eye Separation",
          "description": "Determines the eye separation used for stereoscopic viewports. If no viewports in the configuration are using stereo, this setting is ignored"
        },
        "pos": {
          "$ref": "sgct.schema.json#/$defs/vec3",
          "title": "Position",
          "description": "A linear offset of the user position. Must define three float attributes x, y, and z. The default values are x=0, y=0, z=0, meaning that no linear offset is applied to the user's position"
        }
      },
      "additionalProperties": false,
      "required": [ "pos" ],
      "description": "Specifies a user position and parameters. In most cases, only a single unnamed user is necessary. However, in more general cases, it is possible to assign Users to specific Viewports to provide a more fine-grained control over the rendering that occurs in that viewport"
    }
  },

  "type": "object",
  "properties": {
    "masteraddress": {
      "$ref": "sgct.schema.json#/$defs/masteraddress"
    },
    "nodes": {
      "type": "array",
      "items": { "$ref": "#/$defs/node" },
      "title": "Nodes"
    },
    "scene": {
      "$ref": "#/$defs/scene",
      "title": "Scene"
    },
    "settings": {
      "$ref": "#/$defs/settings",
      "title": "Settings"
    },
    "version": {
      "type": "integer"
    },
    "users": {
      "type": "array",
      "items": { "$ref": "#/$defs/user" },
      "title": "Users"
    },
    "generator": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "major": { "type": "integer" },
        "minor": { "type": "integer" }
      },
      "required": [ "name", "major", "minor" ]
    }
  },
  "additionalProperties": false,
  "required": [
    "version", "masteraddress", "scene", "users", "generator"
  ]
}
