не могу понять, почему у меня у сохраненных мной префабах периодически сбрасывается одно недавно добавленное поле.
тоесть на объектах был некий скрипт. потом я в скрипт добавил еще одно публичное поле
выставляю это поле на объектах. на некоторых оно тупо слетает в дефолное значение
поле задал вот так
[SerializeField] public string m_AvatarPresetName = "Default. change it";
опять поменяли Vertexlayout в SkinnedMesh, никакой оффициальной инфы по внутреннему устройству этого безобразия как всегда нет. и не оффициальной тоже(
как то не уместно реализоввывать функцию GetNativeVertexBufferPtr не давая никаких средств к опознаванию структуры
Mira
Отличается от того, что в справке по GetNativeVertexBufferPtr?
Сделал отслеживалку текущей позиции произвольной точки (необязательно вершины) на SkinnedMesh. Может, кому ещё пригодится.
https://bitbucket.org/snippets/alexzzzz/EeLzq8/captures-and-keeps… a-position-of
Пример использования:
var capturer = new SkinPointCapturer(skinnedMeshRenderer); var pointA = capturer.CapturePoint( someWorldPosition); var pointB = capturer.CapturePoint( someWorldPosition2);
void LateUpdate() { var positionA = pointA.GetCurrentPosition( ); var positionB = pointB.GetCurrentPosition( ); }
Правда, найти точку на скинедмеше, чтобы её потом отслеживать ― сама по себе нетривиальная задача, но это другой вопрос.
alexzzzz
Полезный скрипт!
Выбор точки мышкой на скин меше по подобному принципу кстати работает. Правда я видел скрипт без bake , там на лету считались трианглы. Но bake по идее должен быть шустрее если он через фидбек работает
В справке по Bake или где-то ещё было написано, что BakeMesh делает всё на CPU. Учитывая, что нам нужны только позиции вершин, пересчитать их вручную может оказаться и быстрее, но я не измерял. Там есть ещё что ускорить при желании.
alexzzzz
А зачем ты ее запекаешь? Чтоб не пересчитывать биндпозы для вершин а тупо запеканку в локальное пространство трансформой закатить?
Когда выбрал точку на скиндмеше для отслеживания и ищешь, в какое место меша она попала (чтобы в итоге быть привязанным к правильным костям), модель уже может стоять в какой-нибудь позе. Нужно знать реальные на данный момент позиции её вершин. Для этого запекаю текущее состояние и в нём ищу, в какой треугольник попала моя точка.
В результате можно расстреливать шариками даже бегущую модель, шарики остаются ровно в тех местах, куда они попали.
alexzzzz
так и говорю, есть прост вариант без аллокаций на Bake
сохраняешь в общем в массивы вершины . веса , индексы, биндпозы и индексы, при выстреле пробегаешь по всем трианглам применяя к ним скиннинг и проверяя сразу на пересечение, находишь хитпойнт ну и там как у тебя, из треугольника в который попал считаешь средний вес.
возможно можно не кешировать , если GetVertices итд дает оригинальный массив без аллокаций и переаллоцирует при изменении как в паскале, но я кешировал, ибо в C# он вроде все дает копиями безявного указания ref
GetVertices копирует позиции в существующий List<Vector3>, который подаётся на вход. Если размера списка достаточно, ничего не аллоцируется.
alexzzzz
во первых, твой скрипт не учитывает блендшейпы
а во вторых скорее всего он будет медленнее чем Bake() с последующим назначением как меш для мешколлайдера и нативный Raycast().
Потому что MeshCollider.Raycast() очень быстр.
Кстати , ты с ParallelFor который в 2018.1 завезли не разбирался? По, идее, с его помощью можно сделать быстрый скриптовый рейкаст скиннед мешей.
Polyflow3d
> Потому что MeshCollider.Raycast() очень быстр.
конечно быстр. потому что он физиксом в Oсttree помещается, вот только эта вставка не такая быстрая как хотелось бы. по этому динамические мешколлайдеры(не конвексы) - тормоза.
видел я этот скрипт, где почти каждый фрейм запекается меш и генерируется мешколлайдер, типа персонаж с коллизией. даже с малым числом полигонов уже притормаживает.
очень быстро работает вариант с кешированной в массивы геометрией и разделением цилиндрами/боксами частей тела как у регдолла.
считаешь сначала стандартно рейкастом, если попал в какой то бокс, то перебираешь трианглы которые в нем, применяя к ним скиннинг. это самый быстрый способ какой я пробовал)
Polyflow3d
> Кстати , ты с ParallelFor который в 2018.1 завезли не разбирался? По, идее, с
> его помощью можно сделать быстрый скриптовый рейкаст скиннед мешей.
в нативном коде проверял многопоточный рейкаст через Parallel. на хай поли модели давало заметный выигрыш, на лоуполи значительно замедляло. так как больше времени требовалось "заводить" таски чем перебирать трианглы SSE )))
если бы юнька поддерживала нормально натив код, можно было бы делать вещи... но они поддерживают ее только условно, на самом деле никаких гарантий и перестраховок нет что при следующем обновлении все не всрется, из за того что они поменяли например VertexLayout или формат буфферов. при этом нет ни программных средств, ни инструментов чтоб к чему то привязаться или контролировать(((( при последних обновах например от балды поменяли местами UV1 и TBN, нашел пальцем в небо.
странно еще, в техразделе сказано что "формат примерно какой-то такой но это не точно", и получая доступ к VB предполагается что вы уже знаете его формат. правда не написано что формат задает вовсе не пользователь а движок.
Polyflow3d
> во первых, твой скрипт не учитывает блендшейпы
Ага. Я вообще скиндмеши не трогал, сейчас по очереди разбираюсь, что с ними можно делать.
> а во вторых скорее всего он будет медленнее чем Bake() с последующим
> назначением как меш для мешколлайдера и нативный Raycast().
> Потому что MeshCollider.Raycast() очень быстр.
Я полноценный рейкаст, кстати, пока и не делаю. Вот эта штука делает*. Я потом просто беру готовую точку, которая где-то на меше и определяю, где именно она на меше.
> Кстати , ты с ParallelFor который в 2018.1 завезли не разбирался? По, идее, с
> его помощью можно сделать быстрый скриптовый рейкаст скиннед мешей.
Не с чем особо разбираться. Вот такие строчки
for (int i = 0; i < bakedPositions.Count; i++) { bakedPositions[i] = GetCurrentWorldPosition( i); }
Parallel.For(0, bakedPositions.Count, i => bakedPositions[i] = GetCurrentWorldPosition( i));
Только оно сходу не заработало, потому что у трансформов костей нельзя читать localToWorldMatrix вне основного потока. Пришлось сначала кэшировать матрицы, что само по себе привело к заметному ускорению. Результаты такие:
1. Трансформация вершин вручную в цикле: ~25000 мкс
2. Parallel.For: ~7000 мкс (на 4-ядернике)
3. BakeMesh:
Гм-м, а в API есть вообще что-то, чтобы читать данные блендшейпов, кроме их имён?
Есть, в типе Mesh.
Текущая версия работает с блендшейпами: https://bitbucket.org/snippets/alexzzzz/EeLzq8/captures-and-keeps… a-position-of