예제 #1
0
        private MyRuntimeEnvironmentItemInfo GetItemForPosition(ref MySurfaceParams surface, int lod)
        {
            var key = new MyBiomeMaterial(surface.Biome, surface.Material);

            m_candidates.Clear();

            List <MyEnvironmentItemMapping> ruleset;

            if (m_environment.MaterialEnvironmentMappings.TryGetValue(key, out ruleset))
            {
                foreach (var rule in ruleset)
                {
                    var sampler = rule.Sampler(lod);
                    if (sampler != null && rule.Rule.Check(surface.HeightRatio, surface.Latitude, surface.Longitude, surface.Normal.Z))
                    {
                        m_candidates.Add(sampler);
                    }
                }
            }

            var seed = surface.Position.GetHashCode();

            float sample = MyHashRandomUtils.UniformFloatFromSeed(seed);

            switch (m_candidates.Count)
            {
            case 0:
                return(null);

            case 1:
                return(m_candidates[0].Sample(sample));

            default:
                return(m_candidates[(int)(MyHashRandomUtils.UniformFloatFromSeed(~seed) * m_candidates.Count)].Sample(sample));
            }
        }
        /**
         * All mighty method for computing material, surface position and surface parameters in a single pass.
         *
         * If material and surface position are required this is the best way to obtain that information.
         *
         * When using the coefficient cache be sure to have it properly set up. (MyPlanetShapeProvider.PrepareCache())
         */
        public void ComputeCombinedMaterialAndSurface(Vector3 position, bool useCache, out MySurfaceParams props)
        {
            if (Closed)
            {
                Debug.Fail("Storage closed!");
                props = new MySurfaceParams();
                return;
            }

            byte occl = 0;

            MyPlanetMaterialProvider.MaterialSampleParams pars;

            position -= Shape.Center();

            float distance = position.Length();

            pars.Gravity = position / distance;

            // Latitude
            props.Latitude = pars.Gravity.Y;

            Vector2 lon = new Vector2(-pars.Gravity.X, -pars.Gravity.Z);
            lon.Normalize();

            props.Longitude = lon.Y;
            if (-pars.Gravity.X > 0)
            {
                props.Longitude = 2 - props.Longitude;
            }

            // Height and slope
            int face;
            Vector2 pos;
            MyCubemapHelpers.CalculateSampleTexcoord(ref position, out face, out pos);

            float value;
            if(!useCache)
                value = Shape.GetValueForPositionCacheless(face, ref pos, out props.Normal);
            else
                value = Shape.GetValueForPositionWithCache(face, ref pos, out props.Normal);

            pars.SampledHeight = value;
            pars.SurfaceDepth = 0;
            pars.Texcoord = pos;
            pars.LodSize = 1.0f;
            pars.Latitude = props.Latitude;
            pars.Longitude = props.Longitude;
            pars.Face = face;
            pars.Normal = props.Normal;

            props.Position = pars.Gravity * (Radius + value) + Shape.Center();

            props.Gravity = pars.Gravity = -pars.Gravity;

            pars.DistanceToCenter = props.Position.Length();

            var rule = Material.GetLayeredMaterialForPosition(ref pars, out props.Biome, ref occl);

            if (rule.FirstOrDefault == null) props.Material = 0;
            else props.Material = rule.FirstOrDefault.Index;

            //props.Altitude = value;

            props.Normal = pars.Normal;

            props.HeightRatio = Shape.AltitudeToRatio(value);
        }