Пример #1
0
        /// <summary>
        /// Import a .tre2 file.
        /// </summary>
        /// <param name="ctx"></param>
        public override void OnImportAsset(AssetImportContext ctx)
        {
            // TODO FIXME
            // Currently the textures come in with incorrect orientation; they should be rotated 90 degrees counterclockwise.
            var asset = ScriptableObject.CreateInstance <TerrainAsset>();

            asset.name = Path.GetFileNameWithoutExtension(ctx.assetPath);

            ctx.AddObjectToAsset("Main", asset);
            ctx.SetMainObject(asset);

            using (var reader = new BinaryReader(new FileStream(ctx.assetPath, FileMode.Open)))
            {
                var version = reader.ReadUInt32();

                uint comboTextureBytes;
                uint materialIdsBytes;
                uint configrationIdsBytes;

                if (version == 4)
                {
                    reader.BaseStream.Seek(WidthOffset, SeekOrigin.Begin);
                    asset.Width = reader.ReadUInt32();

                    reader.BaseStream.Seek(HeightOffset, SeekOrigin.Begin);
                    asset.Height = reader.ReadUInt32();

                    reader.BaseStream.Seek(HighPerLowOffset, SeekOrigin.Begin);
                    asset.HighPerLow = reader.ReadUInt32();

                    reader.BaseStream.Seek(MaxLodOffset, SeekOrigin.Begin);
                    asset.MaxLod = reader.ReadUInt32();

                    reader.BaseStream.Seek(GridDistanceOffset, SeekOrigin.Begin);
                    asset.GridDistance = reader.ReadSingle();

                    reader.BaseStream.Seek(HeightFormatOffset, SeekOrigin.Begin);
                    asset.HeightFormat = reader.ReadUInt32();

                    reader.BaseStream.Seek(HeightFormatOffset, SeekOrigin.Begin);
                    asset.HeightFormat = reader.ReadUInt32();

                    reader.BaseStream.Seek(HeightRangeMaxOffset, SeekOrigin.Begin);
                    asset.HeightRangeMax = reader.ReadSingle();

                    reader.BaseStream.Seek(HeightRangeMinOffset, SeekOrigin.Begin);
                    asset.HeightRangeMin = reader.ReadSingle();

                    reader.BaseStream.Seek(ComboTextureBytesOffset, SeekOrigin.Begin);
                    comboTextureBytes = reader.ReadUInt32();

                    reader.BaseStream.Seek(MaterialIdsBytesOffset, SeekOrigin.Begin);
                    materialIdsBytes = reader.ReadUInt32();

                    reader.BaseStream.Seek(ConfigrationIdsBytesOffset, SeekOrigin.Begin);
                    configrationIdsBytes = reader.ReadUInt32();

                    reader.BaseStream.Seek(DistanceHeightmapWidthOffset, SeekOrigin.Begin);
                    asset.DistanceHeightmapWidth = reader.ReadUInt32();

                    reader.BaseStream.Seek(DistanceHeightmapHeightOffset, SeekOrigin.Begin);
                    asset.DistanceHeightmapHeight = reader.ReadUInt32();
                }
                else
                {
                    Debug.LogError("Unrecognized tre2 version number: " + version);
                    return;
                }

                // Read heightmaps.
                reader.BaseStream.Seek(HeightmapsOffset, SeekOrigin.Begin);

                // FIXME
                // The first few are not heightmaps; the 5th one onwards are, though
                for (var i = 0; i < 7; i++)
                {
                    var resolution = asset.DistanceHeightmapHeight / 2;
                    if (i >= 6)
                    {
                        resolution *= 2;
                    }

                    var heights = new float[resolution, resolution];

                    for (var x = 0; x < resolution; x++)
                    {
                        for (var y = 0; y < resolution; y++)
                        {
                            var val = reader.ReadSingle();

                            // TODO Figure out wtf the first few heightmaps are
                            if (i >= 4)
                            {
                                val = (val - asset.HeightRangeMin) / (asset.HeightRangeMax - asset.HeightRangeMin);
                            }

                            heights[y, x] = val;
                        }
                    }

                    var heightmap =
                        new Texture2D((int)resolution, (int)resolution, TextureFormat.RFloat, true)
                    {
                        name =
                            $"Heightmap {i}"
                    };
                    heightmap.SetPixels((from height in heights.Cast <float>()
                                         select new Color(height, 0, 0)).ToArray());
                    heightmap.Apply(true);
                    asset.DistanceHeightmaps.Add(heightmap);

                    ctx.AddObjectToAsset(heightmap.name, heightmap);
                }

                // Read combo texture.
                {
                    var resolution = Mathf.FloorToInt(Mathf.Sqrt(comboTextureBytes / 4));
                    var vals       = new Color32[resolution, resolution];

                    for (var x = 0; x < resolution; x++)
                    {
                        for (var y = 0; y < resolution; y++)
                        {
                            var r = reader.ReadByte();
                            var g = reader.ReadByte();
                            var b = reader.ReadByte();
                            var a = reader.ReadByte();

                            vals[y, x] = new Color32(r, g, b, a);
                        }
                    }

                    var combo =
                        new Texture2D((int)resolution, (int)resolution, TextureFormat.RGBA32, true)
                    {
                        name = "ComboTexture"
                    };
                    combo.SetPixels32((from height in vals.Cast <Color32>()
                                       select height).ToArray());
                    combo.Apply(true);
                    asset.ComboTexture = combo;

                    ctx.AddObjectToAsset(combo.name, combo);
                }

                // Read material IDs.
                {
                    var resolution = Mathf.FloorToInt(Mathf.Sqrt(materialIdsBytes / 4));
                    var vals       = new Color32[resolution, resolution];

                    for (var x = 0; x < resolution; x++)
                    {
                        for (var y = 0; y < resolution; y++)
                        {
                            var r = reader.ReadByte();
                            var g = reader.ReadByte();
                            var b = reader.ReadByte();
                            var a = reader.ReadByte();

                            vals[y, x] = new Color32(r, g, b, a);
                        }
                    }

                    var ids =
                        new Texture2D((int)resolution, (int)resolution, TextureFormat.RGBA32, true)
                    {
                        name = "Material IDs"
                    };
                    ids.SetPixels32((from height in vals.Cast <Color32>()
                                     select height).ToArray());
                    ids.Apply(true);
                    asset.MaterialIds = ids;

                    ctx.AddObjectToAsset(ids.name, ids);
                }

                // Read configration IDs.
                {
                    var resolution = Mathf.FloorToInt(Mathf.Sqrt(configrationIdsBytes / 4));
                    var vals       = new Color32[resolution, resolution];

                    for (var x = 0; x < resolution; x++)
                    {
                        for (var y = 0; y < resolution; y++)
                        {
                            var r = reader.ReadByte();
                            var g = reader.ReadByte();
                            var b = reader.ReadByte();
                            var a = reader.ReadByte();

                            vals[y, x] = new Color32(r, g, b, a);
                        }
                    }

                    var configration =
                        new Texture2D((int)resolution, (int)resolution, TextureFormat.RGBA32, true)
                    {
                        name = "Configration IDs"
                    };
                    configration.SetPixels32((from height in vals.Cast <Color32>()
                                              select height).ToArray());
                    configration.Apply(true);
                    asset.ConfigrationIds = configration;

                    ctx.AddObjectToAsset(configration.name, configration);
                }
            }
        }