public void Evaluating_the_rule_for_a_CSG_operation( CsgOperation op, CsgOperand hitShape, bool insideLeft, bool insideRight, bool expectedResult) { var result = Csg.IntersectionAllowed(op, hitShape, insideLeft, insideRight); result.Should().Be(expectedResult); }
private Shape CreateBottomHoleForA() { var leftTriangle = CreateTrianglePrism(); leftTriangle.Transform = Transformation.Translation(-0.42, 0, 0) .Chain(Transformation.Scaling(0.2, 0.2, 1)) .Chain(Transformation.Scaling(0.5, 1, 1)) .Chain(Transformation.Translation(0, -0.01, -0.1)); var rightTriangle = CreateTrianglePrism(); rightTriangle.Transform = Transformation.Translation(0.42, 0, 0) .Chain(Transformation.Scaling(0.2, 0.2, 1)) .Chain(Transformation.Scaling(0.5, 1, 1)) .Chain(Transformation.Translation(0, -0.01, -0.1)); var middleBox = new Cube(); middleBox.Transform = Transformation.Translation(0, -1.25, 0.9) .Chain(Transformation.Scaling(0.45, 1, 1)); //AddShapesToWorld(middleBox); var bothTriangles = new Csg(CsgOperation.Union, leftTriangle, rightTriangle); var all = new Csg(CsgOperation.Union, bothTriangles, middleBox); AddShapesToWorld(all); return(all); }
public void RayMissesCsgObject() { var c = new Csg(Operation.Union, new Sphere(), new Cube()); var r = new Ray(Vector4.CreatePosition(0, 2, -5), Vector4.CreateDirection(0, 0, 1)); var xs = c.LocalIntersect(r); Assert.Empty(xs); }
public void A_ray_misses_a_CSG_object() { var csg = new Csg(CsgOperation.Union, Sphere.UnitSphere(), new Cube()); var ray = new Ray(Tuple.Point(0, 2, -5), Tuple.Vector(0, 0, 1)); var xs = csg.LocalIntersect(ray); xs.Intersections.Should().BeEmpty(); }
public void CreateCsg() { var s1 = new Sphere(); var s2 = new Cube(); var csg = new Csg(Operation.Union, s1, s2); Assert.Equal(s1, csg.Left); Assert.Equal(s2, csg.Right); Assert.Equal(Operation.Union, csg.Operation); }
public void Filtering_a_list_of_intersections(CsgOperation operation, int index1, int index2) { var s1 = Sphere.UnitSphere(); var s2 = new Cube(); var csg = new Csg(operation, s1, s2); var xs = IntersectionCollection.Create((1, s1), (2, s2), (3, s1), (4, s2)); var result = csg.FilterIntersections(xs); result.Intersections.Should().HaveCount(2); result[0].Should().Be(xs[index1]); result[1].Should().Be(xs[index2]); }
public void CSG_is_created_with_an_operation_and_two_shapes() { var s1 = Sphere.UnitSphere(); var s2 = new Cube(); var csg = new Csg(CsgOperation.Union, s1, s2); csg.Left.Should().Be(s1); csg.Right.Should().Be(s2); s1.Parent.Should().Be(csg); s2.Parent.Should().Be(csg); }
public void IntersectCsgTestsChildrenIfBoxHit() { var left = new TestShape(); var right = new TestShape(); var shape = new Csg(Operation.Difference, left, right); var r = new Ray( Vector4.CreatePosition(0, 0, -5), Vector4.CreateDirection(0, 0, 1)); var xs = shape.Intersect(r); Assert.NotNull(left.SavedRay); Assert.NotNull(right.SavedRay); }
public void EvaluatingRuleForCsgOperation( Operation op, bool lhit, bool inl, bool inr, bool expected) { var actual = Csg.IntersectionAllowed( op, lhit, inl, inr); Assert.Equal(expected, actual); }
private Shape CreateTrianglePrism() { var cube = new Cube(); cube.Transform = Transformation.RotationZ(Math.PI / 4) .Chain(Transformation.Translation(0, 0, 1)); var floor = new Cube(); floor.Transform = Transformation.Translation(0, -1, 1) .Chain(Transformation.Scaling(2, 1, 1.1)); var trianglePrism = new Csg(CsgOperation.Difference, cube, floor); return(trianglePrism); }
public void A_ray_hits_a_CSG_object() { var s1 = Sphere.UnitSphere(); var s2 = Sphere.UnitSphere(); s2.Transform = Transformation.Translation(0, 0, 0.5); var csg = new Csg(CsgOperation.Union, s1, s2); var ray = new Ray(Tuple.Point(0, 0, -5), Tuple.Vector(0, 0, 1)); var xs = csg.LocalIntersect(ray); xs.Intersections.Should().HaveCount(2); xs[0].T.Should().Be(4); xs[0].Object.Should().Be(s1); xs[1].T.Should().Be(6.5); xs[1].Object.Should().Be(s2); }
public void CsgHasBoundingBoxThatContainsItsChildren() { var left = new Sphere(); var right = new Sphere() { Transform = Transform.Translate(2, 3, 4), }; var shape = new Csg(Operation.Difference, left, right); var box = shape.GetBounds(); Assert.Equal( Vector4.CreatePosition(-1, -1, -1), box.Min); Assert.Equal( Vector4.CreatePosition(3, 4, 5), box.Max); }
public void RayHitsCsgObject() { var s1 = new Sphere(); var s2 = new Sphere() { Transform = Transform.Translate(0, 0, 0.5), }; var c = new Csg(Operation.Union, s1, s2); var r = new Ray(Vector4.CreatePosition(0, 0, -5), Vector4.CreateDirection(0, 0, 1)); var xs = c.LocalIntersect(r); Assert.Equal(2, xs.Count); Assert.Equal(4, xs[0].T); Assert.Equal(s1, xs[0].Object); Assert.Equal(6.5, xs[1].T); Assert.Equal(s2, xs[1].Object); }
public void FilterListOfIntersections( Operation op, int x0, int x1) { var s1 = new Sphere(); var s2 = new Cube(); var csg = new Csg(op, s1, s2); var xs = IntersectionList.Create( new Intersection(1, s1), new Intersection(2, s2), new Intersection(3, s1), new Intersection(4, s2)); var result = csg.FilterIntersections(xs); Assert.Equal(2, result.Count); Assert.Equal(xs[x0], result[0]); Assert.Equal(xs[x1], result[1]); }
public void SubdividingCsgShapeSubdividesItsChildren() { var s1 = new Sphere() { Transform = Transform.Translate(-1.5, 0, 0), }; var s2 = new Sphere() { Transform = Transform.Translate(1.5, 0, 0), }; var left = new Group(); left.Add(s1); left.Add(s2); var s3 = new Sphere() { Transform = Transform.Translate(0, 0, -1.5), }; var s4 = new Sphere() { Transform = Transform.Translate(0, 0, 1.5), }; var right = new Group(); right.Add(s3); right.Add(s4); var shape = new Csg(Operation.Difference, left, right); shape.Divide(1); Assert.Contains(s1, (Group)left[0]); Assert.Contains(s2, (Group)left[1]); Assert.Contains(s3, (Group)right[0]); Assert.Contains(s4, (Group)right[1]); }
private Shape CreateC() { var sphere = Sphere.UnitSphere(); sphere.Transform = Transformation.Scaling(1, 0.7, 1); var frontCube = new Cube(); frontCube.Transform = Transformation.Translation(0, 0, -1); var frontShavedOff = new Csg(CsgOperation.Difference, sphere, frontCube); var rightCube = new Cube(); rightCube.Transform = Transformation.Translation(1, 0, 0); var rightSideShavedOff = new Csg(CsgOperation.Difference, frontShavedOff, rightCube); var shot = new Cylinder(-1, 1, true); shot.Transform = Transformation.Translation(0.3, 0, 0) .Chain(Transformation.Scaling(1, 0.5, 1)) .Chain(Transformation.RotationX(Math.PI / 2)); return(new Csg(CsgOperation.Difference, rightSideShavedOff, shot)); }
private Shape CreateA() { var trianglePrism = CreateTrianglePrism(); trianglePrism.Transform = Transformation.Scaling(0.5, 1, 0.3); var trianglePrismHole = CreateTrianglePrism(); trianglePrismHole.Transform = Transformation.Translation(0, 0.7, 0) .Chain(Transformation.Scaling(0.3, 0.3, 1)) .Chain(Transformation.Scaling(0.5, 1, 2)) .Chain(Transformation.Translation(0, 0, -0.1)); //AddShapesToWorld(trianglePrismHole); var withHole = new Csg(CsgOperation.Difference, trianglePrism, trianglePrismHole); var bottomHole = CreateBottomHoleForA(); //AddShapesToWorld(bottomHole); var withBothHoles = new Csg(CsgOperation.Difference, withHole, bottomHole); withBothHoles.Transform = Transformation.Translation(0, -0.5, 0); return(withBothHoles); }
/// <summary> /// Gets the bounding box for a level /// </summary> /// <param name="node">Root node</param> /// <returns>Returns the level bounding rectangle</returns> private Rectangle GetLevelBounds( Csg.BspNode node ) { Point2 minPt = new Point2( float.MaxValue, float.MaxValue ); Point2 maxPt = new Point2( float.MinValue, float.MinValue ); GetLevelBounds( node, minPt, maxPt ); return new Rectangle( minPt, maxPt ); }
/// <summary> /// Clips a BSP node, returns a triangle list /// </summary> private static void ClippetyClip( Csg.BspNode node, float x, float y, float mX, float mY, TriBuilder builder ) { if ( node == null ) { return; } ClipNode( node.Quad, x, y, mX, mY, builder ); ClippetyClip( node.InFront, x, y, mX, mY, builder ); ClippetyClip( node.Behind, x, y, mX, mY, builder ); }
public PolygonMesh.Mesh CsgToMeshRecursive(Csg.Solids.Mesh objectToPrecess) { return objectToPrecess.GetMesh(); }
public void RenderToGlRecursive(Csg.Solids.Mesh objectToProcess) { RGBA_Floats partColor = new RGBA_Floats(.8, .8, 1); RenderMeshToGl.Render(objectToProcess.GetMesh(), partColor); }
/// <summary> /// Gets the bounding rectangle for a node and its children /// </summary> /// <param name="node">Node to check</param> /// <param name="min">Current minimum bounds</param> /// <param name="max">Current maximum bounds</param> private void GetLevelBounds( Csg.BspNode node, Point2 min, Point2 max ) { if ( node == null ) { return; } min.X = Utils.Min( Utils.Min( node.Edge.P0.X, min.X ), node.Edge.P1.X ); min.Y = Utils.Min( Utils.Min( node.Edge.P0.Y, min.Y ), node.Edge.P1.Y ); max.X = Utils.Max( Utils.Max( node.Edge.P0.X, max.X ), node.Edge.P1.X ); max.Y = Utils.Max( Utils.Max( node.Edge.P0.Y, max.Y ), node.Edge.P1.Y ); GetLevelBounds( node.InFront, min, max ); GetLevelBounds( node.Behind, min, max ); }
public static Tuple <World, Camera> Example13(int width, int height) { var world = new World(); var yellow = new Material { Color = new Color(0.8, 0.8, 0.05), }; var col1 = new Material { Color = new Color(0.2, 0.4, 0.65), }; var col2 = new Material { Color = new Color(0.1, 0.45, 0.55), }; var cyl1 = new Cylinder() { Minimum = -1, Maximum = 1, IsClosed = true, Transform = Transform.Scale(0.5, 1, 0.5), Material = yellow, }; var cyl2 = new Cylinder() { Minimum = -1, Maximum = 1, IsClosed = true, Transform = Transform.RotateZ(Math.PI / 2) * Transform.Scale(0.5, 1, 0.5), Material = yellow, }; var cyl3 = new Cylinder() { Minimum = -1, Maximum = 1, IsClosed = true, Transform = Transform.RotateX(Math.PI / 2) * Transform.Scale(0.5, 1, 0.5), Material = yellow, }; var union1 = new Csg(Operation.Union, cyl1, cyl2); var union2 = new Csg(Operation.Union, union1, cyl3) { Transform = Transform.Scale(1.2, 1.2, 1.2), }; var sphere1 = new Sphere() { // Transform = Transform.Scale(Math.Sqrt(2), Math.Sqrt(2), Math.Sqrt(2)), Transform = Transform.Scale(1.4, 1.4, 1.4), Material = col1, }; var cube1 = new Cube() { Material = col2, }; var intersec1 = new Csg(Operation.Intersect, cube1, sphere1); var diff1 = new Csg(Operation.Difference, intersec1, union2); world.Objects.Add(diff1); var light = new PointLight( Vector4.CreatePosition(10, 10, -10), Color.White); world.Lights.Add(light); var camera = new Camera(width, height, Math.PI / 4.8) { Transform = Transform.View( Vector4.CreatePosition(3.5, 3.5, -5), Vector4.CreatePosition(0, 0.0, 0), Vector4.CreateDirection(0, 1, 0)), ProgressMonitorFactory = (_rows, _cols) => new DefaultProgressMonitor(), }; return(Tuple.Create(world, camera)); }