Beispiel #1
0
        dirward FragmentShader(VertexOut vertex, Field <dirward> Dirward, Field <geo> Geo, Field <geo> ShiftedGeo, Field <geo_info> Info, Field <geo_info> ShiftedInfo, [Dir.Vals] float dir)
        {
            geo
           geo_here  = Geo[Here],
           geo_shift = ShiftedGeo[Here];

            if (geo_here.dir == _0)
            {
                return(dirward.Nothing);
            }

            geo_info
                info_here  = Info[Here],
                info_shift = ShiftedInfo[Here];

            if (geo_here.pos_storage != geo_shift.pos_storage)
            {
                return(Dirward[Here]);
            }

            float
                dist_here  = unpack_val(info_here.xy),
                dist_shift = unpack_val(info_shift.xy),
                circum     = unpack_val(info_here.zw);

            float diff = dist_here - dist_shift;

            float clockwise = 0, counterclockwise = 0;

            if (diff > 0)
            {
                clockwise        = diff;
                counterclockwise = circum - diff;
            }
            else
            {
                clockwise        = circum + diff;
                counterclockwise = -diff;
            }

            dirward output = dirward.Nothing;

            output.polarity     = clockwise > counterclockwise ? 0 : 1;
            output.polarity_set = _true;

            return(output);
        }
Beispiel #2
0
        geo_info FragmentShader(VertexOut vertex, Field <geo> Geo, Field <geo_info> Info)
        {
            geo_info info_here = Info[Here];
            geo      here      = Geo[Here];

            if (here.dir == _0)
            {
                return(geo_info.Zero);
            }

            vec2          pos_here  = vertex.TexCoords * Geo.Size;
            vec2          start_pos = geo_pos_id(here);
            RelativeIndex GeoStart  = (RelativeIndex)(start_pos - pos_here);

            geo
                right = Geo[GeoStart + RightOne],
                up    = Geo[GeoStart + UpOne],
                left  = Geo[GeoStart + LeftOne],
                down  = Geo[GeoStart + DownOne];

            float circum = 0;

            if (right.pos_storage == here.pos_storage)
            {
                circum = max(circum, polar_dist(Info[GeoStart + RightOne]));
            }
            if (up.pos_storage == here.pos_storage)
            {
                circum = max(circum, polar_dist(Info[GeoStart + UpOne]));
            }
            if (left.pos_storage == here.pos_storage)
            {
                circum = max(circum, polar_dist(Info[GeoStart + LeftOne]));
            }
            if (down.pos_storage == here.pos_storage)
            {
                circum = max(circum, polar_dist(Info[GeoStart + DownOne]));
            }

            // Pack the polar circumference into 2-bytes
            set_circumference(ref info_here, circum);

            return(info_here);
        }
Beispiel #3
0
 protected static void set_circumference(ref geo_info info, float circumference)
 {
     info.circumference = pack_val_2byte(circumference);
 }
Beispiel #4
0
 protected static float circumference(geo_info info)
 {
     return(unpack_val(info.circumference));
 }
Beispiel #5
0
 protected static void set_polar_dist(ref geo_info info, float polar_dist)
 {
     info.polar_dist = pack_val_2byte(polar_dist);
 }
Beispiel #6
0
 protected static float polar_dist(geo_info info)
 {
     return(unpack_val(info.polar_dist));
 }
Beispiel #7
0
        geo_info FragmentShader(VertexOut vertex, Field <geo> Geo, Field <geo_info> Info)
        {
            geo
           here  = Geo[Here],
           right = Geo[RightOne],
           up    = Geo[UpOne],
           left  = Geo[LeftOne],
           down  = Geo[DownOne];

            float
                dist_right = polar_dist(Info[RightOne]),
                dist_up    = polar_dist(Info[UpOne]),
                dist_left  = polar_dist(Info[LeftOne]),
                dist_down  = polar_dist(Info[DownOne]);

            if (here.dir == _0)
            {
                return(geo_info.Zero);
            }

            float dist = 0;

            // Calculate the geo_id of this cell
            geo  temp_geo = geo.Nothing;
            vec2 pos      = vertex.TexCoords * Geo.Size;

            set_geo_pos_id(ref temp_geo, pos);

            // ... if that geo_id matches the id of the geo info here, then this is the "master" or "12 o' clock" cell of the geodesic line going through this cell.
            if (here.pos_storage == temp_geo.pos_storage)
            {
                // That means its polar distance is 0 by definition.
                dist = 0;
            }
            else
            {
                // If this geodesic flows into another tile, then the polar distance here should be 1 less than the distance of the tile it flows into.
                // This is a fail safe condition that covers degenerate tiles which have nothing flowing into them and only flow out.
                if (here.dir == Dir.Left)
                {
                    dist = max(_0, dist_left - 1);
                }
                if (here.dir == Dir.Right)
                {
                    dist = max(_0, dist_right - 1);
                }
                if (here.dir == Dir.Up)
                {
                    dist = max(_0, dist_up - 1);
                }
                if (here.dir == Dir.Down)
                {
                    dist = max(_0, dist_down - 1);
                }

                // The polar distance is also 1 plus the polar distance of whatever cell comes "before" it (by following the geo backwards "counterclockwise").
                if (right.dir == Dir.Left && dist_right >= dist)
                {
                    dist = dist_right + 1;
                }
                if (left.dir == Dir.Right && dist_left >= dist)
                {
                    dist = dist_left + 1;
                }
                if (up.dir == Dir.Down && dist_up >= dist)
                {
                    dist = dist_up + 1;
                }
                if (down.dir == Dir.Up && dist_down >= dist)
                {
                    dist = dist_down + 1;
                }
            }

            // Pack the polar distance into 2-bytes and return it in
            geo_info output = geo_info.Zero;

            set_polar_dist(ref output, dist);

            return(output);
        }