public CPatchManager(CPatchConfig config, CPlanet planet) { for (byte i=0; i<16; i++) { GenGrid(i, config, planet); } }
public CPatchManager(CPatchConfig config, CPlanet planet) { for (byte i = 0; i < 16; i++) { GenGrid(i, config, planet); } }
private void GenGrid(byte edges, CPatchConfig config, CPlanet planet) { /* +++ +O+ +++ +O+ +++ +++ O+O O+O +++ +O+ +++ +O+ +O+ +++ +++ +++ +++ ++O +++ O++ +++ +++ +O+ +++ +O+ +++ +++ +O+ ++O ++O O++ O++ +++ +O+ +O+ +++ +O+ +O+ +++ +O+ O+O ++O O+O O++ +++ +O+ +O+ +O+ */ // number of triangles in one full-res line // discounting the two extremities triangles that aren't included on this edge ushort edgeFullTrianglesCount = (ushort)((config.PatchSize-1) * 2 - 2); // number of indices in one full-res edge ushort edgeFullIndexCount = (ushort)(edgeFullTrianglesCount * 3); // number of triangles in one half-res edge // discounting the two extremities triangles that aren't included on this edge ushort edgeHalfTriangleCount = (ushort)((edgeFullTrianglesCount/2) + (edgeFullTrianglesCount/4)); // number of indices in one half-res edge ushort edgeHalfIndexCount = (ushort)(edgeHalfTriangleCount * 3); // number of indices within the main part of the patch, // discounting the four edges that will sum up to this ushort mainIndexCount = (ushort)(((config.PatchSize - 3) * (config.PatchSize - 3)) * 6); // our total of indices // starts with the mainIndexCount, // and gets update with edges index counts ushort totalIndexCount = mainIndexCount; // add index count for each edge int i=1; while (i < 16) { if ((edges & i) > 0) { // half-res edge totalIndexCount += edgeHalfIndexCount; } else { // full-res edge totalIndexCount += edgeFullIndexCount; } i <<= 1; } // allocate indices (triangles) for the patch type int[] idxList = new int[totalIndexCount]; // // generate indices for the interior of the patch - at full-res // ushort idx = 0; for (ushort lin=1; lin<config.PatchSize-2; lin++) { ushort pos = (ushort)(lin * config.PatchSize); for (ushort col = 1; col < config.PatchSize - 2; col++) { ushort pp = (ushort)(pos + col); // x, x+1, x+config.PatchSize idxList[idx++] = pp + config.PatchSize; idxList[idx++] = pp+1; idxList[idx++] = pp; // x+config.PatchSize, x+1, x+1+config.PatchSize idxList[idx++] = pp + 1 + config.PatchSize; idxList[idx++] = pp+1; idxList[idx++] = pp + config.PatchSize; } } // // generate indices for the edges // // 0000 == all edges at full-res // 0001 (1) == top edge at half-res // 0010 (2) == right edge at half-res // 0100 (4) == bottom edge at half-res // 1000 (8) == left edge at half-res // // top edge // if ((edges & (1 << (int)en_NeighborDirection.NB_Top)) > 0) { // top edge at half-resolution bool flag = false; ushort x = 0; ushort pp = 0; while (x < config.PatchSize-2) { if (!flag) { idxList[idx++] = pp; idxList[idx++] = pp+config.PatchSize+1; idxList[idx++] = pp+2; x += 2; pp += 2; } else { idxList[idx++] = pp; idxList[idx++] = pp+config.PatchSize-1; idxList[idx++] = pp+config.PatchSize; idxList[idx++] = pp; idxList[idx++] = pp+config.PatchSize; idxList[idx++] = pp+config.PatchSize+1; } flag = !flag; } } else { // top edge at full-resolution bool flag = false; ushort x = 0; ushort pp = 0; while (x < config.PatchSize-2) { if (!flag) { idxList[idx++] = pp; idxList[idx++] = pp+config.PatchSize+1; idxList[idx++] = pp+1; idxList[idx++] = pp+1; idxList[idx++] = pp+config.PatchSize+1; idxList[idx++] = pp+2; x += 2; pp += 2; } else { idxList[idx++] = pp; idxList[idx++] = pp+config.PatchSize-1; idxList[idx++] = pp+config.PatchSize; idxList[idx++] = pp; idxList[idx++] = pp+config.PatchSize; idxList[idx++] = pp+config.PatchSize+1; } flag = !flag; } } // // right edge // if ((edges & (1 << (int)en_NeighborDirection.NB_Right)) > 0) { // right edge at half-resolution bool flag = false; ushort y = 0; ushort pp = (ushort)(config.PatchSize-1); while (y < config.PatchSize-2) { if (!flag) { idxList[idx++] = pp; idxList[idx++] = pp+config.PatchSize-1; idxList[idx++] = pp+config.PatchSize*2; y += 2; pp += (ushort)(config.PatchSize*2); } else { idxList[idx++] = pp; idxList[idx++] = pp-config.PatchSize-1; idxList[idx++] = pp-1; idxList[idx++] = pp; idxList[idx++] = pp-1; idxList[idx++] = pp+config.PatchSize-1; } flag = !flag; } } else { // right edge at full-resolution bool flag = false; ushort y = 0; ushort pp = (ushort)(config.PatchSize-1); while (y < config.PatchSize-2) { if (!flag) { idxList[idx++] = pp; idxList[idx++] = pp+config.PatchSize-1; idxList[idx++] = pp+config.PatchSize; idxList[idx++] = pp+config.PatchSize; idxList[idx++] = pp+config.PatchSize-1; idxList[idx++] = pp+config.PatchSize*2; y += 2; pp += (ushort)(config.PatchSize*2); } else { idxList[idx++] = pp; idxList[idx++] = pp-config.PatchSize-1; idxList[idx++] = pp-1; idxList[idx++] = pp; idxList[idx++] = pp-1; idxList[idx++] = pp+config.PatchSize-1; } flag = !flag; } } // // bottom edge // if ((edges & (1 << (int)en_NeighborDirection.NB_Bottom)) > 0) { // bottom edge at half-resolution bool flag = false; ushort x = 0; ushort pp = (ushort)((config.PatchSize-1) * config.PatchSize); while (x < config.PatchSize-2) { if (!flag) { idxList[idx++] = pp; idxList[idx++] = pp+2; idxList[idx++] = pp-config.PatchSize+1; x += 2; pp += 2; } else { idxList[idx++] = pp; idxList[idx++] = pp-config.PatchSize; idxList[idx++] = pp-config.PatchSize-1; idxList[idx++] = pp; idxList[idx++] = pp-config.PatchSize+1; idxList[idx++] = pp-config.PatchSize; } flag = !flag; } } else { // bottom edge at full-resolution bool flag = false; ushort x = 0; ushort pp = (ushort)((config.PatchSize-1) * config.PatchSize); while (x < config.PatchSize-2) { if (!flag) { idxList[idx++] = pp; idxList[idx++] = pp+1; idxList[idx++] = pp-config.PatchSize+1; idxList[idx++] = pp+1; idxList[idx++] = pp+2; idxList[idx++] = pp-config.PatchSize+1; x += 2; pp += 2; } else { idxList[idx++] = pp; idxList[idx++] = pp-config.PatchSize; idxList[idx++] = pp-config.PatchSize-1; idxList[idx++] = pp; idxList[idx++] = pp-config.PatchSize+1; idxList[idx++] = pp-config.PatchSize; } flag = !flag; } } // // left edge // if ((edges & (1 << (int)en_NeighborDirection.NB_Left)) > 0) { // left edge at half-resolution bool flag = false; ushort y = 0; ushort pp = 0; while (y < config.PatchSize-2) { if (!flag) { idxList[idx++] = pp; idxList[idx++] = pp+config.PatchSize*2; idxList[idx++] = pp+config.PatchSize+1; y += 2; pp += (ushort)(config.PatchSize*2); } else { idxList[idx++] = pp; idxList[idx++] = pp+1; idxList[idx++] = pp-config.PatchSize+1; idxList[idx++] = pp; idxList[idx++] = pp+config.PatchSize+1; idxList[idx++] = pp+1; } flag = !flag; } } else { // left edge at full-resolution bool flag = false; ushort y = 0; ushort pp = 0; while (y < config.PatchSize-2) { if (!flag) { idxList[idx++] = pp; idxList[idx++] = pp+config.PatchSize; idxList[idx++] = pp+config.PatchSize+1; idxList[idx++] = pp+config.PatchSize; idxList[idx++] = pp+config.PatchSize*2; idxList[idx++] = pp+config.PatchSize+1; y += 2; pp += (ushort)(config.PatchSize*2); } else { idxList[idx++] = pp; idxList[idx++] = pp+config.PatchSize+1; idxList[idx++] = pp+1; idxList[idx++] = pp; idxList[idx++] = pp+1; idxList[idx++] = pp-config.PatchSize+1; } flag = !flag; } } m_patches.Add(idxList); }
private void GenGrid(byte edges, CPatchConfig config, CPlanet planet) { /* +++ +O+ +++ +O+ +++ +++ O+O O+O +++ +O+ +++ +O+ +++ +O+ +++ +++ +++ +++ ++O +++ O++ +++ +++ +O+ +++ +++ +O+ +++ +++ +O+ ++O ++O O++ O++ +++ +O+ +O+ +++ +++ +O+ +O+ +++ +O+ +++ O+O ++O O+O O++ +++ +O+ +O+ +O+ */ // number of triangles in one full-res line // discounting the two extremities triangles that aren't included on this edge ushort edgeFullTrianglesCount = (ushort)((config.PatchSize - 1) * 2 - 2); // number of indices in one full-res edge ushort edgeFullIndexCount = (ushort)(edgeFullTrianglesCount * 3); // number of triangles in one half-res edge // discounting the two extremities triangles that aren't included on this edge ushort edgeHalfTriangleCount = (ushort)((edgeFullTrianglesCount / 2) + (edgeFullTrianglesCount / 4)); // number of indices in one half-res edge ushort edgeHalfIndexCount = (ushort)(edgeHalfTriangleCount * 3); // number of indices within the main part of the patch, // discounting the four edges that will sum up to this ushort mainIndexCount = (ushort)(((config.PatchSize - 3) * (config.PatchSize - 3)) * 6); // our total of indices // starts with the mainIndexCount, // and gets update with edges index counts ushort totalIndexCount = mainIndexCount; // add index count for each edge int i = 1; while (i < 16) { if ((edges & i) > 0) { // half-res edge totalIndexCount += edgeHalfIndexCount; } else { // full-res edge totalIndexCount += edgeFullIndexCount; } i <<= 1; } // allocate indices (triangles) for the patch type int[] idxList = new int[totalIndexCount]; // // generate indices for the interior of the patch - at full-res // ushort idx = 0; for (ushort lin = 1; lin < config.PatchSize - 2; lin++) { ushort pos = (ushort)(lin * config.PatchSize); for (ushort col = 1; col < config.PatchSize - 2; col++) { ushort pp = (ushort)(pos + col); // x, x+1, x+config.PatchSize idxList[idx++] = pp + config.PatchSize; idxList[idx++] = pp + 1; idxList[idx++] = pp; // x+config.PatchSize, x+1, x+1+config.PatchSize idxList[idx++] = pp + 1 + config.PatchSize; idxList[idx++] = pp + 1; idxList[idx++] = pp + config.PatchSize; } } // // generate indices for the edges // // 0000 == all edges at full-res // 0001 (1) == top edge at half-res // 0010 (2) == right edge at half-res // 0100 (4) == bottom edge at half-res // 1000 (8) == left edge at half-res // // top edge // if ((edges & (1 << (int)en_NeighborDirection.NB_Top)) > 0) { // top edge at half-resolution bool flag = false; ushort x = 0; ushort pp = 0; while (x < config.PatchSize - 2) { if (!flag) { idxList[idx++] = pp; idxList[idx++] = pp + config.PatchSize + 1; idxList[idx++] = pp + 2; x += 2; pp += 2; } else { idxList[idx++] = pp; idxList[idx++] = pp + config.PatchSize - 1; idxList[idx++] = pp + config.PatchSize; idxList[idx++] = pp; idxList[idx++] = pp + config.PatchSize; idxList[idx++] = pp + config.PatchSize + 1; } flag = !flag; } } else { // top edge at full-resolution bool flag = false; ushort x = 0; ushort pp = 0; while (x < config.PatchSize - 2) { if (!flag) { idxList[idx++] = pp; idxList[idx++] = pp + config.PatchSize + 1; idxList[idx++] = pp + 1; idxList[idx++] = pp + 1; idxList[idx++] = pp + config.PatchSize + 1; idxList[idx++] = pp + 2; x += 2; pp += 2; } else { idxList[idx++] = pp; idxList[idx++] = pp + config.PatchSize - 1; idxList[idx++] = pp + config.PatchSize; idxList[idx++] = pp; idxList[idx++] = pp + config.PatchSize; idxList[idx++] = pp + config.PatchSize + 1; } flag = !flag; } } // // right edge // if ((edges & (1 << (int)en_NeighborDirection.NB_Right)) > 0) { // right edge at half-resolution bool flag = false; ushort y = 0; ushort pp = (ushort)(config.PatchSize - 1); while (y < config.PatchSize - 2) { if (!flag) { idxList[idx++] = pp; idxList[idx++] = pp + config.PatchSize - 1; idxList[idx++] = pp + config.PatchSize * 2; y += 2; pp += (ushort)(config.PatchSize * 2); } else { idxList[idx++] = pp; idxList[idx++] = pp - config.PatchSize - 1; idxList[idx++] = pp - 1; idxList[idx++] = pp; idxList[idx++] = pp - 1; idxList[idx++] = pp + config.PatchSize - 1; } flag = !flag; } } else { // right edge at full-resolution bool flag = false; ushort y = 0; ushort pp = (ushort)(config.PatchSize - 1); while (y < config.PatchSize - 2) { if (!flag) { idxList[idx++] = pp; idxList[idx++] = pp + config.PatchSize - 1; idxList[idx++] = pp + config.PatchSize; idxList[idx++] = pp + config.PatchSize; idxList[idx++] = pp + config.PatchSize - 1; idxList[idx++] = pp + config.PatchSize * 2; y += 2; pp += (ushort)(config.PatchSize * 2); } else { idxList[idx++] = pp; idxList[idx++] = pp - config.PatchSize - 1; idxList[idx++] = pp - 1; idxList[idx++] = pp; idxList[idx++] = pp - 1; idxList[idx++] = pp + config.PatchSize - 1; } flag = !flag; } } // // bottom edge // if ((edges & (1 << (int)en_NeighborDirection.NB_Bottom)) > 0) { // bottom edge at half-resolution bool flag = false; ushort x = 0; ushort pp = (ushort)((config.PatchSize - 1) * config.PatchSize); while (x < config.PatchSize - 2) { if (!flag) { idxList[idx++] = pp; idxList[idx++] = pp + 2; idxList[idx++] = pp - config.PatchSize + 1; x += 2; pp += 2; } else { idxList[idx++] = pp; idxList[idx++] = pp - config.PatchSize; idxList[idx++] = pp - config.PatchSize - 1; idxList[idx++] = pp; idxList[idx++] = pp - config.PatchSize + 1; idxList[idx++] = pp - config.PatchSize; } flag = !flag; } } else { // bottom edge at full-resolution bool flag = false; ushort x = 0; ushort pp = (ushort)((config.PatchSize - 1) * config.PatchSize); while (x < config.PatchSize - 2) { if (!flag) { idxList[idx++] = pp; idxList[idx++] = pp + 1; idxList[idx++] = pp - config.PatchSize + 1; idxList[idx++] = pp + 1; idxList[idx++] = pp + 2; idxList[idx++] = pp - config.PatchSize + 1; x += 2; pp += 2; } else { idxList[idx++] = pp; idxList[idx++] = pp - config.PatchSize; idxList[idx++] = pp - config.PatchSize - 1; idxList[idx++] = pp; idxList[idx++] = pp - config.PatchSize + 1; idxList[idx++] = pp - config.PatchSize; } flag = !flag; } } // // left edge // if ((edges & (1 << (int)en_NeighborDirection.NB_Left)) > 0) { // left edge at half-resolution bool flag = false; ushort y = 0; ushort pp = 0; while (y < config.PatchSize - 2) { if (!flag) { idxList[idx++] = pp; idxList[idx++] = pp + config.PatchSize * 2; idxList[idx++] = pp + config.PatchSize + 1; y += 2; pp += (ushort)(config.PatchSize * 2); } else { idxList[idx++] = pp; idxList[idx++] = pp + 1; idxList[idx++] = pp - config.PatchSize + 1; idxList[idx++] = pp; idxList[idx++] = pp + config.PatchSize + 1; idxList[idx++] = pp + 1; } flag = !flag; } } else { // left edge at full-resolution bool flag = false; ushort y = 0; ushort pp = 0; while (y < config.PatchSize - 2) { if (!flag) { idxList[idx++] = pp; idxList[idx++] = pp + config.PatchSize; idxList[idx++] = pp + config.PatchSize + 1; idxList[idx++] = pp + config.PatchSize; idxList[idx++] = pp + config.PatchSize * 2; idxList[idx++] = pp + config.PatchSize + 1; y += 2; pp += (ushort)(config.PatchSize * 2); } else { idxList[idx++] = pp; idxList[idx++] = pp + config.PatchSize + 1; idxList[idx++] = pp + 1; idxList[idx++] = pp; idxList[idx++] = pp + 1; idxList[idx++] = pp - config.PatchSize + 1; } flag = !flag; } } m_patches.Add(idxList); }
public void Rebuild() { CGlobal global = CGlobal.GetInstance(); m_LutGen = new CLutGenerator(); m_LutLayers[0] = new CLutLayer(m_Diffuse1LutLayer.minh, m_Diffuse1LutLayer.maxh, m_Diffuse1LutLayer.slope, m_Diffuse1LutLayer.aperture); m_LutLayers[1] = new CLutLayer(m_Diffuse2LutLayer.minh, m_Diffuse2LutLayer.maxh, m_Diffuse2LutLayer.slope, m_Diffuse2LutLayer.aperture); m_LutLayers[2] = new CLutLayer(m_Diffuse3LutLayer.minh, m_Diffuse3LutLayer.maxh, m_Diffuse3LutLayer.slope, m_Diffuse3LutLayer.aperture); m_LutLayers[3] = new CLutLayer(m_Diffuse4LutLayer.minh, m_Diffuse4LutLayer.maxh, m_Diffuse4LutLayer.slope, m_Diffuse4LutLayer.aperture); m_LutGen.UpdateLutTex(m_LutLayers); m_PatchConfig = new CPatchConfig(m_PatchQuality, m_NormalQuality, m_FilteredHeights); m_PatchManager = new CPatchManager(m_PatchConfig, this); global.Setup(); // --- // destroy the previous planet tree DestroyPlanet(); // // rebuild patch tree // m_Quadtrees.Add(new CQuadtree(new Vector3(0, 1, 0), new Vector3(0, 0, -1), this, m_ShapeTop)); // 0: top m_Quadtrees.Add(new CQuadtree(new Vector3(0, -1, 0), new Vector3(0, 0, 1), this, m_ShapeBottom)); // 1: bottom m_Quadtrees.Add(new CQuadtree(new Vector3(-1, 0, 0), new Vector3(0, 1, 0), this, m_ShapeLeft)); // 2: left m_Quadtrees.Add(new CQuadtree(new Vector3(1, 0, 0), new Vector3(0, 1, 0), this, m_ShapeRight)); // 3: right m_Quadtrees.Add(new CQuadtree(new Vector3(0, 0, 1), new Vector3(0, 1, 0), this, m_ShapeFront)); // 4: front m_Quadtrees.Add(new CQuadtree(new Vector3(0, 0, -1), new Vector3(0, 1, 0), this, m_ShapeBack)); // 5: back // link neighbors of TOP quadtree m_Quadtrees[0].SetNeighbor(en_NeighborDirection.NB_Top, m_Quadtrees[5], en_NeighborDirection.NB_Top); // back m_Quadtrees[0].SetNeighbor(en_NeighborDirection.NB_Bottom, m_Quadtrees[4], en_NeighborDirection.NB_Top); // front m_Quadtrees[0].SetNeighbor(en_NeighborDirection.NB_Left, m_Quadtrees[2], en_NeighborDirection.NB_Top); // left m_Quadtrees[0].SetNeighbor(en_NeighborDirection.NB_Right, m_Quadtrees[3], en_NeighborDirection.NB_Top); // right // link neighbors of BOTTOM quadtree m_Quadtrees[1].SetNeighbor(en_NeighborDirection.NB_Top, m_Quadtrees[4], en_NeighborDirection.NB_Bottom); // front m_Quadtrees[1].SetNeighbor(en_NeighborDirection.NB_Bottom, m_Quadtrees[5], en_NeighborDirection.NB_Bottom); // back m_Quadtrees[1].SetNeighbor(en_NeighborDirection.NB_Left, m_Quadtrees[2], en_NeighborDirection.NB_Bottom); // left m_Quadtrees[1].SetNeighbor(en_NeighborDirection.NB_Right, m_Quadtrees[3], en_NeighborDirection.NB_Bottom); // right // link neighbors of LEFT quadtree m_Quadtrees[2].SetNeighbor(en_NeighborDirection.NB_Top, m_Quadtrees[0], en_NeighborDirection.NB_Left); // top m_Quadtrees[2].SetNeighbor(en_NeighborDirection.NB_Bottom, m_Quadtrees[1], en_NeighborDirection.NB_Left); // bottom m_Quadtrees[2].SetNeighbor(en_NeighborDirection.NB_Left, m_Quadtrees[5], en_NeighborDirection.NB_Right); // back m_Quadtrees[2].SetNeighbor(en_NeighborDirection.NB_Right, m_Quadtrees[4], en_NeighborDirection.NB_Left); // front // link neighbors of RIGHT quadtree m_Quadtrees[3].SetNeighbor(en_NeighborDirection.NB_Top, m_Quadtrees[0], en_NeighborDirection.NB_Right); // top m_Quadtrees[3].SetNeighbor(en_NeighborDirection.NB_Bottom, m_Quadtrees[1], en_NeighborDirection.NB_Right); // bottom m_Quadtrees[3].SetNeighbor(en_NeighborDirection.NB_Left, m_Quadtrees[4], en_NeighborDirection.NB_Right); // front m_Quadtrees[3].SetNeighbor(en_NeighborDirection.NB_Right, m_Quadtrees[5], en_NeighborDirection.NB_Left); // back // link neighbors of FRONT quadtree m_Quadtrees[4].SetNeighbor(en_NeighborDirection.NB_Top, m_Quadtrees[0], en_NeighborDirection.NB_Bottom); // top m_Quadtrees[4].SetNeighbor(en_NeighborDirection.NB_Bottom, m_Quadtrees[1], en_NeighborDirection.NB_Top); // bottom m_Quadtrees[4].SetNeighbor(en_NeighborDirection.NB_Left, m_Quadtrees[2], en_NeighborDirection.NB_Right); // left m_Quadtrees[4].SetNeighbor(en_NeighborDirection.NB_Right, m_Quadtrees[3], en_NeighborDirection.NB_Left); // right // link neighbors of BACK quadtree m_Quadtrees[5].SetNeighbor(en_NeighborDirection.NB_Top, m_Quadtrees[0], en_NeighborDirection.NB_Top); // top m_Quadtrees[5].SetNeighbor(en_NeighborDirection.NB_Bottom, m_Quadtrees[1], en_NeighborDirection.NB_Bottom); // bottom m_Quadtrees[5].SetNeighbor(en_NeighborDirection.NB_Left, m_Quadtrees[3], en_NeighborDirection.NB_Right); // right m_Quadtrees[5].SetNeighbor(en_NeighborDirection.NB_Right, m_Quadtrees[2], en_NeighborDirection.NB_Left); // left // atmosphere m_AtmosRadius = m_Radius + m_HeightScale * m_AtmosScale; m_LodSpheres = new CLodSphere[] { new CLodSphere(true, this), // outer sphere new CLodSphere(false, this) // inner sphere }; if (m_Camera == null) { Debug.Log("[ETHEREA1] Planet " + this.name + " had no associated Camera. Main Camera is being selected as the Camera for this Planet."); m_Camera = Camera.main; } if (m_SunTransform == null) { Debug.Log("[ETHEREA1] Planet " + this.name + " has no Sun. Please select a Light as the Sun for this Planet."); } }