protected override SceneryTriangleNode Read(ContentReader input, SceneryTriangleNode existingInstance) { //Triángulos Triangle[] triangles = input.ReadObject <Triangle[]>(); //Indices int indexKeyCount = input.ReadInt32(); Dictionary <LOD, SceneryNodeIndexInfo> indexesInfo = new Dictionary <LOD, SceneryNodeIndexInfo>(); for (int k = 0; k < indexKeyCount; k++) { LOD key = (LOD)input.ReadInt32(); SceneryNodeIndexInfo indexInfo = input.ReadObject <SceneryNodeIndexInfo>(); indexesInfo.Add(key, indexInfo); } return(new SceneryTriangleNode(triangles, indexesInfo)); }
/// <summary> /// Construye la información de nodos del terreno /// </summary> /// <param name="vertList">Lista de vértices</param> /// <param name="width">Anchura del terreno</param> /// <param name="deep">Profundidad del terreno</param> /// <param name="levels">Niveles distintos de detalle</param> /// <returns>Devuelve la información de nodos del terreno</returns> public static SceneryNodeInfo Build( VertexMultitextured[] vertList, int width, int deep, int levels) { // Lista resultante de nodos List <SceneryTriangleNode> nodes = new List <SceneryTriangleNode>(); // Diccionario de índices Dictionary <LOD, IndexCollection> indices = new Dictionary <LOD, IndexCollection>(); IndexCollection highIndices = new IndexCollection(); IndexCollection mediumIndices = new IndexCollection(); IndexCollection lowIndices = new IndexCollection(); // Tamaño de la cuadrícula int totalCellsX = width; int totalCellsZ = deep; // Número de divisiones int divisions = Convert.ToInt32(Math.Pow(4, levels)); int divisionsX = divisions / 2; int divisionsZ = divisions / 2; // Número de vértices en X y en Z int numVertexesX = (totalCellsX / divisionsX); int numVertexesZ = (totalCellsZ / divisionsZ); // Número total de vértices, triángulos e índices int totalVertices = totalCellsX * totalCellsZ; int totalTriangles = (totalCellsX - 1) * (totalCellsZ - 1) * 2; int totalIndices = totalTriangles * 3; for (int x = 0; x < divisionsX; x++) { int offsetX = x * numVertexesX; int cellsX = numVertexesX; for (int z = 0; z < divisionsZ; z++) { int offsetZ = z * numVertexesZ; int cellsZ = numVertexesZ; // Crear índices para generar la lista de triángulos de colisión int[] collisionIndices = SceneryNodeInfo.CreateCollisionIndices( offsetX, offsetZ, cellsX, cellsZ, totalCellsX, totalCellsZ); // Crear la lista de triángulos Triangle[] quadTriangles = SceneryNodeInfo.BuildPrimitiveList(vertList, collisionIndices); // Crear los índices para alta resolución SceneryNodeIndexInfo quadHighInfo = null; Int32[] quadHighIndices = Build( LOD.High, highIndices.Count, offsetX, offsetZ, cellsX, cellsZ, totalCellsX, totalCellsZ, out quadHighInfo); // Crear los índices para media resolución SceneryNodeIndexInfo quadMediumInfo = null; Int32[] quadMediumIndices = Build( LOD.Medium, mediumIndices.Count, offsetX, offsetZ, cellsX, cellsZ, totalCellsX, totalCellsZ, out quadMediumInfo); // Crear los índices para baja resolución SceneryNodeIndexInfo quadLowInfo = null; Int32[] quadLowIndices = Build( LOD.Low, lowIndices.Count, offsetX, offsetZ, cellsX, cellsZ, totalCellsX, totalCellsZ, out quadLowInfo); // Añadir los índices a la colección de índices para cada resolución highIndices.AddRange(quadHighIndices); mediumIndices.AddRange(quadMediumIndices); lowIndices.AddRange(quadLowIndices); Dictionary <LOD, SceneryNodeIndexInfo> info = new Dictionary <LOD, SceneryNodeIndexInfo>(); info.Add(LOD.High, quadHighInfo); info.Add(LOD.Medium, quadMediumInfo); info.Add(LOD.Low, quadLowInfo); // Crear el nodo con los triángulos para la colisión, los índices de inicio y el número de triángulos para cada resolución SceneryTriangleNode newQuadNode = new SceneryTriangleNode(quadTriangles, info); nodes.Add(newQuadNode); } } // Crear el diccionario de buffers de índices para cada resolución indices = new Dictionary <LOD, IndexCollection>(); indices.Add(LOD.High, highIndices); indices.Add(LOD.Medium, mediumIndices); indices.Add(LOD.Low, lowIndices); // Devolver la información de nodos del escenario return(new SceneryNodeInfo() { Nodes = nodes.ToArray(), Indices = indices, }); }
/// <summary> /// Construye los índices del nivel de detalle especificado, dentro de los límites del nodo /// </summary> /// <param name="lodType">Nivel de detalle</param> /// <param name="indexOffset">Posición del primer índice a generar, informado desde la colección global de índices</param> /// <param name="offsetX">Coordenada X</param> /// <param name="offsetZ">Coordenada Z</param> /// <param name="cellsX">Número de celdas del nodo en X</param> /// <param name="cellsZ">Número de celdas del nodo en Y</param> /// <param name="totalCellsX">Número total de celdas en X</param> /// <param name="totalCellsZ">Número total de celdas en Z</param> /// <param name="info">Devuelve la información de los índices del nodo</param> /// <returns>Devuelve la colección de índices del nodo</returns> /// <remarks>La colección contiene los nodos centrales, los cuatro bordes normales y los cuatro bordes para conectar con niveles de detalle menores</remarks> private static Int32[] Build( LOD lodType, int indexOffset, int offsetX, int offsetZ, int cellsX, int cellsZ, int totalCellsX, int totalCellsZ, out SceneryNodeIndexInfo info) { info = new SceneryNodeIndexInfo(); int level = (int)lodType; List <Int32> indices = new List <Int32>(); if (lodType == LOD.Low) { Int32[] allIndices = CreateAllQuadIndices(level, offsetX, offsetZ, cellsX, cellsZ, totalCellsX, totalCellsZ); indices.AddRange(allIndices); info.CenterPrimitiveCount = allIndices.Length / 3; info.BorderPrimitiveCount = 0; info.BorderConnectionPrimitiveCount = 0; info.CenterOffset = indexOffset; info.WestOffset = 0; info.EastOffset = 0; info.NorthOffset = 0; info.SouthOffset = 0; info.WestConnectionOffset = 0; info.EastConnectionOffset = 0; info.NorthConnectionOffset = 0; info.SouthConnectionOffset = 0; } else { Int32[] centralIndices = CreateCentralQuadIndices(level, offsetX, offsetZ, cellsX, cellsZ, totalCellsX, totalCellsZ); Int32[] northQuadIndices = CreateNorthQuadIndices(level, offsetX, offsetZ, cellsX, cellsZ, totalCellsX, totalCellsZ); Int32[] southQuadIndices = CreateSouthQuadIndices(level, offsetX, offsetZ, cellsX, cellsZ, totalCellsX, totalCellsZ); Int32[] eastQuadIndices = CreateEastQuadIndices(level, offsetX, offsetZ, cellsX, cellsZ, totalCellsX, totalCellsZ); Int32[] westQuadIndices = CreateWestQuadIndices(level, offsetX, offsetZ, cellsX, cellsZ, totalCellsX, totalCellsZ); Int32[] northConnectionQuadIndices = CreateConnectionNorthQuadIndices(level, offsetX, offsetZ, cellsX, cellsZ, totalCellsX, totalCellsZ); Int32[] southConnectionQuadIndices = CreateConnectionSouthQuadIndices(level, offsetX, offsetZ, cellsX, cellsZ, totalCellsX, totalCellsZ); Int32[] eastConnectionQuadIndices = CreateConnectionEastQuadIndices(level, offsetX, offsetZ, cellsX, cellsZ, totalCellsX, totalCellsZ); Int32[] westConnectionQuadIndices = CreateConnectionWestQuadIndices(level, offsetX, offsetZ, cellsX, cellsZ, totalCellsX, totalCellsZ); indices.AddRange(centralIndices); indices.AddRange(northQuadIndices); indices.AddRange(southQuadIndices); indices.AddRange(eastQuadIndices); indices.AddRange(westQuadIndices); indices.AddRange(northConnectionQuadIndices); indices.AddRange(southConnectionQuadIndices); indices.AddRange(eastConnectionQuadIndices); indices.AddRange(westConnectionQuadIndices); info.CenterPrimitiveCount = centralIndices.Length / 3; info.BorderPrimitiveCount = westQuadIndices.Length / 3; info.BorderConnectionPrimitiveCount = westConnectionQuadIndices.Length / 3; info.CenterOffset = indexOffset; info.NorthOffset = info.CenterOffset + centralIndices.Length; info.SouthOffset = info.NorthOffset + northQuadIndices.Length; info.EastOffset = info.SouthOffset + southQuadIndices.Length; info.WestOffset = info.EastOffset + eastQuadIndices.Length; info.NorthConnectionOffset = info.WestOffset + westQuadIndices.Length; info.SouthConnectionOffset = info.NorthConnectionOffset + northConnectionQuadIndices.Length; info.EastConnectionOffset = info.SouthConnectionOffset + southConnectionQuadIndices.Length; info.WestConnectionOffset = info.EastConnectionOffset + eastConnectionQuadIndices.Length; } return(indices.ToArray()); }