// Copyright (c) 2023 Lachlan McDonald
// This work is licensed under the MIT License (MIT)
// https://github.com/lachlanmcdonald/magicavoxel-shaders
//
// xs primitive/prism [Mode] [Size X] [Size Y] [Steps]
//
// xs_begin
// author : '@lmcdx.bsky.social'
// arg : { name = 'Mode'  var = 'm_mode'  range = '0 2'  value = '0'  step = '1'  precision = '0' }
// arg : { name = 'Size X'  var = 'm_size_x'  range = '0 256'  value = '12'  step = '1'  precision = '0' }
// arg : { name = 'Size Y'  var = 'm_size_y'  range = '0 256'  value = '12'  step = '1'  precision = '0' }
// arg : { name = 'Steps'  var = 'm_steps'  range = '0 128'  value = '0'  step = '1'  precision = '0' }
// xs_end

float PI2 = acos(-1.0) * 2.0;
int mode = int(m_mode);

float pal(float p) {
	float f = floor(mix(0.0, float(i_num_color_sels), p));
	return color_sel(f);
}

float range(float value, float inMin, float inMax, float outMin, float outMax) {
  return outMin + (outMax - outMin) * (value - inMin) / (inMax - inMin);
}

float smootherstep(float a, float b, float x) {
  x = clamp((x - a) / (b - a), 0.0, 1.0);
  return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);
}

float map(vec3 v) {
	vec3 uv = v / i_volume_size;
	vec2 s = vec2(min(m_size_x, i_volume_size.x / 2.0),
				  min(m_size_y, i_volume_size.y / 2.0)) / i_volume_size.xy;

	if (mode == 0) {
		uv.x = min(clamp(uv.x / s.x, 0.0, 1.0), clamp((1.0 - uv.x) / s.x, 0.0, 1.0));
		uv.y = min(clamp(uv.y / s.y, 0.0, 1.0), clamp((1.0 - uv.y) / s.y, 0.0, 1.0));
	} else if (mode == 1) {
		uv.x = min(smoothstep(0.0, s.x, uv.x), smoothstep(1.0, 1.0 - s.x, uv.x));
		uv.y = min(smoothstep(0.0, s.y, uv.y), smoothstep(1.0, 1.0 - s.y, uv.y));
	} else if (mode == 2) {
		uv.x = min(smootherstep(0.0, s.x, uv.x), smootherstep(1.0, 1.0 - s.x, uv.x));
		uv.y = min(smootherstep(0.0, s.y, uv.y), smootherstep(1.0, 1.0 - s.y, uv.y));
	}

	float m = 1.0 / i_volume_size.z;
	float d = range(min(uv.x, uv.y), 0.0, 1.0, m, 1.0);

	if (m_steps > 0.0) {
		float k = 1.0 / m_steps;
		d = d - mod(d, k) + k;
	}

	return d >= uv.z ? pal(uv.z) : 0.0;
}