Введение в Физику мягких форм (Перевод) Часть 1

Введение

В последнее время широкое распространение получило использование моделирования физических процессов
в играх. Возможно, это произошло из-за необходимости передачи реалистичности движения объектов. В частности это моделирование динамики твердого тела, когда объекты двигаются и вращаются, но не изменяют формы, и модели «физики тряпичной куклы» (ragdoll physics), когда движение персонажа обусловлено внешним воздействием.

Впрочем, до сих пор, моделирование физики мягкого тела мало использовалось при программировании игр, и возможно пора обратить внимание на этот тип моделирования, чтобы вы могли начать применять некоторые мягкие объекты (soft bodies), при программировании игр.

Мягкий объект (soft body) — это объект, изменяющий всю свою форму под внешним воздействием. Приведем некоторые примеры мягких объектов — это ткань, воздушный шар и желе. Ткань спадает складками книзу из-за гравитационных сил и развивается на ветру. Таким же образом, воздушный шар раздувается, когда внутреннее давление увеличивается и деформируется, когда ребенок сжимает его. Такой вид поведения объекта интересен для наблюдения, особенно в игре, где значение зрелищности крайне высоко.

Эта статья написана, для того чтобы дать вам некоторые основы знания того, что скрывается за моделированием мягкого тела в реальном времени. Она проста для начинающих, так как мы начнем с самого простого. В попытке показать применимость физики мягкого тела(soft body physics), некоторые примеры, данные в этой статье, также иллюстрируют, как это можно использовать в качестве быстрой замены для случаев, в которых применение моделирования негнущихся предметов будет значительно дороже.

Есть 4 главных части в этой статье, и мы будем создавать разные модели мягких тел для каждой из них. Эта статья постепенно формирует объектно-ориентированное моделирование физики мягких тел, таким образом, мы будем интенсивно использовать и наследовать код уже написанный раннее в предыдущих частях. Это означает, что вы должны иметь простейшее понимание объектно-ориентированного программирования.

Эта статья первоначально нацелена на тех, кто использует Microsoft XNA 3.0, но идеи и алгоритмы легко можно использовать и для других языков и APIs, тех к которым вы привыкли.

К концу всего этого занятия вы будете в состоянии создать такие модели:

Видео 1: согласованная (An interactive) (взаимодействующая сама с собой) модель ткани.

http://www.youtube.com/watch?v=JncQOCg9FS0&feature=player_embedded

Видео 2: Согласованная модель пружинки (созданная с использованием целевой основы (goal-based) мягкого тела \ целевого мягкого тела)

http://www.youtube.com/watch?v=_yR_Tiqze2E&feature=player_embedded

Видео 3: Согласованная модель цепи (созданная с использованием ограничения длины и упругости(springs))

http://www.youtube.com/watch?v=XNyO0XXhh_o&feature=player_embedded

Основной
код.

Я добавил некоторые основные игровые компоненты и классы в файлы проектов из каждой части, так чтобы некоторые основные уроки могли быть выполнены без проблем. Некоторые пункты, которые эти игровые компоненты могут включать в себя:

  1. загрузка и рисование модели из файла называемого LoadMadel(«theFileName»)
  2. преобразование модели в сцене путем установки Translate, Rotate и Scale properties
  3. создание камеры путем создания CameraComponent и добавления его в game.Components
  4. Обнаружение зажатой кнопки, единожды нажатой или просто отпущенной путем вызова методов IsKeyHeldDown(), IsKeyJustDown(), IsKeyJustUp() в указанном порядке
  5. создание 3D линии просто путем создания Line3DComponent, добавление его в game.Components и установки StartPosition, EndPosition и Color properties

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

Для использования основ кода вам просто необходимо создать новый экземпляр класса для каждого из компонентов и добавить их в список this.Components в вашей игре. Это было сделано для вас в Game1.cs в файлах каждой части.

(Game1.cs, дополнение кода жирным шрифтом)

using Microsoft.Xna.Framework;

using Microsoft.Xna.Framework.Graphics;

using Microsoft.Xna.Framework.Input;

using SkeelSoftBodyPhysicsTutorial.Main;
namespace SkeelSoftBodyPhysicsTutorial

{

    public
class
Game1 : Microsoft.Xna.Framework.Game

    {

        GraphicsDeviceManager graphics;

        SpriteBatch spriteBatch;
        //component members

        CameraComponent cameraComponent;

        InputComponent inputComponent;

        ModelComponent modelComponent;

        Line3DComponent line3DComponent;
        public Game1()

        {

            graphics = new
GraphicsDeviceManager(this);

            Content.RootDirectory = «Content»;
            //instantiate the components and add them to this.Components

            Vector3 cameraPosition = new
Vector3(0, 10, 10);

            Vector3 targetPosition = Vector3.Zero;

            Vector3 upVector = Vector3.UnitY;

            string backgroundImage = «»;

            cameraComponent = new
CameraComponent(this, cameraPosition, targetPosition, upVector, backgroundImage);

            this.Components.Add(cameraComponent);
            bool showMouse = false;

            inputComponent = new
InputComponent(this, showMouse);

            this.Components.Add(inputComponent);
            modelComponent = new
ModelComponent(this);

            this.Components.Add(modelComponent);
            line3DComponent = new
Line3DComponent(this);

            this.Components.Add(line3DComponent);

        }
        protected
override
void Initialize()

        {

            base.Initialize();

        }

        protected
override
void LoadContent()

        {

            spriteBatch = new
SpriteBatch(GraphicsDevice);

        }
        protected
override
void UnloadContent()

        {
        }
        protected
override
void Update(GameTime gameTime)

        {

            base.Update(gameTime);

        }
        protected
override
void Draw(GameTime gameTime)

        {

            GraphicsDevice.Clear(Color.CornflowerBlue);

            base.Draw(gameTime);

        }

    }

}

Остальной код сверху это просто стандартные шаблоны кода, которые появляются, когда вы создаете новый проект в XNA Game Studio, с удаленными комментариями.

Глава 1 — Моделирование Упругой нити(Spring Simulation)

Скачайте исходный файл для начала этой главы.

Мы начнем обучение с имплементации простого моделирования упругой нити где 2 объекта прикреплены друг к другу при помощи нити (spring). Изучая как создавать моделирование упругой нити вы получите достаточно знаний для создания модели мягкого тела в играх. Это простое моделирование, таким образом, подготовит вас к более сложным моделям мягкого тела в более поздних главах.

К концу этой главы у вас должно получиться простое моделирование нити похожее на это:

видео4: простая модель упругой нити между 2мя объектами

http://www.youtube.com/watch?v=GBvH4nvYBg8&feature=player_embedded

это не выглядит чрезвычайно впечатляюще из-за того, что это только простейший пример как создать нить и запустить моделирование. Как бы то не было, не беспокойтесь по этому поводу, так как мы создадим более интересные модели в последующих главах.

  1. Алгоритм моделирования физики.

Для осуществления любого физического моделирования в играх нам надо проделать следующие шаги (по порядку):

  1. суммировать все силы, действующие на тело/вершины, для получения результирующей силы
  2. найти ускорение, путем деления результирующей силы на массу объекта: a = f / m

(Второй закон Ньютона для постоянных масс)

  1. выполнить числовую интеграцию на ускорение, чтобы получить скорость/положение
  2. обновить тело/вершины новыми скорость/положение и повторить с 1го пункта

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

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

В порядке реализации этой моделирующей системы, существует 4 главных групп классов, которые мы будем создавать:

  • Объекты моделирования: это объект (может быть модель, вершина, треугольник и т.д.) вместе со своими атрибутами моделирования, такими как позиция, скорость и масса, упакованный в один блок.
  • Источники силы: к ним относятся явления, которые могут порождать силу, такую как упругость(spring) или гравитация.
  • Интеграторы: они выполняют числовую интеграцию, используя ускорение для поиска новой позиции/скорости, и обновляют соответствующие атрибуты в данном объекте моделирования.
  • Моделирования: это главные классы, которые будут обеспечивать весь алгоритм моделирования. В задачи, которые они выполняют, включаются инициализация всех переменных, соединение упругих нитей(the springs) и обновление моделирования.
  1. Классы объекта моделирования

Вспомните, что нам надо следить за позицией и возможно за скоростью объекта текущего моделирования. Это будет более просто сделать, если мы совместим объект моделирования и его атрибуты. Таким образом, давайте для начала начнем с классов объекта моделирования.

1.2.1 Абстрактный класс SimObject.

Мы сначала создадим абстрактный класс SimObject. Он будет содержать необходимые методы и функции, которые будут наследоваться другими классами объекта моделирования.

Используя Solution Explorer, добавьте новую папку по имени SimObjects в существующую папку SoftBody. Потом создайте новый файл класса и назовите его SimObject.cs.

(SimObject.cs)
using Microsoft.Xna.Framework;

using SkeelSoftBodyPhysicsTutorial.Main;
namespace SkeelSoftBodyPhysicsTutorial.SoftBody.SimObjects

{

    public
enum
SimObjectType { PASSIVE, ACTIVE }

    public
abstract
class
SimObject

    {

        private
float mass;

        private
SimObjectType simObjectType;

        protected
Vector3 currPosition;

        protected
Vector3 prevPosition;

        protected
Vector3 currVelocity;

        public
float Mass

        {

            get { return mass; }

            set { mass = value; }

        }
        public
SimObjectType SimObjectType

        {

            get { return simObjectType; }

            set { simObjectType = value; }

        }
        public
Vector3 CurrPosition

        {

            get { return currPosition; }

            set { currPosition = value; }

        }
        public
float CurrPositionX

        {

            get { return currPosition.X; }

            set { currPosition.X = value; }

        }
        public
float CurrPositionY

        {

            get { return currPosition.Y; }

            set { currPosition.Y = value; }

        }
        public
float CurrPositionZ

        {

            get { return currPosition.Z; }

            set { currPosition.Z = value; }

        }
        public
Vector3 PrevPosition

        {

            get { return prevPosition; }

            set { prevPosition = value; }

        }
        public
Vector3 CurrVelocity

        {

            get { return currVelocity; }

            set { currVelocity = value; }

        }
        //——————————————————————
        public SimObject(float mass, SimObjectType simObjectType)

        {

            this.mass = mass;

            this.currPosition = Vector3.Zero;

            this.prevPosition = currPosition;

            this.currVelocity = Vector3.Zero;

            this.simObjectType = simObjectType;

        }

    }

}

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

В конструкторе выше, мы также инициализируем currPosition, prevPosition и currVelocity переменные к нулевому вектору.

Вспомните, что мы должны суммировать действующие на этот объект моделирования силы. Будет удобно объекту непосредственно хранить значение результирующей силы так, чтобы объект мог быть передан различным классам, и результирующая сила все еще прослеживалась и хранилась. Таким образом, мы создадим resultantForce переменную как элемент класса в SimObject.

(элемент класса в SimObject.cs)
        protected
Vector3 resultantForce;

        public
Vector3 ResultantForce

        {

            get { return resultantForce; }

            set { resultantForce = value; }

        }

Мы также создадим метод, сбрасывающий результирующую силу. Этот метод будет обычно вызываться либо в конце, либо в начале каждого временного шага.

(метод класса в SimObject.cs)
        public
void ResetForces()

        {

            this.resultantForce = Vector3.Zero;

        }

Наконец, у любого класса, который наследовал класс SimObject, должен быть свой собственный метод Update, чтобы осуществить это, мы определяем абстрактный метод под названием Update, чтобы сделать его обязательным для производных классов.

(метод класса в SimObject.cs)
        public
abstract
void Update(GameTime gameTime);

Реклама
Запись опубликована в рубрике Uncategorized. Добавьте в закладки постоянную ссылку.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s