public PlanetMaterial GetLayeredMaterialForPosition(ref MaterialSampleParams ps, out byte spawnsItems, ref byte occlusion)
        {
            if (ps.DistanceToCenter < 0.01)
            {
                spawnsItems = 255;
                occlusion = 0;
                return m_defaultMaterial;
            }

            Byte roundedMaterial = 0;
            PlanetMaterial voxelMaterial = null;
            byte spawns = 0;

            bool computeOcclusion = m_occlusionMap != null && ps.SurfaceDepth > -(ps.LodSize * 2) && occlusion != 0;

            if (m_biomeMap != null)
                spawns = m_biomeMap.Faces[ps.Face].GetValue(ps.Texcoord.X, ps.Texcoord.Y);

            if (m_biomePixelSize < ps.LodSize)
            {
                if (m_materialMap != null)
                    roundedMaterial = m_materialMap.Faces[ps.Face].GetValue(ps.Texcoord.X, ps.Texcoord.Y);

                if (computeOcclusion)
                    occlusion = m_occlusionMap.Faces[ps.Face].GetValue(ps.Texcoord.X, ps.Texcoord.Y);
                else
                    occlusion = 0;
            }
            else
            {
                if (m_biomeMap != null)
                    roundedMaterial = ComputeMapBlend(ps.Texcoord, ps.Face, ref m_materialBC,
                        m_materialMap.Faces[ps.Face]);

                if (computeOcclusion)
                    occlusion = ComputeMapBlend(ps.Texcoord, ps.Face, ref m_occlusionBC,
                        m_occlusionMap.Faces[ps.Face]);
                else occlusion = 0;
            }
            m_materials.TryGetValue(roundedMaterial, out voxelMaterial);

            if (MyFakes.ENABLE_DEFINITION_ENVIRONMENTS && voxelMaterial == null && m_biomes != null)
            {
                var rules = m_rangeBiomes[roundedMaterial];

                if (rules != null && rules.Count != 0)
                {
                    float height = (ps.SampledHeight - m_planetShape.MinHillHeight) * m_invHeightRange;

                    foreach (var rule in rules)
                    {
                        if (rule.Check(height, ps.Latitude, ps.Longitude, ps.Normal.Z))
                        {
                            voxelMaterial = rule;
                            break;
                        }
                    }
                }
            }

            if (voxelMaterial == null)
            {
                voxelMaterial = m_defaultMaterial;
            }

            spawnsItems = spawns;

            return voxelMaterial;
        }
        public void GetPositionParams(ref Vector3 pos, float lodSize, out MaterialSampleParams ps, bool skipCache = false)
        {
            Vector3 localPosition = pos - m_planetShape.Center();
            ps.DistanceToCenter = localPosition.Length();

            ps.LodSize = lodSize;

            if (ps.DistanceToCenter < 0.01f)
            {
                ps.SurfaceDepth = 0;
                ps.Gravity = Vector3.Down;
                ps.Latitude = 0;
                ps.Longitude = 0;
                ps.Texcoord = Vector2.One / 2;
                ps.Face = 0;
                ps.Normal = Vector3.Backward;
                ps.SampledHeight = 0;
                return;
            }

            ps.Gravity = localPosition / ps.DistanceToCenter;

            MyCubemapHelpers.CalculateSampleTexcoord(ref localPosition, out ps.Face, out ps.Texcoord);

            // this guarantess texcoord in [0,1)
            if (skipCache)
                ps.SampledHeight = m_planetShape.GetValueForPositionCacheless(ps.Face, ref ps.Texcoord, out ps.Normal);
            else
                ps.SampledHeight = m_planetShape.GetValueForPositionWithCache(ps.Face, ref ps.Texcoord, out ps.Normal);

            ps.SurfaceDepth = m_planetShape.SignedDistanceWithSample(lodSize, ps.DistanceToCenter, ps.SampledHeight) * ps.Normal.Z;
            ps.Latitude = ps.Gravity.Y;

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

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