Esempio n. 1
0
        /// <summary>
        /// Reverses the roles of vertices and faces, as when taking the dual of a polyhedron.
        /// </summary>
        public virtual void MakeDual()
        {
            if (firstExternalFaceIndex < faceFirstEdgeIndices.Length)
            {
                throw new InvalidOperationException("A dual topology cannot be derived from a topology with external faces.");
            }

            GeneralUtility.Swap(ref vertexNeighborCounts, ref faceNeighborCounts);
            GeneralUtility.Swap(ref vertexFirstEdgeIndices, ref faceFirstEdgeIndices);

            firstExternalFaceIndex = faceFirstEdgeIndices.Length;

            var dualEdgeData = new EdgeData[edgeData.Length];

            for (int i = 0; i < edgeData.Length; ++i)
            {
                // Edges rotate clockwise to point at next faces becoming far vertices, with their
                // side toward far vertices becoming prev faces.
                dualEdgeData[i] = new EdgeData(
                    edgeData[i].twin,                                // twin remains the same
                    edgeData[edgeData[edgeData[i].twin].fNext].twin, // vNext becomes twin of vPrev, where vPrev is the fNext of twin
                    edgeData[i].vNext,                               // fNext becomes what vNext had been
                    edgeData[edgeData[i].twin].face,                 // far vertex becomes what had been next face
                    edgeData[i].vertex);                             // prev face becomes what had been far vertex
            }
            edgeData = dualEdgeData;

            // Due to rotations, face data (which had been vertex data) still points to the same edges,
            // but vertex data (which had been face data) is now backwards, pointing to edges which
            // point back at the vertex; this needs to be reversed by setting first edges to their twins.
            for (int i = 0; i < vertexFirstEdgeIndices.Length; ++i)
            {
                vertexFirstEdgeIndices[i] = edgeData[vertexFirstEdgeIndices[i]].twin;
            }
        }
Esempio n. 2
0
 private void BubbleUp(int index)
 {
     while (index > 0)
     {
         var parentIndex = (index - 1) / 2;
         if (AreOrdered(_heap[parentIndex], _heap[index]))
         {
             break;
         }
         GeneralUtility.Swap(ref _heap[index], ref _heap[parentIndex]);
         index = parentIndex;
     }
 }
Esempio n. 3
0
        private void PickChange(Vector2 mousePosition)
        {
            GeneralUtility.DisableAndThrowOnUnassignedReference(this, partitioning, "The FaceSpatialPartitioningPicker component requires a reference to a UniversalFaceSpatialPartitioning scriptable object.  Either create a saved asset using generators available in the Assets/Create/Topology menu, or create and assign one at runtime before the picker's Start() event runs.");

            var ray  = Geometry.InverseTransformRay(transform, camera.ScreenPointToRay(mousePosition));
            var face = partitioning.FindFace(ray);

            if (face && _currentFace != face)
            {
                var previousFace = _currentFace;
                _currentFace = face;
                OnPickChange.Invoke(previousFace, face);
            }
        }
Esempio n. 4
0
        private void PickStart(Vector2 mousePosition, int button)
        {
            GeneralUtility.DisableAndThrowOnUnassignedReference(this, partitioning, "The FaceSpatialPartitioningPicker component requires a reference to a UniversalFaceSpatialPartitioning scriptable object.  Either create a saved asset using generators available in the Assets/Create/Topology menu, or create and assign one at runtime before the picker's Start() event runs.");

            var ray       = Geometry.InverseTransformRay(transform, camera.ScreenPointToRay(mousePosition));
            var startFace = partitioning.FindFace(ray);

            if (startFace)
            {
                _currentFace     = startFace;
                _picking[button] = true;
                OnPickStart.Invoke(startFace, button);
            }
            else
            {
                _picking[button] = false;
                _currentFace     = Topology.Face.none;
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Resets the current grid surface with new values for the tile shape and arrangement, origin, orientation, wrapping behavior, and grid size.
        /// </summary>
        /// <param name="hexDescriptor">The descriptor structure with details about the shape and arrangement of hexagonal tiles.</param>
        /// <param name="origin">The origin of the plane.</param>
        /// <param name="orientation">The orientation of the plane.</param>
        /// <param name="isAxis0Wrapped">Indicates whether the first axis exhibits wrap-around behavior at the grid boundaries.</param>
        /// <param name="isAxis1Wrapped">Indicates whether the second axis exhibits wrap-around behavior at the grid boundaries.</param>
        /// <param name="size">The size of the grid, in terms of the number of tiles along the first and second axes of the surface..</param>
        /// <returns>A reference to the current surface.</returns>
        public RectangularHexGrid Reset(HexGridDescriptor hexDescriptor, Vector3 origin, Quaternion orientation, bool isAxis0Wrapped, bool isAxis1Wrapped, IntVector2 size)
        {
            midpoint    = hexDescriptor.midpoint;
            majorCorner = hexDescriptor.majorCorner;
            minorCorner = hexDescriptor.minorCorner;

            midpointIsFirstAxis = hexDescriptor.midpointIsFirstAxis;
            axisStyle           = hexDescriptor.axisStyle;

            _originIsObtuse = Vector2.Dot(midpoint, minorCorner) < Vector2.Dot(midpoint, majorCorner);

            if (axisStyle == HexGridAxisStyles.Straight)
            {
                _faceAxis0 = midpoint * 2f;
                _faceAxis1 = majorCorner + minorCorner;
            }
            else
            {
                _faceAxis0 = midpoint * 2f;

                if (_originIsObtuse)
                {
                    _faceAxis1 = majorCorner + minorCorner + midpoint;
                }
                else
                {
                    _faceAxis1 = majorCorner + minorCorner - midpoint;
                }
            }

            if (!midpointIsFirstAxis)
            {
                GeneralUtility.Swap(ref _faceAxis0, ref _faceAxis1);
            }

            Reset(new WrappableAxis2(_faceAxis0 * size.x, isAxis0Wrapped), new WrappableAxis2(_faceAxis1 * size.y, isAxis1Wrapped), origin, orientation);

            this.size = size;
            topology  = null;
            Initialize();
            return(this);
        }
Esempio n. 6
0
        private void BubbleDown(int index)
        {
            var leftChildIndex  = index * 2 + 1;
            var rightChildIndex = leftChildIndex + 1;

            while (leftChildIndex < _size)
            {
                if (rightChildIndex < _size)
                {
                    if (AreOrdered(_heap[index], _heap[leftChildIndex]) && AreOrdered(_heap[index], _heap[rightChildIndex]))
                    {
                        break;
                    }
                    if (AreOrdered(_heap[leftChildIndex], _heap[rightChildIndex]))
                    {
                        GeneralUtility.Swap(ref _heap[index], ref _heap[leftChildIndex]);
                        index = leftChildIndex;
                    }
                    else
                    {
                        GeneralUtility.Swap(ref _heap[index], ref _heap[rightChildIndex]);
                        index = rightChildIndex;
                    }
                    leftChildIndex  = index * 2 + 1;
                    rightChildIndex = leftChildIndex + 1;
                }
                else
                {
                    if (AreOrdered(_heap[index], _heap[leftChildIndex]))
                    {
                        break;
                    }
                    GeneralUtility.Swap(ref _heap[index], ref _heap[leftChildIndex]);
                    index = leftChildIndex;
                    break;
                }
            }
        }
Esempio n. 7
0
 void Start()
 {
     GeneralUtility.DisableAndThrowOnUnassignedReference(this, camera, "The FaceSpatialPartitioningPicker component requires a reference to a Camera component.");
     _collider = GetComponent <Collider>();
 }