public EnvironmentEvaluation(Vector3D coords) : base()
        {
            //Non Planet Checks
            DistanceFromWorldCenter  = Vector3D.Distance(Vector3D.Zero, coords);
            DirectionFromWorldCenter = Vector3D.Normalize(coords);

            InsideTerritories       = new List <string>();
            InsideStrictTerritories = new List <string>();

            //Planet Checks
            NearestPlanet = SpawnResources.GetNearestPlanet(coords, true);

            if (NearestPlanet == null || !MyAPIGateway.Entities.Exist(NearestPlanet))
            {
                return;
            }

            AltitudeAtPosition = Vector3D.Distance(NearestPlanet.GetClosestSurfacePointGlobal(coords), coords);
            NearestPlanetName  = NearestPlanet.Generator.Id.SubtypeName;
            PlanetDiameter     = NearestPlanet.AverageRadius * 2;

            var planetEntity    = NearestPlanet as IMyEntity;
            var gravityProvider = planetEntity.Components.Get <MyGravityProviderComponent>();

            if (gravityProvider != null)
            {
                if (gravityProvider.IsPositionInRange(coords) == true)
                {
                    IsOnPlanet = true;
                }
            }

            if (!IsOnPlanet)
            {
                return;
            }

            //On Planet Checks
            GravityAtPosition    = gravityProvider.GetGravityMultiplier(coords);
            AtmosphereAtPosition = NearestPlanet.GetAirDensity(coords);
            OxygenAtPosition     = NearestPlanet.GetOxygenForPosition(coords);
            IsNight           = MyVisualScriptLogicProvider.IsOnDarkSide(NearestPlanet, coords);
            WeatherAtPosition = MyVisualScriptLogicProvider.GetWeather(coords) ?? "";

            //Terrain Material Checks
            var upDir         = Vector3D.Normalize(coords - NearestPlanet.PositionComp.WorldAABB.Center);
            var downDir       = upDir * -1;
            var forward       = Vector3D.CalculatePerpendicularVector(upDir);
            var matrix        = MatrixD.CreateWorld(coords, forward, upDir);
            var directionList = new List <Vector3D>();

            directionList.Add(matrix.Forward);
            directionList.Add(matrix.Backward);
            directionList.Add(matrix.Left);
            directionList.Add(matrix.Right);

            var terrainTypes = new Dictionary <string, int>();

            for (int i = 1; i < 12; i++)
            {
                foreach (var direction in directionList)
                {
                    try {
                        var checkCoordsRough   = direction * (i * 15) + coords;
                        var checkSurfaceCoords = NearestPlanet.GetClosestSurfacePointGlobal(checkCoordsRough);
                        var checkMaterial      = NearestPlanet.GetMaterialAt(ref checkSurfaceCoords);

                        if (checkMaterial == null)
                        {
                            continue;
                        }

                        if (terrainTypes.ContainsKey(checkMaterial.MaterialTypeName))
                        {
                            terrainTypes[checkMaterial.MaterialTypeName]++;
                        }
                        else
                        {
                            terrainTypes.Add(checkMaterial.MaterialTypeName, 1);
                        }
                    } catch (Exception e) {
                        Logger.AddMsg("Caught Exception Trying To Determine Terrain Material", true);
                        Logger.AddMsg(e.ToString(), true);
                    }
                }
            }

            string highestCountName   = "";
            int    highestCountNumber = 0;

            foreach (var material in terrainTypes.Keys)
            {
                if (string.IsNullOrWhiteSpace(highestCountName) || terrainTypes[material] > highestCountNumber)
                {
                    highestCountName   = material;
                    highestCountNumber = terrainTypes[material];
                }
            }

            if (!string.IsNullOrWhiteSpace(highestCountName))
            {
                CommonTerrainAtPosition = highestCountName;
            }
        }
Esempio n. 2
0
        public void Draw(bool closestToCamera)
        {
            if (face.water == null || face.water.planet == null)
            {
                return;
            }

            //if (WaterUtils.IsUnderGround(face.water.planet, face.position + (Vector3D.Normalize(position + ((-face.axisA + -face.axisB) * radius) - face.position) * face.water.currentRadius), radius))
            //return;

            if (children != null)
            {
                foreach (var child in children)
                {
                    child.Draw(closestToCamera);
                }
            }
            else
            {
                Vector3D normal1 = Vector3D.Normalize(position + ((-face.axisA + -face.axisB) * radius) - face.position);
                Vector3D normal2 = Vector3D.Normalize(position + ((face.axisA + face.axisB) * radius) - face.position);
                Vector3D normal3 = Vector3D.Normalize(position + ((-face.axisA + face.axisB) * radius) - face.position);
                Vector3D normal4 = Vector3D.Normalize(position + ((face.axisA + -face.axisB) * radius) - face.position);

                Vector3D corner1 = face.water.GetClosestSurfacePoint(face.position + (normal1 * face.water.currentRadius));

                float distToCamera = Vector3.RectangularDistance(corner1, WaterMod.Session.CameraPosition);

                if (distToCamera > 100)
                {
                    if (closestToCamera && (distToCamera > WaterMod.Session.DistanceToHorizon + (radius * 6)))
                    {
                        return;
                    }

                    if (Vector3.Dot((corner1 - WaterMod.Session.CameraPosition), WaterMod.Session.CameraRotation) < WaterData.DotMaxFOV)
                    {
                        return;
                    }
                }

                Vector3D corner2 = face.water.GetClosestSurfacePoint(face.position + (normal2 * face.water.currentRadius));
                Vector3D corner3 = face.water.GetClosestSurfacePoint(face.position + (normal3 * face.water.currentRadius));
                Vector3D corner4 = face.water.GetClosestSurfacePoint(face.position + (normal4 * face.water.currentRadius));

                Vector3D average = ((corner1 + corner2 + corner3 + corner4) / 4.0);

                if (face.water.planet != null)
                {
                    MyPlanet planet = face.water.planet;

                    if (WaterUtils.GetAltitude(planet, average) < -radius * 2 && (planet.GetMaterialAt(ref average) != null && planet.GetMaterialAt(ref corner1) != null && planet.GetMaterialAt(ref corner2) != null && planet.GetMaterialAt(ref corner3) != null && planet.GetMaterialAt(ref corner4) != null))
                    {
                        return;
                    }
                }

                Vector4 WaterColor     = WaterData.WaterColor;
                Vector4 WaterFadeColor = WaterData.WaterFadeColor;
                Vector4 WhiteColor     = Vector4.One;

                float dot = face.water.lit ? MyMath.Clamp(Vector3.Dot(normal1, WaterMod.Session.SunDirection) + 0.22f, 0.22f, 1f) : 1;

                if (face.water.lit)
                {
                    WaterColor      *= dot;
                    WaterColor.W     = WaterData.WaterColor.W;
                    WaterFadeColor  *= dot;
                    WaterFadeColor.W = WaterData.WaterFadeColor.W;
                    WhiteColor       = new Vector4(dot, dot, dot, 1);
                }

                MyQuadD quad = new MyQuadD()
                {
                    Point0 = corner1,
                    Point1 = corner3,
                    Point2 = corner2,
                    Point3 = corner4
                };

                if (!WaterMod.Session.CameraUnderwater && closestToCamera)
                {
                    if (face.water.enableFoam && radius < 128 * WaterMod.Settings.Quality)
                    {
                        Vector3D noisePosition = (average + (Vector3D.One * face.water.waveTimer)) * face.water.waveScale;

                        float intensity = (float)MyMath.Clamp((face.water.noise.GetNoise(noisePosition.X, noisePosition.Y, noisePosition.Z) / 0.25f), 0, 1);

                        if (intensity > 0.1f)
                        {
                            WaterMod.Static.QuadBillboards.Push(new WaterMod.QuadBillboard(ref WaterData.FoamMaterials[textureId], ref quad, WhiteColor * intensity));
                        }

                        if (intensity < 0.9f)
                        {
                            WaterMod.Static.QuadBillboards.Push(new WaterMod.QuadBillboard(ref WaterData.FoamLightMaterials[textureId], ref quad, WhiteColor * (1f - (intensity * intensity))));
                        }
                    }
                }

                if (face.water.transparent)
                {
                    if (closestToCamera)
                    {
                        if (WaterMod.Session.CameraUnderwater)
                        {
                            WaterMod.Static.QuadBillboards.Push(new WaterMod.QuadBillboard(ref face.water.textureId, ref quad, WaterColor * 0.5f));
                        }
                        else
                        {
                            if (detailLevel > 4)
                            {
                                int count = (int)Math.Max(Math.Min(Math.Ceiling((detailLevel - 2) * WaterMod.Settings.Quality), 8), 3);

                                Vector3D layerSeperation = -normal1 * (1.0f / count) * 20f;

                                for (int i = 0; i < count; i++)
                                {
                                    if (i == count - 1)
                                    {
                                        quad.Point0 += layerSeperation;
                                        quad.Point1 += layerSeperation;
                                        quad.Point2 += layerSeperation;
                                        quad.Point3 += layerSeperation;

                                        WaterMod.Static.QuadBillboards.Push(new WaterMod.QuadBillboard(ref face.water.textureId, ref quad, ref WhiteColor));
                                    }
                                    else
                                    {
                                        if (i == 0)
                                        {
                                            WaterMod.Static.QuadBillboards.Push(new WaterMod.QuadBillboard(ref face.water.textureId, ref quad, ref WaterColor));
                                        }
                                        else
                                        {
                                            quad.Point0 += layerSeperation;
                                            quad.Point1 += layerSeperation;
                                            quad.Point2 += layerSeperation;
                                            quad.Point3 += layerSeperation;
                                            WaterMod.Static.QuadBillboards.Push(new WaterMod.QuadBillboard(ref face.water.textureId, ref quad, ref WaterFadeColor));
                                        }
                                    }
                                }
                            }
                            else
                            {
                                WaterMod.Static.QuadBillboards.Push(new WaterMod.QuadBillboard(ref face.water.textureId, ref quad, ref WhiteColor));
                            }
                        }
                    }
                    else
                    {
                        if (WaterMod.Session.CameraUnderwater)
                        {
                            return;
                        }
                        else
                        {
                            WaterMod.Static.QuadBillboards.Push(new WaterMod.QuadBillboard(ref face.water.textureId, ref quad, ref WaterColor));
                            Vector3D offset = normal1 * 100;
                            quad.Point0 += offset;
                            quad.Point1 += offset;
                            quad.Point2 += offset;
                            quad.Point3 += offset;
                            WaterMod.Static.QuadBillboards.Push(new WaterMod.QuadBillboard(ref face.water.textureId, ref quad, ref WhiteColor));
                        }
                    }
                }
                else
                {
                    WaterMod.Static.QuadBillboards.Push(new WaterMod.QuadBillboard(ref face.water.textureId, ref quad, ref WhiteColor));

                    if (!WaterMod.Session.CameraUnderwater)
                    {
                        Vector3D Seperator = normal1 * face.water.waveHeight;

                        quad.Point0 -= Seperator;
                        quad.Point1 -= Seperator;
                        quad.Point2 -= Seperator;
                        quad.Point3 -= Seperator;
                        WaterMod.Static.QuadBillboards.Push(new WaterMod.QuadBillboard(ref face.water.textureId, ref quad, ref WhiteColor));
                    }
                }
            }
        }