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

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

(в самом верху Game1.cs)
using SkeelSoftBodyPhysicsTutorial.SoftBody.Integrators;
(внутри InitClothScene()in Game1.cs)
            //create an integrator and assign it to the sim

            float drag = 0.01f;

            Integrator integrator = new
VerletNoVelocityIntegrator(this, drag);

            clothSim.Integrator = integrator;

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

(метод класса, дополнительный код жирным шрифтом)
        protected
override
void LoadContent()

        {

            spriteBatch = new
SpriteBatch(GraphicsDevice);

            clothPlane.LoadContent();

        }

Затем, мы должны попросить, чтобы моделирование ткани обновлялось на каждом временном шаге.

(метод класса, дополнительный код жирным шрифтом)
        protected
override
void Update(GameTime gameTime)

        {

            //update the sim

            clothSim.Update(gameTime);
            base.Update(gameTime);

        }

Наконец, мы должны рисовать ткань в каждом временном шаге так, чтобы это было видно на экране. Мы также отменим culling mode. По умолчанию состояние рендеринга — отбрасывание невидимых поверхностей модели, что сделает одну сторону ткани невидимой, хотя она может быть перед камерой. Как только мы это отменим, мы будем в состоянии видеть обе стороны плоскости.

(метод класса, дополнительный код жирным шрифтом)
        protected
override
void Draw(GameTime gameTime)

        {

            GraphicsDevice.Clear(Color.CornflowerBlue);

            GraphicsDevice.RenderState.CullMode = CullMode.None;

            base.Draw(gameTime);

            clothPlane.Draw(gameTime);

        }

Если Вы скомпилируете и выполните программу теперь, Вы должны видеть, что ткань спадает складками вниз с двумя прикрепленными верхними углами.

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

(метод класса, дополнительный код жирным шрифтом
        protected
override
void Update(GameTime gameTime)

        {

            //poll for input

            HandleInput(gameTime);
            //update the sim

            clothSim.Update(gameTime);
            base.Update(gameTime);

        }
        private
void HandleInput(GameTime gameTime)

        {

            if (inputComponent.IsMouseHeldDown(MouseButtonType.Left))

            {

                topLeftCorner.PointX += -inputComponent.MouseMoved.X / 40;

                topLeftCorner.PointY += inputComponent.MouseMoved.Y / 40;

            }

            if (inputComponent.IsMouseHeldDown(MouseButtonType.Right))

            {

                topRightCorner.PointX += -inputComponent.MouseMoved.X / 40;

                topRightCorner.PointY += inputComponent.MouseMoved.Y / 40;

            }

        }

Так как пространство экрана и мировое пространство существуют в различных масштабах, мы должны разделить значение MouseMoved на определенное значение масштаба. Подходящее значение, найдено как 40 после некоторых проб и ошибок.

Скомпилируйте и выполните программу, и Вы должны получить управляемое моделирование ткани точно такое же как на Видео 5, которое Вы видели в начале этой главы!

В этой главе мы затронули несколько важных понятий, связанных с моделированием ткани. Мы обсудили ограничения, почему они нам нужны и обеспечили реализацию, которая использует метод ослабления. Затем мы создали интегратор Verlet, который работает вместе с ограничениями, которые у нас есть, так как нет никакой скорости, используемой или сохраненной в интеграторе Verlet. Затем мы начали реализовывать класс SimVertex, класс SoftBodySim и класс ClothSim, которые основаны на том, что было создано в предыдущей главе. Наконец, мы создали экземпляр класса моделирования ткани.

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

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

Глава 3 – Целевое Моделирование Мягких Тел(Goal Soft Bodies): Моделирование слинки

Загрузите исходные файлы для начала этой главы

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

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

Видео 9: Модель псевдо слинки, с использованием целевого мягкого тела

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

3.1 Класс целевого мягкого тела

Давайте начнем с того, что посмотрим, как пойдет создание целевого мягкого тела. Что касается Рис. 7, мы можем видеть, что есть фактически два объекта: целевой объект и мягкий объект тела. Мы прикрепляем нить между каждой вершиной мягкого тела и соответствующей вершиной целевого объекта. Поскольку целевой объект преобразовывается с течением времени, вершина мягкого тела будет перемещена вперед, создавая нам эффект мягкого тела, который нам нужен.


Рис 7: основная идея целевого мягкого тела.

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

Это аналогично тому как мягкие тела создаются в 3D-пакетах таких как Maya, где есть целевой объект и мягкий объект тела, который следует за целевым на основе вершин. Мы просто создадим тот же самый объект дважды, одним из них будет мягким объектом тела, а другой — целевым объектом.

Теперь давайте создадим класс GoalSoftBodySim. В папке Simulations создайте новый файл класса GoalSoftBodySim.cs.

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

using SkeelSoftBodyPhysicsTutorial.Primitives;

using SkeelSoftBodyPhysicsTutorial.SoftBody.SimObjects;
namespace SkeelSoftBodyPhysicsTutorial.SoftBody.Simulations

{

    public
sealed
class
GoalSoftBodySim : SoftBodySim

    {

        private
TexturedPrimitive softBodyObject;

        private
TexturedPrimitive softBodyGoalObject;

        public GoalSoftBodySim(Game game, TexturedPrimitive softBodyObject, TexturedPrimitive softBodyGoalObject, float mass, float stiffness, float damping)

            : base(game)

        {

            this.softBodyObject = softBodyObject;

            this.softBodyGoalObject = softBodyGoalObject;
            //create sim vertices on both the goal and non-goal object

            CreateSimVertices(softBodyObject, mass);

            CreateSimVerticesForGoal(softBodyGoalObject, mass);
            //connect springs between the vertices of the goal and non-goal object

            ConnectSprings(stiffness, damping);

        }

    }

}

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

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

(метод класса в GoalSoftBodySim.cs)
        private
void CreateSimVertices(TexturedPrimitive softBodyObject, float mass)

        {

            int numVertices = softBodyObject.NumVertices;

            float vertexMass = mass / numVertices;

            simVertices = new
SimVertex[numVertices];

            for (int i = 0; i < numVertices; i++)

            {

                simVertices[i] = new
SimVertex(vertexMass, SimObjectType.ACTIVE, i, softBodyObject);

                this.AddSimObject(simVertices[i]);

            }

        }

Реализация для CreateSimVerticesForGoal похожа. Единственное различие — то, что мы создаем другой массив, чтобы сохранить этот список целевого SimVertexs, и что эти SimVertexs установлены как пассивные.

(член класса в GoalSoftBodySim.cs)
        private
SimVertex[] simVerticesForGoal;

(метод класса в GoalSoftBodySim.cs)
        private
void CreateSimVerticesForGoal(TexturedPrimitive softBodyObject, float mass)

        {

            int numVertices = softBodyObject.NumVertices;

            float vertexMass = mass / numVertices;

            simVerticesForGoal = new
SimVertex[numVertices];

            for (int i = 0; i < numVertices; i++)

            {

                simVerticesForGoal[i] = new
SimVertex(vertexMass, SimObjectType.PASSIVE, i, softBodyObject);

                this.AddSimObject(simVerticesForGoal[i]);

            }

        }

Затем, мы присоединяем нити от мягкого тела до целевого объекта, выполняя метод CreateSprings. Отметьте, что мы передали одну жесткость для всех нитей, что не даст приличный результат мягкого тела. Варьируем жесткость нитей, которые мы создали, основываясь на единственной определенной жесткости. Мы начнем с половины жесткости для первой нити, и увеличивая постепенно до полной жесткости для последней нити. Сначала обнаружим значение приращения и затем будем увеличивать жесткости каждой последующей нити на это количество. Мы также будем использовать то же самое значение силы сопротивления для всех нитей.

(метод класса в GoalSoftBodySim.cs)
        private
void ConnectSprings(float stiffness, float damping)

        {

            //find the increment step for each subsequent spring

            float increment = (0.5f * stiffness) / softBodyObject.NumVertices;
            for (int i = 0; i < softBodyObject.NumVertices; i++)

            {

                //create a gradient stiffness from 0.5 stiffness to 1.0 stiffness

                float thisStiffness = (increment * i) + 0.5f * stiffness;

                this.AddSpring(thisStiffness, damping, simVertices[i], simVerticesForGoal[i]);

            }

        }

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

(метод класса в GoalSoftBodySim.cs)
        public
override
void Update(GameTime gameTime)

        {

            //call base.Update() to update the vertex positions

            base.Update(gameTime);
            //recalculate the vertex normals

            softBodyObject.RecalculateNormals();
            //commit the vertex position and normal changes

            softBodyObject.CommitChanges();

        }

3.2 Создание Целевого гибкого Тела

Теперь мы готовы создать целевое гибкое тело в Game1.cs. Во-первых, мы готовим метод, чтобы инициализировать сцену.

(метод класса в Game1.cs, дополнительный код жирным шрифтом)
        protected
override
void Initialize()

        {

            InitGoalSoftBodyScene();

            base.Initialize();

        }
        private
void InitGoalSoftBodyScene()

        {

        }

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

(снаружи InitGoalSoftBodyScene() в Game1.cs)
        TexturedCylinder cylinder;
(внутри InitGoalSoftBodyScene() в Game1.cs)
            //cylinder attribute

            float length = 10.0f;

            float radius = 3.0f;

            int lengthSegments = 30;

            int radialSegments = 50;
            //load in the cylinder

            cylinder = new
TexturedCylinder(this, length, radius, lengthSegments, radialSegments, «checkerboard»);

            cylinder.Initialize();

Затем мы загружаем другой TexturedCylinder как целевой объект.

outside InitGoalSoftBodyScene() in Game1.cs)
        TexturedCylinder goalCylinder;
(внутри InitGoalSoftBodyScene() в Game1.cs)
            //load in another same cylinder as the goal

            goalCylinder = new
TexturedCylinder(this, length, radius, lengthSegments, radialSegments, «checkerboard»);

            goalCylinder.Initialize();

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

(снаружи InitGoalSoftBodyScene() в Game1.cs)
        GoalSoftBodySim goalSoftBodySim;
(внутри InitGoalSoftBodyScene() в Game1.cs)
            //create a goal soft body sim

            float mass = 0.1f;

            float stiffness = 0.03f;

            float damping = 0.0f;

            goalSoftBodySim = new
GoalSoftBodySim(this, cylinder, goalCylinder, mass, stiffness, damping);

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

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

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

Логотип WordPress.com

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

Фотография Twitter

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

Фотография Facebook

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

Google+ photo

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

Connecting to %s