Moved methods outside Vector3f

This commit is contained in:
Marc Gilleron 2022-05-21 21:12:16 +01:00
parent 4e1c7cf485
commit 6aad611215
8 changed files with 92 additions and 100 deletions

View File

@ -45,8 +45,8 @@ inline TriangleIntersectionResult ray_intersects_triangle(const Vector3f &p_from
const Vector3f &p_v0, const Vector3f &p_v1, const Vector3f &p_v2) {
const Vector3f e1 = p_v1 - p_v0;
const Vector3f e2 = p_v2 - p_v0;
const Vector3f h = p_dir.cross(e2);
const float a = e1.dot(h);
const Vector3f h = math::cross(p_dir, e2);
const float a = math::dot(e1, h);
if (Math::abs(a) < 0.00001f) {
return { TriangleIntersectionResult::PARALLEL, -1 };
@ -55,15 +55,15 @@ inline TriangleIntersectionResult ray_intersects_triangle(const Vector3f &p_from
const float f = 1.0f / a;
const Vector3f s = p_from - p_v0;
const float u = f * s.dot(h);
const float u = f * math::dot(s, h);
if ((u < 0.0f) || (u > 1.0f)) {
return { TriangleIntersectionResult::NO_INTERSECTION, -1 };
}
const Vector3f q = s.cross(e1);
const Vector3f q = math::cross(s, e1);
const float v = f * p_dir.dot(q);
const float v = f * math::dot(p_dir, q);
if ((v < 0.0f) || (u + v > 1.0f)) {
return { TriangleIntersectionResult::NO_INTERSECTION, -1 };
@ -71,7 +71,7 @@ inline TriangleIntersectionResult ray_intersects_triangle(const Vector3f &p_from
// At this stage we can compute t to find out where
// the intersection point is on the line.
const float t = f * e2.dot(q);
const float t = f * math::dot(e2, q);
if (t > 0.00001f) { // ray intersection
//r_res = p_from + p_dir * t;
@ -134,7 +134,7 @@ TriangleIntersectionResult ray_intersects_triangle2(const Vector3f &p_from, cons
}
inline Vector3f get_normal(const Triangle &t) {
return t.v13.cross(t.v1 - t.v2).normalized();
return math::cross(t.v13, math::normalized(t.v1 - t.v2));
}
// const Triangle *raycast(Span<const Triangle> triangles, Vector3f ray_position, Vector3f ray_dir) {
@ -264,7 +264,7 @@ bool find_sdf_sign_with_raycast(
//ZN_PROFILE_SCOPE();
const Vector3f ref_center = (ref_triangle.v1 + ref_triangle.v2 + ref_triangle.v3) / 3.f;
const Vector3f ray_dir = (ref_center - ray_position).normalized();
const Vector3f ray_dir = math::normalized(ref_center - ray_position);
#ifdef ZN_MESH_SDF_DEBUG_BATCH
DDD::draw_line(ray_position, ray_position + ray_dir * 10.f, Color(0, 1, 0));
@ -283,14 +283,14 @@ bool find_sdf_sign_with_raycast(
if (s_tri_not_found_error == false) {
s_tri_not_found_error = true;
ZN_PRINT_VERBOSE(
format("Could not find triangle by raycast, dp: {}", get_normal(ref_triangle).dot(ray_dir)));
format("Could not find triangle by raycast, dp: {}", math::dot(get_normal(ref_triangle), ray_dir)));
}
#endif
return false;
}
const Vector3f triangle_normal = get_normal(*selected_triangle);
const float dp = triangle_normal.dot(ray_dir);
const float dp = math::dot(triangle_normal, ray_dir);
// Same direction (+): we are inside, sign is negative
// Opposite direction (-): we are outside, sign is positive
out_sign = dp < 0.f ? 1 : -1;
@ -626,26 +626,26 @@ float get_distance_to_triangle_squared(const Vector3f v1, const Vector3f v2, con
float get_distance_to_triangle_squared_precalc(const Triangle &t, const Vector3f p) {
// https://iquilezles.org/articles/triangledistance/
using namespace math;
const Vector3f p1 = p - t.v1;
const Vector3f p2 = p - t.v2;
const Vector3f p3 = p - t.v3;
const float det = //
math::sign_nonzero(t.v21_cross_nor.dot(p1)) + //
math::sign_nonzero(t.v32_cross_nor.dot(p2)) + //
math::sign_nonzero(t.v13_cross_nor.dot(p3));
sign_nonzero(dot(t.v21_cross_nor, p1)) + //
sign_nonzero(dot(t.v32_cross_nor, p2)) + //
sign_nonzero(dot(t.v13_cross_nor, p3));
if (det < 2.f) {
// Outside of the prism: get distance to closest edge
return math::min(
math::min( //
(t.v21 * math::clamp(t.v21.dot(p1) * t.inv_v21_length_squared, 0.f, 1.f) - p1).length_squared(),
(t.v32 * math::clamp(t.v32.dot(p2) * t.inv_v32_length_squared, 0.f, 1.f) - p2)
.length_squared()),
(t.v13 * math::clamp(t.v13.dot(p3) * t.inv_v13_length_squared, 0.f, 1.f) - p3).length_squared());
return min(min( //
length_squared(t.v21 * clamp(dot(t.v21, p1) * t.inv_v21_length_squared, 0.f, 1.f) - p1),
length_squared(t.v32 * clamp(dot(t.v32, p2) * t.inv_v32_length_squared, 0.f, 1.f) - p2)),
length_squared(t.v13 * clamp(dot(t.v13, p3) * t.inv_v13_length_squared, 0.f, 1.f) - p3));
} else {
// Inside the prism: get distance to plane
return math::squared(t.nor.dot(p1)) * t.inv_nor_length_squared;
return squared(dot(t.nor, p1)) * t.inv_nor_length_squared;
}
}
@ -656,14 +656,14 @@ void precalc_triangles(Span<Triangle> triangles) {
t.v21 = t.v2 - t.v1;
t.v32 = t.v3 - t.v2;
t.v13 = t.v1 - t.v3;
t.nor = t.v21.cross(t.v13);
t.v21_cross_nor = t.v21.cross(t.nor);
t.v32_cross_nor = t.v32.cross(t.nor);
t.v13_cross_nor = t.v13.cross(t.nor);
t.inv_v21_length_squared = 1.f / t.v21.length_squared();
t.inv_v32_length_squared = 1.f / t.v32.length_squared();
t.inv_v13_length_squared = 1.f / t.v13.length_squared();
t.inv_nor_length_squared = 1.f / t.nor.length_squared();
t.nor = math::cross(t.v21, t.v13);
t.v21_cross_nor = math::cross(t.v21, t.nor);
t.v32_cross_nor = math::cross(t.v32, t.nor);
t.v13_cross_nor = math::cross(t.v13, t.nor);
t.inv_v21_length_squared = 1.f / math::length_squared(t.v21);
t.inv_v32_length_squared = 1.f / math::length_squared(t.v32);
t.inv_v13_length_squared = 1.f / math::length_squared(t.v13);
t.inv_nor_length_squared = 1.f / math::length_squared(t.nor);
}
}
@ -732,9 +732,9 @@ float get_mesh_signed_distance_at(const Vector3f pos, Span<const Triangle> trian
//} else {
// normal = (p_point1 - p_point2).cross(p_point1 - p_point3);
//}
const float plane_d = plane_normal.dot(ct.v1);
const float plane_d = math::dot(plane_normal, ct.v1);
if (plane_normal.dot(pos) > plane_d) {
if (math::dot(plane_normal, pos) > plane_d) {
return d;
}
return -d;
@ -780,9 +780,9 @@ float get_mesh_signed_distance_at(const Vector3f pos, const ChunkGrid &chunk_gri
//} else {
// normal = (p_point1 - p_point2).cross(p_point1 - p_point3);
//}
const float plane_d = plane_normal.dot(closest_tri->v1);
const float plane_d = math::dot(plane_normal, closest_tri->v1);
if (plane_normal.dot(pos) > plane_d) {
if (math::dot(plane_normal, pos) > plane_d) {
return d;
}
return -d;
@ -843,7 +843,7 @@ void generate_mesh_sdf_approx_interp(Span<float> sdf_grid, const Vector3i res, S
const unsigned int node_size_cells = 1 << node_size_po2;
const Vector3i node_grid_size = math::ceildiv(res, node_size_cells) + Vector3i(1, 1, 1);
const float node_size = node_size_cells * cell_size.length();
const float node_size = node_size_cells * math::length(cell_size);
const float node_subdiv_threshold = 0.6f * node_size;
std::vector<float> node_grid;
@ -1445,7 +1445,7 @@ void generate_mesh_sdf_approx_floodfill(Span<float> sdf_grid, const Vector3i res
dds[0b001] = cell_size.z;
dds[0b101] = Math::sqrt(math::squared(cell_size.x) + math::squared(cell_size.z));
dds[0b011] = Math::sqrt(math::squared(cell_size.y) + math::squared(cell_size.z));
dds[0b111] = cell_size.length();
dds[0b111] = math::length(cell_size);
std::vector<Seed> seeds1;

View File

@ -468,7 +468,7 @@ static void bake_mesh_geometry(VoxelBlockyModel &config, VoxelBlockyModel::Baked
tangent[0] = t[0];
tangent[1] = t[1];
tangent[2] = t[2];
tangent[3] = (bt.dot(to_vec3f(normals[indices[i]]).cross(t))) < 0 ? -1.0f : 1.0f;
tangent[3] = (math::dot(bt, math::cross(to_vec3f(normals[indices[i]]), t))) < 0 ? -1.0f : 1.0f;
}
if (L::get_triangle_side(tri_positions[0], tri_positions[1], tri_positions[2], side)) {

View File

@ -257,7 +257,7 @@ void generate_blocky_mesh(std::vector<VoxelMesherBlocky::Arrays> &out_arrays_per
if (bake_occlusion) {
for (unsigned int i = 0; i < vertex_count; ++i) {
Vector3f vertex_pos = side_positions[i];
const Vector3f vertex_pos = side_positions[i];
// General purpose occlusion colouring.
// TODO Optimize for cubes
@ -271,7 +271,7 @@ void generate_blocky_mesh(std::vector<VoxelMesherBlocky::Arrays> &out_arrays_per
static_cast<float>(shaded_corner[corner]);
//float k = 1.f - Cube::g_corner_position[corner].distance_to(v);
float k = 1.f -
Cube::g_corner_position[corner].distance_squared_to(vertex_pos);
math::distance_squared(Cube::g_corner_position[corner], vertex_pos);
if (k < 0.0) {
k = 0.0;
}

View File

@ -127,7 +127,7 @@ bool can_split(Vector3i node_origin, int node_size, const VoxelAccess &voxels, f
float interpolated_value = math::interpolate_trilinear(v0, v1, v2, v3, v4, v5, v6, v7, positions_ratio[i]);
float gradient_magnitude = value.gradient.length();
float gradient_magnitude = math::length(value.gradient);
if (gradient_magnitude < FLT_EPSILON) {
gradient_magnitude = 1.0;
}
@ -1039,26 +1039,22 @@ void DualGridGenerator::node_proc(OctreeNode *node) {
inline Vector3f interpolate(const Vector3f &v0, const Vector3f &v1, const HermiteValue &val0, const HermiteValue &val1,
Vector3f &out_normal) {
if (Math::abs(val0.sdf - SURFACE_ISO_LEVEL) <= FLT_EPSILON) {
out_normal = val0.gradient;
out_normal.normalize();
out_normal = math::normalized(val0.gradient);
return v0;
}
if (Math::abs(val1.sdf - SURFACE_ISO_LEVEL) <= FLT_EPSILON) {
out_normal = val1.gradient;
out_normal.normalize();
out_normal = math::normalized(val1.gradient);
return v1;
}
if (Math::abs(val1.sdf - val0.sdf) <= FLT_EPSILON) {
out_normal = val0.gradient;
out_normal.normalize();
out_normal = math::normalized(val0.gradient);
return v0;
}
float mu = (SURFACE_ISO_LEVEL - val0.sdf) / (val1.sdf - val0.sdf);
out_normal = val0.gradient + mu * (val1.gradient - val0.gradient);
out_normal.normalize();
out_normal = math::normalized(val0.gradient + mu * (val1.gradient - val0.gradient));
return v0 + mu * (v1 - v0);
}
@ -1101,16 +1097,16 @@ void polygonize_cell_marching_squares(const Vector3f *cube_corners, const Hermit
HermiteValue inner_val;
inner_val = values[0]; // mSrc->getValueAndGradient(intersection_points[0]);
intersection_normals[0] = inner_val.gradient.normalized(); // * (inner_val.value + 1.0);
intersection_normals[0] = math::normalized(inner_val.gradient); // * (inner_val.value + 1.0);
inner_val = values[1]; // mSrc->getValueAndGradient(intersection_points[2]);
intersection_normals[2] = inner_val.gradient.normalized(); // * (inner_val.value + 1.0);
intersection_normals[2] = math::normalized(inner_val.gradient); // * (inner_val.value + 1.0);
inner_val = values[2]; // mSrc->getValueAndGradient(intersection_points[4]);
intersection_normals[4] = inner_val.gradient.normalized(); // * (inner_val.value + 1.0);
intersection_normals[4] = math::normalized(inner_val.gradient); // * (inner_val.value + 1.0);
inner_val = values[3]; // mSrc->getValueAndGradient(intersection_points[6]);
intersection_normals[6] = inner_val.gradient.normalized(); // * (inner_val.value + 1.0);
intersection_normals[6] = math::normalized(inner_val.gradient); // * (inner_val.value + 1.0);
if (edge & 1) {
intersection_points[1] = interpolate(cube_corners[corner_map[0]], cube_corners[corner_map[1]], values[0],

View File

@ -92,7 +92,7 @@ inline uint8_t get_border_mask(const Vector3i &pos, const Vector3i &block_size)
}
inline Vector3f normalized_not_null(Vector3f n) {
const float lengthsq = n.length_squared();
const float lengthsq = math::length_squared(n);
if (lengthsq == 0) {
return Vector3f(0, 1, 0);
} else {

View File

@ -18,6 +18,10 @@ inline bool has_nan(const Vector3 &v) {
return Math::is_nan(v.x) || Math::is_nan(v.y) || Math::is_nan(v.z);
}
inline bool is_normalized(const Vector3 &v) {
return v.is_normalized();
}
} // namespace zylann::math
#endif // ZN_VECTOR3_H

View File

@ -34,53 +34,6 @@ struct Vector3f {
Vector3f(float p_x, float p_y, float p_z) : x(p_x), y(p_y), z(p_z) {}
inline float length_squared() const {
return x * x + y * y + z * z;
}
inline float length() const {
return Math::sqrt(length_squared());
}
inline float distance_squared_to(const Vector3f &p_to) const {
return (p_to - *this).length_squared();
}
inline Vector3f cross(const Vector3f &p_with) const {
const Vector3f ret( //
(y * p_with.z) - (z * p_with.y), //
(z * p_with.x) - (x * p_with.z), //
(x * p_with.y) - (y * p_with.x));
return ret;
}
inline float dot(const Vector3f &p_with) const {
return x * p_with.x + y * p_with.y + z * p_with.z;
}
inline void normalize() {
const float lengthsq = length_squared();
if (lengthsq == 0) {
x = y = z = 0;
} else {
const float length = Math::sqrt(lengthsq);
x /= length;
y /= length;
z /= length;
}
}
inline Vector3f normalized() const {
Vector3f v = *this;
v.normalize();
return v;
}
bool is_normalized() const {
// use length_squared() instead of length() to avoid sqrt(), makes it more stringent.
return Math::is_equal_approx(length_squared(), 1, float(UNIT_EPSILON));
}
inline const float &operator[](const unsigned int p_axis) const {
#ifdef DEBUG_ENABLED
ZN_ASSERT(p_axis < AXIS_COUNT);
@ -214,8 +167,47 @@ inline bool has_nan(const Vector3f &v) {
return Math::is_nan(v.x) || Math::is_nan(v.y) || Math::is_nan(v.z);
}
inline float length_squared(const Vector3f v) {
return v.x * v.x + v.y * v.y + v.z * v.z;
}
inline float length(const Vector3f &v) {
return Math::sqrt(length_squared(v));
}
inline float distance_squared(const Vector3f &a, const Vector3f &b) {
return length_squared(b - a);
}
inline Vector3f cross(const Vector3f &a, const Vector3f &b) {
const Vector3f ret( //
(a.y * b.z) - (a.z * b.y), //
(a.z * b.x) - (a.x * b.z), //
(a.x * b.y) - (a.y * b.x));
return ret;
}
inline float dot(const Vector3f &a, const Vector3f &b) {
return a.x * b.x + a.y * b.y + a.z * b.z;
}
inline Vector3f normalized(const Vector3f &v) {
const float lengthsq = length_squared(v);
if (lengthsq == 0) {
return Vector3f();
} else {
const float length = Math::sqrt(lengthsq);
return v / length;
}
}
inline bool is_normalized(const Vector3f &v) {
// use length_squared() instead of length() to avoid sqrt(), makes it more stringent.
return Math::is_equal_approx(length_squared(v), 1, float(UNIT_EPSILON));
}
inline float distance(const Vector3f &a, const Vector3f &b) {
return Math::sqrt(a.distance_squared_to(b));
return Math::sqrt(distance_squared(a, b));
}
} // namespace math

View File

@ -52,7 +52,7 @@ bool voxel_raycast(Vec3f_T ray_origin, Vec3f_T ray_direction, Predicate_F predic
// Note : the grid is assumed to have 1-unit square cells.
ZN_ASSERT_RETURN_V(ray_direction.is_normalized(), false); // Must be normalized
ZN_ASSERT_RETURN_V(math::is_normalized(ray_direction), false); // Must be normalized
/* Initialisation */