Beispiel #1
0
        public override void Mouse_Move(MouseEventArgs e)
        {
            _endMouseRay = Editor.Camera.GetWorldRay(new Vector2(e.X, e.Y));
            if (!_startSet)
            {
                _startPositions.Clear();
                foreach (var control in Editor.Selection)
                {
                    _startPositions.Add(control, control.Position);
                }
                _startMouseRay = _endMouseRay;
                _cameraPlane = new Plane(Editor.Camera.LookAt, Editor.Camera.LookAt + Editor.Camera.Right, Editor.Camera.LookAt + Editor.Camera.UpEffective);
                _startSet = true;
            }

            float? distanceStart, distance;
            _startMouseRay.Intersects(ref _cameraPlane, out distanceStart);
            _endMouseRay.Intersects(ref _cameraPlane, out distance);

            if (distanceStart != null && distance != null)
            {
                var deltaMouse = (_endMouseRay.Position + Vector3.Multiply(_endMouseRay.Direction, distance.Value))
                    - (_startMouseRay.Position + Vector3.Multiply(_startMouseRay.Direction, distanceStart.Value));

                foreach (var control in Editor.Selection)
                {
                    control.Position = _startPositions[control] + deltaMouse;
                }
            }
        }
Beispiel #2
0
        public static bool RayVsPlane(Ray ray, Plane plane, out float outDistance, out Vector3 intersectPoint)
        {
            bool bIntersect = SegmentVsPlane(ray.Origin, ray.Origin + ray.Direction * float.MaxValue, plane, out outDistance, out intersectPoint);
            outDistance *= float.MaxValue;

            return bIntersect;
        }
Beispiel #3
0
 public CSGMesh(Plane[] planes, List<Polygon> polygons, List<HalfEdge> edges, List<Vector3> vertices, AABBi bounds)
 {
     this.Planes = planes;
     this.Polygons = polygons;
     this.Edges = edges;
     this.Vertices = vertices;
     this.Bounds.Set(bounds);
 }
Beispiel #4
0
 public override void Mouse_Down(MouseEventArgs e)
 {
     if (e.Button == MouseButtons.Middle)
     {
         //freeze camera
         _camera = Editor.Camera.Clone();
         _startMouseRay = _camera.GetWorldRay(new Vector2(e.X, e.Y));
         _cameraPlane = new Plane(_camera.LookAt, _camera.LookAt + _camera.Right, _camera.LookAt + _camera.UpEffective);
     }
 }
        public static Frustum ExtractFrustum(Matrix4 viewProjMatrix)
        {
            Frustum frustum = new Frustum();

            Plane left = new Plane();
            left.A = viewProjMatrix.M14 + viewProjMatrix.M11;
            left.B = viewProjMatrix.M24 + viewProjMatrix.M21;
            left.C = viewProjMatrix.M34 + viewProjMatrix.M31;
            left.D = viewProjMatrix.M44 + viewProjMatrix.M41;
            left.Normalize();
            frustum.Left = left;

            Plane right = new Plane();
            right.A = viewProjMatrix.M14 - viewProjMatrix.M11;
            right.B = viewProjMatrix.M24 - viewProjMatrix.M21;
            right.C = viewProjMatrix.M34 - viewProjMatrix.M31;
            right.D = viewProjMatrix.M44 - viewProjMatrix.M41;
            right.Normalize();
            frustum.Right = right;

            Plane top = new Plane();
            top.A = viewProjMatrix.M14 - viewProjMatrix.M12;
            top.B = viewProjMatrix.M24 - viewProjMatrix.M22;
            top.C = viewProjMatrix.M34 - viewProjMatrix.M32;
            top.D = viewProjMatrix.M44 - viewProjMatrix.M42;
            top.Normalize();
            frustum.Top = top;

            Plane bottom = new Plane();
            bottom.A = viewProjMatrix.M14 + viewProjMatrix.M12;
            bottom.B = viewProjMatrix.M24 + viewProjMatrix.M22;
            bottom.C = viewProjMatrix.M34 + viewProjMatrix.M32;
            bottom.D = viewProjMatrix.M44 + viewProjMatrix.M42;
            bottom.Normalize();
            frustum.Bottom = bottom;

            Plane near = new Plane();
            near.A = viewProjMatrix.M13;
            near.B = viewProjMatrix.M23;
            near.C = viewProjMatrix.M33;
            near.D = viewProjMatrix.M43;
            near.Normalize();
            frustum.Near = near;

            Plane far = new Plane();
            far.A = viewProjMatrix.M14 - viewProjMatrix.M13;
            far.B = viewProjMatrix.M24 - viewProjMatrix.M23;
            far.C = viewProjMatrix.M34 - viewProjMatrix.M33;
            far.D = viewProjMatrix.M44 - viewProjMatrix.M43;
            far.Normalize();
            frustum.Far = far;

            return frustum;
        }
Beispiel #6
0
 public override void DrawGui(LineBatch lineBatch, SpriteBatch spriteBatch)
 {
     var ray = Camera.GetWorldRay(MousePos);
     var plane = new Plane(new Vector3(0, 0, 0), new Vector3(1, 0, 0), new Vector3(0, 1, 0));
     float? distance;
     ray.Intersects(ref plane, out distance);
     if (distance != null)
     {
         var pos = ray.Position + Vector3.Multiply(ray.Direction, distance.Value);
         spriteBatch.AddText(GuiFont, 250, 0, string.Format("X={0:n2} Y={1:n2}", pos.X, pos.Y), Color.White, HorizontalAlignment.Left, VerticalAlignment.Top);
     }
 }
Beispiel #7
0
        public static bool SegmentVsPlane(Vector3 pointA, Vector3 pointB, Plane plane, out float outFraction, out Vector3 intersectPoint)
        {
            //Compute the t value for the directed line ab intersecting the plane.
            Vector3 ab = pointB - pointA;

            //Plane ABC is the plane's normal.
            outFraction = (plane.D - Vector3.Dot(new Vector3(plane.A, plane.B, plane.C), pointA)) / Vector3.Dot(new Vector3(plane.A, plane.B, plane.C), ab);

            //If t in [0..1] compute and return intersection point
            if (outFraction >= 0f && outFraction <= 1f)
            {
                intersectPoint = pointA + outFraction * ab;
                return true;
            }

            //Else, no intersection.
            intersectPoint = Vector3.Zero;
            return false;
        }
Beispiel #8
0
        public bool Intersection(Plane plane, out Vector3 intersection)
        {
            float normDot = Vector3.Dot(Normal, plane.Normal);
            if (normDot == 0)
            {
                intersection = Vector3.Zero;
                return false;
            }

            float t = -(Vector3.Dot(Origin, plane.Normal) + plane.D) / normDot;
            if (t <= 0)
            {
                intersection = Vector3.Zero;
                return false;
            }

            intersection = Origin + t * Normal;
                return true;
        }
Beispiel #9
0
        // Note: This method is not optimized! Code is simplified for clarity!
        //          for example: Plane.Distance / Plane.OnSide should be inlined manually and shouldn't use enums, but floating point values directly!
        public PolygonSplitResult PolygonSplit(Plane cuttingPlane, Vector3 translation, ref Polygon inputPolygon, out Polygon outsidePolygon)
        {
            HalfEdge prev = Edges[inputPolygon.FirstIndex];
            HalfEdge current = Edges[prev.NextIndex];
            HalfEdge next = Edges[current.NextIndex];
            HalfEdge last = next;
            HalfEdge enterEdge = null;
            HalfEdge exitEdge = null;

            var prevVertex = Vertices[prev.VertexIndex];
            var prevDistance = cuttingPlane.SignedDistance(prevVertex);		// distance to previous vertex
            var prevSide = Plane.OnSide(prevDistance);				// side of plane of previous vertex

            var currentVertex = Vertices[current.VertexIndex];
            var currentDistance = cuttingPlane.SignedDistance(currentVertex);		// distance to current vertex
            var currentSide = Plane.OnSide(currentDistance);			// side of plane of current vertex

            do
            {
                var nextVertex = Vertices[next.VertexIndex];
                var nextDistance = cuttingPlane.SignedDistance(nextVertex);		// distance to next vertex
                var nextSide = Plane.OnSide(nextDistance);				// side of plane of next vertex

                if (prevSide != currentSide)							// check if edge crossed the plane ...
                {
                    if (currentSide != PlaneSideResult.Intersects)		// prev:inside/outside - current:inside/outside - next:??
                    {
                        if (prevSide != PlaneSideResult.Intersects)		// prev:inside/outside - current:outside        - next:??
                        {
                            // Calculate intersection of edge with plane split the edge into two, inserting the new vertex
                            var newVertex = Plane.Intersection(prevVertex, currentVertex, prevDistance, currentDistance);
                            var newEdge = EdgeSplit(current, newVertex);

                            if (prevSide == PlaneSideResult.Inside)		// prev:inside         - current:outside        - next:??
                            {
                                //edge01 exits:
                                //
                                //      outside
                                //         1
                                //         *
                                // ......./........ intersect
                                //       /
                                //      0
                                //      inside

                                exitEdge = current;
                            }
                            else
                                if (prevSide == PlaneSideResult.Outside)		// prev:outside - current:inside - next:??
                                {
                                    //edge01 enters:
                                    //
                                    //      outside
                                    //      0
                                    //       \
                                    // .......\........ intersect
                                    //         *
                                    //         1
                                    //      inside

                                    enterEdge = current;
                                }

                            prevDistance = 0;
                            prev = Edges[prev.NextIndex];
                            prevSide = PlaneSideResult.Intersects;

                            if (exitEdge != null &&
                                enterEdge != null)
                                break;

                            current = Edges[prev.NextIndex];
                            currentVertex = Vertices[current.VertexIndex];

                            next = Edges[current.NextIndex];
                            nextVertex = Vertices[next.VertexIndex];
                        }
                    }
                    else												// prev:??                - current:intersects - next:??
                    {
                        if (prevSide == PlaneSideResult.Intersects ||	// prev:intersects        - current:intersects - next:??
                            nextSide == PlaneSideResult.Intersects ||	// prev:??                - current:intersects - next:intersects
                            prevSide == nextSide)						// prev:inside/outde      - current:intersects - next:inside/outde
                        {
                            if (prevSide == PlaneSideResult.Inside ||	// prev:inside            - current:intersects - next:intersects/inside
                                nextSide == PlaneSideResult.Inside)		// prev:intersects/inside - current:intersects - next:inside
                            {
                                //      outside
                                // 0       1
                                // --------*....... intersect
                                //          \
                                //           2
                                //       inside
                                //
                                //      outside
                                //         1      2
                                // ........*------- intersect
                                //        /
                                //       0
                                //      inside
                                //
                                //     outside
                                //        1
                                //........*....... intersect
                                //       / \
                                //      0   2
                                //      inside
                                //

                                prevSide = PlaneSideResult.Inside;
                                enterEdge = exitEdge = null;
                                break;
                            }
                            else
                                if (prevSide == PlaneSideResult.Outside ||		// prev:outside            - current:intersects - next:intersects/outside
                                    nextSide == PlaneSideResult.Outside)		// prev:intersects/outside - current:intersects - next:outside
                                {
                                    //     outside
                                    //          2
                                    //         /
                                    //..------*....... intersect
                                    //  0     1
                                    //     inside
                                    //
                                    //     outside
                                    //      0
                                    //       \
                                    //........*------- intersect
                                    //        1      2
                                    //     inside
                                    //
                                    //     outside
                                    //      0   2
                                    //       \ /
                                    //........*....... intersect
                                    //        1
                                    //     inside
                                    //

                                    prevSide = PlaneSideResult.Outside;
                                    enterEdge = exitEdge = null;
                                    break;
                                }
                        }
                        else											// prev:inside/outside - current:intersects - next:inside/outside
                        {
                            if (prevSide == PlaneSideResult.Inside)		// prev:inside         - current:intersects - next:outside
                            {
                                //find exit edge:
                                //
                                //      outside
                                //           2
                                //        1 /
                                // ........*....... intersect
                                //        /
                                //       0
                                //       inside

                                exitEdge = current;
                                if (enterEdge != null)
                                    break;
                            }
                            else										// prev:outside        - current:intersects - next:inside
                            {
                                //find enter edge:
                                //
                                //      outside
                                //       0
                                //        \ 1
                                // ........*....... intersect
                                //          \
                                //           2
                                //       inside

                                enterEdge = current;
                                if (exitEdge != null)
                                    break;
                            }
                        }
                    }
                }

                prev = current;
                current = next;
                next = Edges[next.NextIndex];

                prevDistance = currentDistance;
                currentDistance = nextDistance;
                prevSide = currentSide;
                currentSide = nextSide;
                prevVertex = currentVertex;
                currentVertex = nextVertex;
            } while (next != last);

            // We should never have only one edge crossing the plane ..
            Debug.Assert((enterEdge == null) == (exitEdge == null));

            // Check if we have an edge that exits and an edge that enters the plane and split the polygon into two if we do
            if (enterEdge != null && exitEdge != null)
            {
                //enter   .
                //        .
                //  =====>*----->
                //        .
                //
                //outside . inside
                //        .
                //  <-----*<=====
                //        .
                //        .  exit

                outsidePolygon = new Polygon();
                var outsidePolygonIndex = (short)this.Polygons.Count;
                this.Polygons.Add(outsidePolygon);

                var outsideEdge = new HalfEdge();
                var outsideEdgeIndex = (short)Edges.Count;

                var insideEdge = new HalfEdge();
                var insideEdgeIndex = (short)(outsideEdgeIndex + 1);

                outsideEdge.TwinIndex = insideEdgeIndex;
                insideEdge.TwinIndex = outsideEdgeIndex;

                //insideEdge.PolygonIndex	= inputPolygonIndex;// index does not change
                outsideEdge.PolygonIndex = outsidePolygonIndex;

                outsideEdge.VertexIndex = exitEdge.VertexIndex;
                insideEdge.VertexIndex = enterEdge.VertexIndex;

                outsideEdge.NextIndex = exitEdge.NextIndex;
                insideEdge.NextIndex = enterEdge.NextIndex;

                exitEdge.NextIndex = insideEdgeIndex;
                enterEdge.NextIndex = outsideEdgeIndex;

                outsidePolygon.FirstIndex = outsideEdgeIndex;
                inputPolygon.FirstIndex = insideEdgeIndex;

                outsidePolygon.Visible = inputPolygon.Visible;
                outsidePolygon.Category = inputPolygon.Category;
                outsidePolygon.PlaneIndex = inputPolygon.PlaneIndex;

                Edges.Add(outsideEdge);
                Edges.Add(insideEdge);

                // calculate the bounds of the polygons
                outsidePolygon.Bounds.Clear();
                var first = Edges[outsidePolygon.FirstIndex];
                var iterator = first;
                do
                {
                    outsidePolygon.Bounds.Add(Vertices[iterator.VertexIndex]);
                    iterator.PolygonIndex = outsidePolygonIndex;
                    iterator = Edges[iterator.NextIndex];
                } while (iterator != first);

                inputPolygon.Bounds.Clear();
                first = Edges[inputPolygon.FirstIndex];
                iterator = first;
                do
                {
                    inputPolygon.Bounds.Add(Vertices[iterator.VertexIndex]);
                    iterator = Edges[iterator.NextIndex];
                } while (iterator != first);

                return PolygonSplitResult.Split;
            }
            else
            {
                outsidePolygon = null;
                switch (prevSide)
                {
                    case PlaneSideResult.Inside: return PolygonSplitResult.CompletelyInside;
                    case PlaneSideResult.Outside: return PolygonSplitResult.CompletelyOutside;
                    default:
                    case PlaneSideResult.Intersects:
                        {
                            var polygonPlane = Planes[inputPolygon.PlaneIndex];
                            var result = Vector3.Dot(polygonPlane.Normal, cuttingPlane.Normal);
                            if (result > 0)
                                return PolygonSplitResult.PlaneAligned;
                            else
                                return PolygonSplitResult.PlaneOppositeAligned;
                        }
                }
            }
        }
Beispiel #10
0
        public void Intersect(AABBi cuttingNodeBounds,
                              Plane[] cuttingNodePlanes,
                              Vector3 cuttingNodeTranslation,
                              Vector3 inputPolygonTranslation,

                              List<Polygon> inputPolygons,
                              List<Polygon> inside,
                              List<Polygon> aligned,
                              List<Polygon> revAligned,
                              List<Polygon> outside)
        {
            var categories = new PolygonSplitResult[cuttingNodePlanes.Length];
            var translatedPlanes = new Plane[cuttingNodePlanes.Length];
            var translation = cuttingNodeTranslation - inputPolygonTranslation;

            // translate the planes we cut our polygons with so that they're located at the same
            // relative distance from the polygons as the brushes are from each other.
            for (int i = 0; i < cuttingNodePlanes.Length; i++)
                translatedPlanes[i] = Plane.Translated(cuttingNodePlanes[i], translation);

            var vertices = this.Vertices;
            var edges = this.Edges;
            var planes = this.Planes;
            for (int i = inputPolygons.Count - 1; i >= 0; i--)
            {
                var inputPolygon = inputPolygons[i];
                if (inputPolygon.FirstIndex == -1)
                    continue;

                var bounds = inputPolygon.Bounds;
                var finalResult = PolygonSplitResult.CompletelyInside;

                // A quick check if the polygon lies outside the planes we're cutting our polygons with.
                if (!AABBi.IsOutside(cuttingNodeBounds, translation, bounds))
                {
                    PolygonSplitResult intermediateResult;
                    Polygon outsidePolygon = null;
                    for (int otherIndex = 0; otherIndex < translatedPlanes.Length; otherIndex++)
                    {
                        var translatedCuttingPlane = translatedPlanes[otherIndex];

                        var side = cuttingNodePlanes[otherIndex].OnSide(bounds, -translation);
                        if (side == PlaneSideResult.Outside)
                        {
                            finalResult = PolygonSplitResult.CompletelyOutside;
                            break;	// nothing left to process, so we exit
                        }
                        else
                            if (side == PlaneSideResult.Inside)
                                continue;

                        var polygon = inputPolygon;
                        intermediateResult = PolygonSplit(translatedCuttingPlane, inputPolygonTranslation, ref polygon, out outsidePolygon);
                        inputPolygon = polygon;

                        if (intermediateResult == PolygonSplitResult.CompletelyOutside)
                        {
                            finalResult = PolygonSplitResult.CompletelyOutside;
                            break;	// nothing left to process, so we exit
                        }
                        else
                            if (intermediateResult == PolygonSplitResult.Split)
                            {
                                if (outside != null)
                                    outside.Add(outsidePolygon);
                                // Note: left over is still completely inside,
                                //		 or plane (opposite) aligned
                            }
                            else
                                if (intermediateResult != PolygonSplitResult.CompletelyInside)
                                    finalResult = intermediateResult;
                    }
                }
                else
                    finalResult = PolygonSplitResult.CompletelyOutside;

                switch (finalResult)
                {
                    case PolygonSplitResult.CompletelyInside: inside.Add(inputPolygon); break;
                    case PolygonSplitResult.CompletelyOutside: outside.Add(inputPolygon); break;

                    // The polygon can only be visible if it's part of the last brush that shares it's surface area,
                    // otherwise we'd get overlapping polygons if two brushes overlap.
                    // When the (final) polygon is aligned with one of the cutting planes, we know it lies on the surface of
                    // the CSG node we're cutting the polygons with. We also know that this node is not the node this polygon belongs to
                    // because we've done that check earlier on. So we flag this polygon as being invisible.
                    case PolygonSplitResult.PlaneAligned: inputPolygon.Visible = false; aligned.Add(inputPolygon); break;
                    case PolygonSplitResult.PlaneOppositeAligned: inputPolygon.Visible = false; revAligned.Add(inputPolygon); break;
                }
            }
        }
Beispiel #11
0
        public CSGMesh Clone()
        {
            var newPlanes = new Plane[Planes.Length];
            for (int i = 0; i < Planes.Length; i++)
            {
                var plane = Planes[i];
                newPlanes[i] = new Plane(plane.A, plane.B, plane.C, plane.D);
            }
            var newPolygons = new List<Polygon>(Polygons.Count);
            foreach (var polygon in Polygons)
            {
                var newPolygon = new Polygon();
                newPolygon.FirstIndex = polygon.FirstIndex;
                newPolygon.Visible = polygon.Visible;
                newPolygon.Category = polygon.Category;
                newPolygon.PlaneIndex = polygon.PlaneIndex;
                newPolygon.Bounds.Set(polygon.Bounds);

                newPolygons.Add(newPolygon);
            }

            var newEdges = new List<HalfEdge>(Edges.Count);
            foreach (var edge in Edges)
            {
                var newEdge = new HalfEdge();
                newEdge.NextIndex = edge.NextIndex;
                newEdge.PolygonIndex = edge.PolygonIndex;
                newEdge.TwinIndex = edge.TwinIndex;
                newEdge.VertexIndex = edge.VertexIndex;
                newEdges.Add(newEdge);
            }

            var newVertices = new List<Vector3>(Vertices.Count);
            foreach (var vertex in Vertices)
            {
                newVertices.Add(vertex);
            }

            var newBounds = new AABBi(Bounds);
            var newMesh = new CSGMesh(
                newPlanes,
                newPolygons,
                newEdges,
                newVertices,
                newBounds);

            return newMesh;
        }
Beispiel #12
0
            public Intersect CalculateIntersect(Vector3 location, Vector3 direction)
            {
                Intersect i = new Intersect();

                i.intersectPoint = new Vector3(0, 0, 0);
                i.intersects = false;

                Plane plane = new Plane(this);

                float distance = plane.Distance(location, direction);
                //Console.WriteLine("Distance = {0}", distance);

                i.distance = distance;
                i.intersectPoint = distance * direction + location;
                if (distance < 0)
                {
                    i.intersects = false;
                }
                else
                {
                    i.intersects = ObjLoader.IsPointInPolygon(this, i.intersectPoint);
                }

                return i;
            }
Beispiel #13
0
        public static CSGMesh CreateFromPlanes(Plane[] brushPlanes)
        {
            var planes = new Plane[brushPlanes.Length];
            for (int i = 0; i < brushPlanes.Length; i++)
            {
                var plane = brushPlanes[i];
                planes[i] = new Plane(plane.A, plane.B, plane.C, plane.D);
            }

            var pointIntersections = new List<PointIntersection>(planes.Length * planes.Length);
            var intersectingPlanes = new List<short>();
            var vertices = new List<Vector3>();
            var edges = new List<HalfEdge>();

            // Find all point intersections where 3 (or more planes) intersect
            for (short planeIndex1 = 0; planeIndex1 < planes.Length - 2; planeIndex1++)
            {
                var plane1 = planes[planeIndex1];
                for (short planeIndex2 = (short)(planeIndex1 + 1); planeIndex2 < planes.Length - 1; planeIndex2++)
                {
                    var plane2 = planes[planeIndex2];
                    for (short planeIndex3 = (short)(planeIndex2 + 1); planeIndex3 < planes.Length; planeIndex3++)
                    {
                        var plane3 = planes[planeIndex3];

                        // Calculate the intersection
                        var vertex = Plane.Intersection(plane1, plane2, plane3);

                        // Check if the intersection is valid
                        if (float.IsNaN(vertex.X) || float.IsNaN(vertex.Y) || float.IsNaN(vertex.Z) ||
                            float.IsInfinity(vertex.X) || float.IsInfinity(vertex.Y) || float.IsInfinity(vertex.Z))
                            continue;

                        intersectingPlanes.Clear();
                        intersectingPlanes.Add(planeIndex1);
                        intersectingPlanes.Add(planeIndex2);
                        intersectingPlanes.Add(planeIndex3);

                        for (short planeIndex4 = 0; planeIndex4 < planes.Length; planeIndex4++)
                        {
                            if (planeIndex4 == planeIndex1 ||
                                planeIndex4 == planeIndex2 ||
                                planeIndex4 == planeIndex3)
                                continue;

                            var plane4 = planes[planeIndex4];
                            var side = plane4.OnSide(vertex);
                            if (side == PlaneSideResult.Intersects)
                            {
                                if (planeIndex4 < planeIndex3)
                                    // Already found this vertex
                                    goto SkipIntersection;

                                // We've found another plane which goes trough our found intersection point
                                intersectingPlanes.Add(planeIndex4);
                            }
                            else
                                if (side == PlaneSideResult.Outside)
                                    // Intersection is outside of brush
                                    goto SkipIntersection;
                        }

                        var vertexIndex = (short)vertices.Count;
                        vertices.Add(vertex);

                        // Add intersection point to our list
                        pointIntersections.Add(new PointIntersection(vertexIndex, intersectingPlanes));

                    SkipIntersection:
                        ;
                    }
                }
            }

            var foundPlanes = new short[2];
            // Find all our intersection edges which are formed by a pair of planes
            // (this could probably be done inside the previous loop)
            for (int i = 0; i < pointIntersections.Count; i++)
            {
                var pointIntersectionA = pointIntersections[i];
                for (int j = i + 1; j < pointIntersections.Count; j++)
                {
                    var pointIntersectionB = pointIntersections[j];
                    var planesIndicesA = pointIntersectionA.PlaneIndices;
                    var planesIndicesB = pointIntersectionB.PlaneIndices;

                    short foundPlaneIndex = 0;
                    foreach (var currentPlaneIndex in planesIndicesA)
                    {
                        if (!planesIndicesB.Contains(currentPlaneIndex))
                            continue;

                        foundPlanes[foundPlaneIndex] = currentPlaneIndex;
                        foundPlaneIndex++;

                        if (foundPlaneIndex == 2)
                            break;
                    }

                    // If foundPlaneIndex is 0 or 1 then either this combination does not exist,
                    // or only goes trough one point
                    if (foundPlaneIndex < 2)
                        continue;

                    // Create our found intersection edge
                    var halfEdgeA = new HalfEdge();
                    var halfEdgeAIndex = (short)edges.Count;
                    edges.Add(halfEdgeA);

                    var halfEdgeB = new HalfEdge();
                    var halfEdgeBIndex = (short)edges.Count;
                    edges.Add(halfEdgeB);

                    halfEdgeA.TwinIndex = halfEdgeBIndex;
                    halfEdgeB.TwinIndex = halfEdgeAIndex;

                    halfEdgeA.VertexIndex = pointIntersectionA.VertexIndex;
                    halfEdgeB.VertexIndex = pointIntersectionB.VertexIndex;

                    // Add it to our points
                    pointIntersectionA.Edges.Add(new EdgeIntersection(
                                                        halfEdgeA,
                                                        foundPlanes[0],
                                                        foundPlanes[1]));
                    pointIntersectionB.Edges.Add(new EdgeIntersection(
                                                        halfEdgeB,
                                                        foundPlanes[0],
                                                        foundPlanes[1]));
                }
            }

            var polygons = new List<Polygon>();
            for (short i = 0; i < (short)planes.Length; i++)
            {
                var polygon = new Polygon();
                polygon.PlaneIndex = i;
                polygons.Add(polygon);
            }

            var bounds = new AABBi();
            var direction = new Vector3();
            for (int i = pointIntersections.Count - 1; i >= 0; i--)
            {
                var pointIntersection = pointIntersections[i];
                var pointEdges = pointIntersection.Edges;

                // Make sure that we have at least 2 edges ...
                // This may happen when a plane only intersects at a single edge.
                if (pointEdges.Count <= 2)
                {
                    pointIntersections.RemoveAt(i);
                    continue;
                }

                var vertexIndex = pointIntersection.VertexIndex;
                var vertex = vertices[vertexIndex];

                for (int j = 0; j < pointEdges.Count - 1; j++)
                {
                    var edge1 = pointEdges[j];
                    for (int k = j + 1; k < pointEdges.Count; k++)
                    {
                        var edge2 = pointEdges[k];

                        int planeIndex1 = -1;
                        int planeIndex2 = -1;

                        // Determine if and which of our 2 planes are identical
                        if (edge1.PlaneIndices[0] == edge2.PlaneIndices[0]) { planeIndex1 = 0; planeIndex2 = 0; }
                        else
                            if (edge1.PlaneIndices[0] == edge2.PlaneIndices[1]) { planeIndex1 = 0; planeIndex2 = 1; }
                            else
                                if (edge1.PlaneIndices[1] == edge2.PlaneIndices[0]) { planeIndex1 = 1; planeIndex2 = 0; }
                                else
                                    if (edge1.PlaneIndices[1] == edge2.PlaneIndices[1]) { planeIndex1 = 1; planeIndex2 = 1; }
                                    else
                                        continue;

                        HalfEdge ingoing;
                        HalfEdge outgoing;
                        short outgoingIndex;

                        var shared_plane = planes[edge1.PlaneIndices[planeIndex1]];
                        var edge1_plane = planes[edge1.PlaneIndices[1 - planeIndex1]];
                        var edge2_plane = planes[edge2.PlaneIndices[1 - planeIndex2]];

                        direction = Vector3.Cross(shared_plane.Normal, edge1_plane.Normal);

                        // Determine the orientation of our two edges to determine
                        // which edge is in-going, and which one is out-going
                        if (Vector3.Dot(direction, edge2_plane.Normal) < 0)
                        {
                            ingoing = edge2.Edge;
                            outgoingIndex = edge1.Edge.TwinIndex;
                            outgoing = edges[outgoingIndex];
                        }
                        else
                        {
                            ingoing = edge1.Edge;
                            outgoingIndex = edge2.Edge.TwinIndex;
                            outgoing = edges[outgoingIndex];
                        }

                        // Link the out-going half-edge to the in-going half-edge
                        ingoing.NextIndex = outgoingIndex;

                        // Add reference to polygon to half-edge, and make sure our
                        // polygon has a reference to a half-edge
                        // Since a half-edge, in this case, serves as a circular
                        // linked list this just works.
                        var polygonIndex = edge1.PlaneIndices[planeIndex1];

                        ingoing.PolygonIndex = polygonIndex;
                        outgoing.PolygonIndex = polygonIndex;

                        var polygon = polygons[polygonIndex];
                        polygon.FirstIndex = outgoingIndex;
                        polygon.Bounds.Add(vertex);
                    }
                }

                // Add the intersection point to the area of our bounding box
                bounds.Add(vertex);
            }

            return new CSGMesh(planes, polygons, edges, vertices, bounds);
        }
Beispiel #14
0
        public static bool ComputeBestFitPlane(Vector3[] points, out Plane plane)
        {
            Vector3 origin = new Vector3(0, 0, 0);

            for (int i = 0; i < points.Length; i++)
            {
                origin = origin + points[i];
            }

            float recip = 1.0f / points.Length; // reciprocol of total weighting

            origin.X *= recip;
            origin.Y *= recip;
            origin.Z *= recip;

            float fSumXX = 0;
            float fSumXY = 0;
            float fSumXZ = 0;

            float fSumYY = 0;
            float fSumYZ = 0;
            float fSumZZ = 0;

            Vector3 kDiff;
            for (int i = 0; i < points.Length; i++)
            {
                Vector3 p = points[i];

                kDiff.X = (p.X - origin.X); // apply vertex weighting!
                kDiff.Y = (p.Y - origin.Y);
                kDiff.Z = (p.Z - origin.Z);

                fSumXX += kDiff.X * kDiff.X; // sume of the squares of the differences.
                fSumXY += kDiff.X * kDiff.Y; // sume of the squares of the differences.
                fSumXZ += kDiff.X * kDiff.Z; // sume of the squares of the differences.

                fSumYY += kDiff.Y * kDiff.Y;
                fSumYZ += kDiff.Y * kDiff.Z;
                fSumZZ += kDiff.Z * kDiff.Z;
            }

            fSumXX *= recip;
            fSumXY *= recip;
            fSumXZ *= recip;
            fSumYY *= recip;
            fSumYZ *= recip;
            fSumZZ *= recip;

            // setup the eigensolver
            Eigen kES = new Eigen();
            kES.mElement[0][0] = fSumXX;
            kES.mElement[0][1] = fSumXY;
            kES.mElement[0][2] = fSumXZ;

            kES.mElement[1][0] = fSumXY;
            kES.mElement[1][1] = fSumYY;
            kES.mElement[1][2] = fSumYZ;

            kES.mElement[2][0] = fSumXZ;
            kES.mElement[2][1] = fSumYZ;
            kES.mElement[2][2] = fSumZZ;

            // compute eigenstuff, smallest eigenvalue is in last position
            kES.DecrSortEigenStuff();

            Vector3 kNormal = new Vector3();
            kNormal.X = kES.mElement[0][2];
            kNormal.Y = kES.mElement[1][2];
            kNormal.Z = kES.mElement[2][2];

            // the minimum energy
            plane = new Plane(kNormal, 0 - Vector3.Dot(kNormal, origin));
            return true;
        }
Beispiel #15
0
        private void Slice(Plane p)
        {
            float epsilon = 0.01f; // TODO: compute proper epsilon value

            List<PolyLine> linePile = new List<PolyLine>(); // Pile of disconnected lines on the slice plane
            List<Vector3> all_points = new List<Vector3>();
            foreach (Face f in this.faces)
            {
                PolyLine newLine = TrianglePlaneIntersect(f, p);

                // Only add lines with exactly 2 points - others are a no match or error
                if (newLine.points.Count() == 2 && (newLine.points[0] - newLine.points[1]).Length> epsilon)
                {
                    linePile.Add(newLine);

                    // Add the vertices to the all_points list - only need to add the first one, the tail will be the head of another point
                    bool matched = false;
                    foreach (Vector3 point in all_points)
                    {
                        if ((point - newLine.points[0]).Length < epsilon)
                        {
                            matched = true;
                            break;
                        }
                    }
                    if (!matched)
                    {
                        all_points.Add(newLine.points[0]);
                    }
                }
            }

            // linePile is a unordered list of line segments.
            // If a line segment is oriented with point[0] on (0, 0, 0) and point[1]
            // somewhere on the positive Y axis, the solid object is in the direction of the positive x axis.
            //
            //              p[1]xxxxxxxxxxxxxxxxxxxxxxxx
            //               xx                       xx
            //               xx  <object over here>   xx
            //               xx                       xx
            //              p[0]xxxxxxxxxxxxxxxxxxxxxxxx
            //

            List<PolyLine> newPolyLines = new List<PolyLine>();
            for (int i = 0; i < linePile.Count(); i++)
            {
                int points = linePile[i].points.Count();

                Vector3 v1 = linePile[i].points[0];
                Vector3 v2 = linePile[i].points[1];

                //DrawCone1(v1, v2);

                List<Vector3> points_on_line = new List<Vector3>();
                foreach (Vector3 v in all_points)
                {
                    if ((v1 - v).Length >= epsilon && (v2 - v).Length >= epsilon && DistanceToCylinder(v1, v2, v) < epsilon)
                    {
                        points_on_line.Add(v);
                    }
                }

                points_on_line.Insert(0, v1);
                points_on_line.Add(v2);

                // Order from v1 to v2
                var sorted = points_on_line.OrderBy(order_vec => (order_vec - v1).Length);

                PolyLine newPolyLine = new PolyLine();
                foreach (Vector3 v in sorted)
                {
                    if (newPolyLine.points.Count() == 0 || (newPolyLine.points[newPolyLine.points.Count() - 1] - v).Length > epsilon)
                    {
                        newPolyLine.points.Add(v);
                    }
                }
                if (newPolyLine.points.Count() >= 2)
                {
                    newPolyLines.Add(newPolyLine);
                }
                if (newPolyLine.points.Count() >= 3)
                {
                    // Shouldn't get here!
                }
            }

            List<LinePointIndices> lpis = new List<LinePointIndices>();
            List<Vector3> vertices = new List<Vector3>();
            List<List<int>> v_lookup = new List<List<int>>();

            foreach (PolyLine l in newPolyLines)
            {
                int lastIndex = -1;
                foreach (Vector3 pointVec in l.points)
                {
                    int currentIndex = -1;
                    for (int i = 0; i < vertices.Count(); i++)
                    {
                        float length = (vertices[i] - pointVec).Length;
                        if (length < epsilon)
                        {
                            currentIndex = i;
                            continue;
                        }
                    }
                    if (currentIndex == -1)
                    {
                        vertices.Add(pointVec);
                        v_lookup.Add(new List<int>());
                        currentIndex = vertices.Count() - 1;
                    }

                    if (lastIndex != -1 && lastIndex != currentIndex)
                    {
                        LinePointIndices line = new LinePointIndices();

                        bool already_matched = false;
                        foreach (int line_index in v_lookup[lastIndex])
                        {
                            LinePointIndices l2 = lpis[line_index];
                            if (l2.indices[1] == currentIndex)
                            {
                                already_matched = true;
                            }
                        }
                        if (!already_matched)
                        {

                            line.indices.Add(lastIndex);
                            line.indices.Add(currentIndex);
                            lpis.Add(line);

                            v_lookup[lastIndex].Add(lpis.Count() - 1);
                            v_lookup[currentIndex].Add(lpis.Count() - 1);
                        }
                    }
                    lastIndex = currentIndex;
                }
            }

            //List<Vector3> scaled = new List<Vector3>();
            List<int> vector_indices_to_see = new List<int>();
            foreach (Vector3 v in vertices)
            {
                //scaled.Add(v / 125);
                vector_indices_to_see.Add(vector_indices_to_see.Count());
            }

            List<LinePointIndices> slices = new List<LinePointIndices>();

            GL.PushMatrix();
            GL.PointSize(10);
            List<int> seenVertices = new List<int>();
            while(vector_indices_to_see.Count() > 0)
            {
                List<int> line_indices = v_lookup [vector_indices_to_see[0]];
                vector_indices_to_see.RemoveAt(0);
                if (line_indices.Count() == 0)
                {
                    continue;
                }
                LinePointIndices line = lpis[line_indices[0]]; // Only need to look at one line with this vertex
                LinePointIndices start_line = new LinePointIndices();
                start_line.indices.Add(line.indices[0]);
                start_line.indices.Add(line.indices[1]);
                GL.Color3(Color.Green);
                DrawCone1(vertices[start_line.indices[0]], vertices[start_line.indices[1]]);
                LinePointIndices loop = FindLoop(seenVertices, p.normal, vertices, v_lookup, lpis, start_line);

                if (loop != null)
                {
                    slices.Add(loop);
                    GL.Color3(Color.LightBlue);
                    GL.Begin(BeginMode.LineLoop);
                    Vector3 add = new Vector3(0, 0, 0);
                    foreach (int i in loop.indices)
                    {
                        vector_indices_to_see.RemoveAll(value => value == i);
                        GL.Vertex3(vertices[i] + add);
                        seenVertices.Add(i);
                        //add += new Vector3(0, 0, 25);
                    }
                    GL.End();
                    //GL.Translate(new Vector3(0, 0, +100));
                }
                //break;
            }
            GL.PointSize(1);
            GL.PopMatrix();

            Vector3 normal = new Vector3(0, 0, 1);
            float toolRadius = 100;
            GL.LineWidth(1);

            List<IntPoint> boundingBox = new List<IntPoint>();
            boundingBox.Add(new IntPoint(-1000, -1000));
            boundingBox.Add(new IntPoint(3000, -1000));
            boundingBox.Add(new IntPoint(3000, 3000));
            boundingBox.Add(new IntPoint(-1000, 3000));

            List<LineLoop> loops = new List<LineLoop>();

            foreach (LinePointIndices l in slices)
            {
                LineStrip line = new LineStrip();
                for (int i = 0; i < l.indices.Count (); i++)
                {
                    line.Append(vertices[l.indices[i]]);
                }
                line.Append(vertices[l.indices[0]]);
                loops.Add(new LineLoop (line));
            }

            if (loops.Count() > 0)
            {
                Vector3 up = new Vector3(0, 0, 1);
                if (Math.Abs (normal.Z) > 0.8)
                {
                    up = new Vector3(1, 0, 0);
                }

                float distance = Vector3.Dot(loops[0].GetVertex(0), normal);

                Matrix4 transform = Matrix4.LookAt(normal * distance, normal * (distance - 1), up);
                Matrix4 inverseTransform = Matrix4.Invert(transform);

                Clipper c = new Clipper();
                c.Clear();

                try
                {
                    // These loops go clockwise
                    foreach (LineLoop loop in loops)
                    {
                        List<IntPoint> polygon = new List<IntPoint>();
                        foreach (Vector3 vertex in loop.Vertices)
                        {
                            Vector3 result = Vector3.Transform(vertex, transform);
                            polygon.Add(new IntPoint((long)result.X, (long)result.Y));
                        }
                        polygon.RemoveAt(0);
                        c.AddPolygon(polygon, PolyType.ptClip);
                        GL.PushMatrix();
                        GL.Translate(new Vector3(0, 0, 100));
                        //loop.Draw();
                        GL.PopMatrix();
                    }
                    List<List<IntPoint>> union = new List<List<IntPoint>>();
                    bool r = c.Execute(ClipType.ctUnion, union, PolyFillType.pftNonZero, PolyFillType.pftNonZero);

                    List<List<IntPoint>> with_offset = Clipper.OffsetPolygons(union, toolRadius, JoinType.jtSquare);
                    List<List<IntPoint>> whatsLeft = Clipper.OffsetPolygons(with_offset, -toolRadius, JoinType.jtRound);

                    List<LineStrip> strips = new List<LineStrip>();
                    foreach (List<IntPoint> polygon in with_offset)
                    {
                        LineStrip strip = new LineStrip();
                        foreach (IntPoint point in polygon)
                        {
                            strip.Append(Vector3.Transform(new Vector3(point.X, point.Y, 0.0f), inverseTransform));
                        }
                        strip.Append(Vector3.Transform(new Vector3(polygon[0].X, polygon[0].Y, 0.0f), inverseTransform));

                        strips.Add(strip);
                        //new LineLoop(strip).Draw();
                    }

                    List<List<IntPoint>> removeArea = new List<List<IntPoint>>();
                    c.Clear();
                    c.AddPolygons(with_offset, PolyType.ptClip);
                    c.AddPolygon(boundingBox, PolyType.ptSubject);
                    List<List<IntPoint>> resultingPolygon = new List<List<IntPoint>>();
                    c.Execute(ClipType.ctDifference, removeArea, PolyFillType.pftNonZero, PolyFillType.pftNonZero);
                    removeArea = Clipper.CleanPolygons(removeArea, toolRadius / 100);

                    c.Clear();
                    c.AddPolygons(removeArea, PolyType.ptClip);
                    PolyTree test = new PolyTree();
                    c.Execute(ClipType.ctUnion, test, PolyFillType.pftNonZero, PolyFillType.pftNonZero);

                    //PolyNode pn = test.GetFirst();
                    //while (pn != null)
                    //{
                    //    if (pn.IsHole)
                    //    {
                    //        LineLoop l = new LineLoop(pn.Contour, inverseTransform);
                    //        l.Draw();
                    //    }
                    //    pn = pn.GetNext();
                    //}
                    List<Polygons> polys = FlattenPolyTree(test);

                    //GL.PushMatrix();
                    foreach (Polygons polygons in polys)
                    {
                        //GL.Translate(new Vector3 (0, 0, 100));
                        //foreach (Polygon polygon in polygons)
                        //{
                        //    LineLoop l = new LineLoop(polygon, inverseTransform);
                        //    l.Draw();
                        //}
                        List<Polygons> paths = ReducePolygon(polygons, toolRadius, inverseTransform);
                        //IOrderedEnumerable<List<IntPoint>> ordered = paths.OrderBy(poly => Clipper.Area(poly));
                        GL.PushMatrix();
                        List<Polygons> paths2 = new List<Polygons>();
                        List<Polygons> paths3 = new List<Polygons>();
                        foreach (Polygons polygons2 in paths)
                        {
                            var newPolys = new Polygons();
                            foreach (Polygon poly in polygons2)
                            {
                                if (Clipper.Area(poly) > 0)
                                {
                                    newPolys.Add(poly);
                                }
                            }
                            paths2.Add(newPolys);

                            //GL.Translate(new Vector3(0, 0, 100));
                            var newInnerPolys = new Polygons();
                            foreach (Polygon poly in polygons2)
                            {

                                if (paths3.Count() == 0)
                                {
                                    //newInnerPoly
                                }
                                if (Clipper.Area(poly) < 0)
                                {
                                  LineLoop l = new LineLoop(poly, inverseTransform);
                                  l.Draw();
                                }
                            }

                        }
                        foreach (Polygons polygons2 in paths2)
                        {
                            GL.Translate(new Vector3(0, 0, 100));
                            foreach (Polygon poly in polygons2)
                            {
                                LineLoop l = new LineLoop(poly, inverseTransform);
                                l.Draw();
                            }
                        }
                        GL.PopMatrix();
                    }
                    //GL.PopMatrix();

                    double boundingBoxArea = Clipper.Area(boundingBox);
                    // Outer Polygon
                    // Inner Polygons
                    //ReducePolygon(boundingBox, with_offset, toolRadius, inverseTransform);

                    //strips = new List<LineStrip>();
                    //double area = 1;
                    //int loopTimes = 0;

                    //List<List<IntPoint>> cutPolygons = new List<List<IntPoint>>();
                    //List<Vector3> parentPoints = new List<Vector3>();
                    //GL.PushMatrix();
                    //while (removeArea.Count() > 0)
                    //{
                    //    List<Vector3> points = new List<Vector3>();
                    //    foreach (List<IntPoint> polygon in removeArea)
                    //    {
                    //        double area = Clipper.Area(polygon);
                    //
                    //        if (area > 0) // Bigger to Smaller
                    //        {
                    //        }
                    //        IntPoint[] newP = new IntPoint[polygon.Count()];
                    //        polygon.CopyTo(newP);
                    //        cutPolygons.Add(new List<IntPoint>(newP));
                    //
                    //
                    //        LineLoop l = new LineLoop(polygon, inverseTransform);
                    //        //l.Draw();
                    //        points.AddRange(l.Vertices);
                    //
                    //        //ReducePolygon(null, polygon, toolRadius, inverseTransform);
                    //        //area += Clipper.Area(polygon);
                    //        //LineStrip strip = new LineStrip();
                    //        //foreach (IntPoint point in polygon)
                    //        //{
                    //        //    strip.Append(Vector3.Transform(new Vector3(point.X, point.Y, 0.0f), inverseTransform));
                    //        //}
                    //        //strip.Append(Vector3.Transform(new Vector3(polygon[0].X, polygon[0].Y, 0.0f), inverseTransform));
                    //
                    //        //strips.Add(strip);
                    //        //new LineLoop(strip).Draw();
                    //    }
                    //
                    //    //GL.Color3(Color.Black);
                    //    //GL.Begin(BeginMode.Lines);
                    //    //foreach (Vector3 v in points)
                    //    //{
                    //    //    foreach (Vector3 v2 in parentPoints)
                    //    //    {
                    //    //        if ((v - v2).Length < toolRadius * 2)
                    //    //        {
                    //    //            GL.Vertex3(v);
                    //    //            GL.Vertex3(v2);
                    //    //        }
                    //    //    }
                    //    //}
                    //    //GL.End();
                    //
                    //    parentPoints = points;
                    //    removeArea = Clipper.OffsetPolygons(removeArea, -toolRadius, JoinType.jtRound);
                    //    removeArea = Clipper.CleanPolygons(removeArea, toolRadius / 100);
                    //}
                    //GL.PopMatrix();

                    //IOrderedEnumerable<List<IntPoint>> ordered = cutPolygons.OrderBy(poly => Clipper.Area(poly));
                    //
                    //GL.PushMatrix();
                    //foreach (List<IntPoint> poly in ordered)
                    //{
                    //    GL.Translate(new Vector3(0, 0, 100));
                    //    LineLoop l = new LineLoop(poly, inverseTransform);
                    //    l.Draw();
                    //}
                    //GL.PopMatrix();

                    ////strips = new List<LineStrip>();
                    //GL.Color3(Color.Red);
                    //GL.LineWidth(2);
                    //foreach (List<IntPoint> polygon in whatsLeft)
                    //{
                    //    LineStrip strip = new LineStrip();
                    //    foreach (IntPoint point in polygon)
                    //    {
                    //        strip.Append(Vector3.Transform(new Vector3(point.X, point.Y, 0.0f), inverseTransform));
                    //    }
                    //    strip.Append(Vector3.Transform(new Vector3(polygon[0].X, polygon[0].Y, 0.0f), inverseTransform));
                    //
                    //    strips.Add(strip);
                    //    new LineLoop(strip).Draw();
                    //}
                    //GL.LineWidth(1);

                }
                catch (Exception e)
                {
                }
            }
        }
Beispiel #16
0
        private PolyLine TrianglePlaneIntersect(Face f, Plane p)
        {
            PolyLine polyLine = new PolyLine();

            float epsilon = 0.01f; // TODO: Auto compute based on scale
            float epsilon_unit = 0.00001f; // Unit size epsilon value
            Vector3 f_normal = f.Normal;
            f_normal.Normalize();
            p.normal.Normalize();

            if ((f_normal - p.normal).Length < epsilon_unit || (f_normal + p.normal).Length < epsilon_unit)
            {
                // No intersection
            }
            else
            {
                Vector3 expected_direction = Vector3.Cross(f.Normal, p.normal);

                // Assume we're dealing with triangles only
                int verts = f.vertices.Count();
                if (verts != 3)
                {
                    throw new Exception("The number of vertices is not 3!");
                }

                float[] d = new float[3];
                for (int i = 0; i < 3; i++)
                {
                    d[i] = p.Distance(f.vertices[i]);
                }

                for (int i = 0; i < 3; i++)
                {
                    // Is the line on the plane?
                    if (Math.Abs(d[i]) < epsilon && Math.Abs(d[(i + 1) % 3]) < epsilon)
                    {
                        polyLine.points.Add(f.vertices[i]);
                        polyLine.points.Add(f.vertices[(i + 1) % 3]);
                        break;
                    }
                }

                if (polyLine.points.Count() == 0)
                {
                    // Line not on a plain: might have an intersection with a point and the opposite line
                    for (int i = 0; i < 3; i++)
                    {
                        float d1 = d[i];
                        float d2 = d[(i + 1) % 3];
                        float d3 = d[(i + 2) % 3];
                        if (Math.Abs(d[i]) < epsilon && Math.Sign(d2) != Math.Sign(d3))
                        {
                            d2 = Math.Abs(d2);
                            d3 = Math.Abs(d3);

                            // One negative, one positive
                            float total = d2 + d3;
                            Vector3 result = (f.vertices[(i + 1) % 3] * d3 + f.vertices[(i + 2) % 3] * d2) / total;
                            polyLine.points.Add(f.vertices[i]);
                            polyLine.points.Add(result);
                            break;
                        }
                    }
                    if (polyLine.points.Count() == 0)
                    {
                        // No edge in plane and no point + line intersect: maybe two lines intersect?
                        for (int i = 0; i < 3; i++)
                        {
                            // Intersection with an edge
                            if (Math.Sign(d[i]) != Math.Sign(d[(i + 1) % 3]))
                            {
                                float d1 = Math.Abs(d[i]);
                                float d2 = Math.Abs(d[(i + 1) % 3]);
                                float total = d1 + d2;
                                Vector3  result = (f.vertices[i] * d2 + f.vertices[(i + 1) % 3] * d1) / total;
                                polyLine.points.Add(result);
                                if (polyLine.points.Count() == 2)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }

                if (polyLine.points.Count() >= 2)
                {
                    //DrawCone1(polyLine.points[0], polyLine.points[1]);
                    Vector3 direction = polyLine.points[1] - polyLine.points[0];
                    if (Vector3.Dot(direction, expected_direction) < 0)
                    {
                        PolyLine reversed = new PolyLine();
                        reversed.points.Add(polyLine.points[1]);
                        reversed.points.Add(polyLine.points[0]);
                        polyLine = reversed;
                    }
                //
                //
                //    Color[] colors = new Color[] { Color.DarkRed, Color.LightGreen, Color.DarkBlue };
                //    int i = 0;
                //    GL.Begin(BeginMode.LineLoop);
                //    foreach (Vector3 v in polyLine.points)
                //    {
                //        GL.Color3(colors[i++]);
                //        GL.Vertex3(v);
                //
                //    }
                //    GL.End();
                //
                //    GL.PointSize(10);
                //    GL.Color3(Color.Orange);
                //    GL.Begin(BeginMode.Points);
                //    foreach (Vector3 v in polyLine.points)
                //    {
                //        GL.Vertex3(v);
                //    }
                //    GL.End();
                //    GL.PointSize(1);
                }
            }
            return polyLine;
        }
Beispiel #17
0
        /// <summary>
        /// Test scene for BezierSurface.
        /// </summary>
        public static void Bezier( IRayScene sc )
        {
            Debug.Assert( sc != null );

              // CSG scene:
              CSGInnerNode root = new CSGInnerNode( SetOperation.Union );
              root.SetAttribute( PropertyName.REFLECTANCE_MODEL, new PhongModel() );
              root.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 1.0, 0.8, 0.1 }, 0.1, 0.5, 0.5, 64 ) );
              sc.Intersectable = root;

              // Background color:
              sc.BackgroundColor = new double[] { 0.0, 0.05, 0.07 };

              // Camera:
              sc.Camera = new StaticCamera( new Vector3d( 0.7, 0.5, -5.0 ),
                                    new Vector3d( 0.0, -0.18, 1.0 ),
                                    50.0 );

              // Light sources:
              sc.Sources = new LinkedList<ILightSource>();
              sc.Sources.Add( new AmbientLightSource( 0.8 ) );
              sc.Sources.Add( new PointLightSource( new Vector3d( -5.0, 3.0, -3.0 ), 1.0 ) );

              // --- NODE DEFINITIONS ----------------------------------------------------

              // Bezier patch (not yet):
              BezierSurface b = new BezierSurface( 1, 2, new double[] {
            0.0, 0.0, 3.0,  // row 0
            1.0, 0.0, 3.0,
            2.0, 0.0, 3.0,
            3.0, 0.0, 3.0,
            4.0, 0.0, 3.0,
            5.0, 0.0, 3.0,
            6.0, 0.0, 3.0,
            0.0, 0.0, 2.0,  // row 1
            1.0, 0.0, 2.0,
            2.0, 3.0, 2.0,
            3.0, 3.0, 2.0,
            4.0, 3.0, 2.0,
            5.0, 0.0, 2.0,
            6.0, 0.0, 2.0,
            0.0, 0.0, 1.0,  // row 2
            1.0, 0.0, 1.0,
            2.0, 0.0, 1.0,
            3.0, 1.5, 1.0,
            4.0, 3.0, 1.0,
            5.0, 0.0, 1.0,
            6.0, 0.0, 1.0,
            0.0, 0.0, 0.0,  // row 3
            1.0, 0.0, 0.0,
            2.0, 0.0, 0.0,
            3.0, 0.0, 0.0,
            4.0, 0.0, 0.0,
            5.0, 0.0, 0.0,
            6.0, 0.0, 0.0,
            } );
              b.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 10.5, 12.0, new double[] { 0.0, 0.0, 0.1 } ) );
              root.InsertChild( b, Matrix4d.RotateY( -0.4 ) * Matrix4d.CreateTranslation( -1.1, -0.9, 0.0 ) );

              // Cylinders for reflections..
              Cylinder c = new Cylinder();
              c.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 0.0, 0.6, 0.0 }, 0.2, 0.6, 0.3, 8 ) );
              root.InsertChild( c, Matrix4d.Scale( 0.15 ) * Matrix4d.RotateX( MathHelper.PiOver2 ) * Matrix4d.CreateTranslation( -0.4, 0.0, 0.0 ) );
              c = new Cylinder();
              c.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 0.8, 0.2, 0.0 }, 0.2, 0.6, 0.3, 8 ) );
              root.InsertChild( c, Matrix4d.Scale( 0.2 ) * Matrix4d.RotateX( MathHelper.PiOver2 ) * Matrix4d.CreateTranslation( -1.9, 0.0, 3.0 ) );

              // Infinite plane with checker:
              Plane pl = new Plane();
              pl.SetAttribute( PropertyName.COLOR, new double[] { 0.3, 0.0, 0.0 } );
              pl.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 0.6, 0.6, new double[] { 1.0, 1.0, 1.0 } ) );
              root.InsertChild( pl, Matrix4d.RotateX( -MathHelper.PiOver2 ) * Matrix4d.CreateTranslation( 0.0, -1.0, 0.0 ) );
        }
Beispiel #18
0
        /// <summary>
        /// Test scene for cylinders
        /// </summary>
        public static void Cylinders( IRayScene sc )
        {
            Debug.Assert( sc != null );

              // CSG scene:
              CSGInnerNode root = new CSGInnerNode( SetOperation.Union );
              root.SetAttribute( PropertyName.REFLECTANCE_MODEL, new PhongModel() );
              root.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 0.6, 0.0, 0.0 }, 0.15, 0.8, 0.15, 16 ) );
              sc.Intersectable = root;

              // Background color:
              sc.BackgroundColor = new double[] { 0.0, 0.05, 0.07 };

              // Camera:
              sc.Camera = new StaticCamera( new Vector3d( 0.7, 3.0, -10.0 ),
                                    new Vector3d( 0.0, -0.2, 1.0 ),
                                    50.0 );

              // Light sources:
              sc.Sources = new LinkedList<ILightSource>();
              sc.Sources.Add( new AmbientLightSource( 1.0 ) );
              sc.Sources.Add( new PointLightSource( new Vector3d( -5.0, 3.0, -3.0 ), 1.6 ) );

              // --- NODE DEFINITIONS ----------------------------------------------------

              // Base plane
              Plane pl = new Plane();
              pl.SetAttribute( PropertyName.COLOR, new double[] { 0.0, 0.2, 0.0 } );
              pl.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 0.5, 0.5, new double[] { 1.0, 1.0, 1.0 } ) );
              root.InsertChild( pl, Matrix4d.RotateX( -MathHelper.PiOver2 ) * Matrix4d.CreateTranslation( 0.0, -1.0, 0.0 ) );

              // Cylinders
              Cylinder c = new Cylinder();
              root.InsertChild( c, Matrix4d.RotateX( MathHelper.PiOver2 ) * Matrix4d.CreateTranslation( -2.1, 0.0, 1.0 ) );
              c = new Cylinder();
              c.SetAttribute( PropertyName.COLOR, new double[] { 0.2, 0.0, 0.7 } );
              c.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 12.0, 1.0, new double[] { 0.0, 0.0, 0.3 } ) );
              root.InsertChild( c, Matrix4d.RotateY( -0.4 ) * Matrix4d.CreateTranslation( 1.0, 0.0, 1.0 ) );
              c = new Cylinder( 0.0, 100.0 );
              c.SetAttribute( PropertyName.COLOR, new double[] { 0.1, 0.7, 0.0 } );
              root.InsertChild( c, Matrix4d.RotateY( 0.2 ) * Matrix4d.CreateTranslation( 5.0, 0.3, 4.0 ) );
              c = new Cylinder( -0.5, 0.5 );
              c.SetAttribute( PropertyName.COLOR, new double[] { 0.8, 0.6, 0.0 } );
              root.InsertChild( c, Matrix4d.Scale( 2.0 ) * Matrix4d.RotateX( 1.2 ) * Matrix4d.CreateTranslation( 2.0, 1.8, 16.0 ) );
        }
Beispiel #19
0
            /// <summary>
            /// Trim interior loops from the line
            /// </summary>
            public void Clean(Vector3 normal)
            {
                List<int> remove = new List<int>();
                for (int i = 0; i < indices.Count(); i++)
                {
                    Vector3 v1 = GetVertex(i);
                    Vector3 v2 = GetVertex((i + 1) % indices.Count());
                    for (int j = 2; j < indices.Count() - 1; j++)
                    {
                        int j1 = (j + i) % indices.Count();
                        int j2 = (j + i + 1) % indices.Count();
                        Vector3 v3 = GetVertex(j1);
                        Vector3 v4 = GetVertex(j2);

                        Vector3 n1 = v2 - v1;
                        Vector3 n2 = v4 - v3;
                        n1.Normalize();
                        n2.Normalize();

                        if ((n1 - n2).Length < 0.0001f)
                        {
                            // No crossing, same direction
                            continue;
                        }

                        Vector3 perp = Vector3.Cross(normal, n2);
                        Plane p = new Plane ();

                        //GL.Begin(BeginMode.Lines);
                        //GL.Vertex3(v4);
                        //GL.Vertex3(v4 + perp * 100);
                        //GL.End();
                        p.normal = perp;
                        p.point = v3;

                        float distance = p.Distance(v1, n1);
                        if (distance > 0 && distance < (v2 - v1).Length && (Vector3.Dot(perp, n1) < 0))//!float.IsInfinity(distance))
                        {
                            Vector3 point = n1 * distance + v1;
                            if (DistanceToCylinder (v3, v4, point) < 0.01f)
                            {
                                for (int k = 0; k < j; k++)
                                {
                                    int removeIndex = (i + 1) % indices.Count();
                                    indices.RemoveAt(removeIndex);
                                }
                                vertices.Add(point);
                                indices.Insert(i + 1, vertices.Count() - 1);
                                //GL.PointSize(15);
                                //GL.Color3(Color.Turquoise);
                                //GL.Begin(BeginMode.Points);
                                //GL.Vertex3(point);
                                //
                                //GL.End();
                                //GL.PointSize(1);
                                i = i - 1;
                                continue;
                            }
                        }
                    }
                }
                LineLoop n = new LineLoop(this);
                this.indices = n.indices;
                this.vertices = n.vertices;
            }
Beispiel #20
0
 /// <summary>
 /// Returns the perpendicular distance from a point to a plane
 /// </summary>
 /// <param name="point">The point to check</param>
 /// <param name="plane">The place to check</param>
 /// <returns>The perpendicular distance from the point to the plane</returns>
 public static float PerpendicularDistance(ref Vector3 point, ref Plane plane)
 {
     // dist = (ax + by + cz + d) / sqrt(a*a + b*b + c*c)
     return (float)Math.Abs((plane.Normal.X * point.X + plane.Normal.Y * point.Y + plane.Normal.Z * point.Z)
                             / Math.Sqrt(plane.Normal.X * plane.Normal.X + plane.Normal.Y * plane.Normal.Y + plane.Normal.Z * plane.Normal.Z));
 }
Beispiel #21
0
 /// <summary>
 /// Returns a value indicating what side (positive/negative) of a plane a point is
 /// </summary>
 /// <param name="point">The point to check with</param>
 /// <param name="plane">The plane to check against</param>
 /// <returns>Greater than zero if on the positive side, less than zero if on the negative size, 0 otherwise</returns>
 public static float ClassifyPoint(ref Vector3 point, ref Plane plane)
 {
     return point.X * plane.Normal.X + point.Y * plane.Normal.Y + point.Z * plane.Normal.Z + plane.D;
 }
Beispiel #22
0
		public void MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if(!glcontrol.Focused)
				glcontrol.Focus();

			mouseDownInsideImageCloud = false;

			if(ContextMenu.MouseDown(sender, e, backbuffersize))
				return;
			
			if(colorTableMgr.Visible && colorTableMgr.MouseDown(e))
				return;

			#if USE_ARG_IDX
			if(argIndex.Visible && argIndex.MouseDown(Size, e))
			{
				mouseDownInsideArgIndex = true;
				return;
			}
			#endif

			#if USE_PARAM_IDX
			if(paramIndex.Visible && paramIndex.MouseDown(Size, e))
			{
				mouseDownInsideParamIndex = true;
				return;
			}
			#endif

			#if USE_CUSTOM_CONTROLS
			if(ccContainer.Visible && ccContainer.MouseDown(Size, e))
			{
				mouseDownInsideCcContainer = true;
				return;
			}
			#endif

			Viewer.RequestInputProcessing();

			if(images == null)
				return;

			mouseDownPos = new Vector2(2.0f * e.X / backbuffersize.Width - 1.0f, 1.0f - 2.0f * e.Y / backbuffersize.Height);
			mouseDownLocation = e.Location;
			mouseDownInsideImageCloud = true;

			Matrix4 invvieworient = freeview.viewmatrix;
			invvieworient.M41 = invvieworient.M42 = invvieworient.M43 = 0.0f;
			invvieworient.Transpose();

			Vector3 vnear = new Vector3(mouseDownPos.X, mouseDownPos.Y, 0.0f);
			Vector3 vfar = new Vector3(vnear.X, vnear.Y, 1.0f);
			Matrix4 invviewprojmatrix = freeview.viewprojmatrix.Inverted();
			vnear = Vector3.TransformPerspective(vnear, invviewprojmatrix);
			vfar = Vector3.TransformPerspective(vfar, invviewprojmatrix);
			Vector3 vdir = (vfar - vnear).Normalized();

			float dist, closest_dist = float.MaxValue;
			Vector2 uv, closest_uv = Vector2.Zero;
			TransformedImage closest_image = default(TransformedImage);
			foreach(TransformedImage image in images.Values)
				if(image != null && (dist = image.CastRay(vnear, vdir, invvieworient, out uv)) < closest_dist)
				{
					closest_dist = dist;
					closest_uv = uv;
					//Global.cle.PrintOutput(closest_uv.ToString());
					closest_image = image;
				}

			if(closest_dist < float.MaxValue)
			{
				mouseDownImage = closest_image;

				bool enableDrag;
				Viewer.browser.OnImageMouseDown(e.Button, closest_image, closest_uv, out enableDrag);
				foreach(ImageTransform transform in closest_image.transforms)
				{
					bool transformAllowsDrag;
					transform.OnImageMouseDown((ImageTransform.MouseButtons)e.Button, closest_image, closest_uv, out transformAllowsDrag);
					enableDrag &= transformAllowsDrag;
				}

				if(enableDrag)
				{
					dragImage = closest_image;
					dragImageOffset = closest_image.Position - (vnear + vdir * closest_dist);

					// dragImagePlane = plane parallel to screen, going through point of intersection
					Vector3 vsnear = Vector3.TransformPerspective(new Vector3(0.0f, 0.0f, 0.0f), invviewprojmatrix);
					Vector3 vsfar = Vector3.TransformPerspective(new Vector3(0.0f, 0.0f, 1.0f), invviewprojmatrix);
					Vector3 vsdir = (vsfar - vsnear).Normalized();
					dragImagePlane = new Plane(vnear + vdir * closest_dist, vsdir);
				}
			}
			else if(e.Button == MouseButtons.Left)
			{
				dragImage = mouseDownImage = null;

				Viewer.browser.OnNonImageMouseDown();
			}
		}
Beispiel #23
0
        public void Draw()
        {
            GL.Color3(Color.DarkGreen);
            GL.PointSize(5);
            GL.Begin(BeginMode.Points);
            GL.Vertex3(mousePoint);
            GL.End();
            GL.PointSize(1);

            foreach (Face bad in this.badfaces)
            {
                GL.Color3(Color.Red);
                GL.Begin(BeginMode.TriangleFan);
                foreach (Vector3 v in bad.vertices)
                {
                    GL.Normal3(bad.Normal);
                    GL.Vertex3(v);
                }
                GL.End();
            }

            for (int i = 0; i < faces.Count(); i++)
            {
                Face f = faces[i];

                Vector3 normal = f.Normal;

                if (withinFace)
                {
                    GL.Color3(Color.Orange);
                }
                else
                {
                    GL.Color3(Color.White);
                }
                GL.Begin(BeginMode.TriangleFan);
                foreach (Vector3 v in f.vertices)
                {
                    GL.Normal3(normal);
                    GL.Vertex3(v);
                }
                GL.End();

                //GL.Color3(Color.LightGray);
                //GL.Begin(BeginMode.LineLoop);
                //foreach (Vector3 v in f.vertices)
                //{
                //    GL.Vertex3(v);
                //}
                //GL.End();

                if (i == closestFace)
                {
                    GL.PointSize(10);
                    GL.Begin(BeginMode.Points);
                    GL.Color3(Color.Red);
                    GL.Vertex3(f.vertices[0]);
                    GL.Color3(Color.Green);
                    GL.Vertex3(f.vertices[1]);
                    GL.Color3(Color.Blue);
                    GL.Vertex3(f.vertices[2]);
                    GL.End();
                    GL.PointSize(1);
                }

                //for (int i = 0; i < 1000; i += 500)
                //{
                //int i = (int)((DateTime.Now.Ticks &  Int32.MaxValue) / 50000) % 1000;
                //int i = (int)mousePoint.Z;

                //GL.Color3(Color.Green);
                //p.normal = new Vector3(0, 1, 0);
                //p.point = new Vector3(0, mousePoint.Y, 0);
                //Slice(f, p);
                //GL.Color3(Color.Red);
                //p.normal = new Vector3(1, 0, 0);
                //p.point = new Vector3(mousePoint.X, 0, 0);
                //Slice(f, p);

                //}
            }

            GL.LineWidth(4);
            GL.Color3(Color.Blue);
            Plane p = new Plane();
            p.point = new Vector3(0, 0, mousePoint.Z);
            p.normal = new Vector3(0, 0, 1);
            Slice(p);
            GL.LineWidth(1);
        }
Beispiel #24
0
		public void DoubleClick(object sender, Point mousepos)
		{
			Viewer.RequestInputProcessing();

			Matrix4 invvieworient = freeview.viewmatrix;
			invvieworient.M41 = invvieworient.M42 = invvieworient.M43 = 0.0f;
			invvieworient.Transpose();

			Vector3 vnear = new Vector3(mouseDownPos.X, mouseDownPos.Y, 0.0f);
			Vector3 vfar = new Vector3(vnear.X, vnear.Y, 1.0f);
			Matrix4 invviewprojmatrix = freeview.viewprojmatrix.Inverted();
			vnear = Vector3.TransformPerspective(vnear, invviewprojmatrix);
			vfar = Vector3.TransformPerspective(vfar, invviewprojmatrix);
			Vector3 vdir = (vfar - vnear).Normalized();

			float dist, closest_dist = float.MaxValue;
			Vector2 uv, closest_uv;
			TransformedImage closest_image = default(TransformedImage);
			foreach(TransformedImage image in images.Values)
				if(image != null && (dist = image.CastRay(vnear, vdir, invvieworient, out uv)) < closest_dist)
				{
					closest_dist = dist;
					closest_uv = uv;
					closest_image = image;
				}

			if(closest_dist < float.MaxValue)
			{
				dragImage = mouseDownImage = closest_image;
				dragImageOffset = closest_image.Position - (vnear + vdir * closest_dist);

				// dragImagePlane = plane parallel to screen, going through point of intersection
				Vector3 vsnear = Vector3.TransformPerspective(new Vector3(0.0f, 0.0f, 0.0f), invviewprojmatrix);
				Vector3 vsfar = Vector3.TransformPerspective(new Vector3(0.0f, 0.0f, 1.0f), invviewprojmatrix);
				Vector3 vsdir = (vsfar - vsnear).Normalized();
				dragImagePlane = new Plane(vnear + vdir * closest_dist, vsdir);

				Viewer.browser.OnImageDoubleClick(closest_image);
			}
		}
Beispiel #25
0
        static float DistanceToCylinder(Vector3 cy1, Vector3 cy2, Vector3 point)
        {
            float distance = 0;

            if ((cy1 - cy2).Length < 0.0001)
            {
                return (cy1 - point).Length;
            }

            Plane p = new Plane();
            p.normal = cy1 - cy2;
            p.normal.Normalize();
            p.point = cy2;

            float d1 = p.Distance(point);

            p.normal = -p.normal;
            p.point = cy1;
            float d2 = p.Distance(point);

            if (float.IsNaN(d2) || float.IsNaN(d1))
            {
            }

            if (Math.Sign(d1) == Math.Sign(d2))
            {
                // Inside Endpoints
                Vector3 pt = point - p.normal * d2;
                distance = (pt - p.point).Length;
            }
            else
            {
                distance = (float)Math.Min((point - cy1).Length, (point - cy2).Length);
            }

            return distance;
        }
Beispiel #26
0
        /// <summary>
        /// Infinite plane with two spheres on it (one of them is transparent)
        /// </summary>
        public static void TwoSpheres( IRayScene sc )
        {
            Debug.Assert( sc != null );

              // CSG scene:
              CSGInnerNode root = new CSGInnerNode( SetOperation.Union );
              root.SetAttribute( PropertyName.REFLECTANCE_MODEL, new PhongModel() );
              root.SetAttribute( PropertyName.MATERIAL, new PhongMaterial( new double[] { 1.0, 0.8, 0.1 }, 0.1, 0.6, 0.4, 128 ) );
              sc.Intersectable = root;

              // Background color:
              sc.BackgroundColor = new double[] { 0.0, 0.05, 0.07 };

              // Camera:
              sc.Camera = new StaticCamera( new Vector3d( 0.7, 0.5, -5.0 ),
                                    new Vector3d( 0.0, -0.18, 1.0 ),
                                    50.0 );

              // Light sources:
              sc.Sources = new LinkedList<ILightSource>();
              sc.Sources.Add( new AmbientLightSource( 0.8 ) );
              sc.Sources.Add( new PointLightSource( new Vector3d( -5.0, 4.0, -3.0 ), 1.2 ) );

              // --- NODE DEFINITIONS ----------------------------------------------------

              // Transparent sphere:
              Sphere s;
              s = new Sphere();
              PhongMaterial pm = new PhongMaterial( new double[] { 0.0, 0.2, 0.1 }, 0.05, 0.05, 0.1, 128 );
              pm.n = 1.6;
              pm.Kt = 0.9;
              s.SetAttribute( PropertyName.MATERIAL, pm );
              root.InsertChild( s, Matrix4d.Identity );

              // Opaque sphere:
              s = new Sphere();
              root.InsertChild( s, Matrix4d.Scale( 1.2 ) * Matrix4d.CreateTranslation( 1.5, 0.2, 2.4 ) );

              // Infinite plane with checker:
              Plane pl = new Plane();
              pl.SetAttribute( PropertyName.COLOR, new double[] { 0.3, 0.0, 0.0 } );
              pl.SetAttribute( PropertyName.TEXTURE, new CheckerTexture( 0.6, 0.6, new double[] { 1.0, 1.0, 1.0 } ) );
              root.InsertChild( pl, Matrix4d.RotateX( -MathHelper.PiOver2 ) * Matrix4d.CreateTranslation( 0.0, -1.0, 0.0 ) );
        }
Beispiel #27
0
		public static float DotNormal(Plane plane, Vector3 normal)
		{
			return Vector3.Dot(plane.Normal, normal);
		}
Beispiel #28
0
		public static float DotCoordinate(Plane plane, Vector3 point)
		{
			return Vector3.Dot(plane.Normal, point) + plane.D;
		}
Beispiel #29
0
        public Vector3? GetIntersectionPoint(Plane plane)
        {
            float t = 0.0f;

            float numerator = Vector3.Dot(plane.Normal, plane.Point - Origin);
            float denominator = Vector3.Dot(plane.Normal, Direction);

            if (denominator != 0)
                t = numerator / denominator;

            return origin + direction * t;
        }