예제 #1
0
        /// <summary>
        /// Busca el duplicado del vertice con texcoord u, si no existe lo crea y retorna el indice.
        /// </summary>
        /// <param name="vertices"></param>
        /// <param name="indices"></param>
        /// <param name="dDup"></param>
        /// <param name="idx"></param>
        /// <param name="u"></param>
        /// <returns></returns>
        protected static int dupWithU(List <Vertex.PositionColoredTexturedNormal> vertices, List <int> indices, Dictionary <int, int> dDup, int idx, float u)
        {
            int newIndx;

            if (!dDup.ContainsKey(indices[idx]))
            {
                Vertex.PositionColoredTexturedNormal newV = vertices[indices[idx]];
                newV.Tu = u;

                newIndx = vertices.Count;
                vertices.Add(newV);

                dDup.Add(indices[idx], newIndx);
            }
            else
            {
                newIndx = dDup[indices[idx]];
            }
            return(newIndx);
        }
예제 #2
0
        /// <summary>
        /// Duplica los vertices que deben tener coordenadas de textura diferentes para diferentes triangulos
        /// </summary>
        /// <param name="vertices"></param>
        /// <param name="indices"></param>
        /// <param name="iverticesU1"></param>
        /// <param name="polos"></param>
        protected virtual void fixTexcoords(List<Vertex.PositionColoredTexturedNormal> vertices, List<int> indices, List<int> iverticesU1, int[] polos)
        {

            Dictionary<int, int> duplicados = new Dictionary<int, int>();
            float U0p5 = 0.5f * UVTiling.X + UVOffset.X;
            float U1 = UVTiling.X + UVOffset.X;

            //Fix compartidos
            foreach (int idx in iverticesU1)
            {
                for (int i = 0; i < indices.Count; i += 3)
                {
                    //Triangulo que tiene ese vertice.
                    if (indices[i] == idx || indices[i + 1] == idx || indices[i + 2] == idx)
                    {
                        int i1 = indices[i];
                        int i2 = indices[i + 1];
                        int i3 = indices[i + 2];

                        //Solo me importan los que tienen un vertice con u=1(fin de la textura) y otro menor a 0.5 (comienzo de la textura)
                        if ((!esPolo(vertices[i1]) && vertices[i1].Tu < U0p5) || (!esPolo(vertices[i2]) && vertices[i2].Tu < U0p5) || (!esPolo(vertices[i3]) && vertices[i3].Tu < U0p5))
                        {

                            List<int> u1 = new List<int>();
                            List<int> um = new List<int>();


                            //Clasifico cada vertice segun su Tu1
                            for (int j = 0; j < 3; j++)
                                if (vertices[indices[i + j]].Tu == U1 || esPolo(vertices[indices[i + j]])) u1.Add(i + j);
                                else if (vertices[indices[i + j]].Tu < U0p5) um.Add(i + j);


                            if (um.Count == 1 && !(esPolo(vertices[indices[u1[0]]]) && vertices[indices[um[0]]].X >= 0))
                            {
                                //Casos:
                                //2 vertices con u=1 o uno con u=1 y otro con u>0.5
                                //1 vertice es el polo, y uno de los vertices esta al final de la textura y otro al principio

                                //La coordenada textura del de u >0.5 pasa a ser 1+u                        
                                indices[um[0]] = dupWithU(vertices, indices, duplicados, um[0], vertices[indices[um[0]]].Tu + UVTiling.X);


                            }
                            else if (!esPolo(vertices[indices[u1[0]]]))
                                // Caso:
                                // 1 vertice con u=1 y dos con u<0.5

                                // El u del vertice con u=1 pasa a ser 0
                                indices[u1[0]] = dupWithU(vertices, indices, duplicados, u1[0], UVOffset.X);


                        }


                    }
                }
            }




            //Fix polos

            for (int p = 0; p < 2; p++)
            {
                bool first = true;
                for (int i = 0; i < indices.Count; i += 3)//Por cada triangulo
                {
                    int iipolo = i;
                    for (; iipolo < i + 3 && indices[iipolo] != polos[p]; iipolo++) ;
                    //Si un vertice es el polo
                    if (iipolo < i + 3)
                    {

                        Vertex.PositionColoredTexturedNormal[] u = new Vertex.PositionColoredTexturedNormal[2];

                        int n = 0;
                        //Guardo los vertices que no son polos.
                        for (int j = 0; j < 3; j++) if (i + j != iipolo) u[n++] = vertices[indices[i + j]];

                        float minU = FastMath.Min(u[0].Tu, u[1].Tu);

                        Vertex.PositionColoredTexturedNormal pole = vertices[polos[p]];

                        //Chequea que no sea un triangulo rectangulo
                        Vertex.PositionColoredTexturedNormal zeroXZ = u[0];
                        bool noRectangulo = false;

                        if (u[0].X != 0 && u[0].Z != 0) zeroXZ = u[0];

                        else if (u[1].X != 0 && u[1].Z != 0) zeroXZ = u[1];

                        else noRectangulo = true;

                        //Interpolo Tu1
                        if (basePoly.Equals(eBasePoly.ICOSAHEDRON) || noRectangulo)

                            pole.Tu = minU + FastMath.Abs(u[0].Tu - u[1].Tu) / 2;

                        else
                            pole.Tu = zeroXZ.Tu;



                        if (first) //Si es la primera vez que lo hago, modifico el vertice.
                        {
                            vertices[polos[p]] = pole;

                            first = false;
                        }
                        else //Sino lo duplico.
                        {
                            indices[iipolo] = vertices.Count;
                            vertices.Add(pole);

                        }



                    }

                }

            }


        }
예제 #3
0
        /// <summary>
        /// Convierte el TgcSphere en un TgcMesh
        /// </summary>
        /// <param name="meshName">Nombre de la malla que se va a crear</param>
        public TgcMesh toMesh(string meshName)
        {
            Device d3dDevice = GuiController.Instance.D3dDevice;

            //Obtener matriz para transformar vertices
            if (autoTransformEnable)
            {
                this.transform = Matrix.Scaling(radius, radius, radius) * Matrix.Scaling(Scale) * Matrix.RotationYawPitchRoll(rotation.Y, rotation.X, rotation.Z) * Matrix.Translation(translation);
            }

            //Crear mesh con DiffuseMap
            if (texture != null)
            {
                //Crear Mesh
                Mesh d3dMesh = new Mesh(indices.Count / 3, indices.Count, MeshFlags.Managed, TgcSceneLoader.TgcSceneLoader.DiffuseMapVertexElements, d3dDevice);

                //Cargar VertexBuffer
                using (VertexBuffer vb = d3dMesh.VertexBuffer)
                {
                    GraphicsStream data = vb.Lock(0, 0, LockFlags.None);
                    for (int j = 0; j < indices.Count; j++)
                    {
                        TgcSceneLoader.TgcSceneLoader.DiffuseMapVertex v       = new TgcSceneLoader.TgcSceneLoader.DiffuseMapVertex();
                        Vertex.PositionColoredTexturedNormal           vSphere = vertices[indices[j]];

                        //vertices
                        v.Position = Vector3.TransformCoordinate(vSphere.getPosition(), this.transform);

                        //normals
                        v.Normal = vSphere.getNormal();

                        //texture coordinates diffuseMap
                        v.Tu = vSphere.Tu;
                        v.Tv = vSphere.Tv;

                        //color
                        v.Color = vSphere.Color;

                        data.Write(v);
                    }
                    vb.Unlock();
                }

                //Cargar IndexBuffer en forma plana
                using (IndexBuffer ib = d3dMesh.IndexBuffer)
                {
                    short[] vIndices = new short[indices.Count];
                    for (int j = 0; j < vIndices.Length; j++)
                    {
                        vIndices[j] = (short)j;
                    }
                    ib.SetData(vIndices, 0, LockFlags.None);
                }

                //Calcular normales
                //d3dMesh.ComputeNormals();

                //Malla de TGC
                TgcMesh tgcMesh = new TgcMesh(d3dMesh, meshName, TgcMesh.MeshRenderType.DIFFUSE_MAP);
                tgcMesh.DiffuseMaps = new TgcTexture[] { texture.clone() };
                tgcMesh.Materials   = new Material[] { TgcD3dDevice.DEFAULT_MATERIAL };
                tgcMesh.createBoundingBox();
                tgcMesh.Enabled = true;
                return(tgcMesh);
            }

            //Crear mesh con solo color
            else
            {
                //Crear Mesh
                Mesh d3dMesh = new Mesh(indices.Count / 3, indices.Count, MeshFlags.Managed, TgcSceneLoader.TgcSceneLoader.VertexColorVertexElements, d3dDevice);

                //Cargar VertexBuffer
                using (VertexBuffer vb = d3dMesh.VertexBuffer)
                {
                    GraphicsStream data = vb.Lock(0, 0, LockFlags.None);
                    for (int j = 0; j < indices.Count; j++)
                    {
                        TgcSceneLoader.TgcSceneLoader.VertexColorVertex v       = new TgcSceneLoader.TgcSceneLoader.VertexColorVertex();
                        Vertex.PositionColoredTexturedNormal            vSphere = vertices[indices[j]];

                        //vertices
                        v.Position = Vector3.TransformCoordinate(vSphere.getPosition(), this.transform);

                        //normals
                        v.Normal = vSphere.getNormal();

                        //color
                        v.Color = vSphere.Color;

                        data.Write(v);
                    }
                    vb.Unlock();
                }

                //Cargar IndexBuffer en forma plana
                using (IndexBuffer ib = d3dMesh.IndexBuffer)
                {
                    short[] vIndices = new short[indices.Count];
                    for (int j = 0; j < vIndices.Length; j++)
                    {
                        vIndices[j] = (short)j;
                    }
                    ib.SetData(vIndices, 0, LockFlags.None);
                }


                //Malla de TGC
                TgcMesh tgcMesh = new TgcMesh(d3dMesh, meshName, TgcMesh.MeshRenderType.VERTEX_COLOR);
                tgcMesh.Materials = new Material[] { TgcD3dDevice.DEFAULT_MATERIAL };
                tgcMesh.createBoundingBox();
                tgcMesh.Enabled = true;
                return(tgcMesh);
            }
        }
예제 #4
0
        /// <summary>
        /// Duplica los vertices que deben tener coordenadas de textura diferentes para diferentes triangulos
        /// </summary>
        /// <param name="vertices"></param>
        /// <param name="indices"></param>
        /// <param name="iverticesU1"></param>
        /// <param name="polos"></param>
        protected virtual void fixTexcoords(List <Vertex.PositionColoredTexturedNormal> vertices, List <int> indices, List <int> iverticesU1, int[] polos)
        {
            Dictionary <int, int> duplicados = new Dictionary <int, int>();
            float U0p5 = 0.5f * UVTiling.X + UVOffset.X;
            float U1   = UVTiling.X + UVOffset.X;

            //Fix compartidos
            foreach (int idx in iverticesU1)
            {
                for (int i = 0; i < indices.Count; i += 3)
                {
                    //Triangulo que tiene ese vertice.
                    if (indices[i] == idx || indices[i + 1] == idx || indices[i + 2] == idx)
                    {
                        int i1 = indices[i];
                        int i2 = indices[i + 1];
                        int i3 = indices[i + 2];

                        //Solo me importan los que tienen un vertice con u=1(fin de la textura) y otro menor a 0.5 (comienzo de la textura)
                        if ((!esPolo(vertices[i1]) && vertices[i1].Tu < U0p5) || (!esPolo(vertices[i2]) && vertices[i2].Tu < U0p5) || (!esPolo(vertices[i3]) && vertices[i3].Tu < U0p5))
                        {
                            List <int> u1 = new List <int>();
                            List <int> um = new List <int>();


                            //Clasifico cada vertice segun su Tu1
                            for (int j = 0; j < 3; j++)
                            {
                                if (vertices[indices[i + j]].Tu == U1 || esPolo(vertices[indices[i + j]]))
                                {
                                    u1.Add(i + j);
                                }
                                else if (vertices[indices[i + j]].Tu < U0p5)
                                {
                                    um.Add(i + j);
                                }
                            }


                            if (um.Count == 1 && !(esPolo(vertices[indices[u1[0]]]) && vertices[indices[um[0]]].X >= 0))
                            {
                                //Casos:
                                //2 vertices con u=1 o uno con u=1 y otro con u>0.5
                                //1 vertice es el polo, y uno de los vertices esta al final de la textura y otro al principio

                                //La coordenada textura del de u >0.5 pasa a ser 1+u
                                indices[um[0]] = dupWithU(vertices, indices, duplicados, um[0], vertices[indices[um[0]]].Tu + UVTiling.X);
                            }
                            else if (!esPolo(vertices[indices[u1[0]]]))
                            {
                                // Caso:
                                // 1 vertice con u=1 y dos con u<0.5

                                // El u del vertice con u=1 pasa a ser 0
                                indices[u1[0]] = dupWithU(vertices, indices, duplicados, u1[0], UVOffset.X);
                            }
                        }
                    }
                }
            }



            //Fix polos

            for (int p = 0; p < 2; p++)
            {
                bool first = true;
                for (int i = 0; i < indices.Count; i += 3)//Por cada triangulo
                {
                    int iipolo = i;
                    for (; iipolo < i + 3 && indices[iipolo] != polos[p]; iipolo++)
                    {
                        ;
                    }
                    //Si un vertice es el polo
                    if (iipolo < i + 3)
                    {
                        Vertex.PositionColoredTexturedNormal[] u = new Vertex.PositionColoredTexturedNormal[2];

                        int n = 0;
                        //Guardo los vertices que no son polos.
                        for (int j = 0; j < 3; j++)
                        {
                            if (i + j != iipolo)
                            {
                                u[n++] = vertices[indices[i + j]];
                            }
                        }

                        float minU = FastMath.Min(u[0].Tu, u[1].Tu);

                        Vertex.PositionColoredTexturedNormal pole = vertices[polos[p]];

                        //Chequea que no sea un triangulo rectangulo
                        Vertex.PositionColoredTexturedNormal zeroXZ = u[0];
                        bool noRectangulo = false;

                        if (u[0].X != 0 && u[0].Z != 0)
                        {
                            zeroXZ = u[0];
                        }

                        else if (u[1].X != 0 && u[1].Z != 0)
                        {
                            zeroXZ = u[1];
                        }

                        else
                        {
                            noRectangulo = true;
                        }

                        //Interpolo Tu1
                        if (basePoly.Equals(eBasePoly.ICOSAHEDRON) || noRectangulo)
                        {
                            pole.Tu = minU + FastMath.Abs(u[0].Tu - u[1].Tu) / 2;
                        }

                        else
                        {
                            pole.Tu = zeroXZ.Tu;
                        }



                        if (first) //Si es la primera vez que lo hago, modifico el vertice.
                        {
                            vertices[polos[p]] = pole;

                            first = false;
                        }
                        else //Sino lo duplico.
                        {
                            indices[iipolo] = vertices.Count;
                            vertices.Add(pole);
                        }
                    }
                }
            }
        }
예제 #5
0
 protected bool esPolo(Vertex.PositionColoredTexturedNormal v)
 {
     return(v.X == 0 && v.Z == 0);
 }