/// <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); } }
/// <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)); }
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); }
public ModelTile(TesseraTile tile, Rotation rotation, Vector3Int offset) { Tile = tile; Rotation = rotation; Offset = offset; }