Добавление брелоков на рабочий стол. Чисто декоративная цель
- C# 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| Assets | ||
| src | ||
| .gitignore | ||
| Breloki.csproj | ||
| README.md | ||
| TODO.md | ||
Брелоки
Акриловые брелоки с физикой, которые висят на панели задач / YASB или в любом месте рабочего стола. Брелоком может быть картинка или своя 3D-модель: glTF (.glb/.gltf), OBJ (+MTL), STL. У каждого брелока есть галочка «3D-режим»: картинка становится объёмной акриловой пластинкой с торцом, брелок крутится вокруг цепочки, качается к себе / от себя и ложится на окна. Без галочки — плоский 2D-спрайт. C# / .NET 9, WinForms + WIC. Без Electron, exe ~300 КБ.
Сборка
dotnet publish -c Release -r win-x64 --self-contained false -p:PublishSingleFile=true -o dist
Нужен .NET 9 Desktop Runtime. Готовый файл: dist\Breloki.exe.
Управление
- Трей: клик — показать/скрыть, двойной клик — настройки, ПКМ — меню (автозагрузка, выход).
- ЛКМ по брелоку — схватить и бросить. ЛКМ по кольцу — перенести крепление (отпустите у нижнего края YASB/панели, и кольцо прилипнет к бару; в другом месте — останется там).
- Двойной клик по брелоку открывает его настройки.
- 3D-брелоки: курсором вбок — раскрутить (скрученная цепочка раскрутит обратно), вверх-вниз — качнуть к себе; колесо мыши над брелоком — крутить; перенося брелок мышью, вы поворачиваете его встречным воздухом. Окно, которое наезжает снизу, не «подпирает» брелок, а тот наклоняется и ложится на него; быстро пролетающее рядом окно обдувает брелоки ветром.
- Повторный запуск exe тоже открывает настройки.
- Звук (по умолчанию выключен; вкладка «Звук» или пункт «Звук» в меню трея): брелоки стукаются друг о друга
и об окна / края экрана. Громкость — общая и по видам ударов, порог скорости; можно выбрать свои файлы
(WAV, MP3, M4A, WMA, FLAC; несколько — играет случайный). Встроенные звуки — CC0, см.
Assets/Sounds/CREDITS.txt.
Как устроено
CharmBaker— обводка по точному евклидову преобразованию расстояний, заливка дыр, торец/фаска, блик, ушко с отверстием, тень, центр масс/инерция, авто-коллизия по внешнему контуру (до N вершин, по умолчанию 24).Raster3D— свой программный растеризатор: z-буфер, сглаживание как MSAA (покрытие по 4/9 сэмплам, цвет — раз на пиксель), текстуры, свет (точечный ключевой + заполняющий, блики, светлый край у акрила), мягкая тень; крупные области рисуются полосами в несколько потоков. Проекция ортографическая.Mesh3D/ModelLoader— сетка и загрузка моделей (glTF 2.0 с текстурами и иерархией узлов, OBJ+MTL, STL; без нормалей — считаются с учётом острых рёбер). Модели копируются в%APPDATA%\Breloki\modelsвместе с MTL/текстурами.- 3D-запекание (
CharmBaker): картинка → пластинка (лицо/спина с текстурой, нарезанные на плитки без пустых, торец по контуру со скруглёнными нормалями, стенка отверстия); модель → поворот, масштаб, центр масс, металлический винт с ушком. Для коллизии — 24 силуэта на полный оборот вокруг вертикальной оси. Physics— position based dynamics с фиксированным подшагом (остаток времени кадра переносится, поэтому неровные кадры не раскачивают брелоки): цепь из частиц, брелок — твёрдое тело, колечко — ограничение-неравенство. Кольцо закреплено неподвижно. Если брелоков на цепочке несколько, от её конца отходят отдельные ветки (длина и разница длин настраиваются). У каждого брелока можно задать место крепления на цепи (% длины) и свою длину ветки. Брелок можно натянуть на несколько цепочек («Ещё прицепить к цепочкам») — ушки сами расходятся по верхнему краю. У 3D-брелока ещё две степени свободы: поворот вокруг вертикальной оси (курсор раскручивает, скрученная цепочка тянет обратно только сверх свободного поворота — по умолчанию ±180°, в этих пределах брелок остаётся, куда его повернули; коллизия — силуэт для текущего угла) и наклон к зрителю — маятник на ушке, ω² = g·L / (L² + r²); при наклоне силуэт сжимается по вертикали. Верх окна под 3D-брелоком работает как полка: брелок плавно опрокидывается (не быстрее 3 рад/с) и ложится на неё. Силуэт-коллизия при повороте не переключается скачком: соседние из 24 силуэтов смешиваются (точки контура, перевыбранные по длине дуги, и поля расстояний), а касание соседа гасит вращение трением.- Настройки 3D: у брелока — толщина, блеск, светлый край, наклон, лёгкость вращения, сглаживание рёбер модели;
в «Общих» — направление и сила света, тень, потоки отрисовки; в «Физике» — скрутка, ветер, раскачка, трение.
Мелкая дрожь гасится «затуханием покоя»; толчок курсором ограничен его скоростью.
Коллизия — контур по реальной форме (может быть вогнутым) + поле расстояний (SDF), с трением
и ограничением скорости расталкивания. Новые цепочки «успокаиваются» перед показом.
Отладка физики без экрана:
Breloki.exe --simtest 600(пишет simtest.txt и snapshot.png в папку данных; папку можно подменить переменной BRELOKI_DIR). SIM_FLAGS:yaw=45 fixyaw— повернуть 3D-брелоки,mouse flick— взмах курсором,vardt— неровный шаг кадров,sound— список ударов со звуком,rise— окно поднимается под брелок,wind— окно пролетает рядом,bench— время отрисовки,q1..q3— сглаживание,threads4— потоки. Столкновения: курсор (только если брелок виден под курсором), окна (кроме панелей YASB / панели задач), края рабочего стола, брелоки между собой. Audio— свой микшер поверх waveOut (низкая задержка, наложение ударов, панорама по положению на экране, случайная высота тона); устройство открыто, только пока что-то звучит. WAV читается сам, остальное — через Media Foundation. Физика сообщает об ударе при новом касании со скоростью сближения выше порога, не чаще раза в 0.12 с на брелок.ChainWindow— layered-окна по размеру цепочки (UpdateLayeredWindow + DIB), по два на цепочку. Кадр рисует собственный растеризатор (Blitter: поворот + билинейка, ~3 мс на кадр), GDI+ — только при запекании спрайтов. Ровный шаг кадров — отдельный поток с таймером 1 мс. нижнее лежит на рабочем столе под окнами программ, верхнее рисует только то, что попадает на YASB/панель задач (при полноэкранном приложении верхнее прячется). Можно включить «поверх всех окон».- Если всё неподвижно, цикл засыпает (10 Гц, без перерисовки).
Данные: %APPDATA%\Breloki (config.json, копии картинок, log.txt).