void create_model_indices(LaserDataSceneNode node, ushort sides, ushort slices)
        {
            // crear los indices
            MeshBuffer mbuffer = node.get_mesh_buffer();

            //uint ind_count =(uint)( (slices - 1) * (sides - 1) * 12);
            uint ind_count = (uint)((slices - 1) * (sides - 1) * 6);

            mbuffer.AllocateIndices(ind_count);


            m_buffer_index = 0;
            for (ushort i = 0; i < slices - 1; i++)
            {
                for (ushort j = 0; j < sides - 1; j++)
                {
                    //first triangle
                    mbuffer.SetIndex(m_buffer_index, (ushort)((i + 1) * sides + j));
                    m_buffer_index++;
                    mbuffer.SetIndex(m_buffer_index, (ushort)(i * sides + j));
                    m_buffer_index++;
                    mbuffer.SetIndex(m_buffer_index, (ushort)((i + 1) * sides + j + 1));
                    m_buffer_index++;
                    //second triangle
                    mbuffer.SetIndex(m_buffer_index, (ushort)((i + 1) * sides + j + 1));
                    m_buffer_index++;
                    mbuffer.SetIndex(m_buffer_index, (ushort)(i * sides + j));
                    m_buffer_index++;
                    mbuffer.SetIndex(m_buffer_index, (ushort)(i * sides + j + 1));
                    m_buffer_index++;

                    /*
                     * //third triangle
                     * mbuffer.SetIndex(m_buffer_index, (ushort)((i + 1) * sides + j));
                     * m_buffer_index++;
                     * mbuffer.SetIndex(m_buffer_index, (ushort)(i * sides + j));
                     * m_buffer_index++;
                     * mbuffer.SetIndex(m_buffer_index, (ushort)((i + 1) * sides + j + 1));
                     * m_buffer_index++;
                     *
                     * //fourth triangle
                     * mbuffer.SetIndex(m_buffer_index, (ushort)((i + 1) * sides + j + 1));
                     * m_buffer_index++;
                     * mbuffer.SetIndex(m_buffer_index, (ushort)(i * sides + j));
                     * m_buffer_index++;
                     * mbuffer.SetIndex(m_buffer_index, (ushort)(i * sides + j + 1));
                     * m_buffer_index++;*/
                }
            }
        }
        public bool init_scene()
        {
            _scene.AddCameraSceneNode(null);

            _scene.ActiveCamera.Position = new Vector3D(0, -15, 0);
            _scene.ActiveCamera.Target   = new Vector3D();

            _scene.AddLightSceneNode(null, new Vector3D(20, -15, 3), new Colorf(1.0f, 1.0f, 1.0f, 1.0f), 100.0f, -1);

            _scene.AddLightSceneNode(null, new Vector3D(-20, -15, -4), new Colorf(1.0f, 1.0f, 1.0f, 1.0f), 100.0f, -1);

            _model3D = new LaserDataSceneNode(null, _scene, 666);

            return(true);
        }
        /// <summary>
        /// Convierte los datos almacenados en un Objeto 3D. Se toma en cuenta el
        /// tipo de barrido (angular o linear vertical).
        /// </summary>
        /// <param name="node">El nodo Irrlicht donde se representarán los datos</param>
        public void export_to_model(LaserDataSceneNode node)
        {
            if (node.has_vertices() == false)
            {
                node.create_mesh();
            }


            if (m_vertical_sampler_angular)
            {
                export_to_model_angular(node);
            }
            else
            {
                export_to_model_linear(node);
            }


            node._mgr.MeshManipulator.RecalculateNormals(node._mesh, true);
        }
        private void export_to_model_angular(LaserDataSceneNode node)
        {
            float min_angle     = m_current_laser_buffer.get_min_angle();
            float ang_increment = m_current_laser_buffer.get_resolution() * m_mesh_resolution;


            uint num_h_samples = m_current_laser_buffer.get_distance_count();

            uint horizontal_count = num_h_samples / m_mesh_resolution;


            float vertical_increment = (m_vertical_sampler_max - m_vertical_sampler_min) / m_vertical_sampler_count;


            ushort sides  = (ushort)horizontal_count;
            ushort slices = (ushort)m_vertical_sampler_count;

            // crear los vertices

            MeshBuffer mbuffer = node.get_mesh_buffer();

            uint vert_count = (uint)(sides * slices);

            mbuffer.AllocateVertices(vert_count);


            m_buffer_index = 0;
            float vertical_value = m_vertical_sampler_min;
            float angular_value  = min_angle;

            for (ushort i = 0; i < slices; i++)
            {
                angular_value = min_angle;
                for (ushort j = 0; j < sides; j++)
                {
                    float    distance = m_laser_distances[num_h_samples * i + j * m_mesh_resolution];
                    Vector3D pivot    = new Vector3D();
                    Vector3D normal   = new Vector3D();

                    normal.Z = -(float)Math.Cos(deg_to_rad((double)angular_value));
                    normal.Y = -(float)Math.Sin(deg_to_rad((double)angular_value));
                    normal.X = 0;
                    normal.RotateXYBy(vertical_value, new Vector3D());

                    //normal.X = (float)Math.Sin(deg_to_rad((double)vertical_value)); ;

                    pivot.Z = normal.Z * distance;
                    pivot.Y = normal.Y * distance;
                    pivot.X = normal.X * distance;


                    Vertex3D newvertex = new Vertex3D();

                    newvertex.Position = pivot;
                    newvertex.Normal   = normal;
                    newvertex.Color    = new Color(255, 255, 0, 100);
                    newvertex.TCoords  = new Vector2D(1, 1);

                    mbuffer.SetVertex(m_buffer_index, newvertex);
                    m_buffer_index++;

                    angular_value += ang_increment;
                }

                vertical_value += vertical_increment;
            }

            create_model_indices(node, sides, slices);
        }
        public bool init_scene()
        {
            _scene.AddCameraSceneNode(null);

            _scene.ActiveCamera.Position = new Vector3D(0, -15, 0);
            _scene.ActiveCamera.Target = new Vector3D();

            _scene.AddLightSceneNode(null, new Vector3D(20, -15, 3), new Colorf(1.0f, 1.0f, 1.0f, 1.0f), 100.0f, -1);

            _scene.AddLightSceneNode(null, new Vector3D(-20, -15, -4), new Colorf(1.0f, 1.0f, 1.0f, 1.0f), 100.0f, -1);

            _model3D = new LaserDataSceneNode(null, _scene, 666);

            return true;
        }
        private void export_to_model_linear(LaserDataSceneNode node)
        {
            float min_angle = m_current_laser_buffer.get_min_angle();
            float ang_increment = m_current_laser_buffer.get_resolution() * m_mesh_resolution;

            uint num_h_samples = m_current_laser_buffer.get_distance_count();

            uint horizontal_count = num_h_samples / m_mesh_resolution;

            float vertical_increment = m_vertical_scale * (m_vertical_sampler_max - m_vertical_sampler_min) / m_vertical_sampler_count;

            ushort sides = (ushort)horizontal_count;
            ushort slices = (ushort)m_vertical_sampler_count;

            // crear los vertices
            MeshBuffer mbuffer = node.get_mesh_buffer();

            uint vert_count = (uint)(sides * slices);

            mbuffer.AllocateVertices(vert_count);

            m_buffer_index = 0;
            float vertical_value = m_vertical_sampler_min * m_vertical_scale;
            float angular_value = min_angle;

            for (ushort i = 0; i < slices; i++)
            {
                angular_value = min_angle;
                for (ushort j = 0; j < sides; j++)
                {
                    float distance = m_laser_distances[num_h_samples*i + j*m_mesh_resolution];
                    Vector3D pivot = new Vector3D();
                    Vector3D normal = new Vector3D();
                    normal.Z = -(float)Math.Cos(deg_to_rad((double)angular_value));
                    normal.Y = -(float)Math.Sin(deg_to_rad((double)angular_value));
                    normal.X = 0;

                    pivot.Z = normal.Z * distance;
                    pivot.Y = normal.Y * distance;
                    pivot.X = vertical_value;

                    Vertex3D newvertex =  new Vertex3D();

                    newvertex.Position = pivot;
                    newvertex.Normal = normal;
                    newvertex.Color = new Color(255, 0, 0, 150);
                    newvertex.TCoords = new Vector2D(1, 1);

                    mbuffer.SetVertex(m_buffer_index, newvertex);
                    m_buffer_index++;

                    angular_value += ang_increment;

                }

                vertical_value += vertical_increment;
            }

            create_model_indices(node, sides, slices);
        }
        void create_model_indices(LaserDataSceneNode node, ushort sides, ushort slices)
        {
            // crear los indices
            MeshBuffer mbuffer = node.get_mesh_buffer();

            //uint ind_count =(uint)( (slices - 1) * (sides - 1) * 12);
            uint ind_count = (uint)((slices - 1) * (sides - 1) * 6);

            mbuffer.AllocateIndices(ind_count);

            m_buffer_index = 0;
            for (ushort i = 0; i < slices - 1; i++)
            {
                for (ushort j = 0; j < sides - 1; j++)
                {
                    //first triangle
                    mbuffer.SetIndex(m_buffer_index, (ushort)((i + 1) * sides + j));
                    m_buffer_index++;
                    mbuffer.SetIndex(m_buffer_index, (ushort)(i * sides + j));
                    m_buffer_index++;
                    mbuffer.SetIndex(m_buffer_index,(ushort)((i + 1) * sides + j + 1));
                    m_buffer_index++;
                    //second triangle
                    mbuffer.SetIndex(m_buffer_index, (ushort)((i + 1) * sides + j + 1));
                    m_buffer_index++;
                    mbuffer.SetIndex(m_buffer_index, (ushort)(i * sides + j));
                    m_buffer_index++;
                    mbuffer.SetIndex(m_buffer_index, (ushort)(i * sides + j + 1));
                    m_buffer_index++;

                    /*
                    //third triangle
                    mbuffer.SetIndex(m_buffer_index, (ushort)((i + 1) * sides + j));
                    m_buffer_index++;
                    mbuffer.SetIndex(m_buffer_index, (ushort)(i * sides + j));
                    m_buffer_index++;
                    mbuffer.SetIndex(m_buffer_index, (ushort)((i + 1) * sides + j + 1));
                    m_buffer_index++;

                    //fourth triangle
                    mbuffer.SetIndex(m_buffer_index, (ushort)((i + 1) * sides + j + 1));
                    m_buffer_index++;
                    mbuffer.SetIndex(m_buffer_index, (ushort)(i * sides + j));
                    m_buffer_index++;
                    mbuffer.SetIndex(m_buffer_index, (ushort)(i * sides + j + 1));
                    m_buffer_index++;*/
                }
            }
        }
        /// <summary>
        /// Convierte los datos almacenados en un Objeto 3D. Se toma en cuenta el 
        /// tipo de barrido (angular o linear vertical).
        /// </summary>
        /// <param name="node">El nodo Irrlicht donde se representarán los datos</param>
        public void export_to_model(LaserDataSceneNode node)
        {
            if (node.has_vertices() == false)
            {
                node.create_mesh();
            }

            if (m_vertical_sampler_angular)
            {
                export_to_model_angular(node);
            }
            else
            {
                export_to_model_linear(node);
            }

            node._mgr.MeshManipulator.RecalculateNormals(node._mesh, true);
        }