public static Voxeland5.Voxeland voxeland; //TODO static is not serialized //TODO: somehow assign voxeland on data asssign or window open #endif //[System.Diagnostics.Conditional("VOXELAND")] //wtf it does not work! public override void Generate(CoordRect rect, Chunk.Results results, Chunk.Size terrainSize, int seed, Func <float, bool> stop = null) { #if VOXELAND if (stop != null && stop(0)) { return; } //finding instance //Voxeland5.Voxeland voxeland = null; //foreach (Voxeland5.Voxeland v in Voxeland5.Voxeland.instances) // if (v.data.generator.mapMagicGens.ContainsGenerator(this)) voxeland = v; if (voxeland == null) { return; } //preparing random //Noise noise = new Noise(123, permutationCount:512); //random to floor floats //preparing area Voxeland5.Data.Area area = new Voxeland5.Data.Area(); area.Init(rect.offset.x / terrainSize.resolution, rect.offset.z / terrainSize.resolution, terrainSize.resolution, null); //TODO get height factor int heightFactor = 200; //iterating layers for (int l = 0; l < layers.Length; l++) { Layer layer = layers[l]; if (!layer.enabled) { continue; } int blockType = layer.blockType; if (blockType >= voxeland.landTypes.array.Length) { blockType = Voxeland5.Data.emptyByte; } //loading inputs Matrix src = (Matrix)layer.input.GetObject(results); Matrix heightSrc = (Matrix)layer.heightInput.GetObject(results); //SpatialHash objectsSrc = (SpatialHash)layer.objectInput.GetObject(results); if (src == null) { continue; } //apply switch (layer.applyType) { //case Voxeland5.Generator.LayerOverlayType.add: area.AddLayer(src, blockType, heightFactor:heightFactor, noise:noise); break; //case Voxeland5.Generator.LayerOverlayType.clampAppend: area.ClampAppendLayer(src, blockType, heightFactor:heightFactor, noise:noise); break; //case Voxeland5.Generator.LayerOverlayType.absolute: area.SetLayer(src, heightSrc, blockType, heightFactor:heightFactor, noise:noise); break; //case Voxeland5.Generator.LayerOverlayType.paint: area.PaintLayer(src, blockType, paintThickness:layer.paintThickness, noise:noise); break; case Voxeland5.Generator.LayerOverlayType.add: area.AddLayer(src.rect.offset.x, src.rect.offset.z, src.rect.size.x, src.array, blockType, heightFactor: heightFactor); break; case Voxeland5.Generator.LayerOverlayType.clampAppend: area.ClampAppendLayer(src.rect.offset.x, src.rect.offset.z, src.rect.size.x, src.array, blockType, heightFactor: heightFactor); break; case Voxeland5.Generator.LayerOverlayType.absolute: area.SetLayer(src.rect.offset.x, src.rect.offset.z, src.rect.size.x, src.array, heightSrc != null? heightSrc.array : null, blockType, heightFactor: heightFactor); break; case Voxeland5.Generator.LayerOverlayType.paint: area.PaintLayer(src.rect.offset.x, src.rect.offset.z, src.rect.size.x, src.array, blockType, paintThickness: layer.paintThickness); break; } } //getting outputs MultiDict <int, int> typeToLayer = new MultiDict <int, int>(); for (int l = 0; l < layers.Length; l++) { typeToLayer.Add(layers[l].blockType, l); } Matrix[] layerMatrices = new Matrix[layers.Length]; for (int l = 0; l < layerMatrices.Length; l++) { layerMatrices[l] = new Matrix(rect); } for (int x = 0; x < rect.size.x; x++) { Voxeland5.Data.Area.Line line = area.lines[x]; for (int z = 0; z < rect.size.z; z++) { int topType = line.columns[z].topType; if (topType == Voxeland5.Data.emptyByte) { continue; //empty column } List <int> typeLayerNums = typeToLayer[topType]; #if WDEBUG if (typeLayerNums == null) { Debug.LogError("This should not happen " + topType); } #endif int matrixPos = z * rect.size.x + x; for (int m = 0; m < typeLayerNums.Count; m++) { layerMatrices[typeLayerNums[m]].array[matrixPos] = 1; } } } for (int l = 0; l < layers.Length; l++) { layers[l].output.SetObject(results, layerMatrices[l]); } //saving results areaOutput.SetObject(results, area); #endif }
public static void Process(CoordRect rect, Chunk.Results results, GeneratorsAsset gens, Chunk.Size terrainSize, Func <float, bool> stop = null) { #if VOXELAND if (stop != null && stop(0)) { return; } if (voxeland == null) { return; } //TODO get height factor int heightFactor = 200; //finding area by rect offset Coord areaCoord = Coord.PickCell(rect.offset.x, rect.offset.z, voxeland.data.areaSize); Voxeland5.Data.Area area = voxeland.data.areas[areaCoord.x, areaCoord.z]; //clearing objects area.ClearObjects(); //preparing random Noise noise = new Noise(12345); //to disable biome objects //processing foreach (VoxelandObjectsOutput gen in gens.GeneratorsOfType <VoxelandObjectsOutput>(onlyEnabled:true, checkBiomes:true)) { //reading output directly //Output output = gen.areaOutput; if (stop != null && stop(0)) { return; //checking stop before reading output } //if (!results.results.ContainsKey(output)) continue; //Voxeland5.Data.Area genArea = (Voxeland5.Data.Area)results.results[output]; //loading biome matrix Matrix biomeMask = null; if (gen.biome != null) { object biomeMaskObj = gen.biome.mask.GetObject(results); if (biomeMaskObj == null) { continue; //adding nothing if biome has no mask } biomeMask = (Matrix)biomeMaskObj; if (biomeMask == null) { continue; } if (biomeMask.IsEmpty()) { continue; //optimizing empty biomes } } //iterating layers for (int l = 0; l < gen.layers.Length; l++) { Layer layer = gen.layers[l]; //loading inputs SpatialHash src = (SpatialHash)layer.input.GetObject(results); if (src == null) { continue; } foreach (SpatialObject obj in src.AllObjs()) { int objX = (int)(obj.pos.x + 0.5f); int objZ = (int)(obj.pos.y + 0.5f); //biome masking float biomeVal = 1; if (gen.biome != null) { if (biomeMask == null) { biomeVal = 0; } else { biomeVal = biomeMask[objX, objZ]; } } if (biomeVal < noise.Random(objX, objZ)) { continue; } //flooring float terrainHeight = layer.relativeHeight? results.heights[objX, objZ] : 0; int objHeight = (int)((obj.height + terrainHeight) * heightFactor + 0.5f); //area.AddObject(new CoordDir(objX, objHeight, objZ), (short)l); area.AddObject(objX, objHeight, objZ, 0, (short)l); } } } //pushing to apply if (stop != null && stop(0)) { return; } results.apply.CheckAdd(typeof(VoxelandOutput), null, replace: true); #endif }
public static void Process(CoordRect rect, Chunk.Results results, GeneratorsAsset gens, Chunk.Size terrainSize, Func <float, bool> stop = null) { #if VOXELAND if (stop != null && stop(0)) { return; } if (voxeland == null) { return; } //finding area by rect offset Coord areaCoord = Coord.PickCell(rect.offset.x, rect.offset.z, voxeland.data.areaSize); Voxeland5.Data.Area area = voxeland.data.areas[areaCoord.x, areaCoord.z]; //clearing grass area.ClearGrass(); //preparing random //Noise noise = new Noise(12345); //to switch grass depending on it's opacity //processing foreach (VoxelandGrassOutput gen in gens.GeneratorsOfType <VoxelandGrassOutput>(onlyEnabled:true, checkBiomes:true)) { //reading output directly if (stop != null && stop(0)) { return; //checking stop before reading output } //loading biome matrix Matrix biomeMask = null; if (gen.biome != null) { object biomeMaskObj = gen.biome.mask.GetObject(results); if (biomeMaskObj == null) { continue; //adding nothing if biome has no mask } biomeMask = (Matrix)biomeMaskObj; if (biomeMask == null) { continue; } if (biomeMask.IsEmpty()) { continue; //optimizing empty biomes } } //iterating layers for (int l = 0; l < gen.layers.Length; l++) { Layer layer = gen.layers[l]; //loading inputs Matrix src = (Matrix)layer.input.GetObject(results); if (src == null) { continue; } //multiplying with biome mask - in SetGrassLayer //apply //area.SetGrassLayer(src, (byte)l, layer.density, noise:noise, layerNum:l, mask:biomeMask); area.SetGrassLayer(src.rect.offset.x, src.rect.offset.z, src.rect.size.x, src.array, (byte)l, layer.density, l, biomeMask == null? null : biomeMask.array); } } //pushing to apply if (stop != null && stop(0)) { return; } results.apply.CheckAdd(typeof(VoxelandOutput), null, replace: true); #endif }
public static void Process(CoordRect rect, Chunk.Results results, GeneratorsAsset gens, Chunk.Size terrainSize, Func <float, bool> stop = null) { #if VOXELAND if (stop != null && stop(0)) { return; } if (voxeland == null) { return; } //TODO get height factor int heightFactor = 200; //finding area by rect offset Coord areaCoord = Coord.PickCell(rect.offset.x, rect.offset.z, voxeland.data.areaSize); Voxeland5.Data.Area area = voxeland.data.areas[areaCoord.x, areaCoord.z]; //clearing area area.ClearLand(); //finding a list of areas and their opacities List <Voxeland5.Data.Area> areas = new List <Voxeland5.Data.Area>(); List <Matrix> opacities = new List <Matrix>(); foreach (VoxelandOutput gen in gens.GeneratorsOfType <VoxelandOutput>(onlyEnabled:true, checkBiomes:true)) { //reading output directly Output output = gen.areaOutput; if (stop != null && stop(0)) { return; //checking stop before reading output } if (!results.results.ContainsKey(output)) { continue; } Voxeland5.Data.Area genArea = (Voxeland5.Data.Area)results.results[output]; //loading biome matrix Matrix biomeMask = null; if (gen.biome != null) { object biomeMaskObj = gen.biome.mask.GetObject(results); if (biomeMaskObj == null) { continue; //adding nothing if biome has no mask } biomeMask = (Matrix)biomeMaskObj; if (biomeMask == null) { continue; } if (biomeMask.IsEmpty()) { continue; //optimizing empty biomes } } areas.Add(genArea); opacities.Add(biomeMask); } //merge areas using biome mask if (areas.Count >= 2) //area.MixAreas(areas.ToArray(), opacities.ToArray()); { float[][] opacityArrays = new float[opacities.Count][]; for (int i = 0; i < opacityArrays.Length; i++) { if (opacities[i] != null) { opacityArrays[i] = opacities[i].array; } } area.MixAreas(areas.ToArray(), rect.offset.x, rect.offset.z, rect.size.x, opacityArrays); } else { Voxeland5.Data.Area.CopyLand(areas[0], area); } //reading heights if (results.heights == null || results.heights.rect.size.x != rect.size.x) { results.heights = new Matrix(rect); } if (results.heights.rect != rect) { results.heights.Resize(rect); } results.heights.Clear(); for (int x = 0; x < results.heights.rect.size.x; x++) { for (int z = 0; z < results.heights.rect.size.z; z++) { results.heights[x + results.heights.rect.offset.x, z + results.heights.rect.offset.z] = 1f * area.lines[x].columns[z].topLevel / heightFactor; } } //pushing to apply if (stop != null && stop(0)) { return; } results.apply.CheckAdd(typeof(VoxelandOutput), null, replace: true); #endif }