/// <summary>
        /// Crear vertices para la cara Up
        /// </summary>
        private void cargarVerticesUp(GraphicsStream data, int color)
        {
            TgcSceneLoader.DiffuseMapVertex v;
            Vector3 n = new Vector3(0, 1, 0);

            v = new TgcSceneLoader.DiffuseMapVertex();
            v.Position = new Vector3(
                center.X - size.X / 2 - skyEpsilon,
                center.Y + size.Y / 2,
                center.Z - size.Z / 2 - skyEpsilon
                );
            v.Normal = n;
            v.Color = color;
            v.Tu = 1;
            v.Tv = 0;
            data.Write(v);

            v = new TgcSceneLoader.DiffuseMapVertex();
            v.Position = new Vector3(
                center.X - size.X / 2 - skyEpsilon,
                center.Y + size.Y / 2,
                center.Z + size.Z / 2 + skyEpsilon
                );
            v.Normal = n;
            v.Color = color;
            v.Tu = 0;
            v.Tv = 0;
            data.Write(v);

            v = new TgcSceneLoader.DiffuseMapVertex();
            v.Position = new Vector3(
                center.X + size.X / 2 + skyEpsilon,
                center.Y + size.Y / 2,
                center.Z + size.Z / 2 + skyEpsilon
                );
            v.Normal = n;
            v.Color = color;
            v.Tu = 0;
            v.Tv = 1;
            data.Write(v);

            v = new TgcSceneLoader.DiffuseMapVertex();
            v.Position = new Vector3(
                center.X + size.X / 2 + skyEpsilon,
                center.Y + size.Y / 2,
                center.Z - size.Z / 2 - skyEpsilon
                );
            v.Normal = n;
            v.Color = color;
            v.Tu = 1;
            v.Tv = 1;
            data.Write(v);
        }
        /// <summary>
        /// Une dos meshes en uno solo.
        /// Crea un nuevo mesh con un merge de los dos. Toma el nombre, layer, userProperties, etc del primer mesh.
        /// No se hace dispose de los dos meshes originales.
        /// Ambos mesh tienen que ser del mismo RenderType.
        /// No se puede hacer merge de un mesh con Lightmap
        /// </summary>
        /// <param name="mesh1">Primer mesh</param>
        /// <param name="mesh2">Segundo mesh</param>
        /// <returns>Nueve mesh con el merge de los dos</returns>
        public TgcMesh mergeTwoMeshes(TgcMesh mesh1, TgcMesh mesh2)
        {
            //Chequear que sea mismo tipo de malla
            if (mesh1.RenderType != mesh2.RenderType)
            {
                throw new Exception("Se intentó juntar dos Mallas de formato distintos: " + mesh1.Name + " y " + mesh2.Name);
            }

            //Por ahora no se pueden unificar LightMaps
            if (mesh1.RenderType == TgcMesh.MeshRenderType.DIFFUSE_MAP_AND_LIGHTMAP)
            {
                throw new Exception("Actualmente no esta soportado juntar dos Mallas que tienen LightMaps: " + mesh1.Name + " y " + mesh2.Name);
            }

            //Crear Mesh de D3D
            int triCount = mesh1.NumberTriangles + mesh2.NumberTriangles;
            int vertexCount = mesh1.NumberVertices + mesh2.NumberVertices;
            VertexElement[] vertexElements = mesh1.RenderType == TgcMesh.MeshRenderType.VERTEX_COLOR ? TgcSceneLoader.VertexColorVertexElements : TgcSceneLoader.DiffuseMapVertexElements;
            Mesh mesh = new Mesh(triCount, vertexCount, MeshFlags.Managed, vertexElements, GuiController.Instance.D3dDevice);

            //VertexColor
            if (mesh1.RenderType == TgcMesh.MeshRenderType.VERTEX_COLOR)
            {
                //Cargar VertexBuffer
                TgcSceneLoader.VertexColorVertex[] vertsData = new TgcSceneLoader.VertexColorVertex[vertexCount];
                //Agregar los datos del mesh1
                TgcSceneLoader.VertexColorVertex[] verts1 = (TgcSceneLoader.VertexColorVertex[])mesh1.D3dMesh.LockVertexBuffer(
                    typeof(TgcSceneLoader.VertexColorVertex), LockFlags.ReadOnly, mesh1.D3dMesh.NumberVertices);
                for (int i = 0; i < verts1.Length; i++)
                {
                    verts1[i].Position = TgcVectorUtils.transform(verts1[i].Position, mesh1.Transform);
                }
                Array.Copy(verts1, vertsData, verts1.Length);
                mesh1.D3dMesh.UnlockVertexBuffer();
                verts1 = null;

                //Agregar los datos del mesh1
                TgcSceneLoader.VertexColorVertex[] verts2 = (TgcSceneLoader.VertexColorVertex[])mesh2.D3dMesh.LockVertexBuffer(
                    typeof(TgcSceneLoader.VertexColorVertex), LockFlags.ReadOnly, mesh2.D3dMesh.NumberVertices);
                for (int i = 0; i < verts2.Length; i++)
                {
                    verts2[i].Position = TgcVectorUtils.transform(verts2[i].Position, mesh2.Transform);
                }
                Array.Copy(verts2, 0, vertsData, mesh1.NumberVertices, verts2.Length);
                mesh2.D3dMesh.UnlockVertexBuffer();
                verts2 = null;

                mesh.SetVertexBufferData(vertsData, LockFlags.None);
            }
            //DiffuseMap
            else if (mesh1.RenderType == TgcMesh.MeshRenderType.DIFFUSE_MAP)
            {
                //Cargar VertexBuffer
                TgcSceneLoader.DiffuseMapVertex[] vertsData = new TgcSceneLoader.DiffuseMapVertex[vertexCount];

                //Agregar los datos del mesh1 (aplicarle la transformacion actual)
                TgcSceneLoader.DiffuseMapVertex[] verts1 = (TgcSceneLoader.DiffuseMapVertex[])mesh1.D3dMesh.LockVertexBuffer(
                    typeof(TgcSceneLoader.DiffuseMapVertex), LockFlags.ReadOnly, mesh1.D3dMesh.NumberVertices);
                for (int i = 0; i < verts1.Length; i++)
                {
                    verts1[i].Position = TgcVectorUtils.transform(verts1[i].Position, mesh1.Transform);
                }
                Array.Copy(verts1, vertsData, verts1.Length);
                mesh1.D3dMesh.UnlockVertexBuffer();
                verts1 = null;

                //Agregar los datos del mesh1
                TgcSceneLoader.DiffuseMapVertex[] verts2 = (TgcSceneLoader.DiffuseMapVertex[])mesh2.D3dMesh.LockVertexBuffer(
                    typeof(TgcSceneLoader.DiffuseMapVertex), LockFlags.ReadOnly, mesh2.D3dMesh.NumberVertices);
                for (int i = 0; i < verts2.Length; i++)
                {
                    verts2[i].Position = TgcVectorUtils.transform(verts2[i].Position, mesh2.Transform);
                }
                Array.Copy(verts2, 0, vertsData, mesh1.NumberVertices, verts2.Length);
                mesh2.D3dMesh.UnlockVertexBuffer();
                verts2 = null;

                mesh.SetVertexBufferData(vertsData, LockFlags.None);
            }

            //Cargar indexBuffer en forma plana
            using (IndexBuffer ib = mesh.IndexBuffer)
            {
                short[] indices = new short[vertexCount];
                for (int i = 0; i < indices.Length; i++)
                {
                    indices[i] = (short)i;
                }
                ib.SetData(indices, 0, LockFlags.None);
            }

            //Cargar texturas y attributeBuffer
            TgcTexture[] textures = null;
            Material[] materials = null;
            if (mesh1.RenderType == TgcMesh.MeshRenderType.DIFFUSE_MAP)
            {
                //Cargar materials
                materials = new Material[mesh1.DiffuseMaps.Length + mesh2.DiffuseMaps.Length];
                int mIdx = 0;
                foreach (Material m in mesh1.Materials)
                {
                    materials[mIdx++] = m;
                }
                foreach (Material m in mesh2.Materials)
                {
                    materials[mIdx++] = m;
                }

                //Texturas del mesh1
                textures = new TgcTexture[mesh1.DiffuseMaps.Length + mesh2.DiffuseMaps.Length];
                int tIdx = 0;
                foreach (TgcTexture t in mesh1.DiffuseMaps)
                {
                    textures[tIdx++] = t.clone();
                }
                //Texturas del mesh2
                foreach (TgcTexture t in mesh2.DiffuseMaps)
                {
                    textures[tIdx++] = t.clone();
                }

                //Cargar el AttributeBuffer con la suma de ambos mesh
                int attIdx = 0;
                int textureId = 0;
                int[] attributeBuffer = mesh.LockAttributeBufferArray(LockFlags.None);

                //AttributeBuffer del mesh 1
                if (mesh1.DiffuseMaps.Length > 1)
                {
                    //Copiar el AttributeBuffer del mesh1 tal cual al mesh unificado
                    int[] attributeBuffer1 = mesh1.D3dMesh.LockAttributeBufferArray(LockFlags.ReadOnly);
                    Array.Copy(attributeBuffer1, attributeBuffer, attributeBuffer1.Length);
                    mesh1.D3dMesh.UnlockAttributeBuffer(attributeBuffer1);
                }
                else
                {
                    //Hay una sola textura, llenar el AttributeBuffer para que apunte solo a esa textura
                    for (int i = 0; i < mesh1.NumberTriangles; i++)
                    {
                        attributeBuffer[i] = textureId;
                    }
                }
                attIdx += mesh1.NumberTriangles;
                textureId += mesh1.DiffuseMaps.Length;

                //AttributeBuffer del mesh 2
                if (mesh2.DiffuseMaps.Length > 1)
                {
                    //Copiar el AttributeBuffer del mesh2 al mesh unificado pero sumando el offset de texturas del primero
                    int[] attributeBuffer2 = mesh2.D3dMesh.LockAttributeBufferArray(LockFlags.ReadOnly);
                    int[] attributeBuffer2Offset = new int[attributeBuffer2.Length];
                    for (int i = 0; i < attributeBuffer2.Length; i++)
                    {
                        attributeBuffer2Offset[i] = attributeBuffer2[i] + textureId;
                    }
                    mesh2.D3dMesh.UnlockAttributeBuffer(attributeBuffer2);
                    Array.Copy(attributeBuffer2Offset, 0, attributeBuffer, attIdx, attributeBuffer2Offset.Length);
                    attributeBuffer2Offset = null;
                }
                else
                {
                    //Hay una sola textura, llenar el AttributeBuffer para que apunte solo a esa textura
                    for (int i = 0; i < mesh2.NumberTriangles; i++)
                    {
                        attributeBuffer[attIdx++] = textureId;
                    }
                    textureId++;
                }

                mesh.UnlockAttributeBuffer(attributeBuffer);
            }

            //Crear mesh de TGC
            TgcMesh tgcMesh = new TgcMesh(mesh, mesh1.Name, mesh1.RenderType);
            tgcMesh.Layer = mesh1.Layer;
            tgcMesh.createBoundingBox();
            tgcMesh.Materials = materials;
            tgcMesh.DiffuseMaps = textures;
            tgcMesh.AlphaBlendEnable = mesh1.AlphaBlendEnable;
            tgcMesh.Enabled = mesh1.Enabled;

            //Transformaciones con la identidad (porque ya transformamos los vertices)
            tgcMesh.Position = new Vector3(0, 0, 0);
            tgcMesh.Rotation = new Vector3(0, 0, 0);
            tgcMesh.Scale = new Vector3(1, 1, 1);
            tgcMesh.Transform = Matrix.Identity;
            tgcMesh.AutoTransformEnable = mesh1.AutoTransformEnable;

            //Agregar userProperties de ambos
            if (mesh1.UserProperties != null || mesh2.UserProperties != null)
            {
                tgcMesh.UserProperties = new Dictionary<string, string>();
                if (mesh1.UserProperties != null)
                {
                    foreach (KeyValuePair<string, string> entry in mesh1.UserProperties)
                    {
                        tgcMesh.UserProperties.Add(entry.Key, entry.Value);
                    }
                }
                if (mesh2.UserProperties != null)
                {
                    foreach (KeyValuePair<string, string> entry in mesh2.UserProperties)
                    {
                        tgcMesh.UserProperties.Add(entry.Key, entry.Value);
                    }
                }
            }

            return tgcMesh;
        }