Суббота, 18.05.2024, 16:59
GAMESTROYГлавная

Регистрация

Вход
Приветствую Вас Гость | RSS
Меню сайта
Категории раздела
Программирование [47]
Графика [2]
Индустрия [0]
Дизайн [0]
Разное [7]
Наш опрос
Игры какого жанра вы предпочитаете делать?
Всего ответов: 68
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Главная » Статьи » Программирование

Моделирование физики в компьютерных играх с помощью частиц

В этой статье описывается принцип создания физической модели и один конкретный способ, который нравится автору, но хочу заметить, что в данной статье вы не найдете описания полного пути моделирования физики. Цель данной статьи дать точку опоры и задать дальнейшее направление для исследования.

Создание модели для описания физического явления вещь сложная. Нужно набить руку, для того, чтобы достаточно быстро осознать какие факторы влияют на данный физический процесс. Из них нужно выделить те, которые являются основными, а какими можно и нужно пренебречь. Почему чем-то нужно пренебрегать? Дело в том, что все учесть невозможно и бессмысленно. Например, моделируя падение камня на землю с высоты одного метра, явно можно пренебречь изменением ускорения свободного падения с высотой, а также притяжением луны и другими факторами. Моделируя же приливы и отливы, притяжением луны пренебречь нельзя, так как оно является основным фактором.

При моделировании физики в играх нужно заботиться о том, чтобы ваша физическая модель не "сожрала" чрезмерно много ресурсов компьютера. Пренебрегать придется даже тем, чем на первый взгляд пренебрегать нежелательно, а возможно даже придется заменить некоторые факторы на эквивалентные им. Вот мы и подошли к самому главному. Не стремитесь воссоздать реальность, стремитесь создать нечто похожее. Кроме того, физика в игре должна подчеркивать какие-то особенности. Если вы делаете веселую аркаду, то делайте физику соответствующую. Можно, а порой и нужно придумывать свои факторы, которых в жизни нет, и не было. Если же вы покушаетесь на реализм, то обманывайте пользователя, придумывайте упрощенную физику похожую на реальную. Реальность неповторима, вы должны лишь поймать основные особенности и воплотить их подобие.

Но нужно помнить и о том, что технологии идут вперед и нужно придумывать новые, более сложные модели. Многие моделируют физику так: создают для объектов би-боксы, при столкновении отталкивают их друг от друга по какому-то правилу. Метод хороший, и при усовершенствовании и доведении до ума может выдать приличные результаты. Если читатель не знает что такое би-бокс, я думаю, найти некоторую информацию в интернете не составит особых проблем. А сейчас я хочу рассказать о другом методе.

Пусть есть две частицы, координаты первой x1, координаты второй x2, где x1 и x2 - вектора. Расстояние между частицами четко задано и равно L. Получается, что между ними существует упругая связь. Для того чтобы восстановить между двумя частицами заданное расстояние, мы должны проделать следующие операции:

  vector3f delta = x2-x1;
float deltalength = Magnitude(delta);
float diff = (deltalength-L)/deltalength;
x1 = x1+delta*(0.5f*diff);
x2 = x2-delta*(0.5f*diff);

Где Magnitude() возвращает длину вектора.

Если у нас больше чем две частицы, то мы должны пройтись по всем связям, возможно, понадобиться повторить данный процесс несколько раз, для увеличения точности.

Сейчас разберемся, с тем, как такую систему частиц перемещать. Казалось бы, чем плохо считать, для каждой частицы, на каждом шаге, её перемещение по формуле x1+=v1*timestep+a1*timestep*timestep/2 ,где v1 - скорость данной частицы, a1 - ускорение данной частицы, а timestep шаг по времени. И скорость еще надо изменить: v1+=a1*timestep. Но дело в том, что после перемещения всей системы нам нужно восстановить начальное расстояние между соединенными частицами. И это может привести к тому, что какая-то частица в итоге сдвинулась вовсе не на рассчитанное нами расстояние, она даже могла уйти в сторону противоположную своей скорости. Что в дальнейшем будет происходить с такой противоречивой системой, я не знаю и знать не хочу.

Существует другой способ, называется Verlet integration. Мы храним не скорость частицы, а ее координаты на этом и предыдущем шаге. Положение частицы на следующем шаге определиться таким образом
x1+=x1-oldx1+a1*timestep*timestep.

Так в движении системы будет учитываться взаимодействие частиц. Но отсутствие значения скорости сильно усложняет работу с системой частиц.

Поэтому, я решил поступать следующим образом. Сохраним положение частиц. Изменим скорость и расстояние, как в первом методе. После, рассчитав положение частиц в зависимости от связей, скорость каждой частицы вычисляем вот так v=(x-oldx)/timestep. Таким образом, мы учтем взаимодействие частиц между собой.

А так выглядит класс на c++.

struct Constraint
{
int particleA, particleB;
float restlength;
};

class ParticleSystemPhys
{
public:
Vector3f m_x[NUM_PARTICLES]; // Current positions
Vector3f m_oldx[NUM_PARTICLES]; // Previous positions
Vector3f m_v[NUM_PARTICLES]; //velocity
Vector3f m_a[NUM_PARTICLES]; // acceleration
Constraint m_constraints[NUM_CONSTRAINTS];
float m_fTimeStep;
int NUM_PARTICLES;
int NUM_CONSTRAINTS;
int NUM_ITERATIONS;
void TimeStep();
private:
void Motion();
void SatisfyConstraints();
void AccumulateForces();
};

Думаю, читатель, основываясь на данном куске кода и рассуждениях автора, сможет написать функции для работы с системой частиц.

А где эти частицы использовать? Ну, во-первых, они удобны для инверсной кинематики, просто делаем скелет из них. А во-вторых, можно из частиц сделать твердое тело, достаточно лишь соединить каждую частицу с каждой. Понятно, что если вершин-частиц много, то такое твердое тело содержать накладно, но ведь геометрия физического объекта не обязана совпадать с геометрией визуализируемого объекта.

Здесь считается, что у вас уже есть функция для определения столкновений, которая возвращает точку столкновения и нормаль.

Вспомним столкновение упругих шаров. m1,m2 - масса первого и второго шаров соответственно, v1,v2 - проекции скоростей шаров на нормаль столкновения до столкновения, u1,u2 - проекции скоростей шаров на нормаль после столкновения. Запишем законы сохранения импульса и энергии.
m1*v1+m2*v2=m1*u1+m2*u2

m1*v1*v1 /2+m2*v2*v2 /2=m1*u1*u1 /2+m2*u2*u2 /2

Запишем эти уравнения так:
m1(u1-v1)=m2(v2-u2) (*)

m1(u1*u1-v1*v1)=m2(v2*v2-u2*u2)


Разделив второе уравнение на первое, получим:
v1+u1=v2+u2

Умножив обе части уравнения на m2 и сложив с (*) получим
u1=((m1-m2)v1+2*m2*v2)/(m1+m2).


Аналогично
u2=((m2-m1)v2+2*m1*v1)/(m1+m2).

А сейчас рассмотрим столкновение двух твердых тел с вершинами-частицами. Рассмотрим первое тело. Сделаем так, чтобы импульс, переданный точке столкновения частицей, зависел от расстояния до этой частицы. То есть чем дальше частица, тем меньше импульс она передала. Не забываем, о том, что частица отдала импульс, то есть скорость у нее должна стать соответствующей. То же самое делаем со вторым телом.

У нас будет скорость и масса для обоих тел в точке пересечения. Рассчитываем новые скорости, как было сделано с шарами. Дальше передаем скорости каждой частице в зависимости от расстояния до точки пересечения.

Итак, я представил модель, для поведения систем связанных частиц при столкновении. И не важно, как с точки зрения физики все происходит в реальности, ведь цель была не воссоздать реальность, а сделать поведение тел похожим на реальное. И на самом деле, тела визуально правдоподобно отскакивают, при чем после столкновения может начаться вращение.

Ну, нужно программно реализовать идею, изложенную выше (а может и не нужно, если не хочется). Возможно, стоит изменить модель или дополнить. Нужно придумать, как реализовать силу трения, а также подумать об оптимизации. Вот, собственно, основные темы, над которыми стоит задуматься читателю.

Категория: Программирование | Добавил: DiMENTOR (18.12.2009)
Просмотров: 15887 | Комментарии: 4 | Рейтинг: 0.0/0
Всего комментариев: 4
4 ritorbiny  
0
Хихи, познавательно

3 KeenoconSwome  
0
Этот пост — одно из немногих исключений, когда читаешь с интересом и что-то для себя выносишь. Спасибо автору. Добавлю в избранноеhttp://voronezh.recikl.ru/ - . smile

2 Liska  
0
Ну вообще-то, многое из того, что Вы пишете не совсем так… Ну да ладно, не важно smile

1 Анонимус  
0
angry biggrin sad cry

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Поиск
Пожертвование
Дорогие посетители , внесите пожертвование в развитие нашего проекта.
Благодарим Вас
WMZ
Реклама
Партнерская программа 1PS.RU Онлайн казино Nirvana
Наш возраст
DiMENTOR Studio © 2024Бесплатный конструктор сайтов - uCoz