Example #1
0
            public void Execute(int index)
            {
                // Use cols=x and rows=y for height data
                int x = JobA.Col(index, hDim);
                int y = JobA.Row(index, hDim);

                float rx           = (float)x / div;
                float ry           = (float)y / div;
                int   ix           = Mathf.FloorToInt(rx);
                int   iy           = Mathf.FloorToInt(ry);
                float sfracx       = (float)x / (float)(hDim - 1);
                float sfracy       = (float)y / (float)(hDim - 1);
                float fracx        = (float)(x - ix * div) / div;
                float fracy        = (float)(y - iy * div) / div;
                float scaledHeight = 0;

                // Bicubic sample small height map for base terrain elevation
                x1            = TerrainHelper.CubicInterpolator(baseHeightValue[JobA.Idx(0, 3, sd)], baseHeightValue[JobA.Idx(1, 3, sd)], baseHeightValue[JobA.Idx(2, 3, sd)], baseHeightValue[JobA.Idx(3, 3, sd)], sfracx);
                x2            = TerrainHelper.CubicInterpolator(baseHeightValue[JobA.Idx(0, 2, sd)], baseHeightValue[JobA.Idx(1, 2, sd)], baseHeightValue[JobA.Idx(2, 2, sd)], baseHeightValue[JobA.Idx(3, 2, sd)], sfracx);
                x3            = TerrainHelper.CubicInterpolator(baseHeightValue[JobA.Idx(0, 1, sd)], baseHeightValue[JobA.Idx(1, 1, sd)], baseHeightValue[JobA.Idx(2, 1, sd)], baseHeightValue[JobA.Idx(3, 1, sd)], sfracx);
                x4            = TerrainHelper.CubicInterpolator(baseHeightValue[JobA.Idx(0, 0, sd)], baseHeightValue[JobA.Idx(1, 0, sd)], baseHeightValue[JobA.Idx(2, 0, sd)], baseHeightValue[JobA.Idx(3, 0, sd)], sfracx);
                baseHeight    = TerrainHelper.CubicInterpolator(x1, x2, x3, x4, sfracy);
                scaledHeight += baseHeight * baseHeightScale;

                // Bicubic sample large height map for noise mask over terrain features
                x1          = TerrainHelper.CubicInterpolator(lhm[JobA.Idx(ix, iy + 0, ld)], lhm[JobA.Idx(ix + 1, iy + 0, ld)], lhm[JobA.Idx(ix + 2, iy + 0, ld)], lhm[JobA.Idx(ix + 3, iy + 0, ld)], fracx);
                x2          = TerrainHelper.CubicInterpolator(lhm[JobA.Idx(ix, iy + 1, ld)], lhm[JobA.Idx(ix + 1, iy + 1, ld)], lhm[JobA.Idx(ix + 2, iy + 1, ld)], lhm[JobA.Idx(ix + 3, iy + 1, ld)], fracx);
                x3          = TerrainHelper.CubicInterpolator(lhm[JobA.Idx(ix, iy + 2, ld)], lhm[JobA.Idx(ix + 1, iy + 2, ld)], lhm[JobA.Idx(ix + 2, iy + 2, ld)], lhm[JobA.Idx(ix + 3, iy + 2, ld)], fracx);
                x4          = TerrainHelper.CubicInterpolator(lhm[JobA.Idx(ix, iy + 3, ld)], lhm[JobA.Idx(ix + 1, iy + 3, ld)], lhm[JobA.Idx(ix + 2, iy + 3, ld)], lhm[JobA.Idx(ix + 3, iy + 3, ld)], fracx);
                noiseHeight = TerrainHelper.CubicInterpolator(x1, x2, x3, x4, fracy);

                x1 = TerrainHelper.CubicInterpolator(noiseHeightMultiplierMap[JobA.Idx(0, 3, sd)], noiseHeightMultiplierMap[JobA.Idx(1, 3, sd)], noiseHeightMultiplierMap[JobA.Idx(2, 3, sd)], noiseHeightMultiplierMap[JobA.Idx(3, 3, sd)], sfracx);
                x2 = TerrainHelper.CubicInterpolator(noiseHeightMultiplierMap[JobA.Idx(0, 2, sd)], noiseHeightMultiplierMap[JobA.Idx(1, 2, sd)], noiseHeightMultiplierMap[JobA.Idx(2, 2, sd)], noiseHeightMultiplierMap[JobA.Idx(3, 2, sd)], sfracx);
                x3 = TerrainHelper.CubicInterpolator(noiseHeightMultiplierMap[JobA.Idx(0, 1, sd)], noiseHeightMultiplierMap[JobA.Idx(1, 1, sd)], noiseHeightMultiplierMap[JobA.Idx(2, 1, sd)], noiseHeightMultiplierMap[JobA.Idx(3, 1, sd)], sfracx);
                x4 = TerrainHelper.CubicInterpolator(noiseHeightMultiplierMap[JobA.Idx(0, 0, sd)], noiseHeightMultiplierMap[JobA.Idx(1, 0, sd)], noiseHeightMultiplierMap[JobA.Idx(2, 0, sd)], noiseHeightMultiplierMap[JobA.Idx(3, 0, sd)], sfracx);
                float noiseHeightMultiplier = TerrainHelper.CubicInterpolator(x1, x2, x3, x4, sfracy);

                scaledHeight += noiseHeight * noiseHeightMultiplier;

                // Additional noise mask for small terrain features at ground level
                // small terrain features' height scale should depend on climate of map pixel
                float extraNoiseScaleTopLeft     = extraNoiseScaleBasedOnClimateTopLeft;
                float extraNoiseScaleTopRight    = extraNoiseScaleBasedOnClimateTopRight;
                float extraNoiseScaleBottomLeft  = extraNoiseScaleBasedOnClimateBottomLeft;
                float extraNoiseScaleBottomRight = extraNoiseScaleBasedOnClimateBottomRight;
                //float extraNoiseScale = (1.0f - sfracx) * (1.0f - sfracy) * extraNoiseScaleTopLeft +
                //                        (sfracx) *(1.0f - sfracy) * extraNoiseScaleTopRight +
                //                        (1.0f - sfracx) * (sfracy) * extraNoiseScaleBottomLeft +
                //                        (sfracx) * (sfracx) * extraNoiseScaleBottomRight;
                float extraNoiseScale = TerrainHelper.BilinearInterpolator(extraNoiseScaleTopLeft, extraNoiseScaleBottomLeft, extraNoiseScaleTopRight, extraNoiseScaleBasedOnClimateBottomRight, sfracx, sfracy);
                //float extraNoiseScale = TerrainHelper.BilinearInterpolator(extraNoiseScaleBottomLeft, extraNoiseScaleTopLeft, extraNoiseScaleBasedOnClimateBottomRight, extraNoiseScaleTopRight , sfracx, sfracy);
                //float extraNoiseScale = extraNoiseScaleBasedOnClimate;
                //// prevent seams between different climate map pixels
                //if (x <= 0 || y <= 0 || x >= hDim - 1 || y >= hDim - 1)
                //{
                //    extraNoiseScale = defaultExtraNoiseScale;
                //}
                int   noisex   = mapPixelX * (hDim - 1) + x;
                int   noisey   = (MapsFile.MaxMapPixelY - mapPixelY) * (hDim - 1) + y;
                float lowFreq  = TerrainHelper.GetNoise(noisex, noisey, 0.3f, 0.5f, 0.5f, 1);
                float highFreq = TerrainHelper.GetNoise(noisex, noisey, 0.9f, 0.5f, 0.5f, 1);

                scaledHeight += (lowFreq * highFreq) * extraNoiseScale;

                // Clamp lower values to ocean elevation
                if (scaledHeight < scaledOceanElevation)
                {
                    scaledHeight = scaledOceanElevation;
                }

                // Set sample
                float height = Mathf.Clamp01(scaledHeight / maxTerrainHeight);

                heightmapData[index] = height;
            }