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); }