//public override Vector3 GetNormal(Point3 pos) { return new Vector3((pos - _centre) * _rRadius); } public override IntersectResult Intersect(Ray ray, out Ray intersect, out float dist) { IntersectResult ret = IntersectResult.MISS; dist = 0; intersect = null; Vector3 v = new Vector3(ray.Origin - _centre); float b = -v.Dot(ray.Direction); float det = (b * b) - v.Dot(v) + _sqRadius; if (det > 0) { det = (float)Math.Sqrt(det); float i1 = b - det; float i2 = b + det; if (i2 > 0) { if (i1 < 0) { dist = i2; ret = IntersectResult.INPRIM; } else { dist = i1; ret = IntersectResult.HIT; } Point3 pt = new Point3(ray.Origin + ray.Direction * dist); intersect = new Ray(pt, new Vector3((pt - _centre) * _rRadius)); } } return(ret); }
public bool findNearest(Ray ray, double farDistance, out double nearest, out Triangle target, out Collision collision) { nearest = double.PositiveInfinity; target = new Triangle(); IntersectResult result = new IntersectResult(); var found = false; foreach (var primitive in primitives) { IntersectResult tmpResult; if (primitive.intersect(ray, out tmpResult) && Constant.EPSILON < tmpResult.t && tmpResult.t < nearest) { result = tmpResult; nearest = tmpResult.t; target = primitive; found = true; } } collision = new Collision(); if (found) { collision = new Collision(ray.origin + result.t * ray.direction, -ray.direction, target.getNormal(result.u, result.v)); } return(found); }
public IntersectResult Intersect(Ray3 ray, double maxDistance) { if (!BoundingBox.Intersect(ray, maxDistance)) { return(IntersectResult.NoHit()); } double minDistance = maxDistance; IntersectResult minResult = IntersectResult.NoHit(); if (nodeTriangles != null) { foreach (var triangle in nodeTriangles) { IntersectResult result = triangle.Intersect(ray, minDistance); if (result.Geometry != null && result.Distance < minDistance) { minDistance = result.Distance; minResult = result; } } } if (children != null) { foreach (var child in children) { IntersectResult result = child.Intersect(ray, minDistance); if (result.Geometry != null && result.Distance < minDistance) { minDistance = result.Distance; minResult = result; } } } return(minResult); }
public IntersectResult Intersect(Ray3 ray, double maxDistance) { if (!BoundingBox.Intersect(ray, maxDistance)) { return(IntersectResult.NoHit()); } if (normal.SqrLength() == 0) { return(IntersectResult.NoHit()); } Vector3 w0 = ray.Origin - vertices[0]; double x = -normal ^ w0; double y = normal ^ ray.Direction; double distance = x / y; if (y == 0 || distance < 0) { return(IntersectResult.NoHit()); } Vector3 position = ray.GetPoint(distance); double uu = edgeAB ^ edgeAB; double uv = edgeAB ^ edgeAC; double vv = edgeAC ^ edgeAC; Vector3 w = position - vertices[0]; double wu = w ^ (edgeAB); double wv = w ^ (edgeAC); double D = uv * uv - uu * vv; double beta = (uv * wv - vv * wu) / D; if (beta < 0 || beta > 1) { return(IntersectResult.NoHit()); } double gamma = (uv * wu - uu * wv) / D; if (gamma < 0 || beta + gamma > 1) { return(IntersectResult.NoHit()); } double alpha = 1 - beta - gamma; Vector3 newNormal = normal; if (distance > 0 && normals != null) { Vector3 n1Interpolated = normals[0] * alpha; Vector3 n2Interpolated = normals[1] * beta; Vector3 n3Interpolated = normals[2] * gamma; newNormal = n1Interpolated + n2Interpolated + n3Interpolated; } IntersectResult result = new IntersectResult(this, distance, position, newNormal); if (textures != null) { Vector2 t1Interpolated = textures[0] * alpha; Vector2 t2Interpolated = textures[1] * beta; Vector2 t3Interpolated = textures[2] * gamma; result.TextureCoordinates = t1Interpolated + t2Interpolated + t3Interpolated; } return(result); }
/// <summary> /// Intersects the specified one. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="one">The one.</param> /// <param name="two">The two.</param> /// <returns></returns> public static IntersectResult <T> Intersect <T>(List <T> one, List <T> two) { var same = new List <T>(); var oneonly = new List <T>(); var twoonly = new List <T>(); var merged = one.Select(s => s).ToList(); merged.AddRange(two); merged = merged.Distinct().ToList(); foreach (var t in merged) { var onehas = one.Contains(t); var twohas = two.Contains(t); if (onehas && twohas) { same.Add(t); } else if (onehas) { oneonly.Add(t); } else { twoonly.Add(t); } } var ret = new IntersectResult <T>(same, oneonly, twoonly); return(ret); }
/// <summary> /// Gets index of closest intersection. /// </summary> /// <param name="intersectionResults"></param> /// <returns></returns> protected int PollIntersections(params IntersectResult[] intersectionResults) { int index = -1; IntersectResult result = null; for (int i = 0; i < intersectionResults.Length; i++) { var intersection = intersectionResults[i]; if (intersection.Hit) { if (result == null) { index = i; result = intersection; } else { if (intersection.PickDistance < result.PickDistance) { result = intersection; index = i; } } } } return(index); }
private async void MyDrawObject_DrawComplete(object sender, DrawEventArgs args) { try { _myDrawObject.IsEnabled = false; if (_cts != null) { _cts.Cancel(); } _cts = new CancellationTokenSource(); QueryTask queryTask = new QueryTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/TaxParcel/AssessorsParcelCharacteristics/MapServer/1"); Query query = new Query() { Geometry = args.Geometry, ReturnGeometry = true, OutSpatialReference = MyMap.SpatialReference }; QueryResult parcelsToIntersectResult = await queryTask.ExecuteTaskAsync(query, _cts.Token); List <Graphic> graphicList = new List <Graphic>(); graphicList.Add(new Graphic() { Geometry = args.Geometry }); SimplifyResult simplifiedIntersectGeometryResult = await _geometryService.SimplifyTaskAsync(graphicList, _cts.Token); IntersectResult intersectedParcelsResult = await _geometryService.IntersectTaskAsync(parcelsToIntersectResult.FeatureSet.ToList(), simplifiedIntersectGeometryResult.Results[0].Geometry, _cts.Token); Random random = new Random(); foreach (Graphic g in intersectedParcelsResult.Results) { SimpleFillSymbol symbol = new SimpleFillSymbol() { Fill = new System.Windows.Media.SolidColorBrush( System.Windows.Media.Color.FromArgb(255, (byte)random.Next(0, 255), (byte)random.Next(0, 255), (byte)random.Next(0, 255))), BorderBrush = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Black), BorderThickness = 1 }; g.Symbol = symbol; _intersectGraphicsLayer.Graphics.Add(g); } } catch (Exception ex) { if (ex is ServiceException) { MessageBox.Show(String.Format("{0}: {1}", (ex as ServiceException).Code.ToString(), (ex as ServiceException).Details[0]), "Error", MessageBoxButton.OK); return; } } }
private IntersectResult Intersect2Curves(Curve a, Curve b) { int clipperPrecision = 100; IntersectResult result = new IntersectResult(); if (Curve.PlanarCurveCollision(a, b, Plane.WorldXY, 0.001f)) { Clipper clipper = new Clipper(); Path subjectA = CurveToPath(a, clipperPrecision); Path subjectB = CurveToPath(b, clipperPrecision); Paths solution = new Paths(); clipper.AddPath(subjectA, PolyType.ptClip, true); clipper.AddPath(subjectB, PolyType.ptSubject, true); clipper.Execute(ClipType.ctIntersection, solution, PolyFillType.pftNonZero, PolyFillType.pftNonZero); if (solution.Count > 0) { result.intersect = true; PolylineCurve pl = PathToPolyline(solution[0], clipperPrecision); result.unionCurve = pl; Point3d minPoint = pl.GetBoundingBox(false).Min; Point3d maxPoint = pl.GetBoundingBox(false).Max; if (maxPoint.X - minPoint.X > maxPoint.Y - minPoint.Y) { result.reboundingVector = new Vector2d(0, -(maxPoint.Y - minPoint.Y)); if (AreaMassProperties.Compute(a).Centroid.Y > AreaMassProperties.Compute(b).Centroid.Y) { result.reboundingVector.Y *= -1; } } else { result.reboundingVector = new Vector2d(-(maxPoint.X - minPoint.X), 0); if (AreaMassProperties.Compute(a).Centroid.X > AreaMassProperties.Compute(b).Centroid.X) { result.reboundingVector.X *= -1; } } } } else { result.intersect = false; result.reboundingVector = Vector2d.Unset; result.unionCurve = null; } return(result); }
public override IntersectResult Intersect(Ray3 ray) { double a = ray.Direction ^ normal; if (a >= 0) { return(IntersectResult.NoHit()); } double b = normal ^ (ray.Origin - position); double distance = -b / a; return(new IntersectResult(this, distance, ray.GetPoint(distance), normal)); }
public override LightSample Sample(Geometry geometry, Vector3 position) { if (shadow) { Ray3 shadowRay = new Ray3(position, vector); IntersectResult shadowResult = geometry.Intersect(shadowRay); if (shadowResult.Geometry != null) { return(LightSample.Zero); } } return(new LightSample(vector, irradiance)); }
public override IntersectResult Intersect(Ray3 ray) { double minDistance = Constant.Infinity; IntersectResult minResult = IntersectResult.NoHit(); foreach (Geometry geometry in geometries) { IntersectResult result = geometry.Intersect(ray); if (result.Geometry != null && result.Distance < minDistance) { minDistance = result.Distance; minResult = result; } } return(minResult); }
public override void Execute(IRaySceneQueryListener listener) { var list = new List <PCZSceneNode>(); //find the nodes that intersect the AAB ((PCZSceneManager)creator).FindNodesIn(ray, ref list, this.startZone, (PCZSceneNode)this.excludeNode); //grab all moveables from the node that intersect... foreach (PCZSceneNode node in list) { foreach (MovableObject m in node.Objects) { if ((m.QueryFlags & queryMask) != 0 && (m.TypeFlags & this.queryTypeMask) != 0 && m.IsAttached) { IntersectResult result = ray.Intersects(m.GetWorldBoundingBox()); if (result.Hit) { listener.OnQueryResult(m, result.Distance); // deal with attached objects, since they are not directly attached to nodes if (m.MovableType == "Entity") { //Check: not sure here... var e = (Entity)m; foreach (MovableObject c in e.SubEntities) { if ((c.QueryFlags & queryMask) > 0) { result = ray.Intersects(c.GetWorldBoundingBox()); if (result.Hit) { listener.OnQueryResult(c, result.Distance); } } } } } } } } // reset startzone and exclude node this.startZone = null; this.excludeNode = null; }
private IntersectResult Intersect2Curves(Curve a, Curve b) { IntersectResult result = new IntersectResult(); if (Curve.PlanarCurveCollision(a, b, Plane.WorldXY, 0.01f)) { Curve[] unionCurveArray = Curve.CreateBooleanIntersection(a, b); if (unionCurveArray.Length > 0) { result.intersect = true; result.unionCurve = unionCurveArray[0]; // Find the smallest dimesion of unionCurve Point3d minPoint = result.unionCurve.GetBoundingBox(false).Min; Point3d maxPoint = result.unionCurve.GetBoundingBox(false).Max; if (maxPoint.X - minPoint.X > maxPoint.Y - minPoint.Y) { result.reboundingVector = new Vector2d(0, -(maxPoint.Y - minPoint.Y)); if (AreaMassProperties.Compute(a).Centroid.Y > AreaMassProperties.Compute(b).Centroid.Y) { result.reboundingVector.Y *= -1; } } else { result.reboundingVector = new Vector2d(-(maxPoint.X - minPoint.X), 0); if (AreaMassProperties.Compute(a).Centroid.X > AreaMassProperties.Compute(b).Centroid.X) { result.reboundingVector.X *= -1; } } } } else { result.intersect = false; result.reboundingVector = Vector2d.Unset; result.unionCurve = null; } return(result); }
public override void FindNodes(Ray t, ref List <PCZSceneNode> list, List <Portal> visitedPortals, bool includeVisitors, bool recurseThruPortals, PCZSceneNode exclude) { // if this zone has an enclosure, check against the enclosure AABB first if (null != mEnclosureNode) { IntersectResult nsect = t.Intersects(mEnclosureNode.WorldAABB); if (!nsect.Hit) { // AABB of zone does not intersect t, just return. return; } } // use the Octree to more efficiently find nodes intersecting the ray this.rootOctree._findNodes(t, ref list, exclude, includeVisitors, false); // if asked to, recurse through portals if (recurseThruPortals) { foreach (Portal portal in mPortals) { // check portal versus boundign box if (portal.intersects(t)) { // make sure portal hasn't already been recursed through if (!visitedPortals.Contains(portal)) { // save portal to the visitedPortals list visitedPortals.Add(portal); // recurse into the connected zone portal.getTargetZone().FindNodes(t, ref list, visitedPortals, includeVisitors, recurseThruPortals, exclude); } } } } }
public override IntersectResult Intersect(Ray3 ray) { Vector3 v = ray.Origin - center; double a0 = v.SqrLength() - radius * radius; double DdotV = ray.Direction ^ v; if (DdotV <= 0) { double discr = DdotV * DdotV - a0; if (discr >= 0) { double distance = -DdotV - Math.Sqrt(discr); Vector3 position = ray.GetPoint(distance); Vector3 normal = (position - center).Normalize(); IntersectResult result = new IntersectResult(this, distance, position, normal); result.TextureCoordinates = new Vector2( (Math.PI + Math.Atan2(position.Z - center.Z, position.X - center.X)) / (Math.PI * 2), 1.0 - ((Math.PI / 2) + Math.Asin((position.Y - center.Y) / radius)) / Math.PI); return(result); } } return(IntersectResult.NoHit()); }
private List <Curve> CollisionDetectionMain(List <Curve> roomCurves, Curve boundary) { List <int> indexes = new List <int>(); for (int i = 0; i < roomCurves.Count; i++) { indexes.Add(i); } Shuffle(ref indexes); for (int l = 0; l < roomCurves.Count; l++) { int i = indexes[l]; // Check roomCurves[i] and roomCurves[j] intersection // Then let's move both rooms by 1/2 of the rebounding vector for (int j = i + 1; j < roomCurves.Count; j++) { IntersectResult intersectResult = new IntersectResult(); intersectResult = Intersect2Curves(roomCurves[i], roomCurves[j]); if (intersectResult.intersect) { if (intersectResult.reboundingVector.X != 0) { // Change the proportions of rooms double iScaleFactor = 1 - Math.Abs(intersectResult.reboundingVector.X / roomCurves[i].GetBoundingBox(false).Diagonal.X / 2); Point3d iScaleAnchor = roomCurves[i].GetBoundingBox(false).Center + new Vector3d(intersectResult.reboundingVector.X > 0 ? roomCurves[i].GetBoundingBox(false).Diagonal.X / 2 : -roomCurves[i].GetBoundingBox(false).Diagonal.X / 2, 0, 0); double jScaleFactor = 1 - Math.Abs(intersectResult.reboundingVector.X / roomCurves[j].GetBoundingBox(false).Diagonal.X / 2); Point3d jScaleAnchor = roomCurves[j].GetBoundingBox(false).Center + new Vector3d(intersectResult.reboundingVector.X > 0 ? -roomCurves[j].GetBoundingBox(false).Diagonal.X / 2 : roomCurves[j].GetBoundingBox(false).Diagonal.X / 2, 0, 0); roomCurves[j].Transform(Transform.Scale(new Plane(jScaleAnchor, Vector3d.ZAxis), jScaleFactor, 1 / jScaleFactor, 1)); roomCurves[i].Transform(Transform.Scale(new Plane(iScaleAnchor, Vector3d.ZAxis), iScaleFactor, 1 / iScaleFactor, 1)); // If the proportions of both rooms are in [0.5; 2] -> ok // Else - change the position of the rooms and return previous scale if (!(GetRoomXYProportion(roomCurves[i]) > 1 / proportionThreshold && GetRoomXYProportion(roomCurves[i]) < proportionThreshold && GetRoomXYProportion(roomCurves[j]) > 1 / proportionThreshold && GetRoomXYProportion(roomCurves[j]) < proportionThreshold)) { roomCurves[j].Transform(Transform.Scale(new Plane(jScaleAnchor, Vector3d.ZAxis), 1 / jScaleFactor, jScaleFactor, 1)); roomCurves[i].Transform(Transform.Scale(new Plane(iScaleAnchor, Vector3d.ZAxis), 1 / iScaleFactor, iScaleFactor, 1)); roomCurves[i].Translate(new Vector3d(intersectResult.reboundingVector.X / 2, 0, 0)); roomCurves[j].Translate(new Vector3d(-intersectResult.reboundingVector.X / 2, 0, 0)); } } else { // Change the proportions of rooms double iScaleFactor = 1 - Math.Abs(intersectResult.reboundingVector.Y / roomCurves[i].GetBoundingBox(false).Diagonal.Y / 2); Point3d iScaleAnchor = roomCurves[i].GetBoundingBox(false).Center + new Vector3d(0, intersectResult.reboundingVector.Y > 0 ? roomCurves[i].GetBoundingBox(false).Diagonal.Y / 2 : -roomCurves[i].GetBoundingBox(false).Diagonal.Y / 2, 0); double jScaleFactor = 1 - Math.Abs(intersectResult.reboundingVector.Y / roomCurves[j].GetBoundingBox(false).Diagonal.Y / 2); Point3d jScaleAnchor = roomCurves[j].GetBoundingBox(false).Center + new Vector3d(0, intersectResult.reboundingVector.Y > 0 ? -roomCurves[j].GetBoundingBox(false).Diagonal.Y / 2 : roomCurves[j].GetBoundingBox(false).Diagonal.Y / 2, 0); roomCurves[i].Transform(Transform.Scale(new Plane(iScaleAnchor, Vector3d.ZAxis), 1 / iScaleFactor, iScaleFactor, 1)); roomCurves[j].Transform(Transform.Scale(new Plane(jScaleAnchor, Vector3d.ZAxis), 1 / jScaleFactor, jScaleFactor, 1)); // If the proportions of both rooms are in [0.5; 2] // Else - change the position of the rooms if (!(GetRoomXYProportion(roomCurves[i]) > 1 / proportionThreshold && GetRoomXYProportion(roomCurves[i]) < proportionThreshold && GetRoomXYProportion(roomCurves[j]) > 1 / proportionThreshold && GetRoomXYProportion(roomCurves[j]) < proportionThreshold)) { roomCurves[i].Transform(Transform.Scale(new Plane(iScaleAnchor, Vector3d.ZAxis), iScaleFactor, 1 / iScaleFactor, 1)); roomCurves[j].Transform(Transform.Scale(new Plane(jScaleAnchor, Vector3d.ZAxis), jScaleFactor, 1 / jScaleFactor, 1)); roomCurves[i].Translate(new Vector3d(0, intersectResult.reboundingVector.Y / 2, 0)); roomCurves[j].Translate(new Vector3d(0, -intersectResult.reboundingVector.Y / 2, 0)); } } } else { if (Curve.PlanarClosedCurveRelationship(roomCurves[i], roomCurves[j], Plane.WorldXY, 0.0001f) != RegionContainment.Disjoint) { BoundingBox aRoomBB = roomCurves[j].GetBoundingBox(false); BoundingBox bRoomBB = roomCurves[i].GetBoundingBox(false); double xDist = Math.Abs((aRoomBB.Center - bRoomBB.Center).X) - (aRoomBB.Diagonal.X / 2 - bRoomBB.Diagonal.X / 2); double yDist = Math.Abs((aRoomBB.Center - bRoomBB.Center).Y) - (aRoomBB.Diagonal.Y / 2 - bRoomBB.Diagonal.Y / 2); if (xDist > yDist) { if ((aRoomBB.Center - bRoomBB.Center).X > 0) { roomCurves[i].Translate(new Vector3d(xDist - bRoomBB.Diagonal.X, 0, 0)); } else { roomCurves[i].Translate(new Vector3d(-xDist + bRoomBB.Diagonal.X, 0, 0)); } } else { if ((aRoomBB.Center - bRoomBB.Center).Y > 0) { roomCurves[i].Translate(new Vector3d(0, yDist - bRoomBB.Diagonal.Y, 0)); } else { roomCurves[i].Translate(new Vector3d(0, -yDist + bRoomBB.Diagonal.Y, 0)); } } } } } // Check roomCurves[i] and boundary intersection // Let's do it twice to be sure that X and Y positions are both defined perfectly for (int t = 0; t < 1; t++) { IntersectResult intersectResult = new IntersectResult(); intersectResult = Intersect2Curves(roomCurves[i], boundary); if (intersectResult.intersect) { double boundaryProportionThreshold = 1;// proportionThreshold; if (Math.Abs(intersectResult.reboundingVector.X) > 0.01f) { // Change the proportions of rooms double iScaleFactor = Math.Abs(intersectResult.reboundingVector.X / roomCurves[i].GetBoundingBox(false).Diagonal.X); Point3d iScaleAnchor = roomCurves[i].GetBoundingBox(false).Center + new Vector3d(intersectResult.reboundingVector.X > 0 ? -roomCurves[i].GetBoundingBox(false).Diagonal.X / 2 : roomCurves[i].GetBoundingBox(false).Diagonal.X / 2, 0, 0); roomCurves[i].Transform(Transform.Scale(new Plane(iScaleAnchor, Vector3d.ZAxis), iScaleFactor, 1 / iScaleFactor, 1)); // If the proportions of both rooms are in [0.5; 2] -> ok // Else - change the position of the rooms and return previous scale if (!(GetRoomXYProportion(roomCurves[i]) > 1 / boundaryProportionThreshold && GetRoomXYProportion(roomCurves[i]) < boundaryProportionThreshold)) { roomCurves[i].Transform(Transform.Scale(new Plane(iScaleAnchor, Vector3d.ZAxis), 1 / iScaleFactor, iScaleFactor, 1)); roomCurves[i].Translate(new Vector3d((intersectResult.reboundingVector.X > 0 ? -1 : 1) * (roomCurves[i].GetBoundingBox(false).Diagonal.X - Math.Abs(intersectResult.reboundingVector.X)), 0, 0)); } } else if (Math.Abs(intersectResult.reboundingVector.Y) > 0.01f) { // Change the proportions of rooms double iScaleFactor = Math.Abs(intersectResult.reboundingVector.Y / roomCurves[i].GetBoundingBox(false).Diagonal.Y); Point3d iScaleAnchor = roomCurves[i].GetBoundingBox(false).Center + new Vector3d(0, intersectResult.reboundingVector.Y > 0 ? -roomCurves[i].GetBoundingBox(false).Diagonal.Y / 2 : roomCurves[i].GetBoundingBox(false).Diagonal.Y / 2, 0); roomCurves[i].Transform(Transform.Scale(new Plane(iScaleAnchor, Vector3d.ZAxis), 1 / iScaleFactor, iScaleFactor, 1)); // If the proportions of both rooms are in [0.5; 2] -> ok // Else - change the position of the rooms and return previous scale if (!(GetRoomXYProportion(roomCurves[i]) > 1 / boundaryProportionThreshold && GetRoomXYProportion(roomCurves[i]) < boundaryProportionThreshold)) { roomCurves[i].Transform(Transform.Scale(new Plane(iScaleAnchor, Vector3d.ZAxis), iScaleFactor, 1 / iScaleFactor, 1)); roomCurves[i].Translate(new Vector3d(0, (intersectResult.reboundingVector.Y > 0 ? -1 : 1) * (roomCurves[i].GetBoundingBox(false).Diagonal.Y - Math.Abs(intersectResult.reboundingVector.Y)), 0)); } } } else { if (Curve.PlanarClosedCurveRelationship(roomCurves[i], boundary, Plane.WorldXY, 0.0001f) != RegionContainment.AInsideB) { BoundingBox boundaryBB = boundary.GetBoundingBox(false); BoundingBox roomBB = roomCurves[i].GetBoundingBox(false); double xDist = Math.Abs((boundaryBB.Center - roomBB.Center).X) - boundaryBB.Diagonal.X / 2 - roomBB.Diagonal.X / 2; double yDist = Math.Abs((boundaryBB.Center - roomBB.Center).Y) - boundaryBB.Diagonal.Y / 2 - roomBB.Diagonal.Y / 2; if (xDist > yDist) { if ((boundaryBB.Center - roomBB.Center).X > 0) { roomCurves[i].Translate(new Vector3d(xDist + roomBB.Diagonal.X, 0, 0)); } else { roomCurves[i].Translate(new Vector3d(-xDist - roomBB.Diagonal.X, 0, 0)); } } else { if ((boundaryBB.Center - roomBB.Center).Y > 0) { roomCurves[i].Translate(new Vector3d(0, yDist + roomBB.Diagonal.Y, 0)); } else { roomCurves[i].Translate(new Vector3d(0, -yDist - roomBB.Diagonal.Y, 0)); } } } } } } return(roomCurves); }
public bool intersect(Ray ray, out IntersectResult result) { return(intersectAlgorithm.intersect(ray, this, out result)); }
public bool RayIntersection(Ray ray, out int x, out int z) { // generate a bounding box for the heightmap in its local space AxisAlignedBox axisAlignedBox = new AxisAlignedBox(new Vector3(0, minHeight, 0), new Vector3(width, maxHeight, height)); Vector3 rayLoc = new Vector3((ray.Origin.x - offsetX) / xzScale, ray.Origin.y / yScale, (ray.Origin.z - offsetZ) / xzScale); Vector3 rayDir = new Vector3(ray.Direction.x / xzScale, ray.Direction.y / yScale, ray.Direction.z / xzScale); rayDir.Normalize(); // convert the ray to local heightmap space Ray tmpRay = new Ray(rayLoc, rayDir); // see if the ray intersects with the bounding box IntersectResult result = tmpRay.Intersects(axisAlignedBox); if (result.Hit) { // move rayLoc up to just before the point of intersection rayLoc = rayLoc + rayDir * ( result.Distance - 1 ); // // deal with edge case where ray is coming from outside the heightmap // and is very near edge of map at intersection. // int insideCounter = 20; while ((!Inside(rayLoc)) && (insideCounter > 0)) { rayLoc += ( rayDir * 0.1f ); insideCounter--; } if (insideCounter == 0) { x = 0; z = 0; return false; } x = (int)Math.Round(rayLoc.x); z = (int)Math.Round(rayLoc.z); if (x < 0) { x = 0; } if (x >= width) { x = width - 1; } if (z < 0) { z = 0; } if (z >= height) { z = height - 1; } bool above = rayLoc.y > heightData[x + z * width]; while (Inside(rayLoc)) { // increment the ray rayLoc += rayDir; x = (int)Math.Round(rayLoc.x); z = (int)Math.Round(rayLoc.z); if (x < 0) { x = 0; } if (x >= width) { x = width - 1; } if (z < 0) { z = 0; } if (z >= height) { z = height - 1; } if (above != (rayLoc.y > heightData[x + z * width])) { // we found a hit return true; } } } x = 0; z = 0; return false; }
internal static IntersectResult oldIntersectSegmentPoly2D(float[] p0, float[] p1, float[] verts, int nverts) { /*TODO:��Ҫ�Ż�*/ IntersectResult result = new IntersectResult(); float EPS = 0.00000001f; float[] dir = new float[3]; vSub(dir, p1, p0); float[] edge = new float[3]; float[] diff = new float[3]; VectorPtr p0v = new VectorPtr(p0); VectorPtr vpj; for (int i = 0, j = nverts - 1; i < nverts; j = i++) { vpj = new VectorPtr(verts, j * 3); vSub(edge, new VectorPtr(verts, i * 3), vpj); vSub(diff, p0v, vpj); float n = vPerp2D(edge, diff); float d = vPerp2D(dir, edge); if (Math.Abs(d) < EPS) { // S is nearly parallel to this edge if (n < 0) { return(result); } else { continue; } } float t = n / d; if (d < 0) { // segment S is entering across this edge if (t > result.tmin) { result.tmin = t; result.segMin = j; // S enters after leaving polygon if (result.tmin > result.tmax) { return(result); } } } else { // segment S is leaving across this edge if (t < result.tmax) { result.tmax = t; result.segMax = j; // S leaves before entering polygon if (result.tmax < result.tmin) { return(result); } } } } result.intersects = true; return(result); }
public void Query(HashSet <ISpatialTreeNode> hashSet, CoordinateRectangle rectangle, IntersectResult parentResult, SpatialQueryIterator i) { //Query elements on the map by coordinate ractengle(indexed search) lock (this) { if (!IsBottomSheet) { if (Sheets.HasChilds) { foreach (var sheet in Sheets.Values) { var res = parentResult == IntersectResult.Supersets ? IntersectResult.Supersets : IntersectResult.None; if (res != IntersectResult.Supersets) { i.Next(); res = sheet.Rectangle.RectangleContains(rectangle); } if (res != IntersectResult.None) { sheet.Query(hashSet, rectangle, res, i); } if (res == IntersectResult.Contains) { break; } } } } else if (Content.HasChilds) { foreach (var node in Content.Values) { var res = parentResult == IntersectResult.Supersets ? IntersectResult.Supersets : IntersectResult.None; if (res != IntersectResult.Supersets) { i.Next(); switch (node.NodeType) { case SpatialTreeNodeTypes.Point: res = rectangle.PointContains(node.Coordinate); break; case SpatialTreeNodeTypes.Line: res = rectangle.LineContains(node.Rectangle); break; case SpatialTreeNodeTypes.Rectangle: res = rectangle.RectangleContains(node.Rectangle); break; case SpatialTreeNodeTypes.Poligon: res = rectangle.PoligonContains(node.Poligon); break; } } if (res != IntersectResult.None) { hashSet.Add(node); } } } } }
public override void FindNodes(Ray t, ref List <PCZSceneNode> list, List <Portal> visitedPortals, bool includeVisitors, bool recurseThruPortals, PCZSceneNode exclude) { // if this zone has an enclosure, check against the enclosure AABB first if (null != mEnclosureNode) { IntersectResult nsect = t.Intersects(mEnclosureNode.WorldAABB); if (!nsect.Hit) { // AABB of zone does not intersect t, just return. return; } } // check nodes at home in this zone foreach (PCZSceneNode pczsn in mHomeNodeList) { if (pczsn != exclude) { // make sure node is not already in the list (might have been added in another // zone it was visiting) if (!list.Contains(pczsn)) { IntersectResult nsect = t.Intersects(pczsn.WorldAABB); if (nsect.Hit) { list.Add(pczsn); } } } } if (includeVisitors) { // check visitor nodes foreach (PCZSceneNode pczsn in mVisitorNodeList) { if (pczsn != exclude) { // make sure node is not already in the list (might have been added in another // zone it was visiting) if (!list.Contains(pczsn)) { IntersectResult nsect = t.Intersects(pczsn.WorldAABB); if (nsect.Hit) { list.Add(pczsn); } } } } } // if asked to, recurse through portals if (recurseThruPortals) { foreach (Portal portal in mPortals) { // check portal versus boundign box if (portal.intersects(t)) { // make sure portal hasn't already been recursed through if (!visitedPortals.Contains(portal)) { // save portal to the visitedPortals list visitedPortals.Add(portal); // recurse into the connected zone portal.getTargetZone().FindNodes(t, ref list, visitedPortals, includeVisitors, recurseThruPortals, exclude); } } } } }
// Check if a portal intersects a ray // NOTE: Kinda using my own invented routine here for quad portals... Better do a lot of testing! public bool intersects(Ray ray) { // Only check if portal is open if (this.mOpen) { if (this.mType == PORTAL_TYPE.PORTAL_TYPE_QUAD) { // since ogre doesn't have built in support for a quad, I'm going to first // find the intersection point (if any) of the ray and the portal plane. Then // using the intersection point, I take the cross product of each side of the portal // (0,1,intersect), (1,2, intersect), (2,3, intersect), and (3,0,intersect). If // all 4 cross products have vectors pointing in the same direction, then the // intersection point is within the portal, otherwise it is outside. IntersectResult result = ray.Intersects(this.mDerivedPlane); if (result.Hit) { // the ray intersects the plane, now walk around the edges Vector3 isect = ray.GetPoint(result.Distance); Vector3 cross, vect1, vect2; Vector3 cross2, vect3, vect4; vect1 = this.mDerivedCorners[1] - this.mDerivedCorners[0]; vect2 = isect - this.mDerivedCorners[0]; cross = vect1.Cross(vect2); vect3 = this.mDerivedCorners[2] - this.mDerivedCorners[1]; vect4 = isect - this.mDerivedCorners[1]; cross2 = vect3.Cross(vect4); if (cross.Dot(cross2) < 0) { return(false); } vect1 = this.mDerivedCorners[3] - this.mDerivedCorners[2]; vect2 = isect - this.mDerivedCorners[2]; cross = vect1.Cross(vect2); if (cross.Dot(cross2) < 0) { return(false); } vect1 = this.mDerivedCorners[0] - this.mDerivedCorners[3]; vect2 = isect - this.mDerivedCorners[3]; cross = vect1.Cross(vect2); if (cross.Dot(cross2) < 0) { return(false); } // all cross products pointing same way, so intersect // must be on the inside of the portal! return(true); } return(false); } else if (this.mType == PORTAL_TYPE.PORTAL_TYPE_AABB) { var aabb = new AxisAlignedBox(this.mDerivedCorners[0], this.mDerivedCorners[1]); IntersectResult result = ray.Intersects(aabb); return(result.Hit); } else // sphere { IntersectResult result = ray.Intersects(this.mDerivedSphere); return(result.Hit); } } return(false); }
private static byte[] ExtractHandler(NameValueCollection boundVariables, JsonObject operationInput, string outputFormat, string requestProperties, out string responseProperties) { responseProperties = null; const string methodName = "ExtractIntersection"; var errors = new ResponseContainer(HttpStatusCode.BadRequest, ""); double? featureId; if (!operationInput.TryGetAsDouble("id", out featureId) && featureId.HasValue) { errors.AddMessage("The id of the shape is required."); } if (errors.HasErrors) { return(Json(errors)); } #if !DEBUG _logger.LogMessage(ServerLogger.msgType.infoStandard, methodName, MessageCode, "Params received"); #endif var fireLayerMap = _featureClassIndexMap.First(x => x.LayerName == "Fire Perimeter"); var fireLayer = fireLayerMap.FeatureClass; var perimeterFeature = fireLayer.GetFeature(Convert.ToInt32(featureId.Value)); var inputGeometry = perimeterFeature.ShapeCopy; #if !DEBUG _logger.LogMessage(ServerLogger.msgType.infoStandard, methodName, MessageCode, "Params valid"); #endif var filterGeometry = (ITopologicalOperator4)inputGeometry; if (filterGeometry == null) { errors.Message = "input geometry could not become a topological operator."; return(Json(errors)); } filterGeometry.IsKnownSimple_2 = false; filterGeometry.Simplify(); var totalArea = ((IArea)inputGeometry).Area; if (totalArea < 0) { ((ICurve)inputGeometry).ReverseOrientation(); } var filter = new SpatialFilter { Geometry = inputGeometry, SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects }; var whole = (ITopologicalOperator4)inputGeometry; whole.Simplify(); var searchResults = new Dictionary <string, IList <IntersectAttributes> > { { "fire", new[] { new IntersectAttributes(new[] { new KeyValuePair <string, object>("total", "total") }) { Intersect = totalArea } } } }; var criterias = new List <Criteria> { new Criteria { LayerIndex = _featureClassIndexMap.First(x => x.LayerName == "Municipal Boundary").Index, Attributes = new[] { "NAME" }, JsonPropertyName = "muni", CalculationCommand = new CalculateIntersectionCommand(whole, _logger) }, new Criteria { LayerIndex = _featureClassIndexMap.First(x => x.LayerName == "Municipal Boundary").Index, FeatureClassIndexMap = _featureClassIndexMap, Attributes = new[] { "NAME" }, JsonPropertyName = "muniPrivate", CalculationCommand = new CalculateMuniPrivateCommand(whole, _logger) { LandOwnership = _featureClassIndexMap.Single(x => x.LayerName == "Land Ownership") } }, new Criteria { LayerIndex = _featureClassIndexMap.First(x => x.LayerName == "County Boundary").Index, Attributes = new[] { "NAME" }, JsonPropertyName = "county", CalculationCommand = new CalculateIntersectionCommand(whole, _logger) }, new Criteria { LayerIndex = _featureClassIndexMap.First(x => x.LayerName == "County Boundary").Index, Attributes = new[] { "NAME" }, JsonPropertyName = "countyPrivate", CalculationCommand = new CalculateCountyPrivateCommand(whole, _logger) { LandOwnership = _featureClassIndexMap.Single(x => x.LayerName == "Land Ownership"), Municipalities = _featureClassIndexMap.First(x => x.LayerName == "Municipal Boundary") } }, new Criteria { LayerIndex = _featureClassIndexMap.Single(x => x.LayerName == "Land Ownership").Index, Attributes = new[] { "OWNER" }, JsonPropertyName = "owner", CalculationCommand = new CalculateIntersectionCommand(whole, _logger) }, new Criteria { LayerIndex = _featureClassIndexMap.Single(x => x.LayerName == "Land Ownership").Index, Attributes = new[] { "ADMIN" }, JsonPropertyName = "admin", CalculationCommand = new CalculateIntersectionCommand(whole, _logger) }, new Criteria { LayerIndex = _featureClassIndexMap.Single(x => x.LayerName == "States Boundary").Index, Attributes = new[] { "STATE_NAME" }, JsonPropertyName = "state", CalculationCommand = new CalculateIntersectionCommand(whole, _logger) } }; foreach (var criteria in criterias) { // get the IFeatureClass var container = _featureClassIndexMap.Single(x => x.Index == criteria.LayerIndex); // get the index of the fields to calculate intersections for var fieldMap = container.FieldMap.Select(x => x.Value) .Where(y => criteria.Attributes.Contains(y.Field.ToUpper())) .ToList(); #if !DEBUG _logger.LogMessage(ServerLogger.msgType.infoStandard, methodName, MessageCode, string.Format("Querying {0} at index {1}", container.LayerName, container.Index)); #endif var cursor = container.FeatureClass.Search(filter, true); IFeature feature; while ((feature = cursor.NextFeature()) != null) { var values = new GetValueAtIndexCommand(fieldMap, feature).Execute(); var attributes = new IntersectAttributes(values); #if !DEBUG _logger.LogMessage(ServerLogger.msgType.infoStandard, methodName, MessageCode, "intersecting " + container.LayerName); #endif IntersectionPart intersectionPart; try { intersectionPart = criteria.GetIntersectionWith(feature); } catch (Exception ex) { return(Json(new ResponseContainer(HttpStatusCode.InternalServerError, ex.Message))); } attributes.Intersect = intersectionPart.Size; if (searchResults.ContainsKey(criteria.JsonPropertyName)) { if (searchResults[criteria.JsonPropertyName].Any(x => new MultiSetComparer <object>().Equals(x.Attributes, attributes.Attributes))) { var duplicate = searchResults[criteria.JsonPropertyName] .Single(x => new MultiSetComparer <object>().Equals(x.Attributes, attributes.Attributes)); duplicate.Intersect += attributes.Intersect; } else { searchResults[criteria.JsonPropertyName].Add(attributes); } } else { searchResults[criteria.JsonPropertyName] = new Collection <IntersectAttributes> { attributes }; } } } var response = new IntersectResult(searchResults); #if !DEBUG _logger.LogMessage(ServerLogger.msgType.infoStandard, methodName, MessageCode, string.Format("Returning results {0}", searchResults.Count)); #endif return(Json(new ResponseContainer <IntersectResult>(response))); }
/// <summary> /// <see cref="RaySceneQuery"/> /// </summary> public void Execute(IRaySceneQueryListener listener, Camera camera) { clearFragmentList(); // if the world is not initialized, then just quit out now with no hits if (!TerrainManager.Instance.Initialized) { return; } ulong mask = QueryMask; SceneQuery.WorldFragment frag; bool terrainQuery = (mask & (ulong)RaySceneQueryType.AllTerrain) != 0 || (mask & (ulong)RaySceneQueryType.FirstTerrain) != 0; // if the query is a terrain query that is exactly vertical, then force it into the "Height" fastpath if (((mask & (ulong)RaySceneQueryType.Height) != 0) || (terrainQuery && (this.Ray.Direction.x == 0.0f) && (this.Ray.Direction.z == 0.0f))) { // we don't want to bother checking for entities because a // UNIT_Y ray is assumed to be a height test, not a ray test frag = new SceneQuery.WorldFragment(); fragmentList.Add(frag); frag.FragmentType = WorldFragmentType.SingleIntersection; Vector3 origin = this.Ray.Origin; origin.y = 0; // ensure that it's within bounds frag.SingleIntersection = getHeightAt(origin); listener.OnQueryResult(frag, Math.Abs(frag.SingleIntersection.y - this.Ray.Origin.y)); } else { // Check for all entity contacts if ((mask & (ulong)RaySceneQueryType.Entities) != 0) { base.Execute(listener); } // Check for contact with the closest entity triangle // or all entity triangles. Ignores entities that // don't have a TriangleIntersector associated with // their meshes. bool firstTriangleQuery = (mask & (ulong)(RaySceneQueryType.FirstEntityTriangle)) != 0; bool allTrianglesQuery = (mask & (ulong)(RaySceneQueryType.AllEntityTriangles)) != 0; if (firstTriangleQuery | allTrianglesQuery) { rayOrigin = this.ray.Origin; // Start by getting the entities whose bounding // boxes intersect the ray. If there are none, // we're done. List <MovableObject> candidates = new List <MovableObject>(); foreach (Dictionary <string, MovableObject> objectMap in creator.MovableObjectMaps) { foreach (MovableObject obj in objectMap.Values) { // skip if unattached or filtered out by query flags if (!obj.IsAttached || (obj.QueryFlags & queryMask) == 0) { continue; } // test the intersection against the world bounding box of the entity IntersectResult results = MathUtil.Intersects(ray, obj.GetWorldBoundingBox()); if (results.Hit) { candidates.Add(obj); } } } // Get the camera.Near value Camera cam = camera; float nearDistance = cam.Near; float closestDistance = float.MaxValue; Vector3 closestIntersection = Vector3.Zero; Entity closestEntity = null; List <EntityAndIntersection> allEntities = new List <EntityAndIntersection>(); foreach (MovableObject obj in candidates) { // skip if unattached or filtered out by query flags if (!obj.IsAttached || (obj.QueryFlags & queryMask) == 0) { continue; } Entity entity = obj as Entity; if (entity == null) { continue; } // skip if its mesh doesn't have triangles if (entity.Mesh == null || entity.Mesh.TriangleIntersector == null) { continue; } // transform the ray to the space of the mesh Matrix4 inverseTransform = entity.ParentNodeFullTransform.Inverse(); Matrix4 inverseWithoutTranslation = inverseTransform; inverseWithoutTranslation.Translation = Vector3.Zero; Vector3 transformedOrigin = inverseTransform * ray.Origin; Ray transformedRay = new Ray(transformedOrigin, (inverseWithoutTranslation * ray.Direction).ToNormalized()); // test the intersection against the world bounding box of the entity Vector3 untransformedIntersection; if (entity.Mesh.TriangleIntersector.ClosestRayIntersection(transformedRay, Vector3.Zero, nearDistance, out untransformedIntersection)) { Vector3 intersection = entity.ParentNodeFullTransform * untransformedIntersection; if (allTrianglesQuery) { allEntities.Add(new EntityAndIntersection(entity, intersection)); } float distance = (ray.Origin - intersection).Length; if (firstTriangleQuery && distance < closestDistance) { closestDistance = distance; closestEntity = entity; closestIntersection = intersection; } } } if (firstTriangleQuery && closestEntity != null) { frag = new SceneQuery.WorldFragment(); fragmentList.Add(frag); frag.FragmentType = WorldFragmentType.SingleIntersection; frag.SingleIntersection = closestIntersection; listener.OnQueryResult(frag, closestDistance); } else if (allTrianglesQuery && allEntities.Count > 0) { allEntities.Sort(distanceToCameraCompare); foreach (EntityAndIntersection ei in allEntities) { listener.OnQueryResult(ei.entity, (rayOrigin - ei.intersection).Length); } } } if (terrainQuery) { Vector3 ray = Ray.Origin; Vector3 land = getHeightAt(ray); float dist = 0, resFactor = TerrainManager.oneMeter; // find the larger of x and z directions of the ray direction float maxXZ = Math.Max(Math.Abs(Ray.Direction.x), Math.Abs(Ray.Direction.z)); // Only bother if the non-default mask has been set if ((mask & (ulong)RaySceneQueryType.OnexRes) != 0) { if ((mask & (ulong)RaySceneQueryType.TwoxRes) != 0) { resFactor = TerrainManager.oneMeter / 2; } else if ((mask & (ulong)RaySceneQueryType.FourxRes) != 0) { resFactor = TerrainManager.oneMeter / 4; } else if ((mask & (ulong)RaySceneQueryType.EightxRes) != 0) { resFactor = TerrainManager.oneMeter / 8; } } // this scales the res factor so that we move along the ray by a distance that results // in shift of one meter along either the X or Z axis (whichever is longer) resFactor = resFactor / maxXZ; SubPageHeightMap sp; // bool east = false; (unused) // bool south = false; (unused) // if ( Ray.Origin.x > 0 ) // { // east = true; // } // if ( Ray.Origin.z > 0 ) // { // south = true; // } ray = Ray.Origin; sp = TerrainManager.Instance.LookupSubPage(ray); while (sp != null) { SubPageHeightMap newsp; AxisAlignedBox tileBounds = sp.BoundingBox; IntersectResult intersect = MathUtil.Intersects(Ray, tileBounds); if (intersect.Hit) { // step through this tile while ((newsp = TerrainManager.Instance.LookupSubPage(RoundRay(ray))) == sp) { land = getHeightAt(ray); if (ray.y < land.y) { frag = new SceneQuery.WorldFragment(); fragmentList.Add(frag); frag.FragmentType = WorldFragmentType.SingleIntersection; frag.SingleIntersection = land; listener.OnQueryResult(frag, dist); if ((mask & (ulong)RaySceneQueryType.FirstTerrain) != 0) { return; } } ray += Ray.Direction * resFactor; dist += 1 * resFactor; } // if we fall off the end of the above loop without getting a hit, then the hit should be // right at the far edge of the tile, so handle that case. land = getHeightAt(ray); if (ray.y < land.y) { frag = new SceneQuery.WorldFragment(); fragmentList.Add(frag); frag.FragmentType = WorldFragmentType.SingleIntersection; frag.SingleIntersection = land; listener.OnQueryResult(frag, dist); //LogManager.Instance.Write("MVSM:RaySceneQuery:End of tile ray collision"); if ((mask & (ulong)RaySceneQueryType.FirstTerrain) != 0) { return; } } else { //LogManager.Instance.Write("MVSM:RaySceneQuery:End of tile reached without expected intersection"); } } else { // step over this tile while ((newsp = TerrainManager.Instance.LookupSubPage(RoundRay(ray))) == sp) { // XXX - this is not the most efficient method... ray += Ray.Direction * resFactor; dist += 1 * resFactor; } } sp = newsp; } } } }