void GetRaySplitParams(Point3D raystart, Vector3D raydir, out Edge edge0, out double param0, out MathUtils.RayLineResult res0, out Edge edge1, out double param1, out MathUtils.RayLineResult res1) { edge0 = null; edge1 = null; param0 = 0; param1 = 0; res0 = MathUtils.RayLineResult.UNKOWN; res1 = MathUtils.RayLineResult.UNKOWN; //find first intersecting edge int i = 0; for (; i < Edges.Count; i++) { double closestdist, closestu; MathUtils.RayLineResult res = Edges[i].ClosestPointRay(out closestdist, out closestu, out param0, raystart, raydir); edge0 = Edges[i]; //valid intersection if we touch the line, the first vertex or fully overlap the edge if (res == MathUtils.RayLineResult.INTERSECTING_LINE || res == MathUtils.RayLineResult.INTERSECTING_POS0 || res == MathUtils.RayLineResult.PARALLEL_OVERLAPPING) { res0 = res; i++; break; } } //find second intersecting edge for (; i < Edges.Count; i++) { double closestdist, closestu; MathUtils.RayLineResult res = Edges[i].ClosestPointRay(out closestdist, out closestu, out param1, raystart, raydir); edge1 = Edges[i]; //valid intersection if we touch the line, the first vertex or fully overlap the edge if (res == MathUtils.RayLineResult.INTERSECTING_LINE || res == MathUtils.RayLineResult.INTERSECTING_POS0 || res == MathUtils.RayLineResult.PARALLEL_OVERLAPPING) { res1 = res; i++; break; } } }
public override void Create() { /*foreach (Node n in Children) * { * Shapes.AddRange(n.Shapes.Select(a => a.Copy())); * } * return;*/ if (Is3d) { } else { Shapes.AddRange(Children[0].Shapes.Select(a => a.Copy())); Shapes[0].Convexes[0].Faces[0].Split(Shapes[0].Convexes[0].Edges[1], 0.3, Shapes[0].Convexes[0].Edges[3], 0.25); Shapes[0].Convexes[0].Faces[0].IntegrityCheck(); Shapes[0].Convexes[0].Faces[1].IntegrityCheck(); double closestdist, closestu, closestv; Point3D raystart = new Point3D(0, 0, 0); Vector3D raydir = new Vector3D(5, 1, 0); MathUtils.RayLineResult res = MathUtils.ClosestPointRayLine(out closestdist, out closestu, out closestv, raystart, raydir, Shapes[0].Convexes[0].Edges[1].Vertices[0].Pos, Shapes[0].Convexes[0].Edges[1].Vertices[1].Pos); Scene.AddDebugLine(raystart - raydir * 10, raystart + raydir * 10); Scene.AddDebugCross(raystart + raydir * closestu, 0.5); Scene.AddDebugCross(Shapes[0].Convexes[0].Edges[1].Vertices[0].Pos + Shapes[0].Convexes[0].Edges[1].Offset * closestv, 0.5); //this'll be the clever algorithm. it takes advantage of the fact that we always maintain: //- for any given node, none of it's child convexes overlap //therefore: //- no node should test it's own convexes against each other /* * * //this is the simplest algorithm - we assume every convex could potentially overlap every other convex * //and keep iterating until no more splits occur. it works, but involves a lot of unnecessary overlap tests * Convexes = new List<Convex>(); * foreach (Node n in Children) * Convexes.AddRange(n.Convexes.Select(a => a.Copy())); * * //draw all initial convexes if this is the current stage * if (!CSGScene.NextStage("Begin union")) * { * foreach (Convex c in Convexes) * c.DebugDraw(); * return; * } * * //now do the iterative splitting * //loop until no splits done * bool done_split = true; * while (done_split) * { * //spin over every convex * done_split = false; * for (int i = 0; i < Convexes.Count; i++) * { * //go over every other convex * for (int j = i + 1; j < Convexes.Count; j++) * { * //get the 2 convexes to compare * Convex acvx = Convexes[i]; * Convex bcvx = Convexes[j]; * * //do a clip test * List<Convex> otherconvexsplit = new List<Convex>(); * Convex overlap = null; * if (Convex.CalculateClippedConvexes2d(acvx, bcvx, otherconvexsplit, ref overlap)) * { * //got a split, so remove the convex that was split (cvx a), and re-add the sections * //that didn't overlap * Convexes.RemoveAt(i); * Convexes.AddRange(otherconvexsplit); * done_split = true; * * //if last stage, draw the convex we were splitting and then bail * if (!CSGScene.NextStage("Done a split")) * { * return; * } * break; * } * } * * //break out (so we iterate round again) if a split happened * if (done_split) * break; * } * }*/ } }