updated extrudes scene, fixed Extrude objects to return backfaces so that boolean objects work properly

git-svn-id: svn://anubis/fart/trunk@280 7f9b0f55-74a9-4bce-be96-3c2cd072584d
This commit is contained in:
Josh Holtrop 2010-07-08 19:01:00 +00:00
parent 53ebaeec3e
commit d2b37a1687
4 changed files with 75 additions and 84 deletions

View File

@ -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> }
}
}

View File

@ -66,29 +66,26 @@ Shape::IntersectionList Extrude::intersect(refptr<Shape> _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<Shape> _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> 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<Shape> _this, const Ray & ray)
Vector ipoint = ray_inv[solutions.results[0]];
for (int p = 0; p < n_polygons; p++)
{
refptr<Polygon> 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;
}
}
}

View File

@ -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/

View File

@ -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