<?xml version="1.0" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<!-- SCENE Element -->
	<xsd:element name="scene">
		<xsd:complexType>
			<xsd:choice minOccurs="0" maxOccurs="unbounded">
				<xsd:element name="sensor" type="sensor"/>
				<xsd:element name="texture" type="texture"/>
				<xsd:element name="bsdf" type="bsdf"/>
				<xsd:element name="subsurface" type="subsurface"/>
				<xsd:element name="integrator" type="integrator"/>
				<xsd:element name="emitter" type="emitter"/>
				<xsd:element name="shape" type="shape"/>
				<xsd:element name="medium" type="medium"/>
				<xsd:element name="phase" type="phase"/>
				<xsd:element name="include" type="include"/>
				<xsd:element name="null" type="null"/>

				<!-- Usual attributes -->
				<xsd:element name="integer" type="integer"/>
				<xsd:element name="float" type="float"/>
				<xsd:element name="boolean" type="boolean"/>
				<xsd:element name="transform" type="transform"/>
				<xsd:element name="string" type="string"/>
				<xsd:element name="spectrum" type="spectrum"/>
				<xsd:element name="rgb" type="rgb"/>
				<xsd:element name="srgb" type="string"/>
				<xsd:element name="blackbody" type="blackbody"/>

				<xsd:element name="alias" type="alias"/>
				<xsd:element name="default" type="string"/>
			</xsd:choice>
			<xsd:attribute name="version" type="xsd:string"/>
		</xsd:complexType>
	</xsd:element>

	<!-- Generic Object -->
	<xsd:group name="objectGroup">
		<!-- Allow all property types -->
		<xsd:choice>
			<xsd:element name="integer" type="integer"/>
			<xsd:element name="float" type="float"/>
			<xsd:element name="point" type="point"/>
			<xsd:element name="vector" type="point"/>
			<xsd:element name="boolean" type="boolean"/>
			<xsd:element name="transform" type="transform"/>
			<xsd:element name="animation" type="animation"/>
			<xsd:element name="string" type="string"/>
			<xsd:element name="spectrum" type="spectrum"/>
			<xsd:element name="rgb" type="rgb"/>
			<xsd:element name="srgb" type="string"/>
			<xsd:element name="blackbody" type="blackbody"/>
			<xsd:element name="default" type="string"/>
		</xsd:choice>
	</xsd:group>

	<xsd:complexType name="objectBase">
		<xsd:attribute name="type" type="xsd:string" use="required"/>
		<xsd:attribute name="name" type="xsd:string"/>
		<xsd:attribute name="id" type="xsd:string"/>
	</xsd:complexType>


	<xsd:complexType name="object">
		<xsd:complexContent>
			<xsd:extension base="objectBase">
				<xsd:choice minOccurs="0" maxOccurs="unbounded">
					<xsd:group ref="objectGroup"/>
				</xsd:choice>
			</xsd:extension>
		</xsd:complexContent>
	</xsd:complexType>


	<!-- REFERENCE -->
	<xsd:complexType name="reference">
		<xsd:attribute name="id" type="xsd:string" use="required"/>
		<xsd:attribute name="name" type="xsd:string"/>
	</xsd:complexType>

	<!-- NULL -->
	<xsd:complexType name="null">
		<xsd:attribute name="id" type="xsd:string" use="required"/>
	</xsd:complexType>

	<!-- SENSOR Element -->
	<xsd:complexType name="sensor">
		<xsd:complexContent>
			<xsd:extension base="objectBase">
				<xsd:choice minOccurs="0" maxOccurs="unbounded">
					<xsd:group ref="objectGroup"/>
					<xsd:element name="sampler" type="object"/>
					<xsd:element name="film" type="film"/>
					<xsd:element name="ref" type="reference"/>
					<xsd:element name="medium" type="medium"/>
				</xsd:choice>
			</xsd:extension>
		</xsd:complexContent>
	</xsd:complexType>

	<!-- INTEGRATOR Element -->
	<xsd:complexType name="integrator">
		<xsd:complexContent>
			<xsd:extension base="objectBase">
				<xsd:choice minOccurs="0" maxOccurs="unbounded">
					<xsd:group ref="objectGroup"/>
					<xsd:element name="integrator" type="integrator"/>
					<xsd:element name="sampler" type="object"/>
				</xsd:choice>
			</xsd:extension>
		</xsd:complexContent>
	</xsd:complexType>

	<!-- EMITTER Element -->
	<xsd:complexType name="emitter">
		<xsd:complexContent>
			<xsd:extension base="objectBase">
				<xsd:choice minOccurs="0" maxOccurs="unbounded">
					<xsd:group ref="objectGroup"/>
					<xsd:element name="texture" type="texture"/>
					<xsd:element name="emitter" type="emitter"/>
					<xsd:element name="medium" type="medium"/>
					<xsd:element name="ref" type="reference"/>
				</xsd:choice>
			</xsd:extension>
		</xsd:complexContent>
	</xsd:complexType>

	<!-- SHAPE Element -->
	<xsd:complexType name="shape">
		<xsd:complexContent>
			<xsd:extension base="objectBase">
				<xsd:choice minOccurs="0" maxOccurs="unbounded">
					<xsd:group ref="objectGroup"/>
					<xsd:element name="bsdf" type="bsdf"/>
                    <xsd:element name="subsurface" type="subsurface"/>
					<xsd:element name="ref" type="reference"/>
					<xsd:element name="sensor" type="sensor"/>
					<xsd:element name="emitter" type="emitter"/>
					<xsd:element name="shape" type="shape"/>
					<xsd:element name="medium" type="medium"/>
					<xsd:element name="texture" type="texture"/>
					<xsd:element name="rfilter" type="object"/>
				</xsd:choice>
			</xsd:extension>
		</xsd:complexContent>
	</xsd:complexType>

    <!-- SINGLESCATTER Element -->
    <xsd:complexType name="subsurface">
        <xsd:complexContent>
            <xsd:extension base="objectBase">
                <xsd:choice minOccurs="0" maxOccurs="unbounded">
                    <xsd:group ref="objectGroup"/>
                    <xsd:element name="phase" type="phase"/>
                    <xsd:element name="bsdf" type="bsdf"/>
                </xsd:choice>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

	<!-- MEDIUM Element -->
	<xsd:complexType name="medium">
		<xsd:complexContent>
			<xsd:extension base="objectBase">
				<xsd:choice minOccurs="0" maxOccurs="unbounded">
					<xsd:group ref="objectGroup"/>
					<xsd:element name="shape" type="shape"/>
					<xsd:element name="volume" type="volume"/>
					<xsd:element name="phase" type="phase"/>
				</xsd:choice>
			</xsd:extension>
		</xsd:complexContent>
	</xsd:complexType>

	<!-- VOLUME Element -->
	<xsd:complexType name="volume">
		<xsd:complexContent>
			<xsd:extension base="objectBase">
				<xsd:choice minOccurs="0" maxOccurs="unbounded">
					<xsd:group ref="objectGroup"/>
					<xsd:element name="volume" type="volume"/>
				</xsd:choice>
			</xsd:extension>
		</xsd:complexContent>
	</xsd:complexType>

	<!-- BSDF Element -->
	<xsd:complexType name="bsdf">
		<xsd:complexContent>
			<xsd:extension base="objectBase">
				<xsd:choice minOccurs="0" maxOccurs="unbounded">
					<xsd:group ref="objectGroup"/>
					<xsd:element name="phase" type="phase"/>
					<xsd:element name="texture" type="texture"/>
					<xsd:element name="bsdf" type="bsdf"/>
					<xsd:element name="ref" type="reference"/>
				</xsd:choice>
			</xsd:extension>
		</xsd:complexContent>
	</xsd:complexType>

	<!-- TEXTURE Element -->
	<xsd:complexType name="texture">
		<xsd:complexContent>
			<xsd:extension base="objectBase">
				<xsd:choice minOccurs="0" maxOccurs="unbounded">
					<xsd:group ref="objectGroup"/>
					<xsd:element name="texture" type="texture"/>
					<xsd:element name="ref" type="reference"/>
					<xsd:element name="rfilter" type="object"/>
				</xsd:choice>
			</xsd:extension>
		</xsd:complexContent>
	</xsd:complexType>

	<!-- PHASE Element -->
	<xsd:complexType name="phase">
		<xsd:complexContent>
			<xsd:extension base="objectBase">
				<xsd:choice minOccurs="0" maxOccurs="unbounded">
					<xsd:group ref="objectGroup"/>
					<xsd:element name="phase" type="phase"/>
				</xsd:choice>
			</xsd:extension>
		</xsd:complexContent>
	</xsd:complexType>

	<!-- FILM Element -->
	<xsd:complexType name="film">
		<xsd:complexContent>
			<xsd:extension base="objectBase">
				<xsd:choice minOccurs="0" maxOccurs="unbounded">
					<xsd:group ref="objectGroup"/>
					<xsd:element name="rfilter" type="object"/>
				</xsd:choice>
			</xsd:extension>
		</xsd:complexContent>
	</xsd:complexType>

	<!-- Types and parameters -->
	<xsd:simpleType name="integerType">
		<xsd:union>
			<xsd:simpleType>
				<xsd:restriction base="xsd:string">
					<xsd:pattern value="$.+"/>
				</xsd:restriction>
			</xsd:simpleType>
			<xsd:simpleType>
				<xsd:restriction base="xsd:integer"/>
			</xsd:simpleType>
		</xsd:union>
	</xsd:simpleType>

	<xsd:simpleType name="doubleType">
		<xsd:union>
			<xsd:simpleType>
				<xsd:restriction base="xsd:string">
					<xsd:pattern value="$.+"/>
				</xsd:restriction>
			</xsd:simpleType>
			<xsd:simpleType>
				<xsd:restriction base="xsd:double"/>
			</xsd:simpleType>
		</xsd:union>
	</xsd:simpleType>

	<xsd:simpleType name="booleanType">
		<xsd:union>
			<xsd:simpleType>
				<xsd:restriction base="xsd:string">
					<xsd:pattern value="$.+"/>
				</xsd:restriction>
			</xsd:simpleType>
			<xsd:simpleType>
				<xsd:restriction base="xsd:string">
					<xsd:enumeration value="true"/>
					<xsd:enumeration value="false"/>
				</xsd:restriction>
			</xsd:simpleType>
		</xsd:union>
	</xsd:simpleType>

	<xsd:complexType name="float">
		<xsd:attribute name="name" type="xsd:string" use="required"/>
		<xsd:attribute name="value" type="doubleType" use="required"/>
	</xsd:complexType>

	<xsd:complexType name="integer">
		<xsd:attribute name="name" type="xsd:string" use="required"/>
		<xsd:attribute name="value" type="integerType" use="required"/>
	</xsd:complexType>

	<xsd:complexType name="boolean">
		<xsd:attribute name="name" type="xsd:string" use="required"/>
		<xsd:attribute name="value" type="booleanType" use="required"/>
	</xsd:complexType>

	<xsd:complexType name="string">
		<xsd:attribute name="name" type="xsd:string" use="required"/>
		<xsd:attribute name="value" type="xsd:string" use="required"/>
	</xsd:complexType>

	<xsd:complexType name="rgb">
		<xsd:attribute name="name" type="xsd:string" use="required"/>
		<xsd:attribute name="value" type="xsd:string" use="required"/>
		<xsd:attribute name="intent" type="xsd:string" use="optional"/>
	</xsd:complexType>

	<xsd:complexType name="spectrum">
		<xsd:attribute name="name" type="xsd:string" use="required"/>
		<xsd:attribute name="filename" type="xsd:string" use="optional"/>
		<xsd:attribute name="value" type="xsd:string" use="optional"/>
		<xsd:attribute name="intent" type="xsd:string" use="optional"/>
	</xsd:complexType>

	<xsd:complexType name="include">
		<xsd:attribute name="filename" type="xsd:string" use="required"/>
	</xsd:complexType>

	<xsd:complexType name="alias">
		<xsd:attribute name="id" type="xsd:string" use="required"/>
		<xsd:attribute name="as" type="xsd:string" use="required"/>
	</xsd:complexType>

	<xsd:complexType name="transform">
		<xsd:choice minOccurs="0" maxOccurs="unbounded">
			<xsd:element name="translate" type="translate"/>
			<xsd:element name="rotate" type="rotate"/>
			<xsd:element name="lookAt" type="lookAt"/>
			<xsd:element name="lookat" type="lookAt"/>
			<xsd:element name="scale" type="scale"/>
			<xsd:element name="matrix" type="matrix"/>
		</xsd:choice>
		<xsd:attribute name="name" type="xsd:string" use="required"/>
	</xsd:complexType>
	<xsd:complexType name="animationTransform">
		<xsd:choice minOccurs="0" maxOccurs="unbounded">
			<xsd:element name="translate" type="translate"/>
			<xsd:element name="rotate" type="rotate"/>
			<xsd:element name="lookAt" type="lookAt"/>
			<xsd:element name="lookat" type="lookAt"/>
			<xsd:element name="scale" type="scale"/>
			<xsd:element name="matrix" type="matrix"/>
		</xsd:choice>
		<xsd:attribute name="time" type="doubleType" use="required"/>
	</xsd:complexType>
	<xsd:complexType name="animation">
		<xsd:choice minOccurs="0" maxOccurs="unbounded">
			<xsd:element name="transform" type="animationTransform"/>
		</xsd:choice>
		<xsd:attribute name="name" type="xsd:string" use="required"/>
	</xsd:complexType>
	<xsd:complexType name="translate">
		<xsd:attribute name="x" type="doubleType"/>
		<xsd:attribute name="y" type="doubleType"/>
		<xsd:attribute name="z" type="doubleType"/>
	</xsd:complexType>
	<xsd:complexType name="matrix">
		<xsd:attribute name="value" type="xsd:string" use="required"/>
	</xsd:complexType>
	<xsd:complexType name="scale">
		<xsd:attribute name="x" type="doubleType"/>
		<xsd:attribute name="y" type="doubleType"/>
		<xsd:attribute name="z" type="doubleType"/>
		<xsd:attribute name="value" type="doubleType"/>
	</xsd:complexType>
	<xsd:complexType name="rotate">
		<xsd:attribute name="x" type="doubleType"/>
		<xsd:attribute name="y" type="doubleType"/>
		<xsd:attribute name="z" type="doubleType"/>
		<xsd:attribute name="angle" type="doubleType" use="required"/>
	</xsd:complexType>
	<xsd:complexType name="lookAt">
		<xsd:attribute name="origin" type="xsd:string" use="required"/>
		<xsd:attribute name="target" type="xsd:string" use="required"/>
		<xsd:attribute name="up" type="xsd:string" use="optional"/>
	</xsd:complexType>
	<xsd:complexType name="point">
		<xsd:attribute name="name" type="xsd:string" use="required"/>
		<xsd:attribute name="x" type="doubleType" use="required"/>
		<xsd:attribute name="y" type="doubleType" use="required"/>
		<xsd:attribute name="z" type="doubleType" use="required"/>
	</xsd:complexType>
	<xsd:complexType name="blackbody">
		<xsd:attribute name="name" type="xsd:string" use="required"/>
		<xsd:attribute name="temperature" type="xsd:string" use="required"/>
		<xsd:attribute name="scale" type="doubleType" use="optional"/>
	</xsd:complexType>
</xsd:schema>
