diff --git a/scenes/extrudes.fart b/scenes/extrudes.fart index 4c977a4..45f9e59 100644 --- a/scenes/extrudes.fart +++ b/scenes/extrudes.fart @@ -3,14 +3,15 @@ scene { options { - multisample 3 + ambient_occlusion 2 + multisample 2 exposure 1.2 } camera { position <0, -10, 10> - look_at <0, 0, 1> + look_at <0, 0, 2> } light { position <10, -12, 8> } @@ -24,30 +25,29 @@ scene } } - extrude + subtract { - polygon - { - <3, 0> - <1, 1> - <2, 3> - <-1, 1> - <-3, 2> - <-2, -1> - <-3, -3> - <-1, -2> - <1, -4> - <1, -1> - } - offset 3 + extrude { ngon 5, 6 offset 2 } + extrude { ngon 5, 5 offset 3 translate <0, 0, -0.5> } material { color <1, 0.7, 0> } - translate <-3, 0, 0> } - extrude + union { - ngon 5, 2 - offset 1 - translate <4, 0, 0> + extrude + { + ngon 6, 2 + offset 3 { scale 0.5 position <4, 0> } + offset 3 + offset 1 { scale 0 } + } + extrude + { + ngon 6, 2 + offset 3 { scale 0.5 position <-4, 0> } + offset 3 + offset 1 { scale 0 } + } + material { color <0, 0.9, 0.9> } } } diff --git a/shapes/Extrude.cc b/shapes/Extrude.cc index b42cdbb..a0876ee 100644 --- a/shapes/Extrude.cc +++ b/shapes/Extrude.cc @@ -66,29 +66,26 @@ Shape::IntersectionList Extrude::intersect(refptr _this, const Ray & ray) Vector e1 = p2 - p1; Vector e2 = p3 - p2; Vector normal = (e1 * e2).normalize(); - if (ray_inv.getDirection() % normal < 0) /* skip backfaces */ + double a = normal[0], b = normal[1], c = normal[2]; + double d = -(a * p1[0] + b * p1[1] + c * p1[2]); + LinearSolver solver( a * ray_inv.getDirection()[0] + + b * ray_inv.getDirection()[1] + + c * ray_inv.getDirection()[2], + a * ray_inv.getOrigin()[0] + + b * ray_inv.getOrigin()[1] + + c * ray_inv.getOrigin()[2] + + d); + Solver::Result solutions = solver.solve(); + if (solutions.numResults > 0 && solutions.results[0] > 0.0) { - double a = normal[0], b = normal[1], c = normal[2]; - double d = -(a * p1[0] + b * p1[1] + c * p1[2]); - LinearSolver solver( a * ray_inv.getDirection()[0] - + b * ray_inv.getDirection()[1] - + c * ray_inv.getDirection()[2], - a * ray_inv.getOrigin()[0] - + b * ray_inv.getOrigin()[1] - + c * ray_inv.getOrigin()[2] - + d); - Solver::Result solutions = solver.solve(); - if (solutions.numResults > 0 && solutions.results[0] > 0.0) + Vector ipoint = ray_inv[solutions.results[0]]; + Polygon quad; + quad.add(p1).add(p2).add(p3).add(p4); + if (quad.containsPointConvex(ipoint)) { - Vector ipoint = ray_inv[solutions.results[0]]; - Polygon quad; - quad.add(p1).add(p2).add(p3).add(p4); - if (quad.containsPointConvex(ipoint)) - { - res.add(Intersection(_this, - m_transform.transform_point(ipoint), - m_transform.transform_normal(normal))); - } + res.add(Intersection(_this, + m_transform.transform_point(ipoint), + m_transform.transform_normal(normal))); } } } @@ -99,8 +96,31 @@ Shape::IntersectionList Extrude::intersect(refptr _this, const Ray & ray) } double a = 0, b = 0, c = -1.0, d = 0.0; - if (ray_inv.getDirection() % Vector(a, b, c) < 0) + LinearSolver solver( a * ray_inv.getDirection()[0] + + b * ray_inv.getDirection()[1] + + c * ray_inv.getDirection()[2], + a * ray_inv.getOrigin()[0] + + b * ray_inv.getOrigin()[1] + + c * ray_inv.getOrigin()[2] + + d); + Solver::Result solutions = solver.solve(); + if (solutions.numResults > 0 && solutions.results[0] > 0.0) { + Vector ipoint = ray_inv[solutions.results[0]]; + for (int p = 0; p < n_polygons; p++) + { + refptr polygon = m_polygons[p]; + if (polygon->containsPoint2D(ipoint)) + { + res.add(Intersection(_this, + m_transform.transform_point(ipoint), + m_transform.transform_normal(Vector(a, b, c)))); + } + } + } + if (scale[0] > 0.0 && scale[1] > 0.0) + { + a = 0, b = 0, c = 1.0, d = -distance; LinearSolver solver( a * ray_inv.getDirection()[0] + b * ray_inv.getDirection()[1] + c * ray_inv.getDirection()[2], @@ -114,47 +134,18 @@ Shape::IntersectionList Extrude::intersect(refptr _this, const Ray & ray) Vector ipoint = ray_inv[solutions.results[0]]; for (int p = 0; p < n_polygons; p++) { - refptr polygon = m_polygons[p]; - if (polygon->containsPoint2D(ipoint)) + Polygon tp = *m_polygons[p]; + for (int i = 0, sz = tp.size(); i < sz; i++) + { + tp[i] = new Vector(tp[i]->mult(scale) + shift); + (*tp[i])[2] += distance; + } + if (tp.containsPoint2D(ipoint)) { res.add(Intersection(_this, m_transform.transform_point(ipoint), m_transform.transform_normal(Vector(a, b, c)))); - } - } - } - } - if (scale[0] > 0.0 && scale[1] > 0.0) - { - a = 0, b = 0, c = 1.0, d = -distance; - if (ray_inv.getDirection() % Vector(a, b, c) < 0) - { - LinearSolver solver( a * ray_inv.getDirection()[0] - + b * ray_inv.getDirection()[1] - + c * ray_inv.getDirection()[2], - a * ray_inv.getOrigin()[0] - + b * ray_inv.getOrigin()[1] - + c * ray_inv.getOrigin()[2] - + d); - Solver::Result solutions = solver.solve(); - if (solutions.numResults > 0 && solutions.results[0] > 0.0) - { - Vector ipoint = ray_inv[solutions.results[0]]; - for (int p = 0; p < n_polygons; p++) - { - Polygon tp = *m_polygons[p]; - for (int i = 0, sz = tp.size(); i < sz; i++) - { - tp[i] = new Vector(tp[i]->mult(scale) + shift); - (*tp[i])[2] += distance; - } - if (tp.containsPoint2D(ipoint)) - { - res.add(Intersection(_this, - m_transform.transform_point(ipoint), - m_transform.transform_normal(Vector(a, b, c)))); - break; - } + break; } } } diff --git a/util/Polygon.cc b/util/Polygon.cc index 6524fb9..a187cb5 100644 --- a/util/Polygon.cc +++ b/util/Polygon.cc @@ -3,7 +3,7 @@ #include "Polygon.h" -#define FP_EQUAL(x,y) (fabs((x)-(y)) < 1E-6) +#define FP_EQUAL(x,y) (fabs((x)-(y)) < 1E-3) /* * from http://local.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/ diff --git a/vim/syntax/fart.vim b/vim/syntax/fart.vim index 85ca63e..8741afa 100644 --- a/vim/syntax/fart.vim +++ b/vim/syntax/fart.vim @@ -10,8 +10,8 @@ endif syn case match -syn keyword fartKeywords ambient ambient_occlusion color define diffuse exposure extrude height jitter look_at material max_depth multisample ngon offset polygon position radius reflectance rotate scale shininess size specular translate transparency union up vfov width -syn keyword fartObjects box camera cyl intersect light options plane scene sphere subtract union +syn keyword fartKeywords ambient ambient_occlusion color define diffuse exposure height jitter look_at material max_depth multisample ngon offset polygon position radius reflectance rotate scale shininess size specular translate transparency union up vfov width +syn keyword fartObjects box camera cyl extrude intersect light options plane scene sphere subtract union syn match fartNumber "\(^\|\W\)\@<=[+-]\=\(\d\+\)\=\.\=\d\+\([eE][+-]\=\d\+\)\=" hi def link fartKeywords Operator