//! Adds a standard data block (type: CLOD mesh declaration) to the chain of all data blocks.
//! Returns the total # of data blocks in the data block chain.
size_t U3DFileWriter::addStandardBlock_CLODMeshDeclaration(const U3DMeshInfoStruct& meshInfo)
{
  U3DDataBlockWriter CLODMeshDeclarationBlock;
  CLODMeshDeclarationBlock.blockType = U3D_BLOCKTYPE_CLODMESHDECLARATION;

  CLODMeshDeclarationBlock.writeString(meshInfo.ResourceName);     // Write Mesh Name (9.6.1.1.1)
  CLODMeshDeclarationBlock.writeU32(U3D_ReservedZero);             // Write Chain Index (9.6.1.1.2) (shall be zero) 

  CLODMeshDeclarationBlock.writeU32(meshInfo.MeshAttributes);      // Write Max Mesh Description - Mesh Attributes (9.6.1.1.3.1)
  CLODMeshDeclarationBlock.writeU32(meshInfo.FaceCount);           // Write Max Mesh Description - Face Count (9.6.1.1.3.2) (# of faces)
  CLODMeshDeclarationBlock.writeU32(meshInfo.VertexCount);         // Write Max Mesh Description - Position Count (9.6.1.1.3.3) (# of vertices)
  CLODMeshDeclarationBlock.writeU32(meshInfo.NormalCount);         // Write Max Mesh Description - Normal Count (9.6.1.1.3.4) (# of normals)
  CLODMeshDeclarationBlock.writeU32(meshInfo.DiffuseColorCount);   // Write Max Mesh Description - Diffuse Color Count (9.6.1.1.3.5)
  CLODMeshDeclarationBlock.writeU32(meshInfo.SpecularColorCount);  // Write Max Mesh Description - Specular Color Count (9.6.1.1.3.6)
  CLODMeshDeclarationBlock.writeU32(0x00000001);                   // Write Max Mesh Description - Texture Coord Count (9.6.1.1.3.7)
  CLODMeshDeclarationBlock.writeU32(0x00000001);                   // Write Max Mesh Description - Shading Count (9.6.1.1.3.8) (shall be 1 since only one shader is supported by this version)
    CLODMeshDeclarationBlock.writeU32(meshInfo.ShadingAttributes); // Write Max Mesh Description - Shading Description - Shading Attributes (9.6.1.1.3.9.1)
    CLODMeshDeclarationBlock.writeU32(0x00000000);                 // Write Max Mesh Description - Shading Description - Texture Layer Count (9.6.1.1.3.9.2) (shall be zero since textures are not supported by this version)
      //CLODMeshDeclarationBlock.writeU32(0x00000002);               // Write Max Mesh Description - Shading Description - Texture Coord Dimensions (9.6.1.1.3.9.3)
    CLODMeshDeclarationBlock.writeU32(0x00000000);                 // Write Max Mesh Description - Shading Description - Original Shading ID (9.6.1.1.3.9.4)

  CLODMeshDeclarationBlock.writeU32(meshInfo.VertexCount);         // Write CLOD Description - Minimum Resolution (9.6.1.1.4.1)  // Min resolution = max resolution -> base mesh only!
  //CLODMeshDeclarationBlock.writeU32(0);                            // Write CLOD Description - Minimum Resolution (9.6.1.1.4.1) 
  CLODMeshDeclarationBlock.writeU32(meshInfo.VertexCount);         // Write CLOD Description - Final Maximum Resolution (9.6.1.1.4.2)

  CLODMeshDeclarationBlock.writeU32(0x000003E8);                   // Write Resource Description - Quality Factors - Position Quality Factor (9.6.1.1.5.1.1)
  CLODMeshDeclarationBlock.writeU32(0x000003E8);                   // Write Resource Description - Quality Factors - Normal Quality Factor (9.6.1.1.5.1.2)
  CLODMeshDeclarationBlock.writeU32(0x000003E8);                   // Write Resource Description - Quality Factors - Texture Coord Quality Factor (9.6.1.1.5.1.3)
  CLODMeshDeclarationBlock.writeF32(1.f/U3DQuant_Position);        // Write Resource Description - Inverse Quantization - Position Inverse Quant (9.6.1.1.5.2.1)
  CLODMeshDeclarationBlock.writeF32(1.f/U3DQuant_Normal);          // Write Resource Description - Inverse Quantization - Normal Inverse Quant (9.6.1.1.5.2.2)
  CLODMeshDeclarationBlock.writeF32(1.f/U3DQuant_TextureCoord);    // Write Resource Description - Inverse Quantization - Texture Coord Inverse Quant (9.6.1.1.5.2.3)
  CLODMeshDeclarationBlock.writeF32(1.f/U3DQuant_DiffuseColor);    // Write Resource Description - Inverse Quantization - Diffuse Color Inverse Quant (9.6.1.1.5.2.4)
  CLODMeshDeclarationBlock.writeF32(1.f/U3DQuant_SpecularColor);   // Write Resource Description - Inverse Quantization - Specular Color Inverse Quant (9.6.1.1.5.2.5)
  CLODMeshDeclarationBlock.writeF32(0.9f);                         // Write Resource Description - Resource Parameters - Normal Crease Parameter (9.6.1.1.5.3.1)
  CLODMeshDeclarationBlock.writeF32(0.5f);                         // Write Resource Description - Resource Parameters - Normal Update Parameter (9.6.1.1.5.3.2)
  CLODMeshDeclarationBlock.writeF32(0.985f);                       // Write Resource Description - Resource Parameters - Normal Tolerance Parameter (9.6.1.1.5.3.3)

  CLODMeshDeclarationBlock.writeU32(0x00000000);                   // Write Skeleton Description - Bone Count (9.6.1.1.6.1) (shall be zero since skeltons are not supported by this version) [UNUSED BY ACROBAT]

  return addDataBlock(CLODMeshDeclarationBlock);
}
//! Adds a standard data block (type: view node) to the chain of all data blocks.
//! Returns the total # of data blocks in the data block chain.
size_t U3DFileWriter::addStandardBlock_ViewNode(const std::string& viewNodeName, const std::string& viewResourceName)
{
    U3DDataBlockWriter ViewNodeBlock;
    ViewNodeBlock.blockType = mlU3D::BLOCKTYPE_VIEWNODE;

    ViewNodeBlock.writeString(viewNodeName);                   // Write View Node Name (9.5.4.1)
    _writeParentNodeData(ViewNodeBlock, "");                   // Write Parent Node Data (9.5.4.2) (Parent Node Name = empty --> = world)
    ViewNodeBlock.writeString(viewResourceName);               // Write View Resource Name (9.5.4.3) (Same as View Node Name) [UNUSED BY ACROBAT]
    ViewNodeBlock.writeU32(mlU3D::VIEWNODEATTRIBUTE_DEFAULT);  // Write View Node Attributes (9.5.4.4)
    ViewNodeBlock.writeF32(0.0f);                              // Write View Near Clip (9.5.4.5.1)
    ViewNodeBlock.writeF32(0.0f);                              // Write View Far Clip (9.5.4.5.2)
    ViewNodeBlock.writeF32(0.0f);                              // Write View Projection (9.5.4.6.1)
    //ViewNodeBlock.writeF32(0.0f);                            // Write View Orthographic Height (9.5.4.6.2) (only for orthographic projection) [UNUSED BY ACROBAT]
    ViewNodeBlock.writeF32(100.0f);                            // Write View Port Width (9.5.4.7.1)
    ViewNodeBlock.writeF32(100.0f);                            // Write View Port Height (9.5.4.7.2)
    ViewNodeBlock.writeF32(50.0f);                             // Write View Port Horizontal Position (9.5.4.7.3)
    ViewNodeBlock.writeF32(50.0f);                             // Write View Port Vertical Position (9.5.4.7.4)
    ViewNodeBlock.writeU32(0x00000000);                        // Write Backdrop Count (9.5.4.8) [UNUSED BY ACROBAT]
    ViewNodeBlock.writeU32(0x00000000);                        // Write Overlay Count (9.5.4.10) [UNUSED BY ACROBAT]

    return addDataBlock(ViewNodeBlock);
}
//! Adds a standard data block (type: point set declaration) to the chain of all data blocks.
//! Returns the total # of data blocks in the data block chain.
size_t U3DFileWriter::addStandardBlock_PointSetDeclaration(const mlU3D::PointSetGenerator& pointSetGenerator)
{
    U3DDataBlockWriter PointSetDeclarationBlock;
    PointSetDeclarationBlock.blockType = mlU3D::BLOCKTYPE_POINTSETDECLARATION;

    PointSetDeclarationBlock.writeString(pointSetGenerator.resourceName);    // Write Point Set Name (9.6.2.1.1)
    PointSetDeclarationBlock.writeU32(mlU3D::ReservedZero);                  // Write Chain Index (9.6.2.1.1) (shall be zero)

    PointSetDeclarationBlock.writeU32(mlU3D::ReservedZero);                  // Write Point Set Description - Point Set Reserved (9.6.2.1.3.1) (shall be zero)
    PointSetDeclarationBlock.writeU32(pointSetGenerator.pointCount);         // Write Point Set Description - Point Count (9.6.2.1.3.2) (# of points)
    PointSetDeclarationBlock.writeU32(pointSetGenerator.pointCount);         // Write Point Set Description - Position Count (9.6.2.1.3.3) (# of positions - equals # of points)
    PointSetDeclarationBlock.writeU32(pointSetGenerator.normalCount);        // Write Point Set Description - Normal Count (9.6.2.1.3.4) (# of normals)
    PointSetDeclarationBlock.writeU32(pointSetGenerator.diffuseColorCount);  // Write Point Set Description - Diffuse Color Count (9.6.2.1.3.5)
    PointSetDeclarationBlock.writeU32(pointSetGenerator.specularColorCount); // Write Point Set Description - Specular Color Count (9.6.2.1.3.6)
    PointSetDeclarationBlock.writeU32(pointSetGenerator.textureCoordCount);  // Write Point Set Description - Texture Coord Count (9.6.2.1.3.7)
    PointSetDeclarationBlock.writeU32(0x00000001);                           // Write Point Set Description - Shading Count (9.6.2.1.3.8)

    PointSetDeclarationBlock.writeU32(pointSetGenerator.shadingAttributes);  // Write Point Set Description - Shading Description - Shading Attributes (9.6.1.1.3.9.1)
    PointSetDeclarationBlock.writeU32(0x00000000);                           // Write Point Set Description - Shading Description - Texture Layer Count (9.6.1.1.3.9.2)
    //PointSetDeclarationBlock.writeU32(0x00000000);                           // Write Point Set Description - Shading Description - Texture Coord Dimensions (9.6.1.1.3.9.3) - only if Texture Layer Count > 0
    PointSetDeclarationBlock.writeU32(0x00000000);                           // Write Point Set Description - Shading Description - Original Shading ID (9.6.1.1.3.9.4)

    PointSetDeclarationBlock.writeU32(0x000003E8);                           // Write Resource Description - Quality Factors - Position Quality Factor (9.6.1.1.5.1.1)       [UNUSED BY ACROBAT]
    PointSetDeclarationBlock.writeU32(0x000003E8);                           // Write Resource Description - Quality Factors - Normal Quality Factor (9.6.1.1.5.1.2)         [UNUSED BY ACROBAT]
    PointSetDeclarationBlock.writeU32(0x000003E8);                           // Write Resource Description - Quality Factors - Texture Coord Quality Factor (9.6.1.1.5.1.3)  [UNUSED BY ACROBAT]
    PointSetDeclarationBlock.writeF32(1.f / mlU3D::Quant_Position);          // Write Resource Description - Inverse Quantization - Position Inverse Quant (9.6.1.1.5.2.1)
    PointSetDeclarationBlock.writeF32(1.f / mlU3D::Quant_Normal);            // Write Resource Description - Inverse Quantization - Normal Inverse Quant (9.6.1.1.5.2.2)
    PointSetDeclarationBlock.writeF32(1.f / mlU3D::Quant_TextureCoord);      // Write Resource Description - Inverse Quantization - Texture Coord Inverse Quant (9.6.1.1.5.2.3)
    PointSetDeclarationBlock.writeF32(1.f / mlU3D::Quant_DiffuseColor);      // Write Resource Description - Inverse Quantization - Diffuse Color Inverse Quant (9.6.1.1.5.2.4)
    PointSetDeclarationBlock.writeF32(1.f / mlU3D::Quant_SpecularColor);     // Write Resource Description - Inverse Quantization - Specular Color Inverse Quant (9.6.1.1.5.2.5)
    PointSetDeclarationBlock.writeU32(mlU3D::ReservedZero);                  // Write Resource Description - Resource Parameters - Reserved Point Set Parameter 1 (9.6.2.1.4.3.1) (shall be zero)
    PointSetDeclarationBlock.writeU32(mlU3D::ReservedZero);                  // Write Resource Description - Resource Parameters - Reserved Point Set Parameter 2 (9.6.2.1.4.3.2) (shall be zero)
    PointSetDeclarationBlock.writeU32(mlU3D::ReservedZero);                  // Write Resource Description - Resource Parameters - Reserved Point Set Parameter 3 (9.6.2.1.4.3.3) (shall be zero)

    PointSetDeclarationBlock.writeU32(0x00000000);                           // Write Skeleton Description - Bone Count (9.6.2.1.5) (shall be zero since skeltons are not supported by this version) [UNUSED BY ACROBAT]

    return addDataBlock(PointSetDeclarationBlock);
}
//! Adds a standard data block (type: material resource) to the chain of all data blocks.
//! Returns the total # of data blocks in the data block chain.
size_t U3DFileWriter::addStandardBlock_MaterialResource(const mlU3D::MaterialResource& materialResource)
{
    U3DDataBlockWriter MaterialResourceBlock;
    MaterialResourceBlock.blockType = mlU3D::BLOCKTYPE_MATERIALRESOURCE;
    MaterialResourceBlock.writeString(materialResource.resourceName);                 // Write Material Resource Name (9.8.4.1)
    MaterialResourceBlock.writeU32(mlU3D::MATERIALRESOURCEATTRIBUTES_ALL);            // Write Material Attributes (9.8.4.2)     [UNUSED BY ACROBAT]
    MaterialResourceBlock.writeF32(materialResource.ambientColor[0]);                 // Ambient Color - Red (9.8.4.3.1)
    MaterialResourceBlock.writeF32(materialResource.ambientColor[1]);                 // Ambient Color - Green (9.8.4.3.2)
    MaterialResourceBlock.writeF32(materialResource.ambientColor[2]);                 // Ambient Color - Blue (9.8.4.3.3)
    MaterialResourceBlock.writeF32(materialResource.diffuseColor[0]);                 // Diffuse Color - Red (9.8.4.4.1)
    MaterialResourceBlock.writeF32(materialResource.diffuseColor[1]);                 // Diffuse Color - Green (9.8.4.4.2)
    MaterialResourceBlock.writeF32(materialResource.diffuseColor[2]);                 // Diffuse Color - Blue (9.8.4.4.3)
    MaterialResourceBlock.writeF32(materialResource.specularColor[0]);                // Specular Color - Red (9.8.4.5.1)
    MaterialResourceBlock.writeF32(materialResource.specularColor[1]);                // Specular Color - Green (9.8.4.5.2)
    MaterialResourceBlock.writeF32(materialResource.specularColor[2]);                // Specular Color - Blue (9.8.4.5.3)
    MaterialResourceBlock.writeF32(materialResource.emissiveColor[0]);                // Emissive Color - Red (9.8.4.6.1)
    MaterialResourceBlock.writeF32(materialResource.emissiveColor[1]);                // Emissive Color - Green (9.8.4.6.2)
    MaterialResourceBlock.writeF32(materialResource.emissiveColor[2]);                // Emissive Color - Blue (9.8.4.6

    MaterialResourceBlock.writeF32(materialResource.reflectivity);                    // Write Reflectivity (9.8.4.7)
    MaterialResourceBlock.writeF32(materialResource.diffuseColor[3]);                 // Write Opacity (9.8.4.8)

    return addDataBlock(MaterialResourceBlock);
}
//! Adds a standard data block (type: material resource) to the chain of all data blocks.
//! Returns the total # of data blocks in the data block chain.
size_t U3DFileWriter::addStandardBlock_MaterialResourceWithDefaultLight(const std::string& materialResourceName)
{
    U3DDataBlockWriter MaterialResourceBlock;
    MaterialResourceBlock.blockType = mlU3D::BLOCKTYPE_MATERIALRESOURCE;
    MaterialResourceBlock.writeString(materialResourceName);                        // Write Material Resource Name (9.8.4.1)
    MaterialResourceBlock.writeU32(mlU3D::MATERIALRESOURCEATTRIBUTES_ALL);          // Write Material Attributes (9.8.4.2)

    MaterialResourceBlock.writeF32(1.0f);                                           // Ambient Color - Red (9.8.4.3.1)
    MaterialResourceBlock.writeF32(1.0f);                                           // Ambient Color - Green (9.8.4.3.2)
    MaterialResourceBlock.writeF32(1.0f);                                           // Ambient Color - Blue (9.8.4.3.3)
    MaterialResourceBlock.writeF32(0.65f);                                          // Diffuse Color - Red (9.8.4.4.1)
    MaterialResourceBlock.writeF32(0.65f);                                          // Diffuse Color - Green (9.8.4.4.2)
    MaterialResourceBlock.writeF32(0.65f);                                          // Diffuse Color - Blue (9.8.4.4.3)
    MaterialResourceBlock.writeF32(0.75f);                                          // Specular Color - Red (9.8.4.5.1)
    MaterialResourceBlock.writeF32(0.75f);                                          // Specular Color - Green (9.8.4.5.2)
    MaterialResourceBlock.writeF32(0.75f);                                          // Specular Color - Blue (9.8.4.5.3)
    MaterialResourceBlock.writeF32(0.0f);                                           // Emissive Color - Red (9.8.4.6.1)
    MaterialResourceBlock.writeF32(0.0f);                                           // Emissive Color - Green (9.8.4.6.2)
    MaterialResourceBlock.writeF32(0.0f);                                           // Emissive Color - Blue (9.8.4.6
    MaterialResourceBlock.writeF32(0.5f);                                           // Write Reflectivity (9.8.4.7)
    MaterialResourceBlock.writeF32(1.0f);                                           // Write Opacity (9.8.4.8)

    return addDataBlock(MaterialResourceBlock);
}
//! Adds a standard data block (type: material resource) to the chain of all data blocks.
//! Returns the total # of data blocks in the data block chain.
size_t U3DFileWriter::addStandardBlock_MaterialResource(const U3DObjectInfoStruct& objectInfo)
{
  U3DDataBlockWriter MaterialResourceBlock;
  MaterialResourceBlock.blockType = U3D_BLOCKTYPE_MATERIALRESOURCE;
  MaterialResourceBlock.writeString(objectInfo.MaterialName);                       // Write Material Resource Name (9.8.4.1)
  MaterialResourceBlock.writeU32(U3D_MATERIALRESOURCEATTRIBUTES_ALL);               // Write Material Attributes (9.8.4.2)     [UNUSED BY ACROBAT]
  MaterialResourceBlock.writeF32(objectInfo.AmbientColor[0]);                       // Ambient Color - Red (9.8.4.3.1)
  MaterialResourceBlock.writeF32(objectInfo.AmbientColor[1]);                       // Ambient Color - Green (9.8.4.3.2)
  MaterialResourceBlock.writeF32(objectInfo.AmbientColor[2]);                       // Ambient Color - Blue (9.8.4.3.3)
  MaterialResourceBlock.writeF32(objectInfo.DiffuseColor[0]);                       // Diffuse Color - Red (9.8.4.4.1)
  MaterialResourceBlock.writeF32(objectInfo.DiffuseColor[1]);                       // Diffuse Color - Green (9.8.4.4.2)
  MaterialResourceBlock.writeF32(objectInfo.DiffuseColor[2]);                       // Diffuse Color - Blue (9.8.4.4.3)
  MaterialResourceBlock.writeF32(objectInfo.SpecularColor[0]);                      // Specular Color - Red (9.8.4.5.1)
  MaterialResourceBlock.writeF32(objectInfo.SpecularColor[1]);                      // Specular Color - Green (9.8.4.5.2)
  MaterialResourceBlock.writeF32(objectInfo.SpecularColor[2]);                      // Specular Color - Blue (9.8.4.5.3)
  MaterialResourceBlock.writeF32(objectInfo.EmissiveColor[0]);                      // Emissive Color - Red (9.8.4.6.1)
  MaterialResourceBlock.writeF32(objectInfo.EmissiveColor[1]);                      // Emissive Color - Green (9.8.4.6.2)
  MaterialResourceBlock.writeF32(objectInfo.EmissiveColor[2]);                      // Emissive Color - Blue (9.8.4.6     

  MaterialResourceBlock.writeF32(0.5f);                                             // Write Reflectivity (9.8.4.7)
  MaterialResourceBlock.writeF32(objectInfo.DiffuseColor[3]);                       // Write Opacity (9.8.4.8)

  return addDataBlock(MaterialResourceBlock);
}
//! Adds a given data block to the chain of all data blocks.
//! Allows to set block type.
//! Returns the total # of data blocks in the data block chain.
size_t U3DFileWriter::addDataBlock(U3DDataBlockWriter& dataBlock, const MLuint32 blockType)
{
    dataBlock.blockType = blockType;

    return addDataBlock(dataBlock);
}