Пример #1
0
        public void ImportMapFromImage(string path, int moveX = 0, int moveY = 0)
        {
            var heightMeta = RawImage.LoadRawMetadataFromJson(path);
            var heightData = RawImage.LoadGrayscale16(path, heightMeta);

            int cellNumberX = heightData.GetLength(1) / MW_CELL;
            int cellNumberY = heightData.GetLength(0) / MW_CELL;

            var landList = new List <Record>();

            for (int y = 0; y < cellNumberY; y++)
            {
                for (int x = 0; x < cellNumberX; x++)
                {
                    var landRecord = new LAND();
                    landRecord.INTV = new INTV
                    {
                        CellX = x + moveX,
                        CellY = y + moveY,
                    };
                    landRecord.DATA = new DATA();
                    landRecord.VHGT = CreateHeightMapSubrecord(x * 64, y * 64, heightData);

                    var cellRecord = new CELL
                    {
                        NAME = new TES3Lib.Subrecords.Shared.NAME
                        {
                            EditorId = ""
                        },
                        DATA = new TES3Lib.Subrecords.CELL.DATA
                        {
                            Flags = new HashSet <TES3Lib.Enums.Flags.CellFlag>(),
                            GridX = landRecord.INTV.CellX,
                            GridY = landRecord.INTV.CellY,
                        },
                    };

                    landList.Add(cellRecord);
                    landList.Add(landRecord);
                }
            }

            var example = new TES3();

            example.Records.Add(createTES3HEader());
            example.Records.AddRange(landList);
            example.TES3Save($"{path}.esp");
        }
Пример #2
0
        internal void VHGTTester(LAND land)
        {
            //testing
            int cordX = HEIGHT_CELL_SIZE * (Math.Abs(minX) + land.INTV.CellX);
            int cordY = HEIGHT_CELL_SIZE * (Math.Abs(minY) + land.INTV.CellY);

            var heightSubrecord = CreateHeightMapSubrecord(cordX, cordY, Heightmap);
            {//compare
                var check = land.VHGT.HeightOffset == heightSubrecord.HeightOffset &&
                            land.VHGT.Unknown1 == heightSubrecord.Unknown1 && land.VHGT.Unknown2 == heightSubrecord.Unknown2;

                for (int i = 0; i < 65; i++)
                {
                    for (int j = 0; j < 65; j++)
                    {
                        if (check && land.VHGT.HeightDelta[i, j] != heightSubrecord.HeightDelta[i, j])
                        {
                            throw new Exception("failed");
                        }
                    }
                }
            }
        }
Пример #3
0
 private void workerLoadPlugins(object sender, System.ComponentModel.DoWorkEventArgs e) {
     map = (LAND[,])Array.CreateInstance(typeof(LAND), new int[] { 501, 501 }, new int[] { -250, -250 });
     DefaultTex = new LTEX();
     DefaultTex.FilePath = "_land_default.tga";
     DefaultTex.index = 0;
     try {
         DefaultTex.LoadTexture();
     } catch (Exception ex) {
         throw new ApplicationException("Failed to load default ground texture (" + ex.Message + ")", ex);
     }
     CellCount = 0;
     int progress = 0;
     List<string> errors = new List<string>();
     foreach (string file in files) {
         if (DEBUG) allWarnings.Add("Loading plugin: " + file);
         BinaryReader br = new BinaryReader(File.OpenRead(file), System.Text.Encoding.Default);
         List<LTEX> Textures = new List<LTEX>();
         //Add the default texture first, because all vtex id's are +1 compared to the ltex ids
         Textures.Add(DefaultTex);
         string s = "";
         while (br.BaseStream.Position < br.BaseStream.Length) {
             s = ReadString(br);
             if (s == "LAND") {
                 int size = br.ReadInt32();
                 int read = 0;
                 br.BaseStream.Position += 8;
                 LAND land = new LAND();
                 land.Textures = Textures;
                 int lx = -999;
                 int ly = -999;
                 while (read < size) {
                     s = ReadString(br);
                     int size2 = br.ReadInt32();
                     read += size2 + 8;
                     switch (s) {
                         case "INTV":
                             lx = br.ReadInt32();
                             ly = br.ReadInt32();
                             land.xpos = lx;
                             land.ypos = ly;
                             break;
                         case "VHGT":
                             int offset = (int)br.ReadSingle();
                             for (int y = 0; y < 65; y++) {
                                 offset += br.ReadSByte();
                                 land.Heights[0, y] = offset;
                                 int pos = offset;
                                 for (int x = 1; x < 65; x++) {
                                     pos += br.ReadSByte();
                                     land.Heights[x, y] = pos;
                                     if (pos > VeryHigh) VeryHigh = pos;
                                     if (pos < VeryLow) VeryLow = pos;
                                 }
                             }
                             br.BaseStream.Seek(3, SeekOrigin.Current);
                             break;
                         case "VNML":
                             for (int y = 0; y < 65; y++) {
                                 for (int x = 0; x < 65; x++) {
                                     sbyte vx, vy, vz;
                                     vx = br.ReadSByte();
                                     vy = br.ReadSByte();
                                     vz = br.ReadSByte();
                                     land.Normals[x, y] = new Normal(vx, vy, vz);
                                 }
                             }
                             break;
                         case "VCLR":
                             for (int y = 0; y < 65; y++) {
                                 for (int x = 0; x < 65; x++) {
                                     land.Color[x, y] = new RGB(br.ReadByte(), br.ReadByte(), br.ReadByte());
                                 }
                             }
                             break;
                         case "VTEX":
                             for (int y1 = 0; y1 < 4; y1++) {
                                 for (int x1 = 0; x1 < 4; x1++) {
                                     for (int y2 = 0; y2 < 4; y2++) {
                                         for (int x2 = 0; x2 < 4; x2++) {
                                             land.Tex[x1 * 4 + x2, y1 * 4 + y2] = br.ReadInt16();
                                         }
                                     }
                                 }
                             }
                             break;
                         default:
                             br.BaseStream.Position += size2;
                             break;
                     }
                 }
                 if (lx != -999 && ly != -999) {
                     //Keep track of map extents
                     if (lx > MapMaxX) { MapMaxX = lx; }
                     if (ly > MapMaxY) { MapMaxY = ly; }
                     if (lx < MapMinX) { MapMinX = lx; }
                     if (ly < MapMinY) { MapMinY = ly; }
                     int max = Math.Max(MapMaxX - MapMinX, MapMaxY - MapMinY);
                     if (max > MapSize) MapSize = max;
                     if (map[lx, ly] == null) CellCount++;
                     map[lx, ly] = land;
                 }
             } else if (s == "LTEX") {
                 //TODO: Fix!
                 //Presumably, not all LTEX's have the subrecords in an identical order
                 LTEX tex = new LTEX();
                 int size = br.ReadInt32();
                 long pos = br.BaseStream.Position + 8;
                 br.BaseStream.Position += 16;
                 ReadCString(br);
                 br.BaseStream.Position += 8;
                 tex.index = br.ReadInt32() + 1;
                 br.BaseStream.Position += 8;
                 tex.FilePath = ReadCString(br).ToLower(Statics.Culture);
                 try {
                     tex.LoadTexture();
                 } catch (Exception ex) {
                     errors.Add("Texture '" + tex.FilePath + "' in plugin '" + file + "' failed to load (" + ex.Message + ")");
                     tex.tex = DefaultTex.tex;
                 }
                 Textures.Add(tex);
                 br.BaseStream.Position = pos + size;
             } else {
                 int size = br.ReadInt32();
                 br.BaseStream.Position += size + 8;
             }
         }
         br.Close();
         Textures.Sort(new LTEXSorter());
         backgroundWorker.ReportProgress(++progress);
     }
 }
Пример #4
0
 private static void GenerateMesh(LAND land, string path) {
     Directory.CreateDirectory(Path.GetDirectoryName(path));
     BinaryWriter bw = new BinaryWriter(File.Create(path));
     for (int x = 0; x < 65; x++) {
         for (int y = 0; y < 65; y++) {
             bw.Write((float)(x * 128));
             bw.Write((float)(y * 128));
             bw.Write((float)(land.Heights[x, y] * 8));
             bw.Write(land.Normals[x, y].X);
             bw.Write(land.Normals[x, y].Y);
             bw.Write(land.Normals[x, y].Z);
             //Need to offset the border texcoords slightly to avoid lines between meshes
             if (x == 0) bw.Write(0.005f);
             else if (x == 64) bw.Write(0.997f);
             else bw.Write((float)x / 64.0f);
             if (y == 0) bw.Write(0.005f);
             else if (y == 64) bw.Write(0.997f);
             else bw.Write((float)y / 64.0f);
         }
     }
     bw.Close();
 }
Пример #5
0
        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);
            }
        }
Пример #6
0
        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();
        }
Пример #7
0
        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 + 2, 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
            WeightVertex[] FinalWeightData = (WeightVertex[])wBuffer.Lock(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++)
                {
                    //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
                        FinalWeightData[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 FirstPassWD, x, y - 2);
                    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 - 2);

                    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;
                    FinalWeightData[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;
                    FinalWeightData[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;
                    FinalWeightData[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;
                    FinalWeightData[i].w4 = (byte)value;
                }
            }

            wBuffer.Unlock();
        }
Пример #8
0
        public void SetCell( LAND cell )
        {
            //Write the new colors and normals into the color buffer
            NormalColorVertex[] ColorNormalData = (NormalColorVertex[])colorBuffer.Lock(0, LockFlags.None);
            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;

                    //Write values
                    ColorNormalData[i].r = cell.Color[x, y].r;
                    ColorNormalData[i].g = cell.Color[x, y].g;
                    ColorNormalData[i].b = cell.Color[x, y].b;
                    ColorNormalData[i].a = 255;

                    ColorNormalData[i].nx = cell.Normals[x, y].X;
                    ColorNormalData[i].ny = cell.Normals[x, y].Y;
                    ColorNormalData[i].nz = cell.Normals[x, y].Z;
                }
            }
            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);
            }
        }
Пример #9
0
        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();
        }