|
|
|
@ -110,9 +110,6 @@ AP_GeodesicGrid::AP_GeodesicGrid()
@@ -110,9 +110,6 @@ AP_GeodesicGrid::AP_GeodesicGrid()
|
|
|
|
|
{{ 9, 8, 7, 12, 14}, 1, 2, 0, 0, 2}, |
|
|
|
|
{{ 1, 2, 4, 5, 3}, 0, 0, 2, 2, 0}, |
|
|
|
|
{{16, 15, 13, 18, 17}, 2, 2, 0, 2, 1}, |
|
|
|
|
{{19, 18, 17, 2, 4}, 1, 2, 0, 0, 2}, |
|
|
|
|
{{11, 12, 14, 15, 13}, 0, 0, 2, 2, 0}, |
|
|
|
|
{{ 6, 5, 3, 8, 7}, 2, 2, 0, 2, 1}, |
|
|
|
|
} |
|
|
|
|
, _inverses{ |
|
|
|
|
{{-0.309017f, 0.500000f, 0.190983f}, |
|
|
|
@ -197,13 +194,20 @@ int AP_GeodesicGrid::section(const Vector3f& v,
@@ -197,13 +194,20 @@ int AP_GeodesicGrid::section(const Vector3f& v,
|
|
|
|
|
return 4 * i + j; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int AP_GeodesicGrid::_neighbor_umbrella_component(int idx, |
|
|
|
|
int comp_idx) const |
|
|
|
|
{ |
|
|
|
|
if (idx < 3) { |
|
|
|
|
return _neighbor_umbrellas[idx].components[comp_idx]; |
|
|
|
|
} |
|
|
|
|
return (_neighbor_umbrellas[idx % 3].components[comp_idx] + 10) % 20; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int AP_GeodesicGrid::_from_neighbor_umbrella(int idx, |
|
|
|
|
const Vector3f& v, |
|
|
|
|
const Vector3f& u, |
|
|
|
|
bool inclusive) const |
|
|
|
|
{ |
|
|
|
|
const struct neighbor_umbrella& umbrella = _neighbor_umbrellas[idx]; |
|
|
|
|
|
|
|
|
|
/* The following comparisons between the umbrella's first and second
|
|
|
|
|
* vertices' coefficients work for this algorithm because all vertices' |
|
|
|
|
* vectors are of the same length. */ |
|
|
|
@ -212,84 +216,87 @@ int AP_GeodesicGrid::_from_neighbor_umbrella(int idx,
@@ -212,84 +216,87 @@ int AP_GeodesicGrid::_from_neighbor_umbrella(int idx,
|
|
|
|
|
/* If the coefficients of the first and second vertices are equal, then
|
|
|
|
|
* v crosses the first component or the edge formed by the umbrella's |
|
|
|
|
* pivot and forth vertex. */ |
|
|
|
|
auto w = _inverses[umbrella.components[0] % 10] * v; |
|
|
|
|
if (umbrella.components[0] > 9) { |
|
|
|
|
int comp = _neighbor_umbrella_component(idx, 0); |
|
|
|
|
auto w = _inverses[comp % 10] * v; |
|
|
|
|
if (comp > 9) { |
|
|
|
|
w = -w; |
|
|
|
|
} |
|
|
|
|
float x0 = w[umbrella.v0_c0]; |
|
|
|
|
float x0 = w[_neighbor_umbrellas[idx % 3].v0_c0]; |
|
|
|
|
if (is_zero(x0)) { |
|
|
|
|
if (!inclusive) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
return umbrella.components[0]; |
|
|
|
|
return comp; |
|
|
|
|
} else if (x0 < 0) { |
|
|
|
|
if (!inclusive) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
return umbrella.components[u.x < u.y ? 3 : 2]; |
|
|
|
|
return _neighbor_umbrella_component(idx, u.x < u.y ? 3 : 2); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return umbrella.components[0]; |
|
|
|
|
return comp; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (u.y > u.x) { |
|
|
|
|
/* If the coefficient of the second vertex is greater than the first
|
|
|
|
|
* one's, then v crosses the first, second or third component. */ |
|
|
|
|
auto w = _inverses[umbrella.components[1] % 10] * v; |
|
|
|
|
if (umbrella.components[1] > 9) { |
|
|
|
|
int comp = _neighbor_umbrella_component(idx, 1); |
|
|
|
|
auto w = _inverses[comp % 10] * v; |
|
|
|
|
if (comp > 9) { |
|
|
|
|
w = -w; |
|
|
|
|
} |
|
|
|
|
float x1 = w[umbrella.v1_c1]; |
|
|
|
|
float x2 = w[umbrella.v2_c1]; |
|
|
|
|
float x1 = w[_neighbor_umbrellas[idx % 3].v1_c1]; |
|
|
|
|
float x2 = w[_neighbor_umbrellas[idx % 3].v2_c1]; |
|
|
|
|
|
|
|
|
|
if (is_zero(x1)) { |
|
|
|
|
if (!inclusive) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
return umbrella.components[x1 < 0 ? 2 : 1]; |
|
|
|
|
return _neighbor_umbrella_component(idx, x1 < 0 ? 2 : 1); |
|
|
|
|
} else if (x1 < 0) { |
|
|
|
|
return umbrella.components[2]; |
|
|
|
|
return _neighbor_umbrella_component(idx, 2); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (is_zero(x2)) { |
|
|
|
|
if (!inclusive) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
return umbrella.components[x2 > 0 ? 1 : 0]; |
|
|
|
|
return _neighbor_umbrella_component(idx, x2 > 0 ? 1 : 0); |
|
|
|
|
} else if (x2 < 0) { |
|
|
|
|
return umbrella.components[0]; |
|
|
|
|
return _neighbor_umbrella_component(idx, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return umbrella.components[1]; |
|
|
|
|
return comp; |
|
|
|
|
} else { |
|
|
|
|
/* If the coefficient of the second vertex is lesser than the first
|
|
|
|
|
* one's, then v crosses the first, fourth or fifth component. */ |
|
|
|
|
auto w = _inverses[umbrella.components[4] % 10] * v; |
|
|
|
|
if (umbrella.components[4] > 9) { |
|
|
|
|
int comp = _neighbor_umbrella_component(idx, 4); |
|
|
|
|
auto w = _inverses[comp % 10] * v; |
|
|
|
|
if (comp > 9) { |
|
|
|
|
w = -w; |
|
|
|
|
} |
|
|
|
|
float x4 = w[umbrella.v4_c4]; |
|
|
|
|
float x0 = w[umbrella.v0_c4]; |
|
|
|
|
float x4 = w[_neighbor_umbrellas[idx % 3].v4_c4]; |
|
|
|
|
float x0 = w[_neighbor_umbrellas[idx % 3].v0_c4]; |
|
|
|
|
|
|
|
|
|
if (is_zero(x4)) { |
|
|
|
|
if (!inclusive) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
return umbrella.components[x4 < 0 ? 0 : 4]; |
|
|
|
|
return _neighbor_umbrella_component(idx, x4 < 0 ? 0 : 4); |
|
|
|
|
} else if (x4 < 0) { |
|
|
|
|
return umbrella.components[0]; |
|
|
|
|
return _neighbor_umbrella_component(idx, 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (is_zero(x0)) { |
|
|
|
|
if (!inclusive) { |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
return umbrella.components[x0 > 0 ? 4 : 3]; |
|
|
|
|
return _neighbor_umbrella_component(idx, x0 > 0 ? 4 : 3); |
|
|
|
|
} else if (x0 < 0) { |
|
|
|
|
return umbrella.components[3]; |
|
|
|
|
return _neighbor_umbrella_component(idx, 3); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return umbrella.components[4]; |
|
|
|
|
return comp; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|