Beispiel #1
0
        private void KeepSnappedHierarchyInSnapSurfaceArea(GameObject hierarchyRoot, ProjectedBoxFacePivotPoints projectedHierarchyBoxFacePivotPoints)
        {
            OrientedBox      hierarchyWorldOrientedBox = hierarchyRoot.GetHierarchyWorldOrientedBox();
            List <Vector3>   worldBoxPoints            = hierarchyWorldOrientedBox.GetCenterAndCornerPoints();
            XZOrientedQuad3D snapSurfaceQuad           = _objectSnapSurface.SurfaceQuad;

            List <Plane>   quadSegmentPlanes = snapSurfaceQuad.GetBoundarySegmentPlanesFacingOutward();
            List <Vector3> pushVectors       = new List <Vector3>(quadSegmentPlanes.Count);

            // All box points which are in front of the surface quad's plane are outside
            // the surface so we will have to push them back.
            for (int segmentPlaneIndex = 0; segmentPlaneIndex < quadSegmentPlanes.Count; ++segmentPlaneIndex)
            {
                Plane   segmentPlane = quadSegmentPlanes[segmentPlaneIndex];
                Vector3 furthestPointInFront;
                if (segmentPlane.GetFurthestPointInFront(worldBoxPoints, out furthestPointInFront))
                {
                    Vector3 projectedPoint = segmentPlane.ProjectPoint(furthestPointInFront);
                    pushVectors.Add(projectedPoint - furthestPointInFront);
                }
            }

            Transform hierarchyRootTransform = hierarchyRoot.transform;

            foreach (Vector3 pushVector in pushVectors)
            {
                hierarchyRootTransform.position += pushVector;
                projectedHierarchyBoxFacePivotPoints.MovePoints(pushVector);
            }
        }
Beispiel #2
0
        private void RenderAllPivotPoints(ProjectedBoxFacePivotPoints projectedBoxFacePivotPoints, ObjectPivotPointsRenderSettings pivotPointsRenderSettings)
        {
            List <Vector3> allPivotPoints = projectedBoxFacePivotPoints.AllPoints;

            if (allPivotPoints.Count != 0)
            {
                ProjectedBoxFacePivotPointsRenderSettings renderSettings = pivotPointsRenderSettings.ProjectedBoxFacePivotPointsRenderSettings;
                IPivotPointRenderer objectPivotPointRenderer             = PivotPointRendererFactory.Create(pivotPointsRenderSettings.ShapeType);

                Color activePivotPointFillColor         = renderSettings.ActivePivotPointRenderSettings.FillColor;
                Color inactivePivotPointFillColor       = renderSettings.InactivePivotPointRenderSettings.FillColor;
                Color activePivotPointBorderLineColor   = renderSettings.ActivePivotPointRenderSettings.BorderLineColor;
                Color inactivePivotPointBorderLineColor = renderSettings.InactivePivotPointRenderSettings.BorderLineColor;

                float pivotPointSizeInPixels  = pivotPointsRenderSettings.PivotPointSizeInPixels;
                float activePivotPointScale   = renderSettings.ActivePivotPointRenderSettings.Scale;
                float inactivePivotPointScale = renderSettings.InactivePivotPointRenderSettings.Scale;

                if (renderSettings.InactivePivotPointRenderSettings.IsVisible)
                {
                    for (int pivotPointIndex = 0; pivotPointIndex < allPivotPoints.Count; ++pivotPointIndex)
                    {
                        if (pivotPointIndex != projectedBoxFacePivotPoints.IndexOfActivePoint)
                        {
                            objectPivotPointRenderer.Render(allPivotPoints[pivotPointIndex], inactivePivotPointFillColor, inactivePivotPointBorderLineColor, pivotPointSizeInPixels * inactivePivotPointScale);
                        }
                    }
                }

                if (renderSettings.ActivePivotPointRenderSettings.IsVisible)
                {
                    objectPivotPointRenderer.Render(allPivotPoints[projectedBoxFacePivotPoints.IndexOfActivePoint], activePivotPointFillColor, activePivotPointBorderLineColor, pivotPointSizeInPixels * activePivotPointScale);
                }
            }
        }
Beispiel #3
0
 public void SnapHierarchyToNearbyObjects(GameObject hierarchyRoot, ProjectedBoxFacePivotPoints projectedBoxFacePivotPoints)
 {
     Object2ObjectSnap.SnapResult snapResult = Object2ObjectSnap.Snap(hierarchyRoot, Settings.ObjectToObjectSnapEpsilon, ObjectSnapping.Get().ObjectSnapMask.ObjectCollectionMask.GetAllMaskedGameObjects());
     if (snapResult.WasSnapped)
     {
         projectedBoxFacePivotPoints.MovePoints(snapResult.SnapDestination - snapResult.SnapPivot);
     }
 }
        public ProjectedBoxFacePivotPoints TakeSnapshot()
        {
            var projectedBoxFacePivotPoints = new ProjectedBoxFacePivotPoints();

            projectedBoxFacePivotPoints._pivotPointCollection   = _pivotPointCollection.TakeSnapshot();
            projectedBoxFacePivotPoints._unprojectedPivotPoints = GetUnprojectedPivotPoints();
            projectedBoxFacePivotPoints._pointsPlane            = PointsPlane;

            return(projectedBoxFacePivotPoints);
        }
Beispiel #5
0
 public void RenderGizmos(ProjectedBoxFacePivotPoints projectedBoxFacePivotPoints, ObjectPivotPointsRenderSettings pivotPointsRenderSettings)
 {
     if (ObjectPlacementGuide.ExistsInSceneAndIsActive &&
         SceneViewCamera.Instance.IsGameObjectHierarchyVisible(ObjectPlacementGuide.SceneObject))
     {
         RenderPivotPointConnectionLines(projectedBoxFacePivotPoints, pivotPointsRenderSettings);
         RenderPivotPointProjectionLines(projectedBoxFacePivotPoints, pivotPointsRenderSettings);
         RenderAllPivotPoints(projectedBoxFacePivotPoints, pivotPointsRenderSettings);
     }
 }
Beispiel #6
0
        private void RenderPivotPointConnectionLines(ProjectedBoxFacePivotPoints projectedBoxFacePivotPoints, ObjectPivotPointsRenderSettings pivotPointsRenderSettings)
        {
            ProjectedBoxFacePivotPointsRenderSettings renderSettings = pivotPointsRenderSettings.ProjectedBoxFacePivotPointsRenderSettings;

            if (renderSettings.RenderPivotPointConnectionLines)
            {
                List <Vector3> pivotPointsNoCenter = projectedBoxFacePivotPoints.GetAllPointsExcludingCenter();
                if (pivotPointsNoCenter.Count != 0)
                {
                    GizmosEx.RenderLinesBetweenPoints(pivotPointsNoCenter, renderSettings.PivotPointConnectionLineColor);
                }
            }
        }
Beispiel #7
0
        public void SnapObjectHierarchy(GameObject hierarchyRoot, ProjectedBoxFacePivotPoints projectedBoxFacePivotPoints, float offsetFromSnapSurface)
        {
            _objectSnapSurface.FromMouseCursorRayHit(GetCursorRayHit());
            if (_objectSnapSurface.IsValid)
            {
                OrientedBox hierarchyWorldOrientedBox = hierarchyRoot.GetHierarchyWorldOrientedBox();
                if (!hierarchyWorldOrientedBox.IsValid())
                {
                    return;
                }

                Vector3 pivotPoint = projectedBoxFacePivotPoints.ActivePoint;
                if (Settings.UseOriginalPivot)
                {
                    pivotPoint = hierarchyRoot.transform.position;
                }

                if (Settings.SnapToCursorHitPoint || Settings.EnableObjectToObjectSnap)
                {
                    SnapObjectHierarchyPosition(hierarchyRoot, pivotPoint, _objectSnapSurface.CursorPickPoint, projectedBoxFacePivotPoints, offsetFromSnapSurface);
                }
                else
                {
                    if (_objectSnapSurface.SurfaceType == SnapSurfaceType.GridCell && Settings.SnapCenterToCenterForXZGrid && !Settings.UseOriginalPivot)
                    {
                        SnapObjectHierarchyToCenterOfSnapSurface(hierarchyRoot, projectedBoxFacePivotPoints.CenterPoint, projectedBoxFacePivotPoints, offsetFromSnapSurface);
                    }
                    else
                    if (_objectSnapSurface.SurfaceType == SnapSurfaceType.ObjectCollider && Settings.SnapCenterToCenterForObjectSurface && !Settings.UseOriginalPivot)
                    {
                        SnapObjectHierarchyToCenterOfSnapSurface(hierarchyRoot, projectedBoxFacePivotPoints.CenterPoint, projectedBoxFacePivotPoints, offsetFromSnapSurface);
                    }
                    else
                    {
                        SnapObjectHierarchyPosition(hierarchyRoot, pivotPoint, _objectSnapSurface.GetSnapDestinationPointClosestToCursorPickPoint(), projectedBoxFacePivotPoints, offsetFromSnapSurface);
                    }
                    if (AllShortcutCombos.Instance.KeepSnappedHierarchyInSnapSurfaceArea.IsActive())
                    {
                        KeepSnappedHierarchyInSnapSurfaceArea(hierarchyRoot, projectedBoxFacePivotPoints);
                    }
                }

                if (Settings.EnableObjectToObjectSnap)
                {
                    SnapHierarchyToNearbyObjects(hierarchyRoot, projectedBoxFacePivotPoints);
                }
            }
        }
Beispiel #8
0
        private void RenderPivotPointProjectionLines(ProjectedBoxFacePivotPoints projectedBoxFacePivotPoints, ObjectPivotPointsRenderSettings pivotPointsRenderSettings)
        {
            ProjectedBoxFacePivotPointsRenderSettings renderSettings = pivotPointsRenderSettings.ProjectedBoxFacePivotPointsRenderSettings;

            if (renderSettings.RenderProjectionLines)
            {
                List <Vector3> allPivotPoints = projectedBoxFacePivotPoints.AllPoints;
                if (allPivotPoints.Count != 0)
                {
                    Color projectionLineColor = renderSettings.ProjectionLineColor;

                    List <Vector3> unprojectedPoints = projectedBoxFacePivotPoints.GetUnprojectedPivotPoints();
                    for (int pointIndex = 0; pointIndex < unprojectedPoints.Count; ++pointIndex)
                    {
                        GizmosEx.RenderLine(allPivotPoints[pointIndex], unprojectedPoints[pointIndex], projectionLineColor);
                    }
                }
            }
        }
Beispiel #9
0
        public void UpdateProjectedBoxFacePivotPoints(GameObject hierarchyRoot, ProjectedBoxFacePivotPoints projectedBoxFacePivotPoints, bool keepCurrentSnapSurface)
        {
            OrientedBox hierarchyWorldOrientedBox = hierarchyRoot.GetHierarchyWorldOrientedBox();

            if (!hierarchyWorldOrientedBox.IsValid())
            {
                return;
            }

            if (keepCurrentSnapSurface)
            {
                if (!_objectSnapSurface.IsValid)
                {
                    return;
                }
                projectedBoxFacePivotPoints.FromOrientedBoxAndSnapSurface(hierarchyWorldOrientedBox, _objectSnapSurface);
            }
            else
            {
                _objectSnapSurface.FromMouseCursorRayHit(GetCursorRayHit());
                projectedBoxFacePivotPoints.FromOrientedBoxAndSnapSurface(hierarchyWorldOrientedBox, _objectSnapSurface);
            }
        }
Beispiel #10
0
        private void SnapObjectHierarchyPosition(GameObject hierarchyRoot, Vector3 snapPivotPoint, Vector3 snapDestinationPoint, ProjectedBoxFacePivotPoints projectedBoxFacePivotPoints, float offsetFromSnapSurface)
        {
            snapDestinationPoint += _objectSnapSurface.Plane.normal * offsetFromSnapSurface;

            Transform hierarchyRootTransform = hierarchyRoot.transform;
            Vector3   snapVector             = hierarchyRootTransform.position - snapPivotPoint;

            hierarchyRootTransform.position = snapDestinationPoint + snapVector;
            projectedBoxFacePivotPoints.MovePoints(snapDestinationPoint - snapPivotPoint);
        }
Beispiel #11
0
        public void SnapObjectHierarchyToCenterOfSnapSurface(GameObject hierarchyRoot, Vector3 snapPivotPoint, ProjectedBoxFacePivotPoints projectedBoxFacePivotPoints, float offsetFromSnapSurface)
        {
            _objectSnapSurface.FromMouseCursorRayHit(GetCursorRayHit());
            if (_objectSnapSurface.IsValid)
            {
                OrientedBox hierarchyWorldOrientedBox = hierarchyRoot.GetHierarchyWorldOrientedBox();
                if (!hierarchyWorldOrientedBox.IsValid())
                {
                    return;
                }

                SnapObjectHierarchyPosition(hierarchyRoot, snapPivotPoint, _objectSnapSurface.Center, projectedBoxFacePivotPoints, offsetFromSnapSurface);
            }
        }
Beispiel #12
0
        public void SnapHierarchyToNearbyObjects(GameObject hierarchyRoot, ProjectedBoxFacePivotPoints projectedBoxFacePivotPoints)
        {
            Vector3 chosenSnapDestination = Vector3.zero, chosenSnapPivot = Vector3.zero;
            float   minDistance = float.MaxValue;
            float   snapEpsilon = Settings.ObjectToObjectSnapEpsilon;

            // Snapping will only work if there is at least one mesh object in the hierarchy or at least one sprite renderer
            // with a valid sprite. So we will first get that out of the way. If this condition is not met, we will just return.
            List <GameObject> meshObjectsInHierarchy   = hierarchyRoot.GetHierarchyObjectsWithMesh();
            List <GameObject> spriteObjectsInHierarchy = hierarchyRoot.GetHierarchyObjectsWithSprites();

            if (meshObjectsInHierarchy.Count == 0 && spriteObjectsInHierarchy.Count == 0)
            {
                return;
            }

            // When snapping, we will need to collect the nearby snap destination points (e.g. vertices or box corner points).
            // In order to do this we will perform an overlap test using the hierarchy's world box. The size of the box is
            // increased by 'snapEpsilon' on all axes to account for the snap espilon.
            Box hierarchyWorldBox = hierarchyRoot.GetHierarchyWorldBox();

            if (!hierarchyWorldBox.IsValid())
            {
                return;
            }
            Box hierarchyQueryBox = hierarchyWorldBox;

            hierarchyQueryBox.Size = hierarchyQueryBox.Size + Vector3.one * snapEpsilon;

            // Acquire the nearby objects that contain the possible snap destination points
            List <GameObject> nearbyObjects = Octave3DScene.Get().OverlapBox(hierarchyQueryBox);

            if (nearbyObjects.Count == 0)
            {
                return;
            }

            // If the user chose vertex snapping, we will only continue if we have at least one mesh in our hierarchy.
            // Otherwise we will resort to box snapping.
            if (Settings.ObjectToObjectSnapMode == ObjectToObjectSnapMode.Vertex && meshObjectsInHierarchy.Count != 0)
            {
                foreach (GameObject gameObject in nearbyObjects)
                {
                    Box objectWorldBox = Box.GetInvalid();

                    // We will first attempt to retrieve the mesh's world box
                    Mesh objectMesh    = gameObject.GetMeshFromFilterOrSkinnedMeshRenderer();
                    bool objectHasMesh = objectMesh != null;

                    Octave3DMesh objectOctave3DMesh = Octave3DMeshDatabase.Get().GetOctave3DMesh(objectMesh);
                    if (objectOctave3DMesh == null)
                    {
                        objectHasMesh = false;
                    }
                    if (objectHasMesh)
                    {
                        objectWorldBox = gameObject.GetMeshWorldBox();
                    }

                    // If the world box is still invalid, we will acquire the object's sprite world box.
                    if (objectWorldBox.IsInvalid())
                    {
                        if (gameObject.HasSpriteRendererWithSprite())
                        {
                            objectWorldBox = gameObject.GetNonMeshWorldBox();
                        }
                    }

                    // If at this point the box is still invalid, it most likely means that the object doesn't have
                    // a mesh or a sprite attached to it, so we will go on to the next iteration of the loop.
                    if (objectWorldBox.IsInvalid())
                    {
                        continue;
                    }

                    Box objectQueryBox = objectWorldBox;
                    objectQueryBox.Size += Vector3.one * snapEpsilon;

                    // At this point, we have a valid world box, but we need to check if it comes from a mesh or from
                    // a sprite. If it's from a mesh, we will perform the vertex-to-vertex snap. Otherwise, we will
                    // snap the vertices of all meshes in our hierarchy to the corner points of the sprite.
                    if (objectHasMesh)
                    {
                        // Detect the object vertices which are overlapped by the hierarchy box
                        List <Vector3> objectOverlappedVerts = objectOctave3DMesh.GetOverlappedWorldVerts(hierarchyQueryBox, gameObject.transform.GetWorldMatrix());

                        // Loop through all meshes in the hierarchy
                        foreach (var meshObjInHierarchy in meshObjectsInHierarchy)
                        {
                            Mesh hierarchyMesh = meshObjInHierarchy.GetMeshFromFilterOrSkinnedMeshRenderer();
                            if (hierarchyMesh == null)
                            {
                                continue;
                            }

                            Octave3DMesh hierarchyOctave3DMesh = Octave3DMeshDatabase.Get().GetOctave3DMesh(hierarchyMesh);
                            if (hierarchyOctave3DMesh == null)
                            {
                                continue;
                            }

                            // Detect all vertices inside the mesh which are overlapped by the object's box (inverse operation of what we performed in the
                            // beginning). The idea is to collect all source vertices that could pottentially intersect with each other.
                            List <Vector3> hierarchyMeshOverlappedVerts = hierarchyOctave3DMesh.GetOverlappedWorldVerts(objectQueryBox, meshObjInHierarchy.transform.GetWorldMatrix());
                            foreach (Vector3 hierarchyVertex in hierarchyMeshOverlappedVerts)
                            {
                                foreach (Vector3 objectVertex in objectOverlappedVerts)
                                {
                                    float distance = (hierarchyVertex - objectVertex).magnitude;
                                    if (distance < minDistance)
                                    {
                                        minDistance           = distance;
                                        chosenSnapDestination = objectVertex;
                                        chosenSnapPivot       = hierarchyVertex;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        List <Vector3> spriteWorldCornerPoints = objectWorldBox.GetCornerPoints();
                        foreach (var meshObjInHierarchy in meshObjectsInHierarchy)
                        {
                            Mesh hierarchyMesh = meshObjInHierarchy.GetMeshFromFilterOrSkinnedMeshRenderer();
                            if (hierarchyMesh == null)
                            {
                                continue;
                            }

                            Octave3DMesh hierarchyOctave3DMesh = Octave3DMeshDatabase.Get().GetOctave3DMesh(hierarchyMesh);
                            if (hierarchyOctave3DMesh == null)
                            {
                                continue;
                            }

                            List <Vector3> hierarchyMeshOverlappedVerts = hierarchyOctave3DMesh.GetOverlappedWorldVerts(objectQueryBox, meshObjInHierarchy.transform.GetWorldMatrix());
                            foreach (Vector3 hierarchyVertex in hierarchyMeshOverlappedVerts)
                            {
                                foreach (Vector3 spriteCornerPt in spriteWorldCornerPoints)
                                {
                                    float distance = (hierarchyVertex - spriteCornerPt).magnitude;
                                    if (distance < minDistance)
                                    {
                                        minDistance           = distance;
                                        chosenSnapDestination = spriteCornerPt;
                                        chosenSnapPivot       = hierarchyVertex;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                List <Vector3> hierarchyBoxCornerPoints = hierarchyWorldBox.GetCornerPoints();
                foreach (GameObject gameObject in nearbyObjects)
                {
                    Box objectWorldBox = Box.GetInvalid();

                    Mesh objectMesh = gameObject.GetMeshFromFilterOrSkinnedMeshRenderer();
                    if (objectMesh != null)
                    {
                        objectWorldBox = gameObject.GetMeshWorldBox();
                    }
                    if (objectWorldBox.IsInvalid() && gameObject.HasSpriteRendererWithSprite())
                    {
                        objectWorldBox = gameObject.GetNonMeshWorldBox();
                    }

                    if (objectWorldBox.IsInvalid())
                    {
                        continue;
                    }

                    List <Vector3> worldBoxCornerPoints = objectWorldBox.GetCornerPoints();
                    foreach (Vector3 hierarchyBoxPt in hierarchyBoxCornerPoints)
                    {
                        foreach (Vector3 objectMeshBoxPt in worldBoxCornerPoints)
                        {
                            float distance = (hierarchyBoxPt - objectMeshBoxPt).magnitude;
                            if (distance < minDistance)
                            {
                                minDistance           = distance;
                                chosenSnapDestination = objectMeshBoxPt;
                                chosenSnapPivot       = hierarchyBoxPt;
                            }
                        }
                    }
                }
            }

            if (minDistance < snapEpsilon)
            {
                SnapObjectHierarchyPosition(hierarchyRoot, chosenSnapPivot, chosenSnapDestination, projectedBoxFacePivotPoints, 0.0f);
            }
        }