Exemple #1
0
 public XZOrientedQuad3D(XZOrientedQuad3D source)
 {
     Center           = source.Center;
     ModelSpaceXZSize = source.ModelSpaceXZSize;
     Rotation         = source.Rotation;
 }
Exemple #2
0
 public static void RenderXZOrientedQuadBorderLines(XZOrientedQuad3D orientedQuad, Color color)
 {
     RenderLinesBetweenPoints(orientedQuad.GetCornerPoints(), color);
 }
        public void FromXZOrientedQuad(XZOrientedQuad3D orientedQuad)
        {
            float desiredCellSize = ObjectSnapSettings.Get().ObjectColliderSnapSurfaceGridSettings.DesiredCellSize;

            // As a first step, ensure that the grid sits in the middle of the quad and has the same orientation
            Grid.SetOriginPosition(orientedQuad.GetOriginPosition());
            Grid.SetRotation(orientedQuad.GetRotation());

            Vector2 quadSize  = orientedQuad.ScaledXZSize;
            float   cellSizeX = desiredCellSize;
            float   cellSizeZ = desiredCellSize;

            int cellCountX, cellCountZ;

            if (cellSizeX > quadSize.x)
            {
                cellSizeX  = quadSize.x;
                cellCountX = 1;
            }
            else
            {
                // Adjust the cell size in such a way that we get an integer number of cells along each dimension
                float divisionResult = quadSize.x / cellSizeX;
                cellCountX = (int)divisionResult;
                float fractionalValue = divisionResult - cellCountX;
                if (fractionalValue != 0.0f)
                {
                    cellSizeX += (fractionalValue / cellCountX) * desiredCellSize;                              // If the fractional value is not 0, it means the cell size needs to be adjusted
                }
                // in such a way that the calculated number of cells ('cellCountX') covers the entire
                // quad area along the corresponding dimension.
            }

            if (cellSizeZ > quadSize.y)
            {
                cellSizeZ  = quadSize.y;
                cellCountZ = 1;
            }
            else
            {
                float divisionResult = quadSize.y / cellSizeZ;
                cellCountZ = (int)divisionResult;
                float fractionalValue = divisionResult - cellCountZ;
                if (fractionalValue != 0.0f)
                {
                    cellSizeZ += (fractionalValue / cellCountZ) * desiredCellSize;
                }
            }

            // Make sure the cell size is not larger than the quad
            if (cellSizeX > quadSize.x)
            {
                cellSizeX = quadSize.x;
            }
            if (cellSizeZ > quadSize.y)
            {
                cellSizeZ = quadSize.y;
            }

            Grid.CellSizeSettings.CellSizeX = cellSizeX;
            Grid.CellSizeSettings.CellSizeZ = cellSizeZ;

            // Store the cell count without taking into consideration the cell which sits at the origin of the grid
            int cellCountXNoMiddle = cellCountX - 1;
            int cellCountZNoMiddle = cellCountZ - 1;

            if (cellCountXNoMiddle % 2 == 0)
            {
                int halfCount = cellCountXNoMiddle / 2;
                Grid.DimensionSettings.FiniteDimensionSettings.XAxisCellIndexRange.Min = -halfCount;
                Grid.DimensionSettings.FiniteDimensionSettings.XAxisCellIndexRange.Max = halfCount;
            }
            else
            {
                int halfCount = cellCountXNoMiddle / 2;
                Grid.DimensionSettings.FiniteDimensionSettings.XAxisCellIndexRange.Min = -halfCount;
                Grid.DimensionSettings.FiniteDimensionSettings.XAxisCellIndexRange.Max = halfCount + 1;
            }

            if (cellCountZNoMiddle % 2 == 0)
            {
                int halfCount = cellCountZNoMiddle / 2;
                Grid.DimensionSettings.FiniteDimensionSettings.ZAxisCellIndexRange.Min = -halfCount;
                Grid.DimensionSettings.FiniteDimensionSettings.ZAxisCellIndexRange.Max = halfCount;
            }
            else
            {
                int halfCount = cellCountZNoMiddle / 2;
                Grid.DimensionSettings.FiniteDimensionSettings.ZAxisCellIndexRange.Min = -halfCount;
                Grid.DimensionSettings.FiniteDimensionSettings.ZAxisCellIndexRange.Max = halfCount + 1;
            }

            // We need to make sure that the grid nicely sits within the boundaries of the quad. In order to do this, we will
            // align the top left corners of the quad and the grid's top left cell.
            Vector3          quadTopLeftCornerPoint     = orientedQuad.GetCornerPoints()[(int)XZOrientedQuad3DCornerPoint.TopLeft];
            XZOrientedQuad3D topLeftCellQuad            = Grid.CalculateCellQuad(Grid.DimensionSettings.FiniteDimensionSettings.XAxisCellIndexRange.Min, Grid.DimensionSettings.FiniteDimensionSettings.ZAxisCellIndexRange.Max);
            Vector3          cellQuadTopLeftCornerPoint = topLeftCellQuad.GetCornerPoints()[(int)XZOrientedQuad3DCornerPoint.TopLeft];
            Vector3          gridOriginMoveVector       = quadTopLeftCornerPoint - cellQuadTopLeftCornerPoint;

            Grid.Translate(gridOriginMoveVector);
        }
        public void UpdateForMouseMovement()
        {
            if (!_isActive)
            {
                return;
            }

            if (MouseButtonStates.Instance.IsMouseButtonDown(MouseButton.Left))
            {
                _state = ObjectVertexSnapSessionState.SnapToDestination;
            }
            else
            {
                _state = ObjectVertexSnapSessionState.SelectSourceVertex;
            }

            if (_state == ObjectVertexSnapSessionState.SelectSourceVertex)
            {
                if (_sourceObjects == null || _sourceObjects.Count == 0)
                {
                    _objectMask.ObjectCollectionMask.UnmaskAll();
                    MouseCursorRayHit cursorRayHit = GetCursorRayHit();
                    if (cursorRayHit.WasAnObjectHit)
                    {
                        GameObjectRayHit objectRayHit = cursorRayHit.ClosestObjectRayHit;
                        MeshRayHit       meshRayHit   = objectRayHit.ObjectMeshHit;
                        if (meshRayHit != null)
                        {
                            Octave3DMesh octaveMesh = meshRayHit.HitMesh;

                            Triangle3D sourceTriangle = octaveMesh.GetTriangle(meshRayHit.HitTriangleIndex);
                            sourceTriangle.TransformPoints(objectRayHit.HitObject.transform.localToWorldMatrix);

                            _sourceVertex = sourceTriangle.GetPointClosestToPoint(meshRayHit.HitPoint);
                            _sourceObject = objectRayHit.HitObject;
                            _objectMask.ObjectCollectionMask.Mask(_sourceObject.transform.root.gameObject.GetAllChildrenIncludingSelf());
                        }
                        else
                        {
                            SpriteRenderer spriteRenderer = objectRayHit.HitObject.GetComponent <SpriteRenderer>();
                            if (spriteRenderer != null)
                            {
                                _sourceObject = objectRayHit.HitObject;
                                _sourceVertex = Vector3Extensions.GetClosestPointToPoint(objectRayHit.ObjectBoxHit.HitBox.GetCenterAndCornerPoints(), objectRayHit.HitPoint);
                                _objectMask.ObjectCollectionMask.Mask(_sourceObject.transform.root.gameObject.GetAllChildrenIncludingSelf());
                            }
                        }
                    }
                }
                else
                {
                    MouseCursorRayHit cursorRayHit = GetCursorRayHit();
                    if (cursorRayHit.WasAnObjectHit)
                    {
                        GameObjectRayHit objectRayHit = cursorRayHit.ClosestObjectRayHit;
                        MeshRayHit       meshRayHit   = objectRayHit.ObjectMeshHit;
                        if (meshRayHit != null)
                        {
                            Octave3DMesh octaveMesh = meshRayHit.HitMesh;

                            Triangle3D sourceTriangle = octaveMesh.GetTriangle(meshRayHit.HitTriangleIndex);
                            sourceTriangle.TransformPoints(objectRayHit.HitObject.transform.localToWorldMatrix);
                            _sourceVertex = sourceTriangle.GetPointClosestToPoint(meshRayHit.HitPoint);
                        }
                        else
                        {
                            SpriteRenderer spriteRenderer = objectRayHit.HitObject.GetComponent <SpriteRenderer>();
                            if (spriteRenderer != null)
                            {
                                _sourceVertex = Vector3Extensions.GetClosestPointToPoint(objectRayHit.ObjectBoxHit.HitBox.GetCenterAndCornerPoints(), objectRayHit.HitPoint);
                            }
                        }
                    }

                    foreach (var parent in _sourceParents)
                    {
                        _objectMask.ObjectCollectionMask.Mask(parent.GetAllChildrenIncludingSelf());
                    }
                }
            }
            else
            {
                MouseCursorRayHit cursorRayHit = GetCursorRayHit();
                if (cursorRayHit.WasAnythingHit)
                {
                    bool useGridCellHit = false;
                    if (!cursorRayHit.WasAnObjectHit)
                    {
                        useGridCellHit = true;
                    }
                    else
                    if (cursorRayHit.WasAnObjectHit && cursorRayHit.WasACellHit)
                    {
                        float gridCellHitEnter = cursorRayHit.GridCellRayHit.HitEnter;
                        float objectHitEnter   = cursorRayHit.ClosestObjectRayHit.HitEnter;
                        if (gridCellHitEnter < Mathf.Max(0.0f, (objectHitEnter - 1e-3f)))
                        {
                            useGridCellHit = true;
                        }
                    }

                    if (useGridCellHit)
                    {
                        XZGridCell       hitCell  = cursorRayHit.GridCellRayHit.HitCell;
                        XZOrientedQuad3D cellQuad = hitCell.Quad;

                        _destinationObject   = null;
                        _destinationGridCell = hitCell;

                        _snapPosition = cellQuad.GetPointClosestToPoint(cursorRayHit.GridCellRayHit.HitPoint, true);
                        SnapToDestination();
                    }
                    else
                    {
                        GameObjectRayHit objectRayHit = cursorRayHit.ClosestObjectRayHit;
                        MeshRayHit       meshRayHit   = objectRayHit.ObjectMeshHit;
                        if (meshRayHit != null)
                        {
                            _destinationObject = objectRayHit.HitObject;
                            Triangle3D destinationTriangle = meshRayHit.HitMesh.GetTriangle(meshRayHit.HitTriangleIndex);
                            destinationTriangle.TransformPoints(_destinationObject.transform.localToWorldMatrix);
                            _destinationGridCell = null;

                            _snapPosition = destinationTriangle.GetPointClosestToPoint(meshRayHit.HitPoint);
                            SnapToDestination();
                        }
                        else
                        {
                            SpriteRenderer spriteRenderer = objectRayHit.HitObject.GetComponent <SpriteRenderer>();
                            if (spriteRenderer != null)
                            {
                                _destinationGridCell = null;
                                _destinationObject   = objectRayHit.HitObject;

                                _snapPosition = Vector3Extensions.GetClosestPointToPoint(objectRayHit.ObjectBoxHit.HitBox.GetCenterAndCornerPoints(), objectRayHit.HitPoint);
                                SnapToDestination();
                            }
                        }
                    }
                }
            }
        }