Skip to content

Commit

Permalink
#5 29.6 Triangle Meshes
Browse files Browse the repository at this point in the history
  • Loading branch information
mandyedi committed Nov 30, 2024
1 parent 254970d commit 31cc7f7
Show file tree
Hide file tree
Showing 8 changed files with 254 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,16 @@ set (SOURCE_PRIMITIVES
set (SOURCE_TRIANGLES
src/GeometricObjects/Triangles/FlatMeshTriangle.cpp
src/GeometricObjects/Triangles/FlatMeshTriangle.h
src/GeometricObjects/Triangles/FlatUVMeshTriangle.cpp
src/GeometricObjects/Triangles/FlatUVMeshTriangle.h
src/GeometricObjects/Triangles/Triangle.cpp
src/GeometricObjects/Triangles/Triangle.h
src/GeometricObjects/Triangles/MeshTriangle.cpp
src/GeometricObjects/Triangles/MeshTriangle.h
src/GeometricObjects/Triangles/SmoothMeshTriangle.cpp
src/GeometricObjects/Triangles/SmoothMeshTriangle.h
src/GeometricObjects/Triangles/SmoothUVMeshTriangle.cpp
src/GeometricObjects/Triangles/SmoothUVMeshTriangle.h
src/GeometricObjects/Triangles/SmoothTriangle.cpp
src/GeometricObjects/Triangles/SmoothTriangle.h
)
Expand Down
17 changes: 16 additions & 1 deletion src/GeometricObjects/Compound/Grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,13 +387,24 @@ bool Grid::hit(const Ray& ray, float& t, ShadeRec& sr) const {
// They are just small wrapper functions that call the functions read_ply_file or read_uv_ply_file that
// do the actual reading
// These use the PLY code by Greg Turk to read the PLY file
void Grid::read_flat_triangles(char* file_name) { read_ply_file(file_name, flat); }
void Grid::read_flat_triangles(char* file_name) {
read_ply_file(file_name, flat);
}

void Grid::read_flat_uv_triangles(char *file_name) {
read_ply_file(file_name, flat);
}

void Grid::read_smooth_triangles(char* file_name) {
read_ply_file(file_name, smooth);
compute_mesh_normals();
}

void Grid::read_smooth_uv_triangles(char *file_name) {
read_ply_file(file_name, smooth);
compute_mesh_normals();
}

// tesselate a unit sphere into flat triangles that are stored directly in the grid
// TODO:: review this function for int float casts and precision
void Grid::tessellate_flat_sphere(const int horizontal_steps, const int vertical_steps) {
Expand Down Expand Up @@ -819,6 +830,10 @@ void Grid::read_ply_file(char* file_name, const int triangle_type) {
*/
}

void Grid::read_uv_ply_file(char *file_name, const int triangle_type) {
// TODO: implement ply file reader for textured objects
}

// this computes the average normal at each vertex
// the calculation is of order(num_vertices)
// some triangles in ply files are not defined properly
Expand Down
6 changes: 6 additions & 0 deletions src/GeometricObjects/Compound/Grid.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,12 @@ class Grid : public Compound {

void read_flat_triangles(char* file_name);

void read_flat_uv_triangles(char *file_name);

void read_smooth_triangles(char* file_name);

void read_smooth_uv_triangles(char *file_name);

void tessellate_flat_sphere(const int horizontal_steps, const int vertical_steps);

void tessellate_smooth_sphere(const int horizontal_steps, const int vertical_steps);
Expand All @@ -80,6 +84,8 @@ class Grid : public Compound {

void read_ply_file(char* file_name, const int triangle_type);

void read_uv_ply_file(char *file_name, const int triangle_type);

void compute_mesh_normals();

BBox get_bounding_box();
Expand Down
71 changes: 71 additions & 0 deletions src/GeometricObjects/Triangles/FlatUVMeshTriangle.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Copyright (C) Kevin Suffern 2000-2007.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

// Copyright notice for changes since the originally published version:
// Copyright (C) Eduárd Mándy 2019-2021
// Though this C++ code was change in a large measure it still has the original copyright notice.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

#include "FlatUVMeshTriangle.h"

#include <limits>

FlatUVMeshTriangle::FlatUVMeshTriangle(Mesh* _mesh_ptr, const int i0, const int i1, const int i2) : MeshTriangle(_mesh_ptr, i0, i1, i2) {}

FlatUVMeshTriangle* FlatUVMeshTriangle::clone() const { return new FlatUVMeshTriangle(*this); }

bool FlatUVMeshTriangle::hit(const Ray& ray, float& tmin, ShadeRec& sr) const {
Point3D v0(mesh_ptr->vertices[index0]);
Point3D v1(mesh_ptr->vertices[index1]);
Point3D v2(mesh_ptr->vertices[index2]);

float a = v0.x - v1.x, b = v0.x - v2.x, c = ray.d.x, d = v0.x - ray.o.x;
float e = v0.y - v1.y, f = v0.y - v2.y, g = ray.d.y, h = v0.y - ray.o.y;
float i = v0.z - v1.z, j = v0.z - v2.z, k = ray.d.z, l = v0.z - ray.o.z;

float m = f * k - g * j, n = h * k - g * l, p = f * l - h * j;
float q = g * i - e * k, s = e * j - f * i;

float inv_denom = 1.0f / (a * m + b * q + c * s);

float e1 = d * m - b * n - c * p;
float beta = e1 * inv_denom;

if (beta < 0.0f) {
return false;
}

float r = e * l - h * i;
float e2 = a * n + d * q + c * r;
float gamma = e2 * inv_denom;

if (gamma < 0.0f) {
return false;
}

if (beta + gamma > 1.0f) {
return false;
}

float e3 = a * p - b * r + d * s;
float t = e3 * inv_denom;

if (t < std::numeric_limits<float>::epsilon()) {
return false;
}

tmin = t;
sr.u = interpolate_u(beta, gamma);
sr.v = interpolate_v(beta, gamma);

// From the book, chapter 29.6 Triangle Meshes, page 663
// Storing local hit point in ShadeRec object is not required here
// because the function ImageTexture::get_color in Listing 29.7
// doesn't use the local hit point when it uses u and v.

return true;
}
37 changes: 37 additions & 0 deletions src/GeometricObjects/Triangles/FlatUVMeshTriangle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (C) Kevin Suffern 2000-2007.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

// Copyright notice for changes since the originally published version:
// Copyright (C) Eduárd Mándy 2019-2021
// Though this C++ code was change in a large measure it still has the original copyright notice.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

#ifndef __FLAT_UV_MESH_TRIANGLE__
#define __FLAT_UV_MESH_TRIANGLE__

#include "MeshTriangle.h"

class FlatUVMeshTriangle : public MeshTriangle {
public:

FlatUVMeshTriangle() = default;

explicit FlatUVMeshTriangle(Mesh* _meshPtr, const int i0, const int i1, const int i2);

~FlatUVMeshTriangle() = default;

FlatUVMeshTriangle(const FlatUVMeshTriangle& fmt) = default;
FlatUVMeshTriangle(FlatUVMeshTriangle&& fmt) = default;
FlatUVMeshTriangle& operator=(const FlatUVMeshTriangle& rhs) = default;
FlatUVMeshTriangle& operator=(FlatUVMeshTriangle&& rhs) = default;

FlatUVMeshTriangle* clone() const override;

bool hit(const Ray& ray, float& tmin, ShadeRec& sr) const override;
};

#endif
2 changes: 1 addition & 1 deletion src/GeometricObjects/Triangles/SmoothMeshTriangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ bool SmoothMeshTriangle::hit(const Ray& ray, float& tmin, ShadeRec& sr) const {
float e2 = a * n + d * q + c * r;
float gamma = e2 * inv_denom;

if (gamma < 0.0) {
if (gamma < 0.0f) {
return false;
}

Expand Down
79 changes: 79 additions & 0 deletions src/GeometricObjects/Triangles/SmoothUVMeshTriangle.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright (C) Kevin Suffern 2000-2007.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

// Copyright notice for changes since the originally published version:
// Copyright (C) Eduárd Mándy 2019-2021
// Though this C++ code was change in a large measure it still has the original copyright notice.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

#include "SmoothUVMeshTriangle.h"

#include <limits>

SmoothUVMeshTriangle::SmoothUVMeshTriangle(Mesh* _mesh_ptr, const int i0, const int i1, const int i2) : MeshTriangle(_mesh_ptr, i0, i1, i2) {}

SmoothUVMeshTriangle* SmoothUVMeshTriangle::clone() const { return new SmoothUVMeshTriangle(*this); }

bool SmoothUVMeshTriangle::hit(const Ray& ray, float& tmin, ShadeRec& sr) const {
Point3D v0(mesh_ptr->vertices[index0]);
Point3D v1(mesh_ptr->vertices[index1]);
Point3D v2(mesh_ptr->vertices[index2]);

float a = v0.x - v1.x, b = v0.x - v2.x, c = ray.d.x, d = v0.x - ray.o.x;
float e = v0.y - v1.y, f = v0.y - v2.y, g = ray.d.y, h = v0.y - ray.o.y;
float i = v0.z - v1.z, j = v0.z - v2.z, k = ray.d.z, l = v0.z - ray.o.z;

float m = f * k - g * j, n = h * k - g * l, p = f * l - h * j;
float q = g * i - e * k, s = e * j - f * i;

float inv_denom = 1.0f / (a * m + b * q + c * s);

float e1 = d * m - b * n - c * p;
float beta = e1 * inv_denom;

if (beta < 0.0f) {
return false;
}

float r = e * l - h * i;
float e2 = a * n + d * q + c * r;
float gamma = e2 * inv_denom;

if (gamma < 0.0f) {
return false;
}

if (beta + gamma > 1.0f) {
return false;
}

float e3 = a * p - b * r + d * s;
float t = e3 * inv_denom;

if (t < std::numeric_limits<float>::epsilon()) {
return false;
}

tmin = t;
sr.normal = interpolate_normal(beta, gamma); // for smooth shading
sr.u = interpolate_u(beta, gamma);
sr.v = interpolate_v(beta, gamma);

// From the book, chapter 29.6 Triangle Meshes, page 663
// Storing local hit point in ShadeRec object is not required here
// because the function ImageTexture::get_color in Listing 29.7
// doesn't use the local hit point when it uses u and v.

return true;
}

Normal SmoothUVMeshTriangle::interpolate_normal(const float beta, const float gamma) const {
Normal normal((1 - beta - gamma) * mesh_ptr->normals[index0] + beta * mesh_ptr->normals[index1] + gamma * mesh_ptr->normals[index2]);
normal.normalize();

return normal;
}
40 changes: 40 additions & 0 deletions src/GeometricObjects/Triangles/SmoothUVMeshTriangle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (C) Kevin Suffern 2000-2007.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

// Copyright notice for changes since the originally published version:
// Copyright (C) Eduárd Mándy 2019-2021
// Though this C++ code was change in a large measure it still has the original copyright notice.
// This C++ code is for non-commercial purposes only.
// This C++ code is licensed under the GNU General Public License Version 2.
// See the file COPYING.txt for the full license.

#ifndef __SMOOTH_UV_MESH_TRIANGLE__
#define __SMOOTH_UV_MESH_TRIANGLE__

#include "MeshTriangle.h"

class SmoothUVMeshTriangle : public MeshTriangle {
public:

SmoothUVMeshTriangle() = default;

explicit SmoothUVMeshTriangle(Mesh* _meshPtr, const int i0, const int i1, const int i2);

~SmoothUVMeshTriangle() = default;
SmoothUVMeshTriangle(const SmoothUVMeshTriangle& fmt) = default;
SmoothUVMeshTriangle(SmoothUVMeshTriangle&& fmt) = default;
SmoothUVMeshTriangle& operator=(const SmoothUVMeshTriangle& rhs) = default;
SmoothUVMeshTriangle& operator=(SmoothUVMeshTriangle&& rhs) = default;

virtual SmoothUVMeshTriangle* clone() const override;

virtual bool hit(const Ray& ray, float& tmin, ShadeRec& sr) const override;

protected:

Normal interpolate_normal(const float beta, const float gamma) const;
};

#endif

0 comments on commit 31cc7f7

Please sign in to comment.