Список постов в категории "Жизнь"

Создание правильного полигона для Box2D

Движок Box2D используется для симуляции физики в двумерном пространстве. Из фигур он поддерживает сферу (круг), бокс (прямоугольник) и выпуклый полигон (с внутренними углами больше 1-10 градусов, иначе будет падение с ошибкой).

Что же делать, если надо нарисовать этот полигон от руки и скормить Box2D, чтоб он не рухнул?

Можно нарисовать составной полигон в виде множества сфер и боксов. Так, например, сделана фигура танка для демки движка NeoAxis Game Engine (этот движок трехмерный, но проблемы с физикой такие же)

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

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

Третий пункт — это просто оптимизация. Делать его необязательно, реализуется простым перебором всех треугольников.

  • находим два треугольника со смежной стороной (две точки должны быть общими)
  • сливаем их в один полигон
  • проверяем на выпуклость (внутренние углы должны быть меньше 180)

И еще один момент: если угол между сторонами полигона равен 180 градусам, можно удалить точку, общую для обеих сторон.

Управляем скоростью полета камеры

Все мы видели как камера плавно перелетает с места на место в различных играх. Попробуем повторить хотя бы минимум этого функционала, а именно: ограничим скорость полета камеры и дистанции текущей позиции камеры до вычисленной (чтобы камера не опаздывала за быстрым перемещением персонажа).

Итак, обозначения:

  • currCameraPos — текущая позиция камеры
  • nextCameraPos — будущая позиция камеры (например на n метров позади объекта наблюдения)
  • speed — скорость камеры в м/с
  • maxDist — максимально допустимая дистанция между currCameraPos и nextCameraPos

Алгоритм:

  • вычисляем направление и длину от текущей до будущей позиций камеры
  • корректируем длину в зависимости от speed и maxDist
  • смещаем камеру из текущей в будущую позицию камеры с учетом длины

А вот, собственно, код этого безобразия:

void updateCameraPosition( float dt )
{
    // Скорость камеры в метрах в секунду
    const float speed = 0.5f;
    // Максимальная дистанция от текущей позиции камеры до будущей
    const float maxDist = 1.0f;

    // Текущая позиция камеры
    const Ogre::Vector3 currCameraPos = camera->getPosition();
    // Будущая позиция камеры
    const Ogre::Vector3 nextCameraPos = calculateCameraPosition();

    // Направление от текущей позиции камеры до будущей
    Ogre::Vector3 direction = nextCameraPos - currCameraPos;
    // Длина смещения камеры
    float dist = direction.length();
    // Нормализуем направление
    direction.normalise();

    // Проверим дистанцию
    if (dist > maxDist)
    {
        camera->setPosition(nextCameraPos - direction * maxDist);
    }
    // Иначе применим скорость
    else
    {
        // Ограничим максимальное смещение, 
        // чтобы не улететь дальше nextCameraPos;
        const float realSpeed = Ogre::Math::Clamp(dt * speed, 0.0f, dist);
        camera->setPosition(currCameraPos + direction * realSpeed);
    }
}

Примечание для специалистов: да, я в курсе, что в играх применяется более плавное движение камеры с учетом инерции. Об этом как-нибудь в другой раз.

Как просверлить квадратное отверстие? Теория и практика

Оказывается, есть способ сверления квадратных отверстий. Ниже подробное описание теории в картинках и видео реальной работы.

Теория

Практика

Источник видео с теорией: «Математические этюды».

Как научиться шевелить ушами. Теория и практика

Иногда меня просят показать шевеление ушами. Но никто не спрашивает как я это делаю. Расскажу вкратце как это делается. Вы смотрели «Полицейскую академию»? Нет? Ну и дурак зря.

Джордж Гейнс Прошу любить и жаловать, комендант Эрик Лассард (в быту Джордж Гейнс). Именно этот человек в каком-то 199x году заставил меня задуматься, как двигать ушами самому.

В те далекие времена у меня было очень много свободного времени, как у того медвежонка из анекдота. Домашнее задание я практически не делал, потому что прогуливал школу периодически. Ремонт в квартире происходил без моего участия, да и запчасти на машину не надо было искать по всему городу, потому что велосипед. А велосипед «Кама», как известно, хрен сломаешь.

Оказалось, что двигать ушами довольно просто. Многие делают это неосознанно. Видели как у военного или стража порядка шевелится фуражка, когда он удивлен? Ты ему: «Да не было тут никогда одностороннего движения», а он тебе так р-р-аз фуражкой недовольно пошевелит: «Пройдемте, мол, уважаемый, в машину, изымем права». А животное (млекопитающее) шевелит ушами ежедневно помногу раз, особенно если эта скотина сожрала все вкусные конфетки со стола, раскидала мусорное ведро по всей кухне и растрепала твой любимый пуфик.

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

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

А еще можно двигать носом влево вправо и вниз, но об этом в другой раз.

Bullet Game Physics изменение позиции и ориентации физического тела

Не буду долго размусоливать. Приведу сразу код:

void setTransform( btRigidBody * body, const btVector3 & position, const btQuaternion & rotation )
{
    // Матрица транформации
    btTransform transform;
    transform.setIdentity();
    
    // Заполним матрицу
    transform.setOrigin(position);
    transform.setRotation(rotation);

    // Применим матрицу к телу
    body->setWorldTransform(transform);

    // Важный этап: обнулим линейную и угловую скорости
    body->setLinearVelocity(btVector3(0, 0, 0));
    body->setAngularVelocity(btVector3(0, 0, 0));
}

Для чего требуется обнуление скоростей? Догадайтесь сами.

Блог Евгения Жирнова