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); }
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); }
protected static void set_circumference(ref geo_info info, float circumference) { info.circumference = pack_val_2byte(circumference); }
protected static float circumference(geo_info info) { return(unpack_val(info.circumference)); }
protected static void set_polar_dist(ref geo_info info, float polar_dist) { info.polar_dist = pack_val_2byte(polar_dist); }
protected static float polar_dist(geo_info info) { return(unpack_val(info.polar_dist)); }
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); }