<?xml version="1.0" encoding="utf-8"?>

<!-- XSG schema: v0.3 -->

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">


<!-- Basic types -->
  
  
<xs:simpleType name="Scalar"><xs:restriction base="xs:float"/></xs:simpleType>
<xs:simpleType name="ScalarArray"><xs:list itemType="Scalar"/></xs:simpleType>
<xs:simpleType name="IndexArray"><xs:list itemType="xs:unsignedShort"/></xs:simpleType>
  
<xs:simpleType name="Vector2">
  <xs:restriction base="ScalarArray">
    <xs:minLength value="2"/>
    <xs:maxLength value="2"/>
  </xs:restriction>
</xs:simpleType>
  
<xs:simpleType name="Vector3">
  <xs:restriction base="ScalarArray">
    <xs:minLength value="3"/>
    <xs:maxLength value="3"/>
  </xs:restriction>
</xs:simpleType>

<xs:simpleType name="Vector4">
  <xs:restriction base="ScalarArray">
    <xs:minLength value="4"/>
    <xs:maxLength value="4"/>
  </xs:restriction>
</xs:simpleType>

<xs:simpleType name="Transform">
  <xs:restriction base="ScalarArray">
    <xs:minLength value="12"/>
    <xs:maxLength value="12"/>
  </xs:restriction>
</xs:simpleType>


<xs:simpleType name="Colour"><xs:restriction base="Vector3"/></xs:simpleType>
  
  

<!-- eXtendible Scene Graph file format defintion -->

<xs:element name="xsg"><xs:complexType>

    <xs:sequence>
        
       <xs:element minOccurs="0" name="scene"><xs:complexType>
            
          <xs:sequence>
              <xs:element ref="material" minOccurs="0" maxOccurs="unbounded"/>
              <xs:element ref="node" minOccurs="0" maxOccurs="unbounded"/>
              <xs:element ref="animation" minOccurs="0" maxOccurs="unbounded"/>
           </xs:sequence>

           <xs:attribute name="id" type="xs:string" use="optional"/>
           <xs:attribute name="ambient" type="Colour" use="optional"/>

         </xs:complexType></xs:element><!-- scene -->

     </xs:sequence>

     <xs:attribute name="version" type="Scalar" use="optional"/>

 </xs:complexType></xs:element><!-- xsg -->


<!-- Hyperlink -->

<xs:element name="link"><xs:complexType>

    <xs:attribute name="id" type="xs:string" use="optional"/>
    <xs:attribute name="dest" type="xs:string" use="optional"/>

</xs:complexType></xs:element><!-- link -->



<!-- Texture map, including extended interactive procedural types -->
  
<xs:element name="texture">
  <xs:complexType>
    <xs:attribute name="src" type="xs:string" use="optional"/>
    <xs:attribute name="type" type="xs:string" use="optional"/>
  </xs:complexType>
</xs:element><!-- texture -->


<!-- Geometry material : TODO: Add custom shader extensions -->

<xs:element name="material"><xs:complexType><xs:sequence>

   <xs:element ref="texture" minOccurs="0" maxOccurs="unbounded"/> 
  
   <xs:element name="component" minOccurs="0" maxOccurs="unbounded"><xs:complexType>
            
          <xs:sequence>
              <xs:element ref="texture" minOccurs="0" maxOccurs="unbounded"/>
          </xs:sequence>

          <xs:attribute name="id" type="xs:string" use="optional"/>
          <xs:attribute name="colour" type="Colour" use="optional"/>
          <xs:attribute name="level" type="Scalar" use="optional"/>
          <xs:attribute name="position" type="Vector2" use="optional"/>
          <xs:attribute name="scale" type="Vector2" use="optional"/>

      </xs:complexType></xs:element><!-- component -->

      </xs:sequence>

      <xs:attribute name="id" type="xs:string" use="optional"/>
      <xs:attribute name="cull" type="xs:string" use="optional"/>
      <xs:attribute name="base" type="Colour" use="optional"/>
      <xs:attribute name="gloss" type="Scalar" use="optional"/>
  
</xs:complexType></xs:element><!-- material -->

  

<!-- Scene graph node -->
 
<xs:element name="node">  <xs:complexType>
  
  <xs:sequence>
    <xs:element ref="node" minOccurs="0"  maxOccurs="unbounded"/>
    <xs:element ref="mesh" minOccurs="0"/>
    <xs:element ref="object" minOccurs="0"/>        
    <xs:element ref="light" minOccurs="0"/>
    <xs:element ref="camera" minOccurs="0"/>
  </xs:sequence>
  
  <xs:attribute name="id" type="xs:string" use="optional"/>
  <xs:attribute name="transform" type="Transform" use="optional"/>
  <xs:attribute name="position" type="Vector3" use="optional"/>
  <xs:attribute name="scale" type="Vector3" use="optional"/>
  <xs:attribute name="rotation" type="Vector3" use="optional"/>
  
</xs:complexType> </xs:element><!-- node -->

  

<!-- Optional node attachments -->

<xs:element name="light"><xs:complexType>
      
	<xs:sequence>
        <!-- TODO -->
      </xs:sequence>

    <xs:attribute name="type" type="xs:string" use="optional"/>
    <xs:attribute name="colour" type="Colour" use="optional"/>

</xs:complexType></xs:element><!-- light -->


<xs:element name="camera">
    <xs:complexType>
      <xs:sequence>
        <!-- TODO -->
      </xs:sequence>
    </xs:complexType>
</xs:element> <!-- camera -->
  

<!-- Polygon mesh -->

<xs:element name="mesh"><xs:complexType><xs:sequence>

        <xs:element ref="influence" minOccurs="0" maxOccurs="unbounded"/>

        <xs:element minOccurs="1" name="position" type="ScalarArray" />
        <xs:element minOccurs="0" name="normal" type="ScalarArray" />
        <xs:element minOccurs="0" name="texture" type="ScalarArray" />

        <xs:element name="faces" minOccurs="0"  maxOccurs="unbounded">
          <xs:complexType>
            <xs:simpleContent>
              <xs:extension base="IndexArray">
                <xs:attribute name="material" type="xs:string" use="optional" />
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element><!-- faces -->
        
</xs:sequence></xs:complexType></xs:element> <!-- mesh -->

  
<!-- Referenced object with optional custom behaviour defined by type -->
  
<xs:element name="object"><xs:complexType>

  <xs:sequence>
    <xs:element ref="link" minOccurs="0"/>
    <xs:element ref="material" minOccurs="0"/>
  </xs:sequence>
  
  <xs:attribute name="geometry" type="xs:string" use="optional"/>
  <xs:attribute name="root" type="xs:string" use="optional"/>
  <xs:attribute name="type" type="xs:string" use="optional"/>
</xs:complexType></xs:element>  <!-- object -->



  
<!-- Skinning influence (aka "bone") -->

<xs:element name="influence"><xs:complexType>
  
   <xs:sequence>
     <xs:element name="vertex" type="IndexArray"/>
     <xs:element name="weight" type="ScalarArray"/>
   </xs:sequence>

   <xs:attribute name="id" type="xs:string" use="optional"/>
   <xs:attribute name="transform" type="Transform" use="optional"/>

</xs:complexType></xs:element> <!-- influence -->


  
<!-- Animation -->


 <xs:element name="animation"><xs:complexType>
    <xs:sequence>
        <xs:element ref="channel" minOccurs="0"  maxOccurs="unbounded"/>
    </xs:sequence>

    <xs:attribute name="id" type="xs:string" use="optional"/>

 </xs:complexType></xs:element><!-- animation -->

  

<xs:element name="keyframes"> <xs:complexType>
   <xs:sequence>
        <xs:element name="time" type="ScalarArray"/>
        <xs:element name="value" type="ScalarArray"/>
    </xs:sequence>

    <xs:attribute name="dest" type="xs:string" use="optional"/>

</xs:complexType></xs:element><!-- keyframes -->  
  
  
<xs:element name="channel"><xs:complexType>

   <xs:sequence>
      <xs:element ref="keyframes" minOccurs="0"  maxOccurs="unbounded"/>
   </xs:sequence>

   <xs:attribute name="id" type="xs:string"/>
   <xs:attribute name="target" type="xs:string"/>
   <xs:attribute name="period" type="Scalar"/>
   <xs:attribute name="dest" type="xs:string" use="optional"/>
   <xs:attribute name="loop" type="xs:boolean" use="optional"/>
    
</xs:complexType></xs:element><!-- channel -->
  
  
  
</xs:schema>
