/// <summary> /// Creates a descriptorfor regular hexagonal tiles with a "flat side up" orientation, and the given additional arrangement details. /// </summary> /// <param name="originIsObtuse">Indicates if second tile along the first axis and the second tile along the second axis form an obtuse or acute angle relative to the first tile.</param> /// <param name="axisStyle">The styles with which the axes of the hexagonal grid should be arranged.</param> /// <returns>A hexagonal tile descriptor.</returns> public static HexGridDescriptor CreateSideUp(bool originIsObtuse, HexGridAxisStyles axisStyle) { return(new HexGridDescriptor( new Vector2(0f, 0.5f), new Vector2(_oneOverSqrtThree, 0f), new Vector2(_halfOverSqrtThree, originIsObtuse ? -0.5f : 0.5f), false, axisStyle)); }
/// <summary> /// Creates a descriptorfor regular hexagonal tiles with a "pointy side up" orientation, and the given additional arrangement details. /// </summary> /// <param name="originIsObtuse">Indicates if second tile along the first axis and the second tile along the second axis form an obtuse or acute angle relative to the first tile.</param> /// <param name="axisStyle">The styles with which the axes of the hexagonal grid should be arranged.</param> /// <returns>A hexagonal tile descriptor.</returns> public static HexGridDescriptor CreateCornerUp(bool originIsObtuse, HexGridAxisStyles axisStyle) { return(new HexGridDescriptor( new Vector2(0.5f, 0f), new Vector2(0f, _oneOverSqrtThree), new Vector2(originIsObtuse ? -0.5f : 0.5f, _halfOverSqrtThree), true, axisStyle)); }
/// <summary> /// Creates a descriptor of the shape and arrangment of hexagonal tiles. /// </summary> /// <param name="midpoint">The vector from the center of each hexagonal tile to the midpoint of one of the edges.</param> /// <param name="majorCorner">The vector from the center of each hexagonal tile to the corner one and a half edges away from the defined edge midpoint.</param> /// <param name="minorCorner">The vector from the center of each hexagonal tile to one of the major corner's neighboring corners</param> /// <param name="midpointIsFirstAxis">Indicates if the midpoint vector is to be used as the first axis, or is instead the second axis.</param> /// <param name="axisStyle">The styles with which the axes of the hexagonal grid should be arranged.</param> /// <returns>A hexagonal tile descriptor.</returns> public HexGridDescriptor(Vector2 midpoint, Vector2 majorCorner, Vector2 minorCorner, bool midpointIsFirstAxis, HexGridAxisStyles axisStyle) { this.midpoint = midpoint; this.majorCorner = majorCorner; this.minorCorner = minorCorner; this.midpointIsFirstAxis = midpointIsFirstAxis; this.axisStyle = axisStyle; }
/// <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); }
protected override void Initialize() { // Fields _version = "1.1"; tileType = TileTypes.Quadrilateral; size = new IntVector2(64, 64); SetHexTileShape(HexTileShapes.RegularPointUp, true); SetQuadTileShape(QuadTileShapes.Square, true); isAxis0Wrapped = false; isAxis1Wrapped = false; hexGridAxisStyle = HexGridAxisStyles.Staggered; swapAxes = false; origin = Vector3.zero; rotation = Vector3.zero; // Outputs OutputSlot.CreateOrReset <QuadrilateralSurface>(ref surfaceOutputSlot, this, "Surface"); OutputSlot.CreateOrReset <Topology>(ref topologyOutputSlot, this, "Topology"); OutputSlot.CreateOrResetGrouped <IVertexAttribute <Vector3> >(ref vertexPositionsOutputSlot, this, "Vertex Positions", "Attributes"); }
private void Updgrade_From_1_0_To_1_1() { switch (planarTileShape) { case PlanarTileShapes.Quadrilateral: { tileType = TileTypes.Quadrilateral; Vector3 declaredAxis0; switch (quadGridHorizontalAxisOptions) { case HorizontalAxisOptions.LeftToRight: declaredAxis0 = Vector3.right * horizontalAxisLength; break; case HorizontalAxisOptions.RightToLeft: declaredAxis0 = Vector3.left * horizontalAxisLength; break; case HorizontalAxisOptions.Custom: declaredAxis0 = horizontalAxis; break; default: throw new System.NotImplementedException(); } Vector3 declaredAxis1; switch (quadGridVerticalAxisOptions) { case VerticalAxisOptions.BottomToTop: declaredAxis1 = Vector3.up * verticalAxisLength; break; case VerticalAxisOptions.TopToBottom: declaredAxis1 = Vector3.down * verticalAxisLength; break; case VerticalAxisOptions.NearToFar: declaredAxis1 = Vector3.forward * verticalAxisLength; break; case VerticalAxisOptions.FarToNear: declaredAxis1 = Vector3.back * verticalAxisLength; break; case VerticalAxisOptions.Custom: declaredAxis1 = verticalAxis; break; default: throw new System.NotImplementedException(); } var computedNormal = Vector3.Cross(declaredAxis1, declaredAxis0); Vector3 declaredNormal; switch (normalOptions) { case NormalOptions.Automatic: declaredNormal = computedNormal; break; case NormalOptions.Back: declaredNormal = Vector3.back; break; case NormalOptions.Forward: declaredNormal = Vector3.forward; break; case NormalOptions.Up: declaredNormal = Vector3.up; break; case NormalOptions.Down: declaredNormal = Vector3.down; break; case NormalOptions.Custom: declaredNormal = normal; break; default: throw new System.NotImplementedException(); } bool isInverted = Vector3.Dot(declaredNormal, computedNormal) < 0f; if (isInverted) { computedNormal = -computedNormal; } if (quadGridHorizontalAxisOptions != HorizontalAxisOptions.Custom) { var axis0Normal = Vector3.Cross(Vector3.right, computedNormal); var orientation = Quaternion.LookRotation(-computedNormal, axis0Normal); var invertedOrientation = Quaternion.Inverse(orientation); axis0 = new Vector2(declaredAxis0.x, 0f); axis1 = invertedOrientation * declaredAxis1; rotation = orientation.eulerAngles; } else if (quadGridVerticalAxisOptions != VerticalAxisOptions.Custom) { var orientation = Quaternion.LookRotation(-computedNormal, declaredAxis1); var invertedOrientation = Quaternion.Inverse(orientation); axis1 = new Vector2(0f, declaredAxis1.y + declaredAxis1.z); axis0 = invertedOrientation * declaredAxis0; rotation = orientation.eulerAngles; } else { var axis0Normal = Vector3.Cross(declaredAxis0, computedNormal); var orientation = Quaternion.LookRotation(-computedNormal, axis0Normal); var invertedOrientation = Quaternion.Inverse(orientation); axis0 = new Vector2(declaredAxis0.magnitude, 0f); axis1 = invertedOrientation * declaredAxis1; rotation = orientation.eulerAngles; } if (axis0 == Vector2.right && axis1 == Vector2.up) { SetQuadTileShape(QuadTileShapes.Square); } else if (axis0.x == 1f && Mathf.Approximately(axis0.y, -1f / Mathf.Sqrt(3f)) && axis1.x == 1f && Mathf.Approximately(axis0.y, +1f / Mathf.Sqrt(3f))) { SetQuadTileShape(QuadTileShapes.Isometric); } else if (axis0.x == 1f && axis0.y == -0.5f && axis1.x == 1f && axis1.y == +0.5f) { SetQuadTileShape(QuadTileShapes.Diamond2x1); } else { SetQuadTileShape(QuadTileShapes.Custom); } break; } case PlanarTileShapes.Hexagonal: { tileType = TileTypes.Hexagonal; bool isObtuse; bool isOblique; bool pointUp; switch (hexGridAxisStyleOptions) { case HexGridAxisStyleOptions.ObliqueAcute: { hexGridAxisStyle = HexGridAxisStyles.Straight; isObtuse = false; isOblique = true; pointUp = hexGridAxisOptions == HexGridAxisOptions.AngledVerticalAxis; break; } case HexGridAxisStyleOptions.StaggeredHorizontallyAcute: { hexGridAxisStyle = variableRowLength ? HexGridAxisStyles.StaggeredSymmetric : HexGridAxisStyles.Staggered; isObtuse = false; isOblique = false; pointUp = false; break; } case HexGridAxisStyleOptions.StaggeredVerticallyAcute: { hexGridAxisStyle = variableRowLength ? HexGridAxisStyles.StaggeredSymmetric : HexGridAxisStyles.Staggered; isObtuse = false; isOblique = false; pointUp = true; break; } case HexGridAxisStyleOptions.ObliqueObtuse: { hexGridAxisStyle = HexGridAxisStyles.Straight; isObtuse = true; isOblique = true; pointUp = hexGridAxisOptions == HexGridAxisOptions.AngledVerticalAxis; break; } case HexGridAxisStyleOptions.StaggeredHorizontallyObtuse: { hexGridAxisStyle = variableRowLength ? HexGridAxisStyles.StaggeredSymmetric : HexGridAxisStyles.Staggered; isObtuse = true; isOblique = false; pointUp = false; break; } case HexGridAxisStyleOptions.StaggeredVerticallyObtuse: { hexGridAxisStyle = variableRowLength ? HexGridAxisStyles.StaggeredSymmetric : HexGridAxisStyles.Staggered; isObtuse = true; isOblique = false; pointUp = true; break; } default: throw new System.NotImplementedException(); } if (hexGridAxisOptions != HexGridAxisOptions.Custom) { bool negateHorizontal = hexGridHorizontalAxisOptions == HorizontalAxisOptions.RightToLeft; bool negateVertical = hexGridVerticalAxisOptions == VerticalAxisOptions.FarToNear || hexGridVerticalAxisOptions == VerticalAxisOptions.TopToBottom; if (isOblique && hexGridAxisOptions == HexGridAxisOptions.RightAngleAxes) { midpoint = new Vector2(horizontalAxisLength / 2f * (negateHorizontal ? -1f : +1f), 0f); majorCorner = new Vector2(horizontalAxisLength / 3f * (!isObtuse ^ negateHorizontal ? -1f : +1f), verticalAxisLength * 2f / 3f * (negateVertical ? -1f : +1f)); minorCorner = new Vector2(horizontalAxisLength / 3f * (isObtuse ^ negateHorizontal ? -1f: +1f), majorCorner.y / 2f); } else if (pointUp) { midpoint = new Vector2(horizontalAxisLength / 2f * (negateHorizontal ? -1f : +1f), 0f); majorCorner = new Vector2(0f, verticalAxisLength / Mathf.Sqrt(3f) * (negateVertical ? -1f : +1f)); minorCorner = new Vector2(midpoint.x * (isObtuse ? -1f : +1f), majorCorner.y / 2f); } else { midpoint = new Vector2(0f, verticalAxisLength / 2f * (negateVertical ? -1f : +1f)); majorCorner = new Vector2(horizontalAxisLength / Mathf.Sqrt(3f) * (negateHorizontal ? -1f : +1f), 0f); minorCorner = new Vector2(majorCorner.x / 2f, midpoint.y * (isObtuse ? -1f : +1f)); } Vector3 inferredNormal; switch (hexGridVerticalAxisOptions) { case VerticalAxisOptions.NearToFar: case VerticalAxisOptions.FarToNear: rotation = new Vector3(90f, 0f, 0f); inferredNormal = Vector3.up; break; case VerticalAxisOptions.BottomToTop: case VerticalAxisOptions.TopToBottom: rotation = new Vector3(0f, 0f, 0f); inferredNormal = Vector3.back; break; default: throw new System.NotImplementedException(); } Vector3 declaredNormal; switch (normalOptions) { case NormalOptions.Automatic: declaredNormal = inferredNormal; break; case NormalOptions.Back: declaredNormal = Vector3.back; break; case NormalOptions.Forward: declaredNormal = Vector3.forward; break; case NormalOptions.Up: declaredNormal = Vector3.up; break; case NormalOptions.Down: declaredNormal = Vector3.down; break; case NormalOptions.Custom: declaredNormal = normal; break; default: throw new System.NotImplementedException(); } bool isInverted = Vector3.Dot(declaredNormal, inferredNormal) < 0f; if (isInverted) { rotation.x = Mathf.Repeat(rotation.x + 180f, 360f); midpoint.y = -midpoint.y; majorCorner.y = -majorCorner.y; minorCorner.y = -minorCorner.y; } } else { var computedNormal = Vector3.Cross(verticalAxis, horizontalAxis); Vector3 declaredNormal; switch (normalOptions) { case NormalOptions.Automatic: declaredNormal = computedNormal; break; case NormalOptions.Back: declaredNormal = Vector3.back; break; case NormalOptions.Forward: declaredNormal = Vector3.forward; break; case NormalOptions.Up: declaredNormal = Vector3.up; break; case NormalOptions.Down: declaredNormal = Vector3.down; break; case NormalOptions.Custom: declaredNormal = normal; break; default: throw new System.NotImplementedException(); } bool isInverted = Vector3.Dot(declaredNormal, computedNormal) < 0f; if (isInverted) { computedNormal = -computedNormal; } var horizontalNormal = Vector3.Cross(horizontalAxis, computedNormal); var orientation = Quaternion.LookRotation(-computedNormal, horizontalNormal); var invertedOrientation = Quaternion.Inverse(orientation); midpoint = new Vector2(horizontalAxis.magnitude / 2f, 0f); var computedVerticalAxis = (Vector2)(invertedOrientation * verticalAxis); majorCorner = (isObtuse ? computedVerticalAxis + midpoint : computedVerticalAxis - midpoint) * 2f / 3f; minorCorner = computedVerticalAxis - majorCorner; rotation = orientation.eulerAngles; } if (midpoint.Approximately(0.5f, 0f) && majorCorner.Approximately(0f, 1f / Mathf.Sqrt(3f)) && minorCorner.Approximately(0.5f, 0.5f / Mathf.Sqrt(3f))) { SetHexTileShape(HexTileShapes.RegularPointUp); } else if (midpoint.Approximately(0f, 0.5f) && majorCorner.Approximately(1f / Mathf.Sqrt(3f), 0f) && minorCorner.Approximately(0.5f / Mathf.Sqrt(3f), 0.5f)) { SetHexTileShape(HexTileShapes.RegularPointUp); } else if (midpoint.Approximately(0.5f, 0f) && majorCorner.Approximately(0f, 0.5f) && minorCorner.Approximately(0.5f, 0.25f)) { SetHexTileShape(HexTileShapes.SquarePointUp); } else if (midpoint.Approximately(0f, 0.5f) && majorCorner.Approximately(0.5f, 0f) && minorCorner.Approximately(0.25f, 0.5f)) { SetHexTileShape(HexTileShapes.SquareSideUp); } else if (midpoint.Approximately(0.5f, 0f) && majorCorner.Approximately(0f, 0.5f) && minorCorner.Approximately(0.5f, 0.5f)) { SetHexTileShape(HexTileShapes.BlockHorizontal); } else if (midpoint.Approximately(0f, 0.5f) && majorCorner.Approximately(0.5f, 0f) && minorCorner.Approximately(0.5f, 0.5f)) { SetHexTileShape(HexTileShapes.BlockVertical); } else if (midpoint.Approximately(0.5f, 0f) && majorCorner.Approximately(0f, 0.125f) && minorCorner.Approximately(0.5f, 0.125f)) { SetHexTileShape(HexTileShapes.Brick); } else { SetHexTileShape(HexTileShapes.Custom); } break; } default: throw new System.NotImplementedException(); } switch (wrapOptions) { case WrapOptions.NoWrap: isAxis0Wrapped = false; isAxis1Wrapped = false; break; case WrapOptions.WrapHorizontally: isAxis0Wrapped = true; isAxis1Wrapped = false; break; case WrapOptions.WrapVertically: isAxis0Wrapped = false; isAxis1Wrapped = true; break; case WrapOptions.WrapBoth: isAxis0Wrapped = true; isAxis1Wrapped = true; break; default: throw new System.NotImplementedException(); } _version = "1.1"; }