/// <summary> /// Compiles the <see cref="Tileset"/> using the specified source data, in order to /// generate optimized target data for rendering and collision detection. /// </summary> public void Compile() { // Clear previous data this.DiscardCompiledData(); // Compile new tileset data using input configs, while // potentially re-using existing data structures. TilesetCompiler compiler = new TilesetCompiler(); TilesetCompilerOutput data = compiler.Compile(new TilesetCompilerInput { TileInput = this.tileInput, RenderConfig = this.renderConfig, AutoTileConfig = this.autoTileConfig, ExistingOutput = new TilesetCompilerOutput { RenderData = this.renderData, TileData = this.tileData, AutoTileData = this.autoTileData } }); // Apply compiled data to the internal tileset data this.renderData = data.RenderData; this.tileData = data.TileData; this.autoTileData = data.AutoTileData; this.tileCount = data.TileCount; this.emptyTileIndex = data.EmptyTileIndex; this.GenerateRenderMaterial(); this.compiled = true; this.compileHash = this.GetCompileHashCode(); }
/// <summary> /// Compiles a <see cref="Tileset"/> using its specified source data, in order to /// generate optimized target data for rendering and collision detection. /// </summary> public TilesetCompilerOutput Compile(TilesetCompilerInput input) { // Clear private working data before beginning a new operation this.ClearWorkingData(); // Initialize private working data with the required space for our new input this.InitWorkingData(input); // Gather data on AutoTiles that are partially transformed from the input tileset, // and partially generated from existing tiles as part of the compilation. this.GatherAutoTileData(input.AutoTileConfig); // Generate metadata for scheduled tiles this.GenerateTileMetadata(); // Draw output pixel data for (int renderInputIndex = 0; renderInputIndex < input.RenderConfig.Count; renderInputIndex++) { TilesetRenderInput renderInput = input.RenderConfig[renderInputIndex] ?? DefaultRenderInput; PixelData sourceLayerData = (renderInput.SourceData.Res ?? Pixmap.Checkerboard.Res).MainLayer; // Determine overall geometry values for this layer, such as tile bounds and texture sizes LayerGeometry layerGeometry = this.CalculateLayerGeometry(renderInput, sourceLayerData); // Generate pixel data and atlas values for this layer's texture LayerPixelData targetLayerData = this.ComposeLayerPixelData( renderInput, sourceLayerData, layerGeometry); // Create the texture to be used for this rendering input using (Pixmap targetPixmap = new Pixmap(targetLayerData.PixelData)) { targetPixmap.Atlas = targetLayerData.Atlas; Texture targetTexture = new Texture( targetPixmap, TextureSizeMode.Enlarge, renderInput.TargetMagFilter, renderInput.TargetMinFilter, TextureWrapMode.Clamp, TextureWrapMode.Clamp, renderInput.TargetFormat); this.renderData.Add(targetTexture); } } // Retrieve texture atlas data for quick lookup during rendering if (this.renderData.Count > 0) { for (int i = 0; i < this.tiles.Count; i++) { this.renderData[0].LookupAtlas(i, out this.tiles.Data[i].TexCoord0); } } // Prepare output, keeping existing structures to avoid allocations TilesetCompilerOutput output = input.ExistingOutput; output.TileCount = this.outputTileCount; output.TileData = output.TileData ?? new RawList <TileInfo>(input.TileInput.Count); output.TileData.Clear(); this.tiles.CopyTo(output.TileData, 0, this.tiles.Count); output.RenderData = output.RenderData ?? new List <Texture>(this.renderData); output.RenderData.Clear(); output.RenderData.AddRange(this.renderData); output.AutoTileData = output.AutoTileData ?? new List <TilesetAutoTileInfo>(); output.AutoTileData.Clear(); this.TransformAutoTileData(output.AutoTileData); output.EmptyTileIndex = this.GetEmptyTileIndex(); this.ClearWorkingData(); return(output); }
/// <summary> /// Compiles a <see cref="Tileset"/> using its specified source data, in order to /// generate optimized target data for rendering and collision detection. /// </summary> public TilesetCompilerOutput Compile(TilesetCompilerInput input) { TilesetCompilerOutput output = input.ExistingOutput; output.TileData = output.TileData ?? new RawList <TileInfo>(input.TileInput.Count); output.RenderData = output.RenderData ?? new List <Texture>(); output.AutoTileData = output.AutoTileData ?? new List <TilesetAutoTileInfo>(); // Clear existing data, but keep the sufficiently big data structures output.TileData.Clear(); output.RenderData.Clear(); output.AutoTileData.Clear(); // Determine how many source tiles we have int sourceTileCount = int.MaxValue; for (int renderInputIndex = 0; renderInputIndex < input.RenderConfig.Count; renderInputIndex++) { TilesetRenderInput renderInput = input.RenderConfig[renderInputIndex] ?? DefaultRenderInput; PixelData sourceLayerData = (renderInput.SourceData.Res ?? Pixmap.Checkerboard.Res).MainLayer; LayerGeometry layerGeometry = this.CalculateLayerGeometry(renderInput, sourceLayerData); sourceTileCount = Math.Min(sourceTileCount, layerGeometry.SourceTileCount); } if (input.RenderConfig.Count == 0) { sourceTileCount = 0; } // Transform AutoTile data for (int autoTileIndex = 0; autoTileIndex < input.AutoTileConfig.Count; autoTileIndex++) { TilesetAutoTileInput autoTileInput = input.AutoTileConfig[autoTileIndex]; TilesetAutoTileInfo autoTileInfo = this.TransformAutoTileData( autoTileIndex, autoTileInput, output.TileData, sourceTileCount); output.AutoTileData.Add(autoTileInfo); } // Initialize all tiles to being visually empty. They will be subtractively updated // during output pixel data generation in the next step. { int tileDataCount = output.TileData.Count; TileInfo[] tileData = output.TileData.Data; for (int i = 0; i < tileDataCount; i++) { tileData[i].IsVisuallyEmpty = true; } } // Generate output pixel data for (int renderInputIndex = 0; renderInputIndex < input.RenderConfig.Count; renderInputIndex++) { TilesetRenderInput renderInput = input.RenderConfig[renderInputIndex] ?? DefaultRenderInput; PixelData sourceLayerData = (renderInput.SourceData.Res ?? Pixmap.Checkerboard.Res).MainLayer; // Determine overal geometry values for this layer, such as tile bounds and texture sizes LayerGeometry layerGeometry = this.CalculateLayerGeometry(renderInput, sourceLayerData); // Generate pixel data and atlas values for this layer's texture LayerPixelData targetLayerData = this.GenerateLayerPixelData( renderInput, sourceLayerData, layerGeometry, output.TileData); // Create the texture to be used for this rendering input using (Pixmap targetPixmap = new Pixmap(targetLayerData.PixelData)) { targetPixmap.Atlas = targetLayerData.Atlas; Texture targetTexture = new Texture( targetPixmap, TextureSizeMode.Enlarge, renderInput.TargetMagFilter, renderInput.TargetMinFilter, TextureWrapMode.Clamp, TextureWrapMode.Clamp, renderInput.TargetFormat); output.RenderData.Add(targetTexture); } } // Generate additional per-tile data this.TransformTileData(input.TileInput, output.TileData, output.RenderData); // Apply global tileset stats output.TileCount = sourceTileCount; return(output); }