예제 #1
0
        /// <summary>
        /// Returns the cell, and a rotator for a tile placed near the generator
        /// A rotator takes vectors in the tile local space, and returns them in generator local space.
        /// It's always an distance presering transform (so it's always one of the symmetries of a cube).
        ///
        /// NB: The cell returned corresponds to offset (0,0,0). The tile may not actually occupy that offset.
        /// </summary>
        internal static bool GetCell(
            Transform transform,
            Vector3 center,
            Vector3 tileSize,
            Vector3Int size,
            TesseraTile tile,
            Matrix4x4 tileLocalToWorldMatrix,
            out Vector3Int cell,
            out MatrixInt3x3 rotator)
        {
            var m = transform.worldToLocalMatrix * tileLocalToWorldMatrix;

            Vector3Int Rotate(Vector3Int v)
            {
                var v1 = m.MultiplyVector(v);
                var v2 = new Vector3Int((int)Math.Round(v1.x), (int)Math.Round(v1.y), (int)Math.Round(v1.z));

                return(v2);
            }

            // True if v is a unit vector along an axis
            bool Ok(Vector3Int v)
            {
                return(Math.Abs(v.x) + Math.Abs(v.y) + Math.Abs(v.z) == 1);
            }

            var rotatedRight   = Rotate(Vector3Int.right);
            var rotatedUp      = Rotate(Vector3Int.up);
            var rotatedForward = Rotate(new Vector3Int(0, 0, 1));

            if (Ok(rotatedRight) && Ok(rotatedUp) && Ok(rotatedForward))
            {
                var localPos = m.MultiplyPoint(tile.center);
                var min      = center - Vector3.Scale(size - Vector3Int.one, tileSize) / 2.0f;
                localPos -= min;
                var x = (int)Mathf.Round(localPos.x / tileSize.x);
                var y = (int)Mathf.Round(localPos.y / tileSize.y);
                var z = (int)Mathf.Round(localPos.z / tileSize.z);
                cell    = new Vector3Int(x, y, z);
                rotator = new MatrixInt3x3
                {
                    col1 = rotatedRight,
                    col2 = rotatedUp,
                    col3 = rotatedForward,
                };
                return(true);
            }
            else
            {
                cell    = default;
                rotator = default;
                return(false);
            }
        }
예제 #2
0
 /// <summary>
 /// Returns the cell, and a rotator for a tile placed near the generator
 /// A rotator takes vectors in the tile local space, and returns them in generator local space.
 /// It's always an distance presering transform (so it's always one of the symmetries of a cube).
 ///
 /// NB: The cell returned corresponds to offset (0,0,0). The tile may not actually occupy that offset.
 /// </summary>
 internal bool GetCell(
     TesseraTile tile,
     Matrix4x4 tileLocalToWorldMatrix,
     out Vector3Int cell,
     out MatrixInt3x3 rotator)
 {
     return(GeometryUtils.GetCell(
                transform,
                center,
                tileSize,
                size,
                tile, tileLocalToWorldMatrix,
                out cell,
                out rotator));
 }
예제 #3
0
 private bool IsSymmetricZ(TesseraTile tile)
 {
     foreach (var of in tile.faceDetails)
     {
         var bounds          = tile.GetBounds();
         var reflectedDir    = of.faceDir == FaceDir.Forward ? FaceDir.Back: of.faceDir == FaceDir.Back ? FaceDir.Forward : of.faceDir;
         var reflectedOffset = new Vector3Int(of.offset.x, of.offset.y, bounds.zMin + bounds.zMax - of.offset.z);
         if (!tile.TryGet(reflectedOffset, reflectedDir, out var reflectedFaceDetails))
         {
             return(false);
         }
         if (!ReflectedEquals(of.faceDetails, reflectedFaceDetails))
         {
             return(false);
         }
     }
     return(true);
 }
예제 #4
0
 public ModelTile(TesseraTile tile, Rotation rotation, Vector3Int offset)
 {
     Tile     = tile;
     Rotation = rotation;
     Offset   = offset;
 }