Difference between revisions of "MMH"

From Dragon Age Toolset Wiki
Jump to: navigation, search
(mmh.xml schema)
(mmh.xml schema)
 
Line 95: Line 95:
 
     <element name="NodeMesh">
 
     <element name="NodeMesh">
 
       <optional>
 
       <optional>
         <attribute name="BonesUsed"/> <!-- list of integer values, representing the BoneIndices, in an order correlating to the Vertex BoneIndices. Used by models with skeletal Animation. -->
+
         <attribute name="BonesUsed"/> <!-- list of integer values, representing the BoneIndices, in an order correlating to the Vertex Blend Indices. Used by models with skeletal Animation. -->
 
       </optional>
 
       </optional>
 
       <optional>
 
       <optional>

Latest revision as of 08:37, 13 February 2011

MMH ("Model Mesh Heirarchy") files are used to describe a wide variety of physical objects that appear in Dragon Age levels. It includes props, visual effects, creature models, weapon models, and so forth.

MMH files are defined by XML files named with the .mmh.xml extension. BioWare generated these XML files using 3DSMax plugins that have some legal encumberances preventing their distribution, but the specifications for .mmh.xml will be released and it is hoped that converters will be able to be written for other file formats. See 3rd_party_extensions for custom model export and import tools.

The XML file is then run through the GraphicsProcessorMMH.exe program (found in the Dragon Age\Toolset\export_processors directory) to produce a binary file that is used by the game. The game can actually use the XML file directly, but this has poor performance (it runs it through GraphicsProcessorMMH every time the object is loaded) and should only be used for testing purposes.

GraphicsProcessorMMH [-outdir <out-dir>] [-platform <x360,pc,ps3>] [options] [-indir<input-directory> / <input-file>]

Other options include:

-byteswapgff[Undocumented]

This is the command line you'll typically need:

GraphicsProcessorMMH -outdir %ls -platform pc %ls.mmh.xml

MMH files reference MSH (mesh) files to define the actual triangles and vertexes used in models.

mmh.xml schema

Joint types:

  • Cylindrical
  • 6DOF
  • Distance
  • Fixed
  • PointInPlane
  • PointOnLine
  • Prismatic
  • Pulley
  • Revolute
  • Spherical

See [1] for information on the RELAX NG 1.0 XML schema format. For a free converter/verifier, see [2].

<?xml version="1.0" encoding="UTF-8"?>
<grammar ns="" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
  <start>
    <element name="ModelHierarchy">
      <optional>
        <attribute name="FXActorName">
          <data type="NCName"/> <!-- An FXA file name -->
        </attribute>
      </optional>
      <attribute name="ModelDataName">
        <data type="NCName"/> <!-- The MSH file name, of where the Mesh Chunks are in by default -->
      </attribute>
      <attribute name="Name">
        <data type="NCName"/> <!-- An MMH file name. This MMH -->
      </attribute>
      <optional>
        <attribute name="PreSimulateTime">
          <data type="decimal"/> <!-- emitter presimulation time -->
        </attribute>
      </optional>
      <optional>
        <attribute name="ReferencedMeshes"/> <!-- List of names of referenced meshes. Most of the files I see this in have an empty string here, but some have one or more .msh files named with spaces separating them. For example: ReferencedMeshes="fx_l_plane.msh fx_l_plane.msh". Every file with ReferencedMeshes defined was exported by the VFX editor so this is a VFX thing.-->
      </optional>
      <optional>
        <attribute name="RemoteMaterialAlpha">
          <data type="decimal"/> <!-- if UseRemoteMaterial is true -->
        </attribute>
      </optional>
      <optional>
        <attribute name="RemoteMaterialDecalName">
          <data type="NCName"/> <!-- if UseRemoteMaterial is true -->
        </attribute>
      </optional>
      <optional>
        <attribute name="RemoteMaterialFresnelFalloff">
          <data type="decimal"/>  <!-- if UseRemoteMaterial is true -->
        </attribute>
      </optional>
      <optional>
        <attribute name="RemoteMaterialInvertFresnel">
          <data type="integer"/>  <!-- if UseRemoteMaterial is true. A true/false value -->
        </attribute>
      </optional>
      <optional>
        <attribute name="RemoteMaterialTintColor"/> <!-- if UseRemoteMaterial is true. Four numbers separated by spaces -->
      </optional>
      <optional>
        <attribute name="UseRemoteMaterial">
          <data type="integer"/> <!-- a true/false value -->
        </attribute>
      </optional>
      <choice>
        <ref name="MeshHierarchy"/> <!-- MeshHierarchy is a deprecated synonym for "NodeMesh". -->
        <ref name="Node"/>
        <ref name="NodeMesh"/>
      </choice>
    </element>
  </start>
  <define name="NodeMesh">
    <element name="NodeMesh">
      <optional>
        <attribute name="BonesUsed"/> <!-- list of integer values, representing the BoneIndices, in an order correlating to the Vertex Blend Indices. Used by models with skeletal Animation. -->
      </optional>
      <optional>
        <attribute name="CastBakedShadow"> <!-- true/false value -->
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="CastRuntimeShadow">  <!-- true/false value -->
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="CutAway"> <!-- true/false value (Cut Away enables Fading out on Isometric view in Dragon Age) -->
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="ID">
          <data type="NCName"/> <!-- A short and unique string. It is unique across every mesh used in whole Dragon Age. Used by lightmapper to reference the mesh -->
        </attribute>
      </optional>
      <optional>
        <attribute name="IsVFXMesh"> <!-- if this mesh is categorized as a VFX Mesh, load in the MaterialColor parameter -->
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="MaterialColor"/> <!-- String with four values - RGBA -->
      </optional>
      <optional>
        <attribute name="MaterialLibrary"> <!-- Strings like "CavesInterior" - reference to MAL files, MAL are material editor file types. (may not actually be useful in the game) -->
          <data type="NCName"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="MaterialObject"> <!-- Strings like "pn_boo_hvyd_l3" here, this is referring to material object (MAO files) create by the material editor -->
          <data type="NMTOKEN"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="MeshGroupName"> <!-- The Meshes Name, used to reference the meshchunk name in the MSH  -->
          <data type="NCName"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="MeshName"> <!-- the mesh file that the meshchunk is in. if this isn't set, it will default to the first mesh in the model (for backwards compatibility) -->
          <data type="NCName"/>
        </attribute>
      </optional>
      <attribute name="Name"> <!-- name of the node -->
        <data type="NCName"/>
      </attribute>
      <optional>
        <attribute name="PunchThrough"> <!-- true/false value -->
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="ReceiveBakedShadow"> <!-- true/false value -->
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="ReceiveRuntimeShadow"> <!-- true/false value -->
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="ReceiveShadow"> <!-- I didn't find this referenced in the source code - deprecated, perhaps? -->
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="ShadowCasting"> <!-- used to set GFF_MMH_MESH_CAST_RUNTIME_SHADOW in the source code, same as CastRuntimeShadow above - synonyms? -->
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="UseVariationTint">
          <data type="integer"/>
        </attribute>
      </optional>
      <zeroOrMore>
        <choice>
          <ref name="Attribute"/>
          <ref name="BoundingBox"/> <!-- may be empty, or may contain something of the form <![CDATA[-8.00051 -32.0 -0.0103784 1.0 8.01207 0.0 30.0 1.0]]>  I believe this is the two corners (min and max) of the bounding box. -->
          <ref name="CollisionObject"/>
          <ref name="Export"/>
          <ref name="Node"/>
          <ref name="NodeCrustHierarchy"/>
          <ref name="NodeMesh"/>
          <ref name="NodePointLight"/>
          <ref name="NodeWeapontrail"/>
          <ref name="Rotation"/>
          <ref name="Translation"/>
          <element name="Scale">
            <data type="decimal"/>
          </element>
        </choice>
      </zeroOrMore>
      <choice>
        <ref name="NodeAmbientLight"/>
        <ref name="NodeUsePoint"/>
        <zeroOrMore>
          <ref name="NodeEmitter"/>
        </zeroOrMore>
      </choice>
    </element>
  </define>
  <define name="Node">
    <element name="Node">
      <optional>
        <attribute name="BoneIndex">
          <data type="integer"/>
        </attribute>
      </optional>
      <attribute name="Name">
        <data type="NMTOKEN"/>
      </attribute>
      <optional>
        <attribute name="SoundMaterialType">
          <data type="integer"/>
        </attribute>
      </optional>
      <zeroOrMore>
        <choice>
          <ref name="BoundingBox"/>
          <ref name="CollisionObject"/>
          <ref name="Export"/>
          <ref name="Node"/>
          <ref name="NodeCrustHierarchy"/>
          <ref name="NodeEmitter"/>
          <ref name="NodeEmitterGroup"/>
          <ref name="NodeEmitterTarget"/>
          <ref name="NodeLightProbe"/>
          <ref name="NodeMesh"/>
          <ref name="NodePointLight"/>
          <ref name="NodeUsePoint"/>
          <ref name="NodeWeapontrail"/>
          <ref name="Rotation"/>
          <ref name="Translation"/>
          <element name="NodeCloth">
            <attribute name="AttachmentResponseCoefficient">
              <data type="decimal"/>
            </attribute>
            <attribute name="AttachmentTearFactor">
              <data type="decimal"/>
            </attribute>
            <attribute name="BendingStiffness">
              <data type="decimal"/>
            </attribute>
            <attribute name="CF_BENDING">
              <data type="integer"/>
            </attribute>
            <attribute name="CF_BENDING_ORTHO">
              <data type="integer"/>
            </attribute>
            <attribute name="CF_COLLISION_TWOWAY">
              <data type="integer"/>
            </attribute>
            <attribute name="CF_COMDAMPING">
              <data type="integer"/>
            </attribute>
            <attribute name="CF_DAMPING">
              <data type="integer"/>
            </attribute>
            <attribute name="CF_DISABLE_COLLISION">
              <data type="integer"/>
            </attribute>
            <attribute name="CF_GRAVITY">
              <data type="integer"/>
            </attribute>
            <attribute name="CF_HARDWARE">
              <data type="integer"/>
            </attribute>
            <attribute name="CF_PRESSURE">
              <data type="integer"/>
            </attribute>
            <attribute name="CF_SELFCOLLISION">
              <data type="integer"/>
            </attribute>
            <attribute name="CF_STATIC">
              <data type="integer"/>
            </attribute>
            <attribute name="CF_TEARABLE">
              <data type="integer"/>
            </attribute>
            <attribute name="CF_VISUALIZATION">
              <data type="integer"/>
            </attribute>
            <attribute name="CollisionResponseCoefficient">
              <data type="decimal"/>
            </attribute>
            <attribute name="DampingCoefficient">
              <data type="decimal"/>
            </attribute>
            <attribute name="Density">
              <data type="decimal"/>
            </attribute>
            <attribute name="Fadeable">
              <data type="boolean"/>
            </attribute>
            <attribute name="Friction">
              <data type="decimal"/>
            </attribute>
            <attribute name="GROUP_MASK_NONWALKABLE">
              <data type="boolean"/>
            </attribute>
            <optional>
              <attribute name="GROUP_MASK_STATICGEOMETRY">
                <data type="boolean"/>
              </attribute>
            </optional>
            <attribute name="GustingDirectionAxisRatio"/> <!-- removed, no longer supported by resource exporter. see bug 114919 -->
            <attribute name="GustingDirectionChange"> <!-- removed, no longer supported by resource exporter. see bug 114919 -->
              <data type="decimal"/>
            </attribute>
            <attribute name="GustingMaxDuration"> <!-- removed, no longer supported by resource exporter. see bug 114919 -->
              <data type="decimal"/>
            </attribute>
            <attribute name="GustingMaxInterval"> <!-- removed, no longer supported by resource exporter. see bug 114919 -->
              <data type="decimal"/>
            </attribute>
            <attribute name="GustingMaxStrength"> <!-- removed, no longer supported by resource exporter. see bug 114919 -->
              <data type="decimal"/>
            </attribute>
            <attribute name="GustingMinDuration"> <!-- removed, no longer supported by resource exporter. see bug 114919 -->
              <data type="decimal"/>
            </attribute>
            <attribute name="GustingMinInterval"> <!-- removed, no longer supported by resource exporter. see bug 114919 -->
              <data type="decimal"/>
            </attribute>
            <attribute name="GustingMinStrength"> <!-- removed, no longer supported by resource exporter. see bug 114919 -->
              <data type="decimal"/>
            </attribute>
            <attribute name="ID">
              <data type="NCName"/>
            </attribute>
            <attribute name="MaterialLibrary">
              <data type="NCName"/>
            </attribute>
            <attribute name="MaterialObject">
              <data type="NCName"/>
            </attribute>
            <attribute name="MeshGroupName">
              <data type="NCName"/>
            </attribute>
            <attribute name="Name">
              <data type="NCName"/>
            </attribute>
            <attribute name="Pressure">
              <data type="decimal"/>
            </attribute>
            <attribute name="SleepLinearVelocity">
              <data type="decimal"/>
            </attribute>
            <attribute name="SolverIterations">
              <data type="integer"/>
            </attribute>
            <attribute name="SpeedTreeWindDirection">  <!-- removed, no longer supported by resource exporter. see bug 114919 -->
              <data type="boolean"/>
            </attribute>
            <attribute name="SpeedTreeWindParams"> <!-- removed, no longer supported by resource exporter. see bug 114919 -->
              <data type="boolean"/>
            </attribute>
            <attribute name="SpeedTreeWindStrength"> <!-- removed, no longer supported by resource exporter. see bug 114919 -->
              <data type="boolean"/>
            </attribute>
            <attribute name="SpeedTreeWindUpdateTime"> <!-- removed, no longer supported by resource exporter. see bug 114919 -->
              <data type="decimal"/>
            </attribute>
            <attribute name="StretchingStiffness">
              <data type="decimal"/>
            </attribute>
            <attribute name="TearFactor">
              <data type="decimal"/>
            </attribute>
            <attribute name="Thickness">
              <data type="decimal"/>
            </attribute>
            <attribute name="WakeUpCounter">
              <data type="decimal"/>
            </attribute>
            <attribute name="WindDirection"/> <!-- removed, no longer supported by resource exporter. see bug 114919 -->
            <attribute name="WindEnabled"> <!-- removed, no longer supported by resource exporter. see bug 114919 -->
              <data type="boolean"/>
            </attribute>
            <attribute name="WindResponse"> <!-- removed, no longer supported by resource exporter. see bug 114919 -->
              <data type="decimal"/>
            </attribute>
            <attribute name="WindResponseLimit"> <!-- removed, no longer supported by resource exporter. see bug 114919 -->
              <data type="decimal"/>
            </attribute>
            <attribute name="WindSpace"> <!-- removed, no longer supported by resource exporter. see bug 114919 -->
              <data type="NCName"/>
            </attribute>
            <attribute name="WindStrength"> <!-- removed, no longer supported by resource exporter. see bug 114919 -->
              <data type="decimal"/>
            </attribute>
            <ref name="Attribute"/>
            <zeroOrMore>
              <ref name="Export"/>
            </zeroOrMore>
            <ref name="Translation"/>
            <ref name="Rotation"/>
            <element name="ClothAttachments">
              <element name="ClothAttachment">
                <attribute name="TearableAttachment">
                  <data type="integer"/>
                </attribute>
                <attribute name="TwoWayAttachment">
                  <data type="integer"/>
                </attribute>
                <attribute name="Type">
                  <data type="NCName"/>
                </attribute>
              </element>
            </element>
            <element name="MeshGroup">
              <attribute name="Name">
                <data type="NCName"/>
              </attribute>
              <oneOrMore>
                <ref name="Data"/>
              </oneOrMore>
            </element>
          </element>
          <element name="NodeSnaptoPoint">
            <attribute name="Name">
              <data type="NCName"/>
            </attribute>
            <zeroOrMore>
              <ref name="Export"/>
            </zeroOrMore>
            <ref name="Translation"/>
            <ref name="Rotation"/>
          </element>
        </choice>
      </zeroOrMore>
      <optional>
        <ref name="NodeAmbientLight"/>
      </optional>
    </element>
  </define>
  <define name="MeshHierarchy"> <!-- MeshHierarchy is a deprecated synonym for "NodeMesh". Only 14 files still use it out of nearly 8000 in our internal sources. -->
    <element name="MeshHierarchy">
      <attribute name="Name">
        <data type="NCName"/>
      </attribute>
      <optional>
        <ref name="BoundingBox"/>
        <oneOrMore>
          <choice>
            <ref name="MeshHierarchy"/>
            <ref name="Rotation"/>
            <ref name="Translation"/>
          </choice>
        </oneOrMore>
      </optional>
      <choice>
        <ref name="NodeLightProbe"/>
        <zeroOrMore>
          <ref name="NodeEmitter"/>
        </zeroOrMore>
      </choice>
    </element>
  </define>
  <define name="NodeCrustHierarchy">
    <element name="NodeCrustHierarchy">
      <attribute name="HookID">
        <data type="integer"/>
      </attribute>
      <attribute name="Name">
        <data type="NCName"/>
      </attribute>
      <zeroOrMore>
        <ref name="Export"/>
      </zeroOrMore>
      <optional>
        <ref name="Translation"/>
        <ref name="Rotation"/>
      </optional>
      <zeroOrMore>
        <choice>
          <ref name="Node"/>
          <ref name="NodeEmitter"/>
          <ref name="NodeEmitterGroup"/>
          <ref name="NodeEmitterTarget"/>
          <ref name="NodePointLight"/>
        </choice>
      </zeroOrMore>
      <optional>
        <ref name="NodeMesh"/>
      </optional>
    </element>
  </define>
  <define name="Export">
    <element name="Export">
      <attribute name="ControllerType">
        <data type="NCName"/>
      </attribute>
      <attribute name="ExportName">
        <data type="NMTOKEN"/>
      </attribute>
      <optional>
        <attribute name="MaterialColor"/> <!-- String with four values - RGBA -->
      </optional>
      <attribute name="TagName">
        <data type="NCName"/>
      </attribute>
    </element>
  </define>
  <define name="BoundingBox">
    <element name="BoundingBox"> <!-- Vector4f min, Vector4f max -->
      <text/>
    </element>
  </define>
  <define name="Translation">
    <element name="Translation">
      <optional>
        <attribute name="MeshParticleRollAxis"/> <!-- Three numbers separated by spaces -->
      </optional>
      <optional>
        <attribute name="MeshParticleUpAxis"/> <!-- Three numbers separated by spaces -->
      </optional>
      <text/>
    </element>
  </define>
  <define name="Rotation">
    <element name="Rotation"> <!-- Quaternionf -->
      <text/>
    </element>
  </define>
  <define name="CollisionObject">
    <element name="CollisionObject">
      <optional>
        <attribute name="Kinematic">
          <data type="boolean"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="Static">
          <data type="boolean"/>
        </attribute>
      </optional>
      <oneOrMore>
        <element name="Shape">
          <attribute name="AllowEmitterSpawn">
            <data type="integer"/>
          </attribute>
          <optional>
            <attribute name="DimX">
              <data type="decimal"/>
            </attribute>
          </optional>
          <optional>
            <attribute name="DimY">
              <data type="double"/>
            </attribute>
          </optional>
          <optional>
            <attribute name="DimZ">
              <data type="decimal"/>
            </attribute>
          </optional>
          <attribute name="Fadeable">
            <data type="boolean"/>
          </attribute>
          <optional>
            <attribute name="GROUP_MASK_CREATURES">
              <data type="boolean"/>
            </attribute>
          </optional>
          <optional>
            <attribute name="GROUP_MASK_ITEMS">
              <data type="boolean"/>
            </attribute>
          </optional>
          <optional>
            <attribute name="GROUP_MASK_NONWALKABLE">
              <data type="boolean"/>
            </attribute>
          </optional>
          <optional>
            <attribute name="GROUP_MASK_PLACEABLES">
              <data type="boolean"/>
            </attribute>
          </optional>
          <optional>
            <attribute name="GROUP_MASK_STATICGEOMETRY">
              <data type="boolean"/>
            </attribute>
          </optional>
          <optional>
            <attribute name="GROUP_MASK_TERRAIN_WALL">
              <data type="boolean"/>
            </attribute>
          </optional>
          <optional>
            <attribute name="GROUP_MASK_TRIGGERS">
              <data type="boolean"/>
            </attribute>
          </optional>
          <optional>
            <attribute name="GROUP_MASK_WALKABLE">
              <data type="boolean"/>
            </attribute>
          </optional>
          <optional>
            <attribute name="Height">
              <data type="double"/>
            </attribute>
          </optional>
          <attribute name="Name">
            <data type="NCName"/>
          </attribute>
          <attribute name="Position"/> <!-- Vector4f -->
          <optional>
            <attribute name="Radius">
              <data type="decimal"/>
            </attribute>
          </optional>
          <attribute name="Rotation"/> <!-- Quaternionf -->
          <attribute name="Type">
            <data type="NCName"/>
          </attribute>
          <optional>
            <element name="VertexData">
              <attribute name="length">
                <data type="integer"/>
              </attribute>
              <text/>
            </element>
            <element name="IndexData"> <!-- UINT16? don't know what this one's for, ask for clarification -->
              <text/>
            </element>
          </optional>
        </element>
      </oneOrMore>
    </element>
  </define>
  <define name="NodePointLight">
    <element name="NodePointLight">
      <optional>
        <attribute name="AffectsDomain"> <!-- A search through the existing files has this as either "1" or "2", no other values. I don't know what these domains represent. -->
          <data type="integer"/>
        </attribute>
      </optional>
      <attribute name="Color"/> <!-- string of four numbers, separated by spaces. -->
      <optional>
        <attribute name="IntensityPeriod">
          <data type="decimal"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="IntensityPeriodDelta">
          <data type="decimal"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="IntensityVariation">
          <data type="decimal"/>
        </attribute>
      </optional>
      <attribute name="IsStatic">
        <data type="integer"/>
      </attribute>
      <attribute name="Name">
        <data type="NCName"/>
      </attribute>
      <attribute name="Radius">
        <data type="decimal"/>
      </attribute>
      <optional>
        <attribute name="UseVariationTint"> <!-- true/false, I believe -->
          <data type="integer"/>
        </attribute>
      </optional>
      <oneOrMore>
        <choice>
          <ref name="Export"/>
          <ref name="Rotation"/>
          <ref name="Translation"/>
        </choice>
      </oneOrMore>
    </element>
  </define>
  <define name="NodeWeapontrail">
    <element name="NodeWeapontrail">
      <attribute name="Duration">
        <data type="decimal"/>
      </attribute>
      <attribute name="MaterialObject"> <!-- All appear to be in either weapontrail_streaks or weapontrail_arrow -->
        <data type="NCName"/>
      </attribute>
      <attribute name="Name">
        <data type="NCName"/>
      </attribute>
      <attribute name="SegmentLength">
        <data type="decimal"/>
      </attribute>
      <ref name="Translation"/>
      <ref name="Rotation"/>
    </element>
  </define>
  <define name="Attribute">
    <element name="Attribute">
      <attribute name="AttributeName"> <!-- This attribute's value is almost universally "BaseLight" (11167 times out of 11170 in 7010 files) -->
        <data type="NCName"/>
      </attribute>
      <attribute name="SourceName">
        <data type="NCName"/> <!-- This attribute's value is almost universally "BaseLight" (11167 times out of 11170 in 7010 files)-->
      </attribute>
    </element>
  </define>
  <define name="NodeUsePoint">
    <element name="NodeUsePoint">
      <attribute name="Name"> <!-- All seem to be of the form "UserPoint##", where ## is a zero-padded low number  (highest I've seen is 14) -->
        <data type="NCName"/>
      </attribute>
      <attribute name="Type"> <!-- "Front", "Back", "Right", "Left" are options. Most items seem to get by with just nodeusepoints of front and back, a few have all four types of nodeusepoint. -->
        <data type="NCName"/>
      </attribute>
      <zeroOrMore>
        <ref name="Export"/>
      </zeroOrMore>
      <ref name="Translation"/>
      <ref name="Rotation"/>
      <optional>
        <ref name="NodeCrustHierarchy"/>
      </optional>
    </element>
  </define>
  <define name="NodeAmbientLight">
    <element name="NodeAmbientLight"> <!-- Only 5 files had one of these; lightrig_day01.mmh.xml, lightrig_int01.mmh.xml, lightrig_night01.mmh.xml, tools_ambient.mmh.xml, and tools_bulb_ambient.mmh.xml. -->
      <attribute name="Color"/> <!-- string of four numbers, separated by spaces. "0.0705882 0.0862745 0.0980392 1.0" for the three lightrigs, "0.498039 0.498039 0.498039 1.0" for the two tools -->
      <attribute name="Name"><!-- "BWDA_OmniLight04" for the three lightrigs, "BWDA_OmniLight01" for the two tools. -->
        <data type="NCName"/>
      </attribute>
      <attribute name="Radius"> <!-- 5.0 for the three lightrigs, "1e+007" for the two tools -->
        <data type="double"/>
      </attribute>
      <zeroOrMore>
        <ref name="Export"/>
      </zeroOrMore>
      <ref name="Translation"/>
      <ref name="Rotation"/>
    </element>
  </define>
  <define name="NodeEmitter">
    <element name="NodeEmitter">
      <attribute name="Acceleration">
        <data type="decimal"/>
      </attribute>
      <optional>
        <attribute name="AgeMapColorMultiplier"/> <!-- string of four numbers, separated by spaces. -->
      </optional>
      <optional>
        <attribute name="AgeMapScaleXMultiplier">
          <data type="decimal"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="AgeMapScaleYMultiplier">
          <data type="decimal"/>
        </attribute>
      </optional>
      <attribute name="Birthrate">
        <data type="decimal"/>
      </attribute>
      <attribute name="BirthrateInParticlesPerMeter">
        <data type="integer"/>
      </attribute>
      <attribute name="BirthrateRange">
        <data type="decimal"/>
      </attribute>
      <optional>
        <attribute name="Bounciness">
          <data type="decimal"/>
        </attribute>
      </optional>
      <attribute name="EmitterType">
        <data type="NCName"/>
      </attribute>
      <attribute name="EnableParticleCollisions">
        <data type="integer"/>
      </attribute>
      <optional>
        <attribute name="FlipbookColumns">
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="FlipbookRows">
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="FlipbookType"/> <!-- UINT8 nFlipbookType = FLIPBOOKTYPE_NONE = 0;  if (a_sFlipbookType.CompareNoCase(L"ContactSheet")) nFlipbookType = FLIPBOOKTYPE_CONTACT_SHEET = 1; if (a_sFlipbookType.CompareNoCase(L"Volume")) nFlipbookType = FLIPBOOKTYPE_VOLUME = 2;-->
      </optional>
      <optional>
        <attribute name="FramesPerSecond">
          <data type="decimal"/>
        </attribute>
      </optional>
      <attribute name="GravityMultiplier">
        <data type="decimal"/>
      </attribute>
      <attribute name="InheritVelocityInsteadOfPosition">
        <data type="integer"/>
      </attribute>
      <optional>
        <attribute name="InitialRotation">
          <data type="decimal"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="InitialRotationRange">
          <data type="decimal"/>
        </attribute>
      </optional>
      <attribute name="InitialRotationSpeed">
        <data type="decimal"/>
      </attribute>
      <attribute name="InitialRotationSpeedRange">
        <data type="decimal"/>
      </attribute>
      <attribute name="InitialSpeed">
        <data type="decimal"/>
      </attribute>
      <attribute name="InitialSpeedRange">
        <data type="decimal"/>
      </attribute>
      <optional>
        <attribute name="InvMovementSpreadUpdateDelay">
          <data type="decimal"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="KillParticleWhenTargetHit">
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="LOD">
          <data type="integer"/>
        </attribute>
      </optional>
      <attribute name="Life">
        <data type="decimal"/>
      </attribute>
      <optional>
        <attribute name="LifeRange">
          <data type="decimal"/>
        </attribute>
      </optional>
      <attribute name="LinkParticlesTogether">
        <data type="integer"/>
      </attribute>
      <attribute name="MaterialLibrary">
        <data type="NCName"/>
      </attribute>
      <attribute name="MaterialObject">
        <data type="NMTOKEN"/>
      </attribute>
      <optional>
        <attribute name="MeshParticleModel">
          <data type="NMTOKEN"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="MeshParticleRollAxis"/> <!-- Three numbers separated by spaces -->
      </optional>
      <optional>
        <attribute name="MeshParticleUpAxis"/> <!-- Three numbers separated by spaces -->
      </optional>
      <attribute name="MovementSpread"/> <!-- Two floating point values, representing movementspread X and movementspread Y -->
      <optional>
        <attribute name="MovementSpreadUpdateDelay">
          <data type="decimal"/>
        </attribute>
      </optional>
      <attribute name="Name">
        <data type="NMTOKEN"/>
      </attribute>
      <optional>
        <attribute name="ObjectSpaceAcceleration">
          <data type="integer"/>
        </attribute>
      </optional>
      <attribute name="OrientationBehaviour">
        <data type="NCName"/>
      </attribute>
      <attribute name="ParticleInheritance">
        <data type="NCName"/>
      </attribute>
      <attribute name="ParticlesAffectedByWind">
        <data type="integer"/>
      </attribute>
      <attribute name="ParticlesFollowPath">
        <data type="integer"/>
      </attribute>
      <optional>
        <attribute name="PhysicsEmitter">
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="PhysicsObjectSpawn">
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="RandomInitialRotation">
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="RandomStartFrame">
          <data type="integer"/>
        </attribute>
      </optional>
      <attribute name="RotationalAcceleration">
        <data type="decimal"/>
      </attribute>
      <attribute name="ScaleRange">
        <data type="decimal"/>
      </attribute>
      <optional>
        <attribute name="SpawnDirectionTracksTarget">
          <data type="integer"/>
        </attribute>
      </optional>
      <attribute name="SpawnSpread"/> <!-- Two floating point values, representing spawnspread X and spawnspread Y -->
      <optional>
        <attribute name="SplatEmitter">
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="TargetAttraction">
          <data type="decimal"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="TargetName">
          <data type="NMTOKEN"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="TargetRadius">
          <data type="decimal"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="UVDistributionSize">
          <data type="integer"/>
        </attribute>
      </optional>
      <attribute name="UpdateOnlyWhenVisible">
        <data type="integer"/>
      </attribute>
      <optional>
        <attribute name="UseVariationTint">
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="UserParamName"/> <!-- ECString, not sure if there's any special formatting here -->
      </optional>
      <optional>
        <attribute name="VertexFormat">
          <data type="NCName"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="WorldAxisAcceleration"/> <!-- Three numbers separated by spaces -->
      </optional>
      <oneOrMore>
        <choice>
          <ref name="Export"/>
          <ref name="Rotation"/>
          <ref name="Translation"/>
          <element name="EmitterAttachments">
            <optional>
              <attribute name="MeshParticleRollAxis"/> <!-- Three numbers separated by spaces -->
            </optional>
            <optional>
              <attribute name="MeshParticleUpAxis"/>  <!-- Three numbers separated by spaces -->
            </optional>
            <element name="EmitterAttachment">
              <optional>
                <attribute name="Name">
                  <data type="NCName"/>
                </attribute>
              </optional>
              <optional>
                <attribute name="SpawnOnSurface">
                  <data type="integer"/>
                </attribute>
              </optional>
              <attribute name="Type">
                <data type="NCName"/>
              </attribute>
              <optional>
                <attribute name="UseNormalForVelocity">
                  <data type="integer"/>
                </attribute>
              </optional>
            </element>
          </element>
          <element name="SpawnVolume">
            <optional>
              <attribute name="Axis"/>
            </optional>
            <attribute name="InvertSpawnVolumeNormals">
              <data type="integer"/>
            </attribute>
            <optional>
              <attribute name="Length">
                <data type="decimal"/>
              </attribute>
            </optional>
            <optional>
              <attribute name="MaxCorner"/>  <!-- Three numbers separated by spaces -->
            </optional>
            <optional>
              <attribute name="MeshParticleRollAxis"/> <!-- Three numbers separated by spaces -->
            </optional>
            <optional>
              <attribute name="MeshParticleUpAxis"/> <!-- Three numbers separated by spaces -->
            </optional>
            <optional>
              <attribute name="MinCorner"/> <!-- Three numbers separated by spaces -->
            </optional>
            <optional>
              <attribute name="Radius">
                <data type="decimal"/>
              </attribute>
            </optional>
            <optional>
              <attribute name="SpawnVolumeType">
                <data type="NCName"/>
              </attribute>
            </optional>
            <attribute name="SpawnWithinVolume">
              <data type="integer"/>
            </attribute>
            <optional>
              <attribute name="UseVolumeNormalsForDirection">
                <data type="integer"/>
              </attribute>
            </optional>
            <zeroOrMore>
              <ref name="Data"/>
            </zeroOrMore>
          </element>
        </choice>
      </oneOrMore>
      <optional>
        <element name="SplatParticle">
          <optional>
            <attribute name="AgeMapColorMultiplier"/> <!-- four numbers separated by spaces -->
          </optional>
          <optional>
            <attribute name="FlipbookColumns">
              <data type="integer"/>
            </attribute>
          </optional>
          <optional>
            <attribute name="FlipbookRows">
              <data type="integer"/>
            </attribute>
          </optional>
          <optional>
            <attribute name="FlipbookType">
              <data type="NCName"/>
            </attribute>
          </optional>
          <optional>
            <attribute name="FramesPerSecond">
              <data type="integer"/>
            </attribute>
          </optional>
          <attribute name="Height">
            <data type="decimal"/>
          </attribute>
          <optional>
            <attribute name="HoldLastFrame">
              <data type="integer"/>
            </attribute>
          </optional>
          <attribute name="Lifespan">
            <data type="integer"/>
          </attribute>
          <attribute name="MaterialObject">
            <data type="NCName"/>
          </attribute>
          <attribute name="NumSamplesH">
            <data type="integer"/>
          </attribute>
          <attribute name="NumSamplesW">
            <data type="integer"/>
          </attribute>
          <attribute name="OrientationRangeRadians">
            <data type="integer"/>
          </attribute>
          <optional>
            <attribute name="RandomStartFrame">
              <data type="integer"/>
            </attribute>
          </optional>
          <attribute name="Width">
            <data type="decimal"/>
          </attribute>
          <optional>
            <ref name="Export"/>
          </optional>
          <ref name="AgeMap"/>
        </element>
      </optional>
      <ref name="AgeMap"/>
    </element>
  </define>
  <define name="Data">
    <element name="Data">
      <optional>
        <attribute name="ElementCount">
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="IndexCount">
          <data type="integer"/>
        </attribute>
      </optional>
      <optional>
        <attribute name="IndexType">
          <data type="NCName"/>
        </attribute>
      </optional>
      <attribute name="Semantic">
        <data type="NCName"/>
      </attribute>
      <optional>
        <attribute name="Type">
          <data type="NCName"/>
        </attribute>
      </optional>
      <text/>
    </element>
  </define>
  <define name="NodeEmitterGroup">
    <element name="NodeEmitterGroup">
      <attribute name="MaterialObject">
        <data type="NCName"/>
      </attribute>
      <attribute name="Name">
        <data type="NMTOKEN"/>
      </attribute>
      <ref name="Translation"/>
      <ref name="Rotation"/>
      <zeroOrMore>
        <ref name="NodeEmitter"/>
      </zeroOrMore>
    </element>
  </define>
  <define name="NodeEmitterTarget">
    <element name="NodeEmitterTarget">
      <attribute name="Name">
        <data type="NCName"/>
      </attribute>
      <ref name="Translation"/>
      <ref name="Rotation"/>
      <zeroOrMore>
        <ref name="Export"/>
      </zeroOrMore>
    </element>
  </define>
  <define name="NodeLightProbe">
    <element name="NodeLightProbe">
      <attribute name="Name">
        <data type="NCName"/>
      </attribute>
      <ref name="Translation"/>
      <ref name="Rotation"/>
      <optional>
        <element name="ReflectionMap">
          <attribute name="ResName">
            <data type="NCName"/>
          </attribute>
        </element>
        <element name="IrradianceMap">
          <attribute name="ResName">
            <data type="NCName"/>
          </attribute>
        </element>
      </optional>
    </element>
  </define>
  <define name="AgeMap">
    <element name="AgeMap">
      <attribute name="Count">
        <data type="integer"/>
      </attribute>
      <oneOrMore>
        <element name="AgeMapElement">
          <attribute name="Alpha">
            <data type="decimal"/>
          </attribute>
          <attribute name="Color"/>
          <attribute name="PercentLifeElapsed">
            <data type="decimal"/>
          </attribute>
          <optional>
            <attribute name="RotationSpeedMultiplier">
              <data type="decimal"/>
            </attribute>
          </optional>
          <attribute name="XScale">
            <data type="decimal"/>
          </attribute>
          <attribute name="YScale">
            <data type="decimal"/>
          </attribute>
        </element>
      </oneOrMore>
    </element>
  </define>
</grammar>

Example .MMH.XML file

<!-- A note on value types:
		List#:type -- means # amount of values of specified type with spaces in between
		
		string -- a series of characters, digits and underscores, can not start with a colon, no spaces
		?string? -- same as above except can start with a colon
		int -- an integer (whole number)
		decimal -- any number including one with digits appearing after a decimal point, 
				   all decimals MUST have a decimal point even if there are no digits after it (ie 1. not 1, or 0.0)
-->

<ModelHierarchy ModelDataName="string" Name="string">
	<!-- Optional Attributes:
		FXActorName="string" -- An FXA file name 
		PreSimulateTime="decimal" -- emitter presimulation time
		ReferencedMeshes="List:string" -- List of names of referenced meshes. Most of the files I see this in have an empty string here, but some 
										  have one or more .msh files named with spaces separating them. For example: 
															ReferencedMeshes="fx_l_plane.msh fx_l_plane.msh"
										  Every file with ReferencedMeshes defined was exported by the VFX editor so this is a VFX thing.
		RemoteMaterialAlpha="decimal" -- if UseRemoteMaterial is true 
		RemoteMaterialDecalName="string" -- if UseRemoteMaterial is true 
		RemoteMaterialFresnelFalloff="decimal" -- if UseRemoteMaterial is true 
		RemoteMaterialInvertFresnel="int" -- if UseRemoteMaterial is true. A true/false value 
		RemoteMaterialTintColor="List4:decimal"-- if UseRemoteMaterial is true. Four numbers separated by spaces 
		UseRemoteMaterial="int" -- a true/false value 
	-->
	<!-- 1 of (defined below): -->
	<MeshHierarchy/> <!-- MeshHierarchy is a deprecated synonym for "NodeMesh". -->
	<Node/>
	<NodeMesh/>	
</ModelHierarchy>

<NodeMesh>
	<!-- Optional Attributes:
		BonesUsed="List:int" -- list of integers. Bodies have a lot of bones listed, other body parts have fewer. Boots, armor, gloves, 
								helmets, hair, eyes, etc. all have bonesused. 
		CastBakedShadow="int" -- true/false value 
		CastRuntimeShadow="int" -- true/false value
		CutAway="int" -- true/false value (Cut Away enables Fading out on Isometric view in Dragon Age)
		ID="string" -- A short and unique string. It is unique across every mesh used in whole Dragon Age. Used by lightmapper to reference the mesh
		IsVFXMesh="int" -- if this mesh is categorized as a VFX Mesh, load in the MaterialColor parameter
		MaterialColor="List4:decimal" -- String with four values - RGBA
		MaterialLibrary="string" -- Strings like "CavesInterior" - reference to MAL files, MAL are material editor file types. (may not actually be useful in the game)
		MaterialObject="?string?" -- Strings like "pn_boo_hvyd_l3" here, this is referring to material object (MAO files) create by the material editor 
		MeshGroupName=string"> -- The Meshes Name, used to reference the meshchunk name in the MSH 
		MeshName="string" -- the mesh file that the meshchunk is in. if this isn't set, it will default to the first mesh in the model (for backwards compatibility)
		Name="string" -- name of the node
		PunchThrough="int" -- true/false value
	    ReceiveBakedShadow="int" -- true/false value 
		ReceiveRuntimeShadow="int" -- true/false value 
		<<UNKNOWN>> ReceiveShadow="int" -- I didn't find this referenced in the source code - deprecated, perhaps? 
		ShadowCasting="int" -- used to set GFF_MMH_MESH_CAST_RUNTIME_SHADOW in the source code, same as CastRuntimeShadow above - synonyms?
		UseVariationTint="int" -- true/false value
	-->
	<!-- 0 or more of the following items come next, definitions follow later -->
	<Attribute/>
	<BoundingBox/>	<!-- may be empty, or may contain something of the form <![CDATA[-8.00051 -32.0 -0.0103784 1.0 8.01207 0.0 30.0 1.0]]> 
						 I believe this is the two corners (min and max) of the bounding box. -->
	<CollisionObject/>
	<Export/>
	<Node/>
	<NodeCrustHierarchy/>
	<NodeMesh/>		<!-- appears to be able to handle a nodemesh within a nodemesh :O -->
	<NodePointLight/>
	<NodeWeapontrail/>
	<Rotation/>
	<Translation/>
	<Scale>"decimal"</Scale>  
	<!-- I am assuming next bit means no more than one of the following (could be none): 
									  <choice>
										<ref name="NodeAmbientLight"/>
										<ref name="NodeUsePoint"/>
										<zeroOrMore>
										  <ref name="NodeEmitter"/>
										</zeroOrMore>
									  </choice>
	-->
	<NodeAmbientLight/>
	<NodeUsePoint/>
	<NodeEmitter/>
</NodeMesh>

<Node Name="?string?">
	<!-- Optional Attributes:
		BoneIndex="int" ---- possibly the bone to which this node is attached to, not included if not attached to a bone?
		SoundMaterialType="int" ---- are there SoundMaterialType definitions somewhere? if so I guess this is the index of one
    -->
	<!-- can have 0 or more of the following(including duplicates), however I assume having more than one of the same type
		 would cause the compiler to go wtf? in some cases (like bounding box or translation). Definitions follow later in file
	-->
	<BoundingBox/>
	<CollisionObject/>
	<Export/>
	<Node/>
	<NodeCrustHierarchy/>
	<NodeEmitter/>
	<NodeEmitterGroup/>
	<NodeEmitterTarget/>
	<NodeLightProbe/>
	<NodeMesh/>
	<NodePointLight/>
	<NodeUsePoint/>
	<NodeWeapontrail/>
	<Rotation/>
	<Translation/>
	<NodeCloth> <!-- has a shit load of attributes with no comments however I assume they all have to do with cloth simulation paramaters -->
	<!-- NodeCloth Attributes:
		AttachmentResponseCoefficient="decimal" 
		AttachmentTearFactor="decimal" 
		BendingStiffness="decimal" 
		CF_BENDING="int"
		CF_BENDING_ORTHO="int"
		CF_COLLISION_TWOWAY="int"
		CF_COMDAMPING="int"
		CF_DAMPING="int"
		CF_DISABLE_COLLISION="int"
		CF_GRAVITY="int"
		CF_HARDWARE="int"
		CF_PRESSURE="int"
		CF_SELFCOLLISION="int"
		CF_STATIC="int"
		CF_TEARABLE="int"
		CF_VISUALIZATION="int"
		CollisionResponseCoefficient="decimal"
		DampingCoefficient="decimal"
		Density="decimal"
		Fadeable="boolean"
		Friction="decimal"
		GROUP_MASK_NONWALKABLE="boolean"
		ID="string"
		MaterialLibrary="string"
		MaterialObject="string"
		MeshGroupName="string"
		Name="string"
		Pressure="decimal"
		SleepLinearVelocity="decimal"
		SolverIterations="int"
		StretchingStiffness="decimal"
		TearFactor="decimal"
		Thickness="decimal"
		WakeUpCounter="decimal"
	-->
	<!-- Optional Attributes:	GROUP_MASK_STATICGEOMETRY="boolean" -->
		<Attribute/>
		<Export/>	<!-- can have 0 or more Exports -->
		<Translation/>
		<Rotation/>
		<ClothAttachments>
		  <ClothAttachment TearableAttachment="int" TwoWayAttachment="int" Type="string">
		  </ClothAttachment>
		</ClothAttachments>
		<MeshGroup Name="string">	<!-- contains 1 or more Data elements, defined later in file -->
			<Data/>	
		</MeshGroup>
	</NodeCloth>
	<NodeSnaptoPoint Name="string">
			<!-- can have 0 or more Exports -->
			<Export/>
			<!-- can have 0 or more of the following, defined later in file -->
            <Translation/>
            <Rotation/>
          </NodeSnapToPoint>
    <NodeAmbientLight/>	<!-- Optional Element defined later in file--> 
</Node>

<!-- <<<WARNING: PROBABLY NOT A GOOD IDEA TO USE THIS ONE!!!>>> -->
<!-- MeshHierarchy is a deprecated synonym for "NodeMesh". Only 14 files still use it out of nearly 8000 in our internal sources. -->
<!-- IE it is a REALLY old version of NodeMesh -->
<MeshHierarchy Name="string"> 
	<BoundingBox/> <!-- Optional -->
	<!-- These are Optional and apparently can have more than one if you want, defined lated in file -->
		<MeshHierarchy/>
		<Rotation/>
		<Translation/>
	<!-- can have either a NodeLightProbe or 0 or more NodeEmitters -->
	<NodeLightProbe/>
	<NodeEmitter/>
</MeshHierarchy>

<NodeCrustHierarchy HookID="int" Name="string">
	<Export/> 		<!-- can have 0 or more Exports, defined later in file -->
	<Translation/> 	<!-- Optional -->
	<Rotation/> 	<!-- Optional -->	
	<NodeMesh/> 	<!-- Optional -->
	<!-- can have 0 or more of the following (including duplicates apparently) -->
	  <Node/>
	  <NodeEmitter/>
	  <NodeEmitterGroup/>
	  <NodeEmitterTarget/>
	  <NodePointLight/>
</NodeCrustHierarchy>

<Rotation> 
  data <!-- data is a Quaternionf and represents the relative rotation from its parent or the world axis if it has no parent-->
</Rotation>

<Export ControllerType="string" ExportName="?string?" TagName="string"/>
  <!-- Optional Attribute: MaterialColor="List4:decimal" -- String with four values - RGBA -->
  <!-- An export is what is used to connect nodes from an animation file to nodes in a model file. The key frames in an animation file affect the translations/rotations of the nodes with the corresponding exports of the same name. -->

<BoundingBox>
	data <!-- data is Vector4f min, Vector4f max (ie: f f f f f f f f -->
</BoundingBox>

<Translation>
	<!-- Optional Attributes:
		MeshParticleRollAxis="List3:decimal" -- Three numbers separated by spaces 
		MeshParticleUpAxis="List3:decimal"-- Three numbers separated by spaces 
	-->
	data <!-- This is a vector4 representing the difference in position from its parent, or the origin if it has no parent -->
</Translation>

<CollisionObject>
<!-- Optional Attributes:
	Kinematic="boolean"
	Static="boolean"
-->
<!-- can have 1 or more Shapes -->
	<Shape>
	<!-- Attributes:
		AllowEmitterSpawn="int"
		Fadeable="boolean"
		Name="string"
		Position --Vector4f but no required type??
		Rotation --Quaternionf but no required type??
		Type="string"
	-->
	<!-- Optional Attributes:
		DimX="decimal"
		DimY="double"  -- why double when other dims are decimal???
		DimZ="decimal"
		GROUP_MASK_CREATURES="boolean"
		GROUP_MASK_ITEMS="boolean"
		GROUP_MASK_NONWALKABLE="boolean"
		GROUP_MASK_PLACEABLES="boolean"
		GROUP_MASK_STATICGEOMETRY="boolean"
		GROUP_MASK_TERRAIN_WALL="boolean"
		GROUP_MASK_TRIGGERS="boolean"
		GROUP_MASK_WALKABLE="boolean"
		Height="double"
		Radius="decimal"
	-->
		<!-- VertexData and IndexData are optional, however you must have both or neither. Can have more than one pair??? -->
		<VertexData length="int"> <!-- I assume length is the number of verts or possibly the number of values given in data -->
		  data <!-- I assume this is a list of vert coords given in a list form (ie: x1,y1,z1,x2,y2,z2,...,xn,yn,zn maybe without commas) -->
		</VertexData>
		<IndexData> <!-- UINT16? don't know what this one's for, ask for clarification -->
		  data		<!-- maybe its vertex indicies for triangles? -->
		</IndexData>
	</Shape>
</CollisionObject>

<NodePointLight Color="list4:decimal" IsStatic="int" Name="string" Radius="decimal"> <!-- Color: string of four numbers, separated by spaces. -->
<!-- Optional Attributes:
	AffectsDomain="int" -- A search through the existing files has this as either "1" or "2", no other values. 
						   I don't know what these domains represent.
    IntensityPeriod="decimal"
    IntensityPeriodDelta="decimal"
    IntensityVariation="decimal"
    UseVariationTint="int"-- true/false, I believe 
-->
	<!-- must have at least 1 of the following, can have more including duplicates apparently -->
	<Export/>
	<Rotation/>
	<Translation/>
</NodePointLight>

<NodeWeapontrail Duration="decimal" MaterialObject="string" Name="string" SegmentLength="decimal">
    <!-- All MaterialObjects appear to be in either weapontrail_streaks or weapontrail_arrow -->
	<Translation/>
	<Rotation/>
</NodeWeaponTrail>
  
<Attribute AttributeName="string" SourceName="string">
      <!-- AttributeName's value is almost universally "BaseLight" (11167 times out of 11170 in 7010 files) -->
      <!-- SourceName's value is almost universally "BaseLight" (11167 times out of 11170 in 7010 files)-->
</Attribute> 
  
<NodeUsePoint Name="string" Type="string">
	<!-- All Name values seem to be of the form "UserPoint##", where ## is a zero-padded low number  (highest I've seen is 14) -->
	<!-- Type values: "Front", "Back", "Right", "Left" are options. Most items seem to get by with just nodeusepoints of front 
		 and back, a few have all four types of nodeusepoint. -->
	<Export/> <!-- 0 or more exports -->
	<Translation/>
	<Rotation/>
	<NodeCrustHierarchy/> <!-- Optional -->
</NodeUsePoint>
 
<!-- Only 5 files had one of these; lightrig_day01.mmh.xml, lightrig_int01.mmh.xml, lightrig_night01.mmh.xml, tools_ambient.mmh.xml, 
	 and tools_bulb_ambient.mmh.xml. 
	 
	 I would assume this type of node is used for calculating ambient light/shadows maybe like a radiosity pass or something.
	 Might make some interesting lighting changes if you fiddle with it but be careful! might break your lighting -->
<NodeAmbientLight Color="List4:decimal" Name="string" Radius="double"> 
    <!-- Color: string of four numbers, separated by spaces. "0.0705882 0.0862745 0.0980392 1.0" for the three lightrigs, 
		 "0.498039 0.498039 0.498039 1.0" for the two tools 
		 Name: "BWDA_OmniLight04" for the three lightrigs, "BWDA_OmniLight01" for the two tools. 
		 Radius: 5.0 for the three lightrigs, "1e+007" (10000000?? big big radius!) for the two tools -->
    <Export/> <!-- 0 or more exports -->
    <Translation/>
	<Rotation/>
</NodeAmbientLight>
  
<NodeEmitter> <!-- has a shit ton of attributes, all of which seem to pertain to particle emitter parameters (makes sense) -->
	<!-- Attributes:
		Acceleration="decimal"
		Birthrate="decimal"
		BirthrateInParticlesPerMeter="int"
		BirthrateRange="decimal"
		EmitterType="string"
		EnableParticleCollisions="int" -- true/false ??
		GravityMultiplier="decimal"
		IneritVelocityInsteadOfPosition="int" -- true/false ??
		InitialRotationSpeedRange="decimal"
		InitialSpeed="decimal"
		InitialSpeedRange="decimal"
		Life="decimal"
		LinkParticlesTogether="int" -- true/false ??
		MaterialLibrary="string"
		MaterialObject="?string?"
		MovementSpread="List2:float" -- Two floating point values, representing movementspread X and movementspread Y 
		Name="?string?" 
		OrientationBehaviour="string"
		ParticleInheritance="string"
		ParticlesAffectedByWind="int" -- true/false ??
		ParticlesFollowPath="int" -- true/false ??
		RotationalAcceleration="decimal"
		ScaleRange="decimal"
		SpawnSpread="List2:float" -- Two floating point values, representing spawnspread X and spawnspread Y
		UpdateOnlyWhenVisible="int" -- true/false ??
	-->	
	<!-- Optional Attributes:
		AgeMapColorMultiplier="List4:decimal"- - string of four numbers, separated by spaces.
		AgeMapScaleXMultiplier="decimal"
		AgeMapScaleYMultiplier="decimal"
		Bounciness="decimal"
		FlipbookColumns="int" -- true/false ??
		FlipbookRows="int" -- true/false??
		FlipbookType="int" -- UINT8 nFlipbookType = FLIPBOOKTYPE_NONE = 0;  
							  if (a_sFlipbookType.CompareNoCase(L"ContactSheet")) nFlipbookType = FLIPBOOKTYPE_CONTACT_SHEET = 1;
							  if (a_sFlipbookType.CompareNoCase(L"Volume")) nFlipbookType = FLIPBOOKTYPE_VOLUME = 2;
		FramesPerSecond="decimal"
		InitialRotation="decimal"
		InitialRotationRange="decimal"
		InitialRotationSpeed="decimal"
		InvMovementSpreadUpdateDelay="decimal"
		KillParticleWhenTargetHit="int" -- true/false ??
		LOD="int" -- true/false maybe?? might be an index/identifier
		LifeRange="decimal"
		MeshParticleModel="?string?"
		MeshParticleRollAxis="List3:decimal" -- Three numbers separated by spaces 
		MeshParticleUpAxis="List3:decimal" -- Three numbers separated by spaces 
		MovementSpreadUpdateDelay="decimal"
		ObjectSpaceAcceleration="int"
		PhysicsEmitter="int" -- true/false ??
		PhysicsObjectSpawn="int -- true/false ??
		RandomInitialRotation="int" -- true/false ??
		RandomStartFrame="int" --true/false ??
		SpawnDirectionTracksTarget="int" -- true/false ??
		SplatEmitter="int" -- true/false ?? might be index of a SplatEmitter if they exist
		TargetAttraction="decimal">
		TargetName="?string?" 
		TargetRadius="decimal"
		UVDistributionSize="int">
		UseVariationTint="int" -- true/false ??
		UserParamName="??????" -- (datatype=ECString) << What is this?? -- ECString, not sure if there's any special formatting here 
		VertexFormat="string" -- are there VertexFormats defined somewhere?>
		WorldAxisAcceleration="List3:decimal" -- Three numbers separated by spaces 
	-->
	<!-- Requires 1 or more of the following, duplicates allowed apparently -->
	<Export/>
	<Rotation/>
	<Translation/>
	<EmitterAttachments>
	<!-- Optional EmitterAttachments Attributes:
		MeshParticleRollAxis="List3:decimal" -- Three numbers separated by spaces
		MeshParticleUpAxis="List3:decimal" -- Three numbers separated by spaces
	-->
		<EmitterAttachment Type="string"/>
		<!-- Optional EmitterAttachment Attributes:
			Name="string"
			SpawnOnSurface="int" -- true/false ??
			UseNormalForVelocity="int" -- true/false ??
		-->
	</EmitterAttachments>
	<SpawnVolume InvertSpawnVolumeNormals="int" SpawnWithinVolume="int" > <!-- both look to be true/false values -->
	<!-- Optional SpawnVolume Attributes:
			Axis="??????" -- no data type specified, assuming 3 numbers
			Length="decimal"
			MaxCorner="List3:decimal" -- Three numbers separated by spaces
			MeshParticleRollAxis="List3:decimal" -- Three numbers separated by spaces
			MeshParticleUpAxis="List3:decimal" -- Three numbers separated by spaces
			MinCorner="List3:decimal" -- Three numbers separated by spaces
			Radius="decimal"
			SpanwVolumeType="string" -- are there SpawnVolumeTypes defined somewhere???
			UseVolumeNormalsForDirection="int" -- true/false ??
	-->
		<Data/><!-- 0 or more of these -->
	</SpawnVolumn>
    <SplatParticle> <!-- Optional - Not included in the 1 or more -->
    <!-- SplatParticle Attributes:
			Height="decimal"
			Lifespan="int"
			MaterialObject="string"
			NumSamplesH="int"
			NumSamplesW="int"
			OrientationRangeRadians="int"
			Width="decimal"
	-->
	<!-- Optional SplatParticle Attributes:
			AgeMapColorMultiplier="List4:decimal" -- four numbers separated by spaces
			FlipbookColumns="int" -- true/false ??
			FlipbookRows="int" -- true/false??
			FlipbookType="string" -- apparently not same as above in NodeEmitter
			FramesPerSecond="int"
			HoldLastFrame="int" -- true/false ??
			RandomStartFrame="int" -- true/false ??
	-->
		<Export/> <!-- Optional -->
		<AgeMap/>
	</SplatParticle>
	<AgeMap/> <!-- Not Optional - Required - Not included in the 1 or more -->
</NodeEmitter>
  
<Data Semantic="string">
<!-- Optional Attributes:
		ElementCount="int"
		IndexCount="int"
		IndexType="string"
		Type="string"
-->
 	data
</Data>

<NodeEmitterGroup MaterialObject="string" Name="?string?"> 
	<Translation/>
	<Rotation/>
	<NodeEmitter/> <!-- 0 or more of these -->
</NodeEmitterGroup>

<NodeEmitterTarget Name="string">
	<Translation/>
	<Rotation/>
	<Export/> <!-- 0 or more exports -->
</NodeEmitterTarget>

<NodeLightProbe Name="string">
	<Translation/>
	<Rotation/>
	<!-- following are optional elements, they are paired, can't have one without the other -->
	<ReflectionMap ResName="string" />
	<IrradianceMap ResName="string" />
</NodeLightProbe>

 <AgeMap Count="int">
 <!-- contains one or more AgeMapElements -->
      <AgeMapElement Alpha="decimal" Color="List4:decimal" PercentLifeElapsed="decimal" XScale="decimal" YScale="decimal" />
	  <!-- Optional AgeMapElement Attributes: RotationSpeedMultiplier="decimal" -->
 </AgeMap>