Skip to content

Commit

Permalink
updated
Browse files Browse the repository at this point in the history
  • Loading branch information
xelatihy committed Jan 31, 2024
1 parent 269eedf commit d99e935
Show file tree
Hide file tree
Showing 6 changed files with 978 additions and 979 deletions.
214 changes: 214 additions & 0 deletions libs/yocto/yocto_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -1188,6 +1188,76 @@ inline bbox3f capsule_bounds(vec3f p0, vec3f p1, float r0, float r1);

} // namespace yocto

// -----------------------------------------------------------------------------
// GEOMETRY UTILITIES
// -----------------------------------------------------------------------------
namespace yocto {

// Line properties.
inline vec3f line_tangent(vec3f p0, vec3f p1);
inline float line_length(vec3f p0, vec3f p1);

// Triangle properties.
inline vec3f triangle_normal(vec3f p0, vec3f p1, vec3f p2);
inline float triangle_area(vec3f p0, vec3f p1, vec3f p2);

// Quad properties.
inline vec3f quad_normal(vec3f p0, vec3f p1, vec3f p2, vec3f p3);
inline float quad_area(vec3f p0, vec3f p1, vec3f p2, vec3f p3);

// Interpolates values over a line parameterized from a to b by u. Same as lerp.
template <typename T>
inline T interpolate_line(const T& p0, const T& p1, float u);

// Interpolates values over a triangle parameterized by u and v along the
// (p1-p0) and (p2-p0) directions. Same as barycentric interpolation.
template <typename T>
inline T interpolate_triangle(const T& p0, const T& p1, const T& p2, vec2f uv);

// Interpolates values over a quad parameterized by u and v along the
// (p1-p0) and (p2-p1) directions. Same as bilinear interpolation.
template <typename T>
inline T interpolate_quad(
const T& p0, const T& p1, const T& p2, const T& p3, vec2f uv);

// Interpolates values along a cubic Bezier segment parametrized by u.
template <typename T>
inline T interpolate_bezier(
const T& p0, const T& p1, const T& p2, const T& p3, float u);

// Computes the derivative of a cubic Bezier segment parametrized by u.
template <typename T>
inline T interpolate_bezier_derivative(
const T& p0, const T& p1, const T& p2, const T& p3, float u);

// Interpolated line properties.
inline vec3f line_point(vec3f p0, vec3f p1, float u);
inline vec3f line_tangent(vec3f t0, vec3f t1, float u);

// Interpolated triangle properties.
inline vec3f triangle_point(vec3f p0, vec3f p1, vec3f p2, vec2f uv);
inline vec3f triangle_normal(vec3f n0, vec3f n1, vec3f n2, vec2f uv);

// Interpolated quad properties.
inline vec3f quad_point(vec3f p0, vec3f p1, vec3f p2, vec2f uv);
inline vec3f quad_normal(vec3f n0, vec3f n1, vec3f n2, vec3f n3, vec2f uv);

// Interpolated sphere properties.
inline vec3f sphere_point(const vec3f p, float r, vec2f uv);
inline vec3f sphere_normal(const vec3f p, float r, vec2f uv);

// Triangle tangent and bitangent from uv
inline pair<vec3f, vec3f> triangle_tangents_fromuv(
vec3f p0, vec3f p1, vec3f p2, vec2f uv0, vec2f uv1, vec2f uv2);

// Quad tangent and bitangent from uv. Note that we pass a current_uv since
// internally we may want to split the quad in two and we need to known where
// to do it. If not interested in the split, just pass vec2f{0,0} here.
inline pair<vec3f, vec3f> quad_tangents_fromuv(vec3f p0, vec3f p1, vec3f p2,
vec3f p3, vec2f uv0, vec2f uv1, vec2f uv2, vec2f uv3, vec2f current_uv);

} // namespace yocto

// -----------------------------------------------------------------------------
// USER INTERFACE UTILITIES
// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -2799,6 +2869,150 @@ inline bbox3f capsule_bounds(vec3f p0, vec3f p1, float r0, float r1) {

} // namespace yocto

// -----------------------------------------------------------------------------
// GEOMETRY UTILITIES
// -----------------------------------------------------------------------------
namespace yocto {

// Line properties.
inline vec3f line_tangent(vec3f p0, vec3f p1) { return normalize(p1 - p0); }
inline float line_length(vec3f p0, vec3f p1) { return length(p1 - p0); }

// Triangle properties.
inline vec3f triangle_normal(vec3f p0, vec3f p1, vec3f p2) {
return normalize(cross(p1 - p0, p2 - p0));
}
inline float triangle_area(vec3f p0, vec3f p1, vec3f p2) {
return length(cross(p1 - p0, p2 - p0)) / 2;
}

// Quad propeties.
inline vec3f quad_normal(vec3f p0, vec3f p1, vec3f p2, vec3f p3) {
return normalize(triangle_normal(p0, p1, p3) + triangle_normal(p2, p3, p1));
}
inline float quad_area(vec3f p0, vec3f p1, vec3f p2, vec3f p3) {
return triangle_area(p0, p1, p3) + triangle_area(p2, p3, p1);
}

// Interpolates values over a line parameterized from a to b by u. Same as lerp.
template <typename T>
inline T interpolate_line(const T& p0, const T& p1, float u) {
return p0 * (1 - u) + p1 * u;
}

// Interpolates values over a triangle parameterized by u and v along the
// (p1-p0) and (p2-p0) directions. Same as barycentric interpolation.
template <typename T>
inline T interpolate_triangle(const T& p0, const T& p1, const T& p2, vec2f uv) {
return p0 * (1 - uv.x - uv.y) + p1 * uv.x + p2 * uv.y;
}

// Interpolates values over a quad parameterized by u and v along the
// (p1-p0) and (p2-p1) directions. Same as bilinear interpolation.
template <typename T>
inline T interpolate_quad(
const T& p0, const T& p1, const T& p2, const T& p3, vec2f uv) {
if (uv.x + uv.y <= 1) {
return interpolate_triangle(p0, p1, p3, uv);
} else {
return interpolate_triangle(p2, p3, p1, 1 - uv);
}
}

// Interpolates values along a cubic Bezier segment parametrized by u.
template <typename T>
inline T interpolate_bezier(
const T& p0, const T& p1, const T& p2, const T& p3, float u) {
return p0 * (1 - u) * (1 - u) * (1 - u) + p1 * 3 * u * (1 - u) * (1 - u) +
p2 * 3 * u * u * (1 - u) + p3 * u * u * u;
}
// Computes the derivative of a cubic Bezier segment parametrized by u.
template <typename T>
inline T interpolate_bezier_derivative(
const T& p0, const T& p1, const T& p2, const T& p3, float u) {
return (p1 - p0) * 3 * (1 - u) * (1 - u) + (p2 - p1) * 6 * u * (1 - u) +
(p3 - p2) * 3 * u * u;
}

// Interpolated line properties.
inline vec3f line_point(vec3f p0, vec3f p1, float u) {
return p0 * (1 - u) + p1 * u;
}
inline vec3f line_tangent(vec3f t0, vec3f t1, float u) {
return normalize(t0 * (1 - u) + t1 * u);
}

// Interpolated triangle properties.
inline vec3f triangle_point(vec3f p0, vec3f p1, vec3f p2, vec2f uv) {
return p0 * (1 - uv.x - uv.y) + p1 * uv.x + p2 * uv.y;
}
inline vec3f triangle_normal(vec3f n0, vec3f n1, vec3f n2, vec2f uv) {
return normalize(n0 * (1 - uv.x - uv.y) + n1 * uv.x + n2 * uv.y);
}

// Interpolated quad properties.
inline vec3f quad_point(vec3f p0, vec3f p1, vec3f p2, vec3f p3, vec2f uv) {
if (uv.x + uv.y <= 1) {
return triangle_point(p0, p1, p3, uv);
} else {
return triangle_point(p2, p3, p1, 1 - uv);
}
}
inline vec3f quad_normal(vec3f n0, vec3f n1, vec3f n2, vec3f n3, vec2f uv) {
if (uv.x + uv.y <= 1) {
return triangle_normal(n0, n1, n3, uv);
} else {
return triangle_normal(n2, n3, n1, 1 - uv);
}
}

// Interpolated sphere properties.
inline vec3f sphere_point(const vec3f p, float r, vec2f uv) {
return p + r * vec3f{cos(uv.x * 2 * pif) * sin(uv.y * pif),
sin(uv.x * 2 * pif) * sin(uv.y * pif), cos(uv.y * pif)};
}
inline vec3f sphere_normal(const vec3f p, float r, vec2f uv) {
return normalize(vec3f{cos(uv.x * 2 * pif) * sin(uv.y * pif),
sin(uv.x * 2 * pif) * sin(uv.y * pif), cos(uv.y * pif)});
}

// Triangle tangent and bitangent from uv
inline pair<vec3f, vec3f> triangle_tangents_fromuv(
vec3f p0, vec3f p1, vec3f p2, vec2f uv0, vec2f uv1, vec2f uv2) {
// Follows the definition in http://www.terathon.com/code/tangent.html and
// https://gist.github.com/aras-p/2843984
// normal points up from texture space
auto p = p1 - p0;
auto q = p2 - p0;
auto s = vec2f{uv1.x - uv0.x, uv2.x - uv0.x};
auto t = vec2f{uv1.y - uv0.y, uv2.y - uv0.y};
auto div = s.x * t.y - s.y * t.x;

if (div != 0) {
auto tu = vec3f{t.y * p.x - t.x * q.x, t.y * p.y - t.x * q.y,
t.y * p.z - t.x * q.z} /
div;
auto tv = vec3f{s.x * q.x - s.y * p.x, s.x * q.y - s.y * p.y,
s.x * q.z - s.y * p.z} /
div;
return {tu, tv};
} else {
return {{1, 0, 0}, {0, 1, 0}};
}
}

// Quad tangent and bitangent from uv.
inline pair<vec3f, vec3f> quad_tangents_fromuv(vec3f p0, vec3f p1, vec3f p2,
vec3f p3, vec2f uv0, vec2f uv1, vec2f uv2, vec2f uv3, vec2f current_uv) {
if (current_uv.x + current_uv.y <= 1) {
return triangle_tangents_fromuv(p0, p1, p3, uv0, uv1, uv3);
} else {
return triangle_tangents_fromuv(p2, p3, p1, uv2, uv3, uv1);
}
}

} // namespace yocto

// -----------------------------------------------------------------------------
// USER INTERFACE UTILITIES
// -----------------------------------------------------------------------------
Expand Down
121 changes: 0 additions & 121 deletions libs/yocto/yocto_modeling.h
Original file line number Diff line number Diff line change
Expand Up @@ -332,13 +332,6 @@ static pair<vector<vec4i>, vector<T>> subdivide_catmullclark_creased(
const vector<vec2i>& creases, const vector<int>& corners,
int subdivisions = 1, bool lock_boundary = false);

// Shape subdivision
inline shape_data subdivide_shape(
const shape_data& shape, int subdivisions, bool catmullclark);

inline fvshape_data subdivide_fvshape(
const fvshape_data& shape, int subdivisions, bool catmullclark);

} // namespace yocto

// -----------------------------------------------------------------------------
Expand All @@ -356,12 +349,6 @@ inline vector<vec3f> displace_vertices(const vector<vec3f>& positions,
const image_t<vec4f>& displacement, float scale = 1.0f,
float offset = 0.5f);

// Shape displacement
inline shape_data displace_shape(const shape_data& shape,
const image_t<float>& displacement, float height = 1, float offset = 0.5f);
inline shape_data displace_shape(const shape_data& shape,
const image_t<vec4f>& displacement, float height = 1, float offset = 0.5f);

} // namespace yocto

// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -2250,90 +2237,6 @@ static pair<vector<vec4i>, vector<T>> subdivide_catmullclark_illustration(
return {quads, vertices};
}

// Shape subdivision
inline shape_data subdivide_shape(
const shape_data& shape, int subdivisions, bool catmullclark) {
// This should probably be re-implemented in a faster fashion,
// but how it is not obvious
if (subdivisions == 0) return shape;
auto subdivided = shape_data{};
if (!subdivided.points.empty()) {
subdivided = shape;
} else if (!subdivided.lines.empty()) {
std::tie(std::ignore, subdivided.normals) = subdivide_lines(
shape.lines, shape.normals, subdivisions);
std::tie(std::ignore, subdivided.texcoords) = subdivide_lines(
shape.lines, shape.texcoords, subdivisions);
std::tie(std::ignore, subdivided.colors) = subdivide_lines(
shape.lines, shape.colors, subdivisions);
std::tie(std::ignore, subdivided.radius) = subdivide_lines(
subdivided.lines, shape.radius, subdivisions);
std::tie(subdivided.lines, subdivided.positions) = subdivide_lines(
shape.lines, shape.positions, subdivisions);
} else if (!subdivided.triangles.empty()) {
std::tie(std::ignore, subdivided.normals) = subdivide_triangles(
shape.triangles, shape.normals, subdivisions);
std::tie(std::ignore, subdivided.texcoords) = subdivide_triangles(
shape.triangles, shape.texcoords, subdivisions);
std::tie(std::ignore, subdivided.colors) = subdivide_triangles(
shape.triangles, shape.colors, subdivisions);
std::tie(std::ignore, subdivided.radius) = subdivide_triangles(
shape.triangles, shape.radius, subdivisions);
std::tie(subdivided.triangles, subdivided.positions) = subdivide_triangles(
shape.triangles, shape.positions, subdivisions);
} else if (!subdivided.quads.empty() && !catmullclark) {
std::tie(std::ignore, subdivided.normals) = subdivide_quads(
shape.quads, shape.normals, subdivisions);
std::tie(std::ignore, subdivided.texcoords) = subdivide_quads(
shape.quads, shape.texcoords, subdivisions);
std::tie(std::ignore, subdivided.colors) = subdivide_quads(
shape.quads, shape.colors, subdivisions);
std::tie(std::ignore, subdivided.radius) = subdivide_quads(
shape.quads, shape.radius, subdivisions);
std::tie(subdivided.quads, subdivided.positions) = subdivide_quads(
shape.quads, shape.positions, subdivisions);
} else if (!subdivided.quads.empty() && catmullclark) {
std::tie(std::ignore, subdivided.normals) = subdivide_catmullclark(
shape.quads, shape.normals, subdivisions);
std::tie(std::ignore, subdivided.texcoords) = subdivide_catmullclark(
shape.quads, shape.texcoords, subdivisions);
std::tie(std::ignore, subdivided.colors) = subdivide_catmullclark(
shape.quads, shape.colors, subdivisions);
std::tie(std::ignore, subdivided.radius) = subdivide_catmullclark(
shape.quads, shape.radius, subdivisions);
std::tie(subdivided.quads, subdivided.positions) = subdivide_catmullclark(
shape.quads, shape.positions, subdivisions);
} else {
// empty shape
}
return subdivided;
}

// Subdivision
inline fvshape_data subdivide_fvshape(
const fvshape_data& shape, int subdivisions, bool catmullclark) {
// This should be probably re-implemeneted in a faster fashion.
if (subdivisions == 0) return shape;
auto subdivided = fvshape_data{};
if (!catmullclark) {
std::tie(subdivided.quadspos, subdivided.positions) = subdivide_quads(
shape.quadspos, shape.positions, subdivisions);
std::tie(subdivided.quadsnorm, subdivided.normals) = subdivide_quads(
shape.quadsnorm, shape.normals, subdivisions);
std::tie(subdivided.quadstexcoord, subdivided.texcoords) = subdivide_quads(
shape.quadstexcoord, shape.texcoords, subdivisions);
} else {
std::tie(subdivided.quadspos, subdivided.positions) =
subdivide_catmullclark(shape.quadspos, shape.positions, subdivisions);
std::tie(subdivided.quadsnorm, subdivided.normals) = subdivide_catmullclark(
shape.quadsnorm, shape.normals, subdivisions);
std::tie(subdivided.quadstexcoord, subdivided.texcoords) =
subdivide_catmullclark(
shape.quadstexcoord, shape.texcoords, subdivisions, true);
}
return subdivided;
}

} // namespace yocto

// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -2367,30 +2270,6 @@ inline vector<vec3f> displace_vertices(const vector<vec3f>& positions,
return displaced;
}

// Displacement
inline shape_data displace_shape(const shape_data& shape,
const image_t<float>& displacement, float height, float offset) {
if (displacement.empty() || shape.texcoords.empty() ||
shape.normals.empty() || (shape.triangles.empty() && shape.quads.empty()))
return shape;
auto displaced = shape;
displaced.positions = displace_vertices(displaced.positions,
displaced.normals, displaced.texcoords, displacement, height, offset);
displaced.normals = compute_normals(displaced);
return displaced;
}
inline shape_data displace_shape(const shape_data& shape,
const image_t<vec4f>& displacement, float height, float offset) {
if (displacement.empty() || shape.texcoords.empty() ||
shape.normals.empty() || (shape.triangles.empty() && shape.quads.empty()))
return shape;
auto displaced = shape;
displaced.positions = displace_vertices(displaced.positions,
displaced.normals, displaced.texcoords, displacement, height, offset);
displaced.normals = compute_normals(displaced);
return displaced;
}

} // namespace yocto

// -----------------------------------------------------------------------------
Expand Down
Loading

0 comments on commit d99e935

Please sign in to comment.