// For each brush // 1D: // Find surfaces that intersect with ray // Find edges on that surface, if intersection is close enough to edge, find closest point on edge static void FindSnapPointsAlongRay(GameObject[] selection, Vector3 worldRayStart, Vector3 worldRayDirection, List <SurfaceSnap> allSurfaceSnapEvents, List <EdgeSnap> allEdgeSnapEvents, List <VertexSnap> allVertexSnapEvents) { if (selection == null || selection.Length == 0) { return; } if (allSurfaceSnapEvents == null && allEdgeSnapEvents == null && allVertexSnapEvents == null) { return; } s_FoundIntersections.Clear(); if (ChiselSceneQuery.FindFirstWorldIntersection(s_FoundIntersections, worldRayStart - worldRayDirection, worldRayStart + worldRayDirection, filter: selection)) { if (allSurfaceSnapEvents != null) { for (int i = 0; i < s_FoundIntersections.Count; i++) { var intersection = s_FoundIntersections[i]; allSurfaceSnapEvents.Add(new SurfaceSnap { brush = intersection.brushIntersection.brush, surfaceIndex = intersection.brushIntersection.surfaceIndex, intersection = intersection.worldPlaneIntersection, normal = intersection.worldPlane.normal, }); } } } if (allEdgeSnapEvents == null && allVertexSnapEvents == null) { return; } foreach (var intersection in s_FoundIntersections) { var csgBrush = intersection.brushIntersection.brush; var csgTree = intersection.brushIntersection.tree; var brushMeshBlob = BrushMeshManager.GetBrushMeshBlob(csgBrush.BrushMesh); if (!brushMeshBlob.IsCreated) { continue; } ref var brushMesh = ref brushMeshBlob.Value; ref var polygons = ref brushMesh.polygons;
internal static GameObject PickNodeOrGameObject(Camera camera, Vector2 pickposition, int layers, ref GameObject[] ignore, ref GameObject[] filter, out ChiselModel model, out ChiselNode node, out CSGTreeBrushIntersection intersection) { TryNextSelection: intersection = new CSGTreeBrushIntersection { surfaceID = -1, brushUserID = -1 }; model = null; node = null; Material sharedMaterial; var gameObject = PickModel(camera, pickposition, layers, ref ignore, ref filter, out model, out sharedMaterial); if (object.Equals(gameObject, null)) { return(null); } if (model) { int filterLayerParameter0 = (sharedMaterial) ? sharedMaterial.GetInstanceID() : 0; { var worldRay = camera.ScreenPointToRay(pickposition); var worldRayStart = worldRay.origin; var worldRayVector = (worldRay.direction * (camera.farClipPlane - camera.nearClipPlane)); var worldRayEnd = worldRayStart + worldRayVector; CSGTreeBrushIntersection tempIntersection; if (ChiselSceneQuery.FindFirstWorldIntersection(model, worldRayStart, worldRayEnd, filterLayerParameter0, layers, ignore, filter, out tempIntersection)) { var clickedBrush = tempIntersection.brush; node = CSGNodeHierarchyManager.FindCSGNodeByInstanceID(clickedBrush.UserID); if (node) { if (ignore != null && ignore.Contains(node.gameObject)) { node = null; return(null); } intersection = tempIntersection; return(node.gameObject); } else { node = null; } } } if (ignore == null) { return(null); } ArrayUtility.Add(ref ignore, gameObject); goto TryNextSelection; } if (object.Equals(gameObject, null)) { return(null); } if (ignore != null && ignore.Contains(gameObject)) { return(null); } return(gameObject); }
static GameObject PickNodeOrGameObject(Camera camera, Vector2 pickposition, int layers, ref GameObject[] ignore, ref GameObject[] filter, out ChiselModel model, out ChiselNode node, out ChiselIntersection intersection) { TryNextSelection: intersection = ChiselIntersection.None; node = null; Material sharedMaterial; var gameObject = PickModelOrGameObject(camera, pickposition, layers, ref ignore, ref filter, out model, out sharedMaterial); if (object.Equals(gameObject, null)) { return(null); } if (ChiselGeneratedComponentManager.IsValidModelToBeSelected(model)) { int filterLayerParameter0 = (sharedMaterial) ? sharedMaterial.GetInstanceID() : 0; { var worldRay = camera.ScreenPointToRay(pickposition); var worldRayStart = worldRay.origin; var worldRayVector = (worldRay.direction * (camera.farClipPlane - camera.nearClipPlane)); var worldRayEnd = worldRayStart + worldRayVector; if (ChiselSceneQuery.FindFirstWorldIntersection(model, worldRayStart, worldRayEnd, filterLayerParameter0, layers, ignore, filter, out var tempIntersection)) { node = tempIntersection.node; if (node) { if (ignore != null && ignore.Contains(node.gameObject)) { node = null; return(null); } intersection = tempIntersection; return(node.gameObject); } else { node = null; } } } if (ignore == null) { return(null); } ArrayUtility.Add(ref ignore, gameObject); goto TryNextSelection; } if (object.Equals(gameObject, null)) { return(null); } if (ignore != null && ignore.Contains(gameObject)) { return(null); } return(gameObject); }
// For each brush // 1D: // Find surfaces that intersect with ray // Find edges on that surface, if intersection is close enough to edge, find closest point on edge static void FindSnapPointsAlongRay(GameObject[] selection, Vector3 worldRayStart, Vector3 worldRayDirection, List <SurfaceSnap> allSurfaceSnapEvents, List <EdgeSnap> allEdgeSnapEvents, List <VertexSnap> allVertexSnapEvents) { if (selection == null || selection.Length == 0) { return; } if (allSurfaceSnapEvents == null && allEdgeSnapEvents == null && allVertexSnapEvents == null) { return; } s_FoundIntersections.Clear(); if (ChiselSceneQuery.FindFirstWorldIntersection(s_FoundIntersections, worldRayStart - worldRayDirection, worldRayStart + worldRayDirection, filter: selection)) { if (allSurfaceSnapEvents != null) { for (int i = 0; i < s_FoundIntersections.Count; i++) { var intersection = s_FoundIntersections[i]; allSurfaceSnapEvents.Add(new SurfaceSnap { brush = intersection.brushIntersection.brush, surfaceIndex = intersection.brushIntersection.surfaceIndex, intersection = intersection.worldPlaneIntersection, normal = intersection.worldPlane.normal, }); } } } if (allEdgeSnapEvents == null && allVertexSnapEvents == null) { return; } foreach (var intersection in s_FoundIntersections) { var csgBrush = intersection.brushIntersection.brush; var csgTree = intersection.brushIntersection.tree; var brushMesh = BrushMeshManager.GetBrushMesh(csgBrush.BrushMesh); var polygons = brushMesh.polygons; var halfEdges = brushMesh.halfEdges; var vertices = brushMesh.vertices; var halfEdgePolygonIndices = brushMesh.halfEdgePolygonIndices; var model = ChiselNodeHierarchyManager.FindChiselNodeByInstanceID(csgTree.UserID) as ChiselModel; var worldToNode = csgBrush.TreeToNodeSpaceMatrix * model.hierarchyItem.WorldToLocalMatrix; var nodeToWorld = model.hierarchyItem.LocalToWorldMatrix * csgBrush.NodeToTreeSpaceMatrix; var brushRayStart = worldToNode.MultiplyPoint(worldRayStart); var brushRayDirection = worldToNode.MultiplyVector(worldRayDirection).normalized; var surfaceIndex = intersection.brushIntersection.surfaceIndex; var polygon = polygons[surfaceIndex]; var firstEdge = polygon.firstEdge; var lastEdge = firstEdge + polygon.edgeCount; for (int e0 = lastEdge - 1, e1 = firstEdge; e1 < lastEdge; e0 = e1, e1++) { var i0 = halfEdges[e0].vertexIndex; var i1 = halfEdges[e1].vertexIndex; var v0 = vertices[i0]; var v1 = vertices[i1]; var result = ClosestPointsBetweenTwoLines(brushRayStart, brushRayDirection, v0, v1, out Vector3 A, out Vector3 B); if (result == ClosestLineResult.None) { continue; } if (result == ClosestLineResult.Aligned) { // TODO: draw edge as being intersecting if we're on the edge right now continue; } var dist = (A - B).magnitude; if (dist > kEdgeDistanceEpsilon) { continue; } if (allVertexSnapEvents != null) { var vertDist = ((Vector3)v0 - B).magnitude; if (vertDist < kVertexDistanceEpsilon) { allVertexSnapEvents.Add(new VertexSnap { brush = csgBrush, surfaceIndex = surfaceIndex, vertexIndex = i0, intersection = nodeToWorld.MultiplyPoint(v0) }); } vertDist = ((Vector3)v1 - B).magnitude; if (vertDist < kVertexDistanceEpsilon) { allVertexSnapEvents.Add(new VertexSnap { brush = csgBrush, surfaceIndex = surfaceIndex, vertexIndex = i1, intersection = nodeToWorld.MultiplyPoint(v1) }); } } if (allEdgeSnapEvents != null) { allEdgeSnapEvents.Add(new EdgeSnap { brush = csgBrush, surfaceIndex0 = surfaceIndex, surfaceIndex1 = halfEdgePolygonIndices[halfEdges[e1].twinIndex], vertexIndex0 = i0, vertexIndex1 = i1, intersection = nodeToWorld.MultiplyPoint(B), from = nodeToWorld.MultiplyPoint(v0), to = nodeToWorld.MultiplyPoint(v1) }); } } } }