/// <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) { var duplicados = new Dictionary <int, int>(); var U0p5 = 0.5f * UVTiling.X + UVOffset.X; var U1 = UVTiling.X + UVOffset.X; //Fix compartidos foreach (var idx in iverticesU1) { for (var i = 0; i < indices.Count; i += 3) { //Triangulo que tiene ese vertice. if (indices[i] == idx || indices[i + 1] == idx || indices[i + 2] == idx) { var i1 = indices[i]; var i2 = indices[i + 1]; var 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)) { var u1 = new List <int>(); var um = new List <int>(); //Clasifico cada vertice segun su Tu1 for (var 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 (var p = 0; p < 2; p++) { var first = true; for (var i = 0; i < indices.Count; i += 3) //Por cada triangulo { var iipolo = i; for (; iipolo < i + 3 && indices[iipolo] != polos[p]; iipolo++) { ; } //Si un vertice es el polo if (iipolo < i + 3) { var u = new Vertex.PositionColoredTexturedNormal[2]; var n = 0; //Guardo los vertices que no son polos. for (var j = 0; j < 3; j++) { if (i + j != iipolo) { u[n++] = vertices[indices[i + j]]; } } var minU = FastMath.Min(u[0].Tu, u[1].Tu); var pole = vertices[polos[p]]; //Chequea que no sea un triangulo rectangulo var zeroXZ = u[0]; var 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); } } } } }
protected bool esPolo(Vertex.PositionColoredTexturedNormal v) { return(v.X == 0 && v.Z == 0); }