public void CalcWeights(LAND cell) { WeightVertex[] WeightData = new WeightVertex[65 * 65]; for (int y = 0; y <= 64; y++) { for (int x = 0; x <= 64; x++) { //Figure out which index to use int i = x * 65 + y; //Figure out which texture is used here int cell_x = cell.xpos; int cell_y = cell.ypos; int tex_x = (int)Math.Floor(((float)y - 1.0f) / 4.0f); //-2.0f int tex_y = (int)Math.Floor(((float)x - 3.0f) / 4.0f); //-2.0f DistantLandForm.ModCell(ref cell_x, ref tex_x); DistantLandForm.ModCell(ref cell_y, ref tex_y); LTEX tmp = DistantLandForm.GetTex(cell_x, cell_y, tex_x, tex_y); string tex_index = tmp.FilePath; //Write values if (t1 != null && t1.FilePath == tex_index) { WeightData[i].w1 = 255; continue; } else { WeightData[i].w1 = 0; } if (t2 != null && t2.FilePath == tex_index) { WeightData[i].w2 = 255; continue; } else { WeightData[i].w2 = 0; } if (t3 != null && t3.FilePath == tex_index) { WeightData[i].w3 = 255; continue; } else { WeightData[i].w3 = 0; } if (t4 != null && t4.FilePath == tex_index) { WeightData[i].w4 = 255; continue; } else { WeightData[i].w4 = 0; } } } //Blur the weights as we transfer them so the transitions aren't quite so blocky and horrible. ////Normal Gaussian //float bf1 = 0.00081723f; //float bf2 = 0.02804153f; //float bf3 = 0.23392642f; //float bf4 = 0.47442968f; //Reduced center influence float bf1 = 0.1f; float bf2 = 0.15f; float bf3 = 0.2f; float bf4 = 0.1f; //Horizontal Pass WeightVertex[] FirstPassWD = new WeightVertex[65 * 65]; for (int y = 0; y <= 64; y++) { for (int x = 0; x <= 64; x++) { //Figure out which index to use int i = y * 65 + x; if (x == 0 || x == 64 || y == 0 || y == 64) { //We're at the edge, so just copy the value (don't want to interfere with the way the edges of cells look FirstPassWD[i] = WeightData[i]; continue; } //We're not at the edge, so add some influence from the surrounding weights //Additional incides WeightVertex wv0, wv1, wv2, wv3, wv4, wv5, wv6; wv0 = SampleWeightData(ref WeightData, x - 3, y); wv1 = SampleWeightData(ref WeightData, x - 2, y); wv2 = SampleWeightData(ref WeightData, x - 1, y); wv3 = SampleWeightData(ref WeightData, x, y); wv4 = SampleWeightData(ref WeightData, x + 1, y); wv5 = SampleWeightData(ref WeightData, x + 2, y); wv6 = SampleWeightData(ref WeightData, x + 3, y); float value; value = 0.0f; value += (float)wv0.w1 * bf1; value += (float)wv1.w1 * bf2; value += (float)wv2.w1 * bf3; value += (float)wv3.w1 * bf4; value += (float)wv4.w1 * bf3; value += (float)wv5.w1 * bf2; value += (float)wv6.w1 * bf1; FirstPassWD[i].w1 = (byte)value; value = 0.0f; value += (float)wv0.w2 * bf1; value += (float)wv1.w2 * bf2; value += (float)wv2.w2 * bf3; value += (float)wv3.w2 * bf4; value += (float)wv4.w2 * bf3; value += (float)wv5.w2 * bf2; value += (float)wv6.w2 * bf1; FirstPassWD[i].w2 = (byte)value; value = 0.0f; value += (float)wv0.w3 * bf1; value += (float)wv1.w3 * bf2; value += (float)wv2.w3 * bf3; value += (float)wv3.w3 * bf4; value += (float)wv4.w3 * bf3; value += (float)wv5.w3 * bf2; value += (float)wv6.w3 * bf1; FirstPassWD[i].w3 = (byte)value; value = 0.0f; value += (float)wv0.w4 * bf1; value += (float)wv1.w4 * bf2; value += (float)wv2.w4 * bf3; value += (float)wv3.w4 * bf4; value += (float)wv4.w4 * bf3; value += (float)wv5.w4 * bf2; value += (float)wv6.w4 * bf1; FirstPassWD[i].w4 = (byte)value; } } //Vertical pass - writes to final vertex buffer DataStream FinalWeightData = wBuffer.Lock(0, 0, LockFlags.None); //Blur the weights as we transfer them so the transitions aren't quite so blocky and horrible. for (int y = 0; y <= 64; y++) { for (int x = 0; x <= 64; x++) { if (x == 0 || x == 64 || y == 0 || y == 64) { //We're at the edge, so just copy the value (don't want to interfere with the way the edges of cells look FinalWeightData.Write(WeightData[65 * y + x]); continue; } //We're not at the edge, so add some influence from the surrounding weights //Additional incides WeightVertex wv0, wv1, wv2, wv3, wv4, wv5, wv6, wvfinal; wv0 = SampleWeightData(ref FirstPassWD, x, y - 3); wv1 = SampleWeightData(ref FirstPassWD, x, y - 2); wv2 = SampleWeightData(ref FirstPassWD, x, y - 1); wv3 = SampleWeightData(ref FirstPassWD, x, y); wv4 = SampleWeightData(ref FirstPassWD, x, y + 1); wv5 = SampleWeightData(ref FirstPassWD, x, y + 2); wv6 = SampleWeightData(ref FirstPassWD, x, y + 3); float value; value = 0.0f; value += (float)wv0.w1 * bf1; value += (float)wv1.w1 * bf2; value += (float)wv2.w1 * bf3; value += (float)wv3.w1 * bf4; value += (float)wv4.w1 * bf3; value += (float)wv5.w1 * bf2; value += (float)wv6.w1 * bf1; wvfinal.w1 = (byte)value; value = 0.0f; value += (float)wv0.w2 * bf1; value += (float)wv1.w2 * bf2; value += (float)wv2.w2 * bf3; value += (float)wv3.w2 * bf4; value += (float)wv4.w2 * bf3; value += (float)wv5.w2 * bf2; value += (float)wv6.w2 * bf1; wvfinal.w2 = (byte)value; value = 0.0f; value += (float)wv0.w3 * bf1; value += (float)wv1.w3 * bf2; value += (float)wv2.w3 * bf3; value += (float)wv3.w3 * bf4; value += (float)wv4.w3 * bf3; value += (float)wv5.w3 * bf2; value += (float)wv6.w3 * bf1; wvfinal.w3 = (byte)value; value = 0.0f; value += (float)wv0.w4 * bf1; value += (float)wv1.w4 * bf2; value += (float)wv2.w4 * bf3; value += (float)wv3.w4 * bf4; value += (float)wv4.w4 * bf3; value += (float)wv5.w4 * bf2; value += (float)wv6.w4 * bf1; wvfinal.w4 = (byte)value; FinalWeightData.Write(wvfinal); } } wBuffer.Unlock(); }
public void SetCell(LAND cell) { //Write the new colors and normals into the color buffer DataStream ColorNormalData = colorBuffer.Lock(0, 0, LockFlags.None); NormalColorVertex ncv; for (int y = 0; y <= 64; y++) { for (int x = 0; x <= 64; x++) { ncv.r = cell.Color[x, y].r; ncv.g = cell.Color[x, y].g; ncv.b = cell.Color[x, y].b; ncv.a = 255; ncv.nx = cell.Normals[x, y].X; ncv.ny = cell.Normals[x, y].Y; ncv.nz = cell.Normals[x, y].Z; ColorNormalData.Write(ncv); } } colorBuffer.Unlock(); //Dispose of any current texture banks texBanks.Clear(); //Group the unique textures in this cell in fours //Find all te uniqe textures in this cell System.Collections.Generic.Dictionary <string, LTEX> tex_dict = new System.Collections.Generic.Dictionary <string, LTEX>(); for (int x = 0; x <= 64; ++x) { for (int y = 0; y <= 64; ++y) { int cell_x = cell.xpos; int cell_y = cell.ypos; int tex_x = (int)Math.Floor(((float)y - 1.0f) / 4.0f); //-2.0f int tex_y = (int)Math.Floor(((float)x - 3.0f) / 4.0f); //-2.0f DistantLandForm.ModCell(ref cell_x, ref tex_x); DistantLandForm.ModCell(ref cell_y, ref tex_y); LTEX tmp = DistantLandForm.GetTex(cell_x, cell_y, tex_x, tex_y); string idx = tmp.FilePath; tex_dict[idx] = tmp; } } //Create one bank for each group of 4 textures int index = 0; TextureBank tb = new TextureBank(); foreach (LTEX tex in tex_dict.Values) { switch (index) { case 0: tb.t1 = tex; ++index; break; case 1: tb.t2 = tex; ++index; break; case 2: tb.t3 = tex; ++index; break; case 3: tb.t4 = tex; texBanks.Add(tb); tb = new TextureBank(); index = 0; break; } } if (index != 0) { texBanks.Add(tb); } if (texBanks.Count > 1) { int blah = 4; int blu = 7; int blablu = blah + blu; } //Calculate weights for all banks foreach (TextureBank bank in texBanks) { bank.CalcWeights(cell); } }
public void CalcWeights(LAND cell) { WeightVertex[] WeightData = new WeightVertex[65 * 65]; for (int y = 0; y <= 64; y++) { for (int x = 0; x <= 64; x++) { // Figure out which index to use int i = y * 65 + x; // Figure out which texture is used here, match Morrowind rounding int cell_x = cell.xpos; int cell_y = cell.ypos; int tex_x = (int)Math.Floor(((float)x - 2.0f) / 4.0f); int tex_y = (int)Math.Ceiling(((float)y - 2.0f) / 4.0f); DistantLandForm.ModCell(ref cell_x, ref tex_x); DistantLandForm.ModCell(ref cell_y, ref tex_y); LTEX tmp = DistantLandForm.GetTex(cell_x, cell_y, tex_x, tex_y); string tex_index = tmp.FilePath; // Write values if (t1 != null && t1.FilePath == tex_index) { WeightData[i].w1 = 255; continue; } else { WeightData[i].w1 = 0; } if (t2 != null && t2.FilePath == tex_index) { WeightData[i].w2 = 255; continue; } else { WeightData[i].w2 = 0; } if (t3 != null && t3.FilePath == tex_index) { WeightData[i].w3 = 255; continue; } else { WeightData[i].w3 = 0; } if (t4 != null && t4.FilePath == tex_index) { WeightData[i].w4 = 255; continue; } else { WeightData[i].w4 = 0; } } } // Blur the weights as we transfer them so the transitions aren't quite so blocky and horrible. // Blur kernel float[] blur = new float[] { 0.04f, 0.16f, 0.6f, 0.16f, 0.04f }; // Horizontal Pass WeightVertex[] FirstPassWD = new WeightVertex[65 * 65]; for (int y = 0; y <= 64; y++) { for (int x = 0; x <= 64; x++) { // Figure out which index to use int i = y * 65 + x; if (x == 0 || x == 64 || y == 0 || y == 64) { // We're at the edge, so just copy the value (don't want to interfere with the way the edges of cells look FirstPassWD[i] = WeightData[i]; continue; } // We're not at the edge, so add some influence from the surrounding weights // Additional incides WeightVertex wv0, wv1, wv2, wv3, wv4; float value; wv0 = SampleWeightData(ref WeightData, x - 2, y); wv1 = SampleWeightData(ref WeightData, x - 1, y); wv2 = SampleWeightData(ref WeightData, x, y); wv3 = SampleWeightData(ref WeightData, x + 1, y); wv4 = SampleWeightData(ref WeightData, x + 2, y); value = (float)wv0.w1 * blur[0] + (float)wv1.w1 * blur[1] + (float)wv2.w1 * blur[2] + (float)wv3.w1 * blur[3] + (float)wv4.w1 * blur[4]; FirstPassWD[i].w1 = (byte)value; value = (float)wv0.w2 * blur[0] + (float)wv1.w2 * blur[1] + (float)wv2.w2 * blur[2] + (float)wv3.w2 * blur[3] + (float)wv4.w2 * blur[4]; FirstPassWD[i].w2 = (byte)value; value = (float)wv0.w3 * blur[0] + (float)wv1.w3 * blur[1] + (float)wv2.w3 * blur[2] + (float)wv3.w3 * blur[3] + (float)wv4.w3 * blur[4]; FirstPassWD[i].w3 = (byte)value; value = (float)wv0.w4 * blur[0] + (float)wv1.w4 * blur[1] + (float)wv2.w4 * blur[2] + (float)wv3.w4 * blur[3] + (float)wv4.w4 * blur[4]; FirstPassWD[i].w4 = (byte)value; } } // Vertical pass - writes to final vertex buffer DataStream FinalWeightData = wBuffer.Lock(0, 0, LockFlags.None); // Blur the weights as we transfer them so the transitions aren't quite so blocky and horrible. for (int y = 0; y <= 64; y++) { for (int x = 0; x <= 64; x++) { if (x == 0 || x == 64 || y == 0 || y == 64) { // We're at the edge, so just copy the value (don't want to interfere with the way the edges of cells look FinalWeightData.Write(WeightData[65 * y + x]); continue; } // We're not at the edge, so add some influence from the surrounding weights // Additional incides WeightVertex wv0, wv1, wv2, wv3, wv4, wvfinal; float value; wv0 = SampleWeightData(ref FirstPassWD, x, y - 2); wv1 = SampleWeightData(ref FirstPassWD, x, y - 1); wv2 = SampleWeightData(ref FirstPassWD, x, y); wv3 = SampleWeightData(ref FirstPassWD, x, y + 1); wv4 = SampleWeightData(ref FirstPassWD, x, y + 2); value = (float)wv0.w1 * blur[0] + (float)wv1.w1 * blur[1] + (float)wv2.w1 * blur[2] + (float)wv3.w1 * blur[3] + (float)wv4.w1 * blur[4]; wvfinal.w1 = (byte)value; value = (float)wv0.w2 * blur[0] + (float)wv1.w2 * blur[1] + (float)wv2.w2 * blur[2] + (float)wv3.w2 * blur[3] + (float)wv4.w2 * blur[4]; wvfinal.w2 = (byte)value; value = (float)wv0.w3 * blur[0] + (float)wv1.w3 * blur[1] + (float)wv2.w3 * blur[2] + (float)wv3.w3 * blur[3] + (float)wv4.w3 * blur[4]; wvfinal.w3 = (byte)value; value = (float)wv0.w4 * blur[0] + (float)wv1.w4 * blur[1] + (float)wv2.w4 * blur[2] + (float)wv3.w4 * blur[3] + (float)wv4.w4 * blur[4]; wvfinal.w4 = (byte)value; FinalWeightData.Write(wvfinal); } } wBuffer.Unlock(); }