IRO UTSUSHI

Приложение, которое никогда не просит назвать чувство словами. Капните цвет на воду, размешайте его пальцем — и движение вашей руки останется единственной картиной.

Доступно в App Store
  • Приложение
  • iPhone / iPad
  • Swift
  • SwiftUI
  • Metal
Загрузить в App Store

Что умеет приложение

Как это устроено

Приложение Swift + SwiftUI, написано как App Package для Swift Playgrounds, без единой внешней зависимости.
Вода Симуляция жидкости, написанная на Metal. Поле скоростей, проекция давления, адвекция, усиление завихрений и смешение пигментов — всё выполняется на GPU.
Пигмент Хранится в виде лагранжевых частиц и накладывается слоями по закону Бера — Ламберта с вычитающим смешением. Поскольку это частицы, они не размываются диффузией со временем.
Внешний вид Преломление и блики рисуются по нормалям, аналитически выведенным из поля высот воды, плюс зернистый шум и дизеринг для предотвращения бандинга.
Ввод Берётся из необработанных событий UIKit, все объединённые (coalesced) касания в пределах одного кадра передаются в жидкость. До пяти одновременных касаний записываются, воспроизводятся и измеряются как независимые штрихи — по одному на палец.
Хранение Список истории содержит в JSON только лёгкую информацию; изображение — это один PNG-файл; последовательность касаний — бинарные данные фиксированной ширины, сжатые LZFSE, в отдельном каталоге для каждой записи.
Воспроизведение и экспорт Вода восстанавливается путём повторного прогона симуляции по сохранённым шагам. MP4 — это не запись экрана: кадры пересобираются из этих шагов и записываются с частотой 30 fps.
Звук Синтезируется внутри приложения — пентатонический звукоряд с полифонией до 16 голосов. Аудиофайлов нет.
Самопроверки Поскольку среда не может использовать XCTest, при запуске в режиме отладки вместо этого выполняется набор написанных для этого приложения проверок (SelfChecks.swift).
Шифрование Не используется вовсе; ответ о соответствии экспортным требованиям (export compliance) включён в приложение.

Технически интересные детали

Хвост продолжает закручиваться после того, как палец прошёл

Адвекция включает поправку MacCormack, которая сохраняет тонкие вихри, исчезающие при простой полулагранжевой адвекции. Палец не толкает воду — он оставляет пару вихрей, вращающихся в противоположные стороны, вдоль направления движения, поэтому вода продолжает закручиваться ещё некоторое время после того, как палец ушёл. Все коэффициенты затухания и следования выражены «в секунду», поэтому движение выглядит одинаково и на устройстве с частотой 60 Гц, и на устройстве с частотой 120 Гц.

Разделение «видимой волны» и «волны, которая двигает»

Видимая сила ряби и её воздействие на пигмент — это отдельные параметры. Более того, рябь напрямую сдвигает положение пигмента, а не его скорость. Скорость пигмента каждый кадр подтягивается обратно к скорости потока воды — с постоянной времени около 0,36 секунды в плотных областях, — а рябь живёт меньше этого времени, поэтому измерения показали, что добавление скорости почти не двигало пигмент. Настройка внешнего вида и настройка ощущений от использования перестали мешать друг другу.

Решение не заставлять пигменты притягиваться друг к другу

Раньше существовала сила «слипания», собирающая пигмент вместе, но единственным устойчивым результатом был круглый комок: со временем вода заполнялась непрозрачными кругами, которые больше никогда не расходились. Теперь потемнение по краям, характерное для акварели, воспроизводится без перемещения пигмента. Поле плотности остаётся прежним, а край рисуется на его основе как затенение на поверхности воды, поэтому картина никак не «застывает».

Одна и та же запись всегда воспроизводится как одна и та же картина

Симуляция зафиксирована на 60 шагах в секунду, и для каждой записи рядом сохраняются реальные номера шагов, на которых был получен ввод UIKit, число шагов разгона, а также временные метки Float32 и координаты UInt16. Воспроизведение доверяет этим сохранённым шагам больше, чем времени настенных часов. Скорость измеряется относительно UITouch.timestamp, поскольку движения в пределах одного кадра невозможно различить по времени настенных часов. Предсказанные касания используются только для оценки скорости и никогда не влияют на положение пигмента.

Кроме того, SimulationEngineRegistry явно направляет каждый сохранённый simulationVersion к соответствующему движку. Версия 6 зафиксирована вплоть до констант, часов и коэффициента переноса чернил, и неизвестная будущая версия никогда молча не передаётся в новейшую симуляцию. Смысл в том, чтобы обновление приложения не пересобирало картину старой записи во что-то другое.

Баллы не показываются первыми

Четыре показателя не обрезаются по потолку — они лежат на кривой, асимптотически приближающейся к 100, поэтому одно быстрое движение не даёт максимальный балл. При этом на экране результата они по умолчанию скрыты. Если приложение, отказывающееся раскладывать чувства по словам, начинает с чисел, эти числа просто становятся новой меткой.

Конфиденциальность и обращения

IRO UTSUSHI хранит ваши записи только на вашем устройстве. В приложении нет регистрации учётной записи, рекламы, аналитики и функций отслеживания пользователей. Подробнее см. в Политике конфиденциальности IRO UTSUSHI.

С отзывами и сообщениями об ошибках вы также можете обратиться через страницу поддержки Sizu dev.