Симуляция поведения ткани в реальном времени
Ткани в симуляторе не существует. Есть 1600 точек и девять тысяч пружин между ними: соседи по сетке, диагонали клеток, изгибы через клетку. Каждый шаг решатель обходит все связи и подтягивает их к исходной длине - и так десяток раз за кадр, 120 раз в секунду.
Складки при этом никто не рисует. Они получаются потому, что ткань почти не тянется вдоль нити, но охотно гнётся поперёк: материалу дешевле собраться в складку, чем растянуться. Ровно поэтому шёлк собирается в мелкие складки, а брезент держит крупные — в модели это три числа податливости на материал, больше ничего.
Когда полотно падает на препятствие, начинается вторая половина работы: каждую точку надо вытолкнуть наружу из шара, куба, конуса. Кажется, что этого достаточно. Не достаточно - и вот почему.
Глаз видит не точки, а треугольники между ними. При сетке 40×40 на полотне два метра шаг между точками около пяти сантиметров. Если две соседние точки оказались по разные стороны от ребра куба, то отрезок между ними срезает угол - уходит внутрь ящика примерно на полтора сантиметра. Точки честно снаружи, а ткань всё равно просвечена углом.
Я это сначала померил отдельным скриптом, а не на глаз: 15.7 мм внутрь при сетке 40, 32 мм при сетке 24. Очевидное лечение - толще «кожа» коллизии, чтобы точки стояли дальше от поверхности. Тот же скрипт показал, чем оно оборачивается: угол уходит до 10 мм, зато ткань поднимается над всеми плоскими гранями на 2.4 см и лежит на ящике как надутая.
Работает другое: проверять не только точки, но и сами отрезки - четверть, середину, три четверти каждого ребра сетки, а поправку раздавать концам. Отрезок начинает вести себя как четыре коротких. Стало 0.34 мм при сетке 40 вместо 15.7, и плоские грани не тронуты вообще: точка, которая уже снаружи, никуда не двигается.
Теперь про разрывы, и это самая поучительная часть.
Связь, растянутая сверх предела, лопается - и в полотне появляется дыра. Предел у меня был один на все ткани: четыре длины покоя. Это чепуха: настоящий хлопок рвётся при нескольких процентах растяжения, брезент ещё раньше, и только резина честно тянется в разы. Поставил физические значения - хлопок 1.15.
Полотно порвалось само. Просто упав на ящик, без единого движения мышью.
Причина в том, что десяток проходов решателя не доводит ошибку до нуля. Остаются десятки процентов невязки, а при ударе она подскакивает за 70%. Мой порог оказался ниже собственной ошибки метода - то есть рвала ткань не нагрузка, а арифметика. Число было физически верным и вычислительно бессмысленным.
Развёл две вещи, которые легко перепутать. Пороги подняты выше невязки, но остались разными у разных тканей. А рвётся связь теперь не сразу: она должна продержаться за пределом четыре шага подряд. Всплеск от удара живёт кадр-другой и не рвёт ничего. Рука, которая тянет полотно, держит натяжение столько, сколько тянет - и рвёт.
Мораль, которую я выучил уже не первый раз: физически верное число верно только тогда, когда метод способен его разрешить. Ниже своей ошибки константы описывают не мир, а вашу собственную приблизительность. И лучше написать это ограничение прямо в коде, чем спрятать в подобранной цифре - тогда тот, кто однажды сделает решатель точнее, будет знать, что порог можно опустить вместе с ним.
Модуль «Ткань» из Makarov Physics Suite. Всего там 132 модуля, вышел в Steam вчера: https://store.steampowered.com/app/4861360/Makarov_Physics_S...







