/// <summary>
        /// Creates geometries for the relevant meshes that are to be included in the collada file
        /// </summary>
        void CreateGeometryList()
        {
            H2.Tags.render_model_group definition = tagManager.TagDefinition as H2.Tags.render_model_group;

            // create a list of shader names
            List <string> shader_names = new List <string>();

            foreach (var material in definition.Materials)
            {
                shader_names.Add(Path.GetFileNameWithoutExtension(material.Shader.ToString()));
            }

            // create a geometry element for each geometry in the modelInfo
            for (int i = 0; i < modelInfo.GetGeometryCount(); i++)
            {
                string name = ColladaUtilities.FormatName(modelInfo.GetGeometryName(i), " ", "_");

                var section = definition.Sections[modelInfo.GetGeometryIndex(i)];

                // create the geometry element
                CreateGeometryHalo2(name, true,
                                    section.SectionInfo,
                                    section.SectionData[0].Section,
                                    shader_names);
            }
        }
        /// <summary>
        /// Creates nodes for the models marker instances
        /// </summary>
        void CreateMarkerList()
        {
            H2.Tags.render_model_group definition = tagManager.TagDefinition as H2.Tags.render_model_group;

            List <Marker> marker_list = new List <Marker>();

            // create a list of generic marker definitions
            foreach (var marker in definition.MarkerGroups)
            {
                string marker_name = ColladaUtilities.FormatName(marker.Name.ToString(), " ", "_");
                foreach (var instance in marker.Markers)
                {
                    string name = marker_name;

                    // the permutation index is 255 it is valid for all permutations so add it regardless
                    if (instance.PermutationIndex.Value != 255)
                    {
                        // if exporting a single permutation and the instance permutation doesnt match, continue
                        // otherwise if we are exporting multiple permutations append the instances permutation index to its name
                        if (!modelInfo.GetIsMultiplePerms())
                        {
                            if (modelInfo.GetPermutation() != instance.PermutationIndex.Value)
                            {
                                continue;
                            }
                        }
                        else
                        {
                            name += "-perm" + instance.PermutationIndex.Value.ToString();
                        }
                    }

                    Marker common_marker = new Marker(name,
                                                      instance.Translation.ToPoint3D(100),
                                                      instance.Rotation.ToQuaternion(),
                                                      instance.NodeIndex);

                    marker_list.Add(common_marker);
                }
            }

            // create the marker node elements
            CreateMarkers(marker_list, RotationVectorY, RotationVectorP, RotationVectorR);
        }
        /// <summary>
        /// Creates a controller to skin each geometry in the file
        /// </summary>
        void CreateControllerList()
        {
            H2.Tags.render_model_group definition = tagManager.TagDefinition as H2.Tags.render_model_group;

            // if there are no bones then skinning isnt necessary
            if (definition.Nodes.Count == 0)
            {
                return;
            }

            // create a controller for each geometry in modelInfo
            for (int i = 0; i < modelInfo.GetGeometryCount(); i++)
            {
                H2.Tags.render_model_section_block.render_model_section_data_block section_block =
                    definition.Sections[modelInfo.GetGeometryIndex(i)].SectionData[0];

                // the node map contains a list of bone indices that the section is rigged to
                List <int> node_map = new List <int>();
                foreach (var node in section_block.NodeMap)
                {
                    node_map.Add(node.NodeIndex.Value);
                }

                List <VertexWeight> vertex_weights = new List <VertexWeight>();
                // create a generic list of vertex weights
                foreach (var vertex in section_block.Section.Value.RawVertices)
                {
                    VertexWeight common_weight = new VertexWeight();

                    // only add the weights with valid nodes
                    for (int weight_index = 0; (weight_index < vertex.Point.NodeIndex.Length) && (vertex.Point.NodeIndex[weight_index] != -1); weight_index++)
                    {
                        common_weight.AddWeight(node_map[vertex.Point.NodeIndex[weight_index]], vertex.Point.NodeWeight[weight_index]);
                    }

                    vertex_weights.Add(common_weight);
                }

                // create the controller element
                CreateSkinController(listGeometry[i].ID, vertex_weights);
            }
        }