public void Execute(int i)
 {
     if (double.IsNegativeInfinity(Heights[i]) == false)
     {
         Heights[i] += SgtTerrainTopology.Sample_Cubic_Equirectangular(Data, Stride, Offset, Size, Points[i]) * Displacement;
     }
 }
            public void Execute()
            {
                var currentExpanded = CurrentOuter.SizeX > 0 && CurrentOuter.SizeY > 0 ? CurrentOuter.GetExpanded(2) : default(SgtLongRect);
                var pendingExpanded = PendingOuter.GetExpanded(2);
                var expandedStep    = (int)currentExpanded.SizeX + 1;
                var index           = 0;

                for (var y = pendingExpanded.minY; y <= pendingExpanded.maxY; y++)
                {
                    for (var x = pendingExpanded.minX; x <= pendingExpanded.maxX; x++)
                    {
                        if (currentExpanded.Contains(x, y) == true)
                        {
                            var expandedX = (int)(x - currentExpanded.minX);
                            var expandedY = (int)(y - currentExpanded.minY);

                            PendingPoints[index] = CurrentPoints[expandedX + expandedY * expandedStep];

                            Heights[index] = double.NegativeInfinity;
                        }
                        else
                        {
                            var faceU = (x + Middle) * Step;
                            var faceV = (y + Middle) * Step;
                            var faceW = 0.0;

                            if (faceU < 0.0)
                            {
                                faceW = -faceU; faceU = 0.0;
                            }
                            if (faceV < 0.0)
                            {
                                faceW = -faceV; faceV = 0.0;
                            }
                            if (faceU > 1.0)
                            {
                                faceW = faceU - 1.0; faceU = 1.0;
                            }
                            if (faceV > 1.0)
                            {
                                faceW = faceV - 1.0; faceV = 1.0;
                            }

                            var cubePos = CubeC + CubeH * faceU + CubeV * faceV + CubeO * faceW;

                            PendingPoints[index] = SgtTerrainTopology.UnitCubeToSphere(cubePos);

                            Heights[index] = Radius;
                        }

                        index++;
                    }
                }
            }
Пример #3
0
        public SgtTerrainQuad(SgtTerrainCube newCube, int newFace, double newTwist, double3 newCubeC, double3 newCubeH, double3 newCubeV)
        {
            cube  = newCube;
            face  = newFace;
            twist = newTwist;
            cubeC = SgtTerrainTopology.Tilt(newCubeC);
            cubeH = SgtTerrainTopology.Tilt(newCubeH);
            cubeV = SgtTerrainTopology.Tilt(newCubeV);
            cubeO = math.cross(math.normalize(cubeH), cubeV);

            Allocate();
        }
Пример #4
0
        public double3 GetAboveGroundObserverCubePoint()
        {
            var localPos    = (double3)(float3)transform.InverseTransformPoint(WorldObserver);
            var localAlt    = math.length(localPos);
            var localHeight = GetLocalHeight(localPos);
            var cubePoint   = SgtTerrainTopology.VectorToUnitCube(localPos);

            if (localAlt > localHeight && localHeight > 0.0)
            {
                cubePoint *= localAlt / localHeight;
            }

            return(cubePoint);
        }
            public void Execute(int i)
            {
                if (double.IsNegativeInfinity(Heights[i]) == false)
                {
                    var weight = 1.0f;

                    if (AreaWeights.Length > 0)
                    {
                        weight = SgtTerrainTopology.Sample_Cubic_Equirectangular(AreaWeights, AreaSplatCount, Area, AreaSize, Points[i]);
                        weight = math.clamp(20000.0f - weight, 0.0f, 20000.0f) / 20000.0f;
                    }

                    if (weight > 0.0f)
                    {
                        Heights[i] -= FBM(Points[i] * Frequency, Amplitude) * weight;
                    }
                }
            }
Пример #6
0
        public double3 GetSpherePoint()
        {
            var localPos    = (double3)(float3)transform.InverseTransformPoint(WorldObserver);
            var localAlt    = math.length(localPos);
            var localHeight = GetLocalHeight(localPos);
            var localDist   = math.abs(localAlt - localHeight) / radius;

            for (var i = 0; i < distances.Count; i++)
            {
                var distance = detail * math.pow(0.5, 1 + i);
                var frac     = math.saturate(localDist / distance);

                distance *= math.cos(math.asin(frac));

                distances[i] = distance;
            }

            return(SgtTerrainTopology.Unwarp(SgtTerrainTopology.VectorToUnitCube(SgtTerrainTopology.Untilt(localPos))));
        }
Пример #7
0
        private void UpdateRoot()
        {
            var point  = cachedTerrain.GetAboveGroundObserverCubePoint();
            var middle = resolution / 2;
            var center = middle * point;
            var bounds = new SgtLongBounds((long)center.x, (long)center.y, (long)center.z, radius);
            var outer  = new SgtLongBounds(-middle, -middle, middle - 1, middle, middle, middle);

            Mark();

            for (var i = 0; i < 6; i++)
            {
                var quadBounds = SgtTerrainTopology.GetQuadBounds(i, bounds);

                quadBounds.ClampTo(outer);

                UpdateColliders(i, quadBounds, middle);
            }

            Sweep();
        }
Пример #8
0
        private void Schedule(Chunk chunk)
        {
            var rng = (double)noise.snoise((float3)chunk.PointC);

            chunk.Clones = new List <GameObject>();

            var jobArea           = default(int);
            var jobAreaSize       = default(int2);
            var jobAreaSplatCount = default(int);
            var jobAreaWeights    = default(NativeArray <float>);

            if (cachedTerrain.Areas != null && cachedTerrain.Areas.SplatCount > 0)
            {
                jobArea           = math.clamp(area, 0, cachedTerrain.Areas.SplatCount - 1);
                jobAreaSize       = cachedTerrain.Areas.Size;
                jobAreaSplatCount = cachedTerrain.Areas.SplatCount;
                jobAreaWeights    = cachedTerrain.Areas.Weights;
            }
            else
            {
                jobArea           = 0;
                jobAreaSize       = int2.zero;
                jobAreaSplatCount = 0;
                jobAreaWeights    = tempWeights;
            }

            for (var i = 0; i < limit; i++)
            {
                var u      = (float)(math.abs(rng * 6829.0) % 1.0);
                var v      = (float)(math.abs(rng * 7351.0) % 1.0);
                var point  = chunk.PointC + chunk.PointH * u + chunk.PointV * v;
                var weight = 1.0f;

                if (jobAreaWeights.Length > 0)
                {
                    weight = SgtTerrainTopology.Sample_Cubic_Equirectangular(jobAreaWeights, jobAreaSplatCount, jobArea, jobAreaSize, point);

                    if (weight > 0.0f)
                    {
                        weight = math.sqrt(weight) / 255.0f;
                    }

                    weight = math.saturate(1.0f - weight);

                    weight = Mathf.InverseLerp(threshold, 1.0f, weight);
                }

                var sample = (float)(math.abs(rng * 4334.94437) % 1.0);

                if (sample > weight)
                {
                    break;
                }

                var clone = Spawn(point, chunk.PointH * 0.01, chunk.PointV * 0.01, sample);

                chunk.Clones.Add(clone.gameObject);

                rng *= 3.12345;
            }
        }
Пример #9
0
        private void UpdateLod()
        {
            var spherePoint = GetSpherePoint();

            for (var i = 0; i < cubes.Count; i++)
            {
                var cube       = cubes[i];
                var cubeBounds = GetCubeBound(i, spherePoint, cube.Middle);
                var cubeLimits = new SgtLongBounds(0, 0, 0, cube.Middle);

                for (var j = 0; j < 6; j++)
                {
                    var quad       = cube.Quads[j];
                    var quadBounds = SgtTerrainTopology.GetQuadBounds(j, cubeBounds);

                    if (i == 0)
                    {
                        quad.PendingOuter = new SgtLongBounds(0, 0, 0, cube.Middle);
                        quad.VirtualOuter = new SgtLongBounds(0, 0, 0, cube.Middle * 2);
                    }
                    else
                    {
                        var prevCube       = cubes[i - 1];
                        var prevQuad       = prevCube.Quads[j];
                        var prevResolution = prevCube.Resolution;

                        quad.PendingOuter = prevQuad.PendingInner * 2;
                        quad.VirtualOuter = prevQuad.VirtualInner * 2;
                    }

                    if (quadBounds.minZ <= cube.Middle && quadBounds.maxZ >= cube.Middle)
                    {
                        quad.VirtualInner = quadBounds;
                    }
                    else
                    {
                        quad.VirtualInner = default(SgtLongBounds);
                    }

                    quad.PendingInner = quad.VirtualInner;
                    quad.PendingInner.ClampTo(cubeLimits);

                    if (quad.PendingOuter.SizeX < 0 || quad.PendingOuter.SizeY < 0 || quad.PendingOuter.SizeZ < 0)
                    {
                        quad.PendingOuter = default(SgtLongBounds);
                        quad.PendingInner = default(SgtLongBounds);
                    }

                    var forceUpdate = false;

                    if (dirty == true)
                    {
                        if (quad.CurrentOuter.Volume > 0 || quad.CurrentInner.Volume > 0)
                        {
                            forceUpdate = true;

                            quad.CurrentOuter.Clear();
                            quad.CurrentInner.Clear();
                        }
                    }

                    if (quad.CurrentOuter.Volume == 0)
                    {
                        quad.CurrentOuter = default(SgtLongBounds);
                    }
                    if (quad.PendingOuter.Volume == 0)
                    {
                        quad.PendingOuter = default(SgtLongBounds);
                    }
                    if (quad.CurrentInner.Volume == 0)
                    {
                        quad.CurrentInner = default(SgtLongBounds);
                    }
                    if (quad.PendingInner.Volume == 0)
                    {
                        quad.PendingInner = default(SgtLongBounds);
                    }

                    if (quad.CurrentOuter != quad.PendingOuter || quad.CurrentInner != quad.PendingInner || forceUpdate == true)
                    {
                        pendingQuads.Push(quad);
                    }
                }
            }

            dirty = false;
        }