Search
Write a publication
Pull to refresh
5
0
Send message
Разлагать пользовательское вращение на составные — нет необходимости. Умножение на матрицу (точнее, в движке идет умножение на кватернион) решает все проблемы.
Новая угловая скорость выглядит так (в локальных координатах):
AngularVelocity = AngularVelocity + I_inv*torque*Time.deltaTime - I_inv*Vector3.Cross(AngularVelocity,(I*AngularVelocity))*Time.deltaTime;

здесь I и I_inv — заранее просчитанные прямая и обратная матрица момента инерции; torque — приведенный к локальной системе суммарный момент.
Все, что теперь нужно — получить новый кватернион ориентации:
deltaOrientation = 0.5f*(Orientation * AngularVelocity)*Time.deltaTime;
Orientation = Orientation + deltaOrientation;
NormalizeQuaternion(Orientation);


(здесь полагаем, что умножение матрицы на вектор, сложение кватернионов и их нормализация определены (что для Unity, вообще-то, не верно) )
Как выяснилось, типовая физика вращения в играх просчитывается в локальных координатах тела. А потому они хранят лишь одну (предпросчитанную) матрицу Ib, а для произвольного положения момент инерции находят как R*Ib*RT (ну, если точнее — они находят обратную).
Но, как вы заметили, проверить, что в Unity реализуется именно эта модель — проблематично. Остается принять это как наиболее правдоподобное положение.
Сам спросил — сам ответил. Момент инерции считается по коллайдеру, предполагая, что тело однородно по плотности. Проверил на примитивах: сферах, кубах, цилиндрах.

С цилиндрами вышел казус: были расхождения теоретически высчитанных Iz и практически полученных в Unity. Пригляделся повнимательней, и увидел, что для цилиндров используется CapsuleCollider. После соответствующих корректировок расчеты стали совпадать.

AngularDrag используется идентично линейному:
rb.angularVelocity = rb.angularVelocity * Mathf.Clamp01(1f - myDrag*Time.deltaTime);

Расцениваю комментарий как предложение мне провести исследование на тему вращательных движений ))
Вопрос и правда интересный. Хотя бы — как они момент инерции рассчитывают с учетом точечного размера Rigidbody?
И вдогонку из справки к Time.fixedDeltaTime: «For reading the delta time it is recommended to use Time.deltaTime instead because it automatically returns the right delta time if you are inside a FixedUpdate function or Update function.»
В целом, меня эта разница не особо интересует. А вот буржуи на каком-то форуме обсуждали, и мелькало сообщение, что fixedDeltaTime возвращает предустановленную константу (ту, которую в настройках можно менять), а deltaTime — реальное значение времени. Лично у меня загрузить машину так, чтобы начала тормозить физика никогда не получалось, так что для меня эти переменные равнозначны.
В общем-то, сами разработчики рекомендуют везде и всюду (что в Update(), что в FixedUpdate()) использовать на Time.deltaTime (например, тут https://docs.unity3d.com/ScriptReference/Time-fixedDeltaTime.html). Однако, я и правда где-то встречал мнение, что drag умножается именно на fixedDeltaTime. Единственное — я не помню, как это там обосновывалось.
С deltaTime и fixedDeltaTime в их теоретическом значении — понятно. Просто имеется рекомендация разработчиков использовать и в FixedUpdate(), и в Update() — deltaTime. Что несколько смущает. Так как автоматически означает рекомендацию не использовать fixedDeltaTime.

«Еще звучал интересный вопрос, который я не совсем понял: коль скоро значение параметра интерполяции не меняется, зачем там вообще deltaTime?»
Я не понял вопрос человека, а не ответ. Который, в свою очередь, очевиден.
Касательно популярности. Собственно, практически _все_ туториалы с официального сайта (https://unity3d.com) используют данный шаблон.

Что делает функция Lerp _сама по себе_ — это как раз понятно. И именно эта понятность и затрудняет понимание вышеприведенного кода, где результат уже не линеен. Именно поэтому и статья.

А «график» приведенного движения довольно прост: при стремлении временного интервала к нулю получаем классическую exp(-k*t), где k — некий коэффициент. Собственно, это видно из базового разностного уравнения.

Если подумать, вопрос был даже не в использовании функции так или иначе (в конечном итоге программист сам решает, как ему использовать имеющиеся инструменты). Вопрос, скорее, в том, что в этих самых туториалах раз за разом дается такая форма без объяснения. Что вызывает у людей вопросы. Или не вызывает, в зависимости от.
А, простите. Думал, Вы говорите про пример из статьи. Прошу прощения.
Как показывает моя практика общения (и комментарии к статье) — поведение не особо предсказуемо. Собственно, потому и статья.
Вы говорите как один из моих знакомых )) Собственно, поэтому я и написал статью. Несмотря на малый размер кода — действие не такое очевидное.
Код работает. Движение происходит от начальной точки к конечной, с плавным замедлением. А вот предложенный выше в комментарих вариант — это уже истинная линейная интерполяция.
Вот как, спасибо.
То есть WBM и YM являются "объектами имущественных прав, возникающими в результате исполнения сторонами обязательств по договорам гражданско-правового характера и используемые в целях стимулирования приобретения товаров, работ, услуг", я правильно понял? Либо они "предусмотрены федеральным законом"?
Я просто не в курсе юридических тонкостей электронных денег. Мне, как их пользователю, интересно — не посадят ли меня за покупку портрета президента через интернет с оплатой посредством WebMoney.
Вопрос: «фантики» на телефоне, которые с точки зрения сотовых операторов не деньги, а некий эквивалент (денежный суррогат) тоже запретят? Webmoney? Yandex.Money? Steam?
Первые — ладно, формально можно притянуть к последнему предложению про договора, хотя и оплата левых услуг через телефон — далеко не редкая штука. Хотят запретить именно криптовалюты, пускай четко формулируют, а так — ерундистика, imho.

Information

Rating
Does not participate
Registered
Activity