예제 #1
0
        public static int GetTerrainHeight(int x, int y, BiomeDefData biomeDef, NativeArray <float2> offsets, NativeArray <int> terrainCurve)
        {
            var sampleNoise     = Noise.GetHeight(x, y, biomeDef.Octaves, biomeDef.Lacunarity, biomeDef.Persistance, biomeDef.Frequency, offsets, biomeDef.Offset);
            var heightFromNoise = Mathf.FloorToInt(GeometryConsts.CHUNK_HEIGHT * sampleNoise);

            return(math.clamp(terrainCurve[biomeDef.TerrainCurveStartPos + heightFromNoise], 0, GeometryConsts.CHUNK_HEIGHT - 1));
        }
예제 #2
0
        public override void PostConstruct()
        {
            base.PostConstruct();

            var defs = GetAllDefinitions();

            //TODO: count lode array size properly!
            const int MAX_LODES_PER_DEF     = 20;
            const int MAX_THRESHOLD_PER_DEF = MAX_LODES_PER_DEF * GeometryConsts.CHUNK_HEIGHT;

            _biomeDefData         = new NativeArray <BiomeDefData>(defs.Length, Allocator.Persistent);
            _terrainCurvesSampled = new NativeArray <int>(defs.Length * GeometryConsts.CHUNK_HEIGHT, Allocator.Persistent);
            _lodes          = new NativeArray <LodeDefData>(defs.Length * MAX_LODES_PER_DEF, Allocator.Persistent);
            _lodeThresholds = new NativeArray <float>(defs.Length * MAX_THRESHOLD_PER_DEF, Allocator.Persistent);

            var lodeIndex = 0;

            for (var i = 0; i < defs.Length; i++)
            {
                var def = defs[i];

                //////////// BIOME DEF /////////////
                _biomeDefData[i] = new BiomeDefData(def, lodeIndex);

                ////////// TERRAIN CURVES //////////
                CurveHelper.SampleCurve(def.TerrainCurve, _terrainCurvesSampled, i * GeometryConsts.CHUNK_HEIGHT);

                ////////////// LODES //////////////
                foreach (var lodeDef in def.lodeDefs)
                {
                    _lodes[lodeIndex] = new LodeDefData(lodeDef);

                    CurveHelper.SampleCurve(lodeDef.ThresholdByY, _lodeThresholds, lodeIndex * GeometryConsts.CHUNK_HEIGHT);

                    lodeIndex++;
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Generates single voxel on world coordinates - called only by WorldModel when we truly want to generate
        /// and know that coordinates are valid
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z"></param>
        /// <param name="terrainHeight"></param>
        /// <param name="biome"></param>
        /// <param name="lodes"></param>
        /// <param name="lodeTresholds"></param>
        /// <returns></returns>
        public static byte GenerateVoxel(int x, int y, int z, int terrainHeight, BiomeDefData biome, NativeArray <LodeDefData> lodes, NativeArray <float> lodeTresholds)
        {
            //TODO: generate whole column, so height biome and determination etc is not called every voxel!


            // ======== STATIC RULES ========

            if (y == 0)
            {
                return(BlockTypeByte.GREY_STONE);
            }


            // ======== BASIC PASS ========

            byte voxelValue = 0;

            //everything higher then terrainHeight is air
            if (y >= terrainHeight)
            {
                return(BlockTypeByte.AIR);
            }

            //top voxels are grass
            if (y == terrainHeight - 1)
            {
                voxelValue = BlockMaskByte.TOP;
            }
            //3 voxels under grass are dirt
            else if (y >= terrainHeight - 4)
            {
                voxelValue = BlockMaskByte.MIDDLE;
            }
            //rest is rock
            else
            {
                voxelValue = BlockMaskByte.BOTTOM;
            }

            //LODES PASS
            bool lodesPassResolved = false;

            for (var i = biome.LodesStartPos; i < biome.LodesCount; i++)
            {
                var lode = lodes[i];

                if ((lode.BlockMask & voxelValue) == 0)
                {
                    continue; //try next lode
                }
                if (y > lode.MinHeight && y < lode.MaxHeight)
                {
                    var treshold = lodeTresholds[biome.LodesStartPos + i * GeometryConsts.CHUNK_HEIGHT + y];

                    if (Noise.GetLodePresence(lode.Algorithm, x, y, z, lode.Offset, lode.Frequency, treshold))
                    {
                        voxelValue        = lode.BlockId;
                        lodesPassResolved = true;
                        break; //We found our block - continue to next pass!
                    }
                }
            }


            //if no lode was applied, show basic biome block for given placeholder
            if (!lodesPassResolved)
            {
                switch (voxelValue)
                {
                case BlockMaskByte.TOP:
                    voxelValue = biome.TopBlock;
                    break;

                case BlockMaskByte.MIDDLE:
                    voxelValue = biome.MiddleBlock;
                    break;

                case BlockMaskByte.BOTTOM:
                    voxelValue = biome.BottomBlock;
                    break;
                }
            }

            return(voxelValue);
        }