nikolay.sykharev Posted December 17, 2022 Posted December 17, 2022 (edited) С AddForce вроде все просто (но на всякий случай спрашиваю, мало ли что не так) - body_Rigid.AddForce(node.GetWorldDirection(MathLib.AXIS.Z) * мощность); А вот с AddTorque что-то ни как в толк не возьму, как мне прикладывать силы так, чтобы тело крутилось именно по локальной оси. Насколько я знаю, это делается через углы Эйлера, а с этим у меня проблемки (ненавижу все эти кватернионы. Кто их вообще придумал?). Нашел вот это, но это скорость, не совсем то. vec3 localVelocity = vec3.FORWARD * -мощность_вращения; node.ObjectBodyRigid.AngularVelocity = node.GetWorldRotation() * localVelocity; Может кто решал подобное? Edited December 20, 2022 by nikolay.sykharev
cash-metall Posted December 19, 2022 Posted December 19, 2022 Здравствуйте! On 12/17/2022 at 7:44 AM, nikolay.sykharev said: А вот с AddTorque что-то ни как в толк не возьму, как мне прикладывать силы так, чтобы тело крутилось именно по локальной оси можно точно так же body.AddTorque(node.GetWorldDirection(MathLib.AXIS.Z) * power); AddTorque применяет силу в мировом пространстве. т.е. нужно локальную ось перевести в глобальную. в общем случае как то так можно body.AddTorque(node.GetWorldRotation() * vec3(0,0,power));
nikolay.sykharev Posted December 19, 2022 Author Posted December 19, 2022 2 hours ago, cash-metall said: Здравствуйте! можно точно так же body.AddTorque(node.GetWorldDirection(MathLib.AXIS.Z) * power); AddTorque применяет силу в мировом пространстве. т.е. нужно локальную ось перевести в глобальную. в общем случае как то так можно body.AddTorque(node.GetWorldRotation() * vec3(0,0,power)); Нет, это не работает. По началу объект как будто крутится как нужно, но чем дольше это происходит, тем больше его начинает разворачивать на глобальную ось. Т.е. меня это просто в тупик ставит - он не крутится сразу по глобальной оси, а его именно полностью разворачивает на глобальную ось и по ней он уже крутится корректно. В общем прикрепил видео с проблемой. 2022-12-19 14-37-38.mkv Код: Rotate.cs
cash-metall Posted December 20, 2022 Posted December 20, 2022 как я понял из видео - у вас у объекта выключена гравитация? тогда это норм) там какие-то физические трюки с тензором инерции (тут я не уверен, надо физиков звать чтобы они толком объяснили почему оси стремятся выровняться). решить эту проблему можно двумя способами - установить шейпы правильной формы (можно сделать один шейп а остальным выключить массу) или выключить shape-based у тела, и исправить матрицу. тогда объект будет нормально вращаться без гравитации. на видео - первый запуск - воспроизведение проблемы второй запуск проблема решена через размер шейпа третий запуск проблема решена через тензор инерции
nikolay.sykharev Posted December 20, 2022 Author Posted December 20, 2022 2 hours ago, cash-metall said: тогда это норм) там какие-то физические трюки с тензором инерции (тут я не уверен, надо физиков звать чтобы они толком объяснили почему оси стремятся выровняться). решить эту проблему можно двумя способами - установить шейпы правильной формы (можно сделать один шейп а остальным выключить массу) или выключить shape-based у тела, и исправить матрицу. тогда объект будет нормально вращаться без гравитации. Дело в том что я просто взял кубик с дефолтной сцены, добавил ему примитив для наглядности и начал его крутить. С шерпами и тензором там все норм. Ну и получалось то что получалось. Но кажется я понял в чем дело, у меня были мутные подозрения что такое возможно (я такое на колесах встречал - надо было всегда обнулять ранее приложенные силы). Так как я делал это через кнопку, то я сразу же отсекал приложение вектора силы как только отпускал кнопку, но вектор не сбрасывался, а как бы оставался не активированным. Когда я еще раз нажимал кнопку, то прикладывался не сброшенный вектор, который вносил свои коррективы в новый вектор или даже смешивался с новым вектором и тело как следствие некорректно разворачивало. Ну или что-то типа того. Плюсом изменение scale у изначального объекта и получалось какое-то хаотичное движение которое в итоге разворачивало на ось тензора инерции. Кстати со скоростью тоже самое, если не собирать вектор и только собранный сообщать телу, просто более наглядно и без инерции. Да, и большая просьба к разработчикам, разберитесь уже с документацией, там постоянные ошибки, то из прошлых версий, то вообще грамматические, что-то найти и так не просто из-за крайне скверной структуризации, а применить из-за глобального отсутствия примеров кода и вообще объяснений что это такое и как конкретно у вас работает. Ну не знаю, сделайте что ли LTE, наведите там порядок если постоянно требуется вводить новые правки в IDE. Так что корректный скрипт, Spoiler public class TestRotate : Component { public BodyRigid body_Rigid; public float мощность_вращения = 1f; vec3 вращение = vec3.ZERO; private void Init() { body_Rigid = node.ObjectBodyRigid; Unigine.Console.Run("console_onscreen 1"); } private void Update() { вращение = vec3.ZERO; if (Input.IsKeyPressed(Input.KEY.DOWN)) { вращение = node.GetWorldDirection(MathLib.AXIS.Z) * мощность_вращения; //или (оси взяты для примера) //вращение = node.GetWorldRotation() * vec3.LEFT * мощность_вращения; } if (Input.IsKeyPressed(Input.KEY.UP)) { вращение = node.GetWorldDirection(MathLib.AXIS.Y) * мощность_вращения; //или (оси взяты для примера) //вращение = node.GetWorldRotation() * vec3.FORWARD * мощность_вращения; } //Log.Message("\n вращение = " + вращение); } void UpdatePhysics() { body_Rigid.AddTorque(вращение); } } силы постоянно прикладываю в UpdatePhysics, а собираю вектор в Update, точнее в данном случае сбрасываю. И теперь, все работает корректно - тело по инерции еще докручивается, к нему прикладываются новые вектор и вектор инерции, и новый приложенный вектор смешивается корректно. Но да, кроме того, надо следить за Inertia при изменении scale у коллайдера физики node и выравнивать значения
Recommended Posts