Вобщем решил покопать немного физику, попробовать физ движок к своей самоделке прикрутить. Конечно же куча вопросов без ответов образовалась.
Вот например непонятки с поведением тела при столкновении.
По картинке проще спрашивать:
Например у нас произошла коллизия в точке P. Теперь мы должны в точке коллизии наше тело пнуть импульсом. Правильно ли я понимаю, что для расчёта нужного импульса обычного импульса m*v недостаточно, ведь в точке P есть ещё и вращение со скоростью W. То есть мы должны "линейный" импульс m*v сложить с вращательной скоростью точки(переведённой в линейную в данной точке) * на момент инерции в данной точке и уже от этого полученного суммарного импульса производить расчёт?
Вопрос 2: момент инерции, если я правильно понимаю, это что-то типа массы, но только в отношении вращения тела а не поступательного движения. Как он зависит от расстояния точки коллизии до центра массы тела?
Вопрос 3: при обнаружении столкновения в примере на картинке, ннормаль к поверхности бокса считать как вектор n1 на картинке(обратный нормали к поверхности плоскости) или же n2(в направлении от центра массы тела к углу бокса)?
пока что такие вопросы, возможно появятся новые(да не возможно, а точно появятся)
Читал эту статью http://www.gamedev.ru/code/articles/?id=4706 ?
Даже скачал себе, но смотрел поверхностно. Правильно я понял, что
float a = n1 * body1->velocity + n2 * body2->velocity + w1 * body1->angularVelocity + w2 * body2->angularVelocity; float b = (n1 * n1 * body1->invMass + w1 * w1 * body1->InvInertia + n2 * n2 * body2->invMass + w2 * w2 * body2->InvInertia); [b]a + b * lambda[/b] = 0;
..это ответ на мой первый вопрос?
А насчёт нормали к поверхности, если есть только угол? считать нормалью обратную нормаль от поверхности другого тела?
В принципе да, это ответ на твой вопрос, но не стоит просто копипастить. Обязательно надо разобраться. Тут нормаль относится не к поверхности а, к контакту, но в принципе она совпадает с нормалью поверхности для твоего случая на рисунке.
UVW
> Вопрос 2: момент инерции, если я правильно понимаю, это что-то типа массы, но
> только в отношении вращения тела а не поступательного движения. Как он зависит
> от расстояния точки коллизии до центра массы тела?
Он не зависит от коллизий, он зависит только от формы тела, и выбранной оси вращения.
Запутался я чего-то. Поразбирался в статьях Суслика, сделал что-то маленько похожее на то, что полагается, после прикручивания трения всё пошло крахом странным образом.. Шар, падающий на плоскость нормально начинал катиться по ней, но соударения двух шаров(до этого будучи правильными) начали странно себя проявлялять. Вобщем, только успел порадоваться, что всё норм, как всплывают косяки. которых раньше и в помине не было в этих случаях. Пока даже не уверен как конкретно вопрос задать, но относительно статьи интересует одна вещ. Lambla - там модуль импульса, который нужно применить к обоим телам, чтоб относительная скорость точек двух тел по нормали столкновения стала такой, как мы хочем. Правильно ли я применяю импульс к телу?
функция применения импульса:
сам импульс считается так collis[c].norm * collis[c].lambda (collis[c] это структура столкновения одного из примитивов с другим)
На данный момент, когда полкода закомментировано, у меня пока только к этому куску кода недоверие. Попробую записать видео применения определённого импульса к разным точкам
Вот визуальзации:
Вектор импульса (0, 0.02, 0) (применяется на каждом кадре)
invmass = 1/2.0f
invinert = 1/2.0f
позиция центра масс (-1, 3, 0)
точка приложения импульса (-1.5, 3, 0)
то-есть импульс будет только на вращение
точка приложения импульса (-1.5, 2.8, 0)
то-есть ввёрх, в точку левее и нихе центра масс
А это то что было с обычным тупым "отскоком" скорости точки, но это ерунда какая то
MaxGucci
> не стоит просто копипастить. Обязательно надо разобраться.
золотые слова. именно поэтому я умышленно не выкладываю код к статье. если читатель не может написать его самостоятельно, значит я статью написал плохо.
UVW
> Vector3f nimp = Projection(impuls, lever); //поступательная составляющая
> импулься
> Vector3f kimp = impuls - nimp; //вращательная
>
> vel += nimp * invmass; //изменим поступ.
> Vector3f kvel = kimp * invinert; //вращательная составляющая импульса
> делённая на момент инерции
>
> Vector3f av = lever ^ kvel; //переводим во вращательную скорость
> avel+=av; //изменяем вр. скорость
лол ну и шняга. в смысле хорошо, что ты попытался вывести это самостоятельно, но пока вышло так себе. правильные формулы: http://www.gamedev.ru/code/articles/?id=4706#opisanie_metoda_sequential_impul (первые две по ссылке)
Suslik
> значит я статью написал плохо.
Статья написана хорошо, но для только 5 минут назад начавшего разбираться с нормальными принципами работы современных физ двигов немного сжато/сложновато (хотя может это я тупой)). Показалось немного непоследовательно для меня. Когда я наткнулся на статью, меня больше интересовала структура двига и как лучше описывать примитивы, как хранить посчитанные коллизии(на каждое тело свою, или одну на два тела и т.д.). Так же интересовало то, пересчитывать ли положение примитивов в мировые коорды на каждом кадре или есть другие подходы, и в какой системе вообще всё считать, чтоб минимум операций. В итоге ничего не нашёл, сделал по своему, хотя понимаю, что по своему без велосипедов с квадратными колёсами не получится.
Тэкс, начнём разбираться
Vector3 velocityAfterCollision =
body->velocity + norm * lambda * body->invMass;
norm * lambda - это ведь импульс, который применится к точке соприкосновения, а здесь формула, как будто бы центр массы находится на нормали к соприкосновению, но у меня ведь не только шары. Что я недопонимаю? (добавлено) Ведь лямбду мы искали с учётом вращательной скорости, а применяется тут весь импульс на поступательное движение.
Кстати, вопрос по организации самого движка, я распишу как я всё сделал, хотелось бы услышать, что не так и что поменять, чтоб не было потом поздно всё переписывать
В общем двиг из себя представляет такую структуру(пока нельзя добавлять новые тела и примитивы к общей массе динамически, с этим бы разобраться)))
Структура тела Fbody представляет такую штуку:
С структурой примитива я поступил странновато(или нет). Чтоб в CollisionDetection(); не разбираться что с чем сравнивать я обобщил все примитивы в один(пока их не много)
Структура коллизии
Это вообще нормальная организация или что/где поменять?
UVW
вообще-то статья по солверам - узко специализирована специально для солверов. есть ещё общая статья: http://www.gamedev.ru/community/gd_physcomm/articles/phys_engine_development читал?
Я её читал, и опять же качнул, чтоб под рукой была, сегодня сидел отлаживал пункт по трению, и всё пошло через анус(причём тело очень отлично катилось сохраняя относительную скорость нулевой в точке коллизии - максимальное трение - хотя оно не должно так делать по всем параметрам, зато там где всё должно быть норм, всё стало неправильно), обычные отскоки начали действовать через раз(точнее не со всеми телами) ошибку я в упор не вижу, потому я пока всё закомментил в коде и начал по шагам разбирать с помощью форума
UVW
> norm * lambda - это ведь импульс, который применится к точке соприкосновения, а
> здесь формула, как будто бы центр массы находится на нормали к соприкосновению,
> но у меня ведь не только шары. Что я недопонимаю?
то, что линейный импульс меняется независимо от точки, к которой он приложен. плечо играет роль только для углового импульса.
"часть импульса" уйти во вращение не может - импульс порождает вращение и поступательное движение. но при нецентральном ударе обменный импульс будет меньше, так как часть энергии столкновения уйдёт во вращение. то есть энергия делится на поступательную и вращательную, импульс же их порождает. ну, можно так сказать.
в коде слишком много грамматических ошибок, не смог дочитать.
Ну импульс это ведь векторная величина, сродни силе(ну и моменту силы соответственно), если силу применить к самсому краешку тела по касательной, ведь всё уйдёт на вращение?(с учётом того, что момент инерции будет близкий к нулю - тело очень легко на вращение) а на поступательное вообще не будет..
UVW
> в коде слишком много грамматических ошибок, не смог дочитать.
Если речь идёт не про комментарии, то извиняюсь, я с инглишем мало знаком(кстати как я понял большинство стоящего материала на англ. но увы я с ним на Вы)
Suslik
> то, что линейный импульс меняется независимо от точки, к которой он приложен
но ведь > norm * lambda это не линейный импульс это импульс по нормали соединения, а он ведь мимо центра тела очень часто идёт, допустим вращения у тел вообще не было, и они, двигаясь навстречу друг-другу, соприкоснулись краями, и нормаль контакта вообще мимо центра пошла, соответственно и импульс "ударит" туда же и закрутит тело
Вобщем пока не сдвигаюсь с полумёртвой точки, видимо анализировать структуру двига никто не захочет, пофиг пока пусть так(сам пока вижу один косяк, что класс модели входит в структуру физического тела, хотя он вообще сюда не должен никаким боком, это во внешнем коде нужно организовать набор объектов, в который войдёт и изображаемая геометрия, и физ. тело, но это потом), импульс к телу вроде как применяется правильно на видео?
UVW
> если силу применить к самсому краешку тела по касательной, ведь всё уйдёт на вращение?
У вас проблема не с движком, а с физикой. Прежде чем программировать рекомендую подтянуть знание механики. Движение центра масс тела абсолютно не зависит от точки приложения силы. Если силу применить к самому краешку, то центр масс будет двигаться так же, как если применить эту силу к центру.
Тема в архиве.