Пример #1
0
        // 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);
        }
Пример #4
0
        // 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)
                        });
                    }
                }
            }
        }