Докуметация Cтарт Статьи Форум Лента Вход
Не официальное русскоязычное сообщество
Главная
    Документация jMonkeyEngine
        jMonkeyEngine Уроки и Документация
            Внешние программы
                3ds Max Анимация Костей для JME3 с использованием плагина OgreMax

3ds Max Анимация Костей для JME3 с использованием плагина OgreMax

Опубликованно: 27.10.2017, 20:40
Последняя редакция, Andry: 17.02.2018 18:57

Asset Management

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

Создание моделей в 3dsMax

Для этого урока я использовал 3D Studio Max 2012 и бесплатную версию OgreMax 2.4.3

Создать модель и кости

  • Создайте новый файл
  • Выберите Create ▸ Standard Primitives ▸ Cylinder
  • 3dsmax-0

  • Нарисуйте цилиндр, скажем, с 8 сегментами высоты (должно быть достаточно для гладкой деформации)
  • Также выберите Generate Mapping Coords.
  • 3dsmax-1

  • Нажмите вкладку Create ▸ Systems ▸ Bones IK Chain
  • 3dsmax-2

  • Добавим кости в центр цилиндра
  • 3dsmax-3

  • Выберите цилиндр, щелкните по нему [ПК Мыши] и выберите Convert To: ▸ Convert to Editable Mesh, чтобы предотвратить проблемы с OgreMax
  • Кликните [ЛК Мыши] по вкладке Modifier List и добавьте модификатор Skin
  • 3dsmax-4

  • Напротив Bones: нажмите кнопку Add и выберите все ваши кости
  • 3dsmax-5

  • Вы также можете редактировать envelopes, но для небольшого теста, настройки по умолчанию вполне подойдут

Создание анимации

  • Выберите цилиндр и нажмите на вкладку Display ▸ Freeze ▸ Freeze Selected, чтобы было легче выбирать кости во время анимации
  • Выберите две верхние кости и включите режим Auto Key
  • 3dsmax-6

  • Первый ключевой кадр будет создан автоматически. Переместите ползунок анимационной дорожки на кадр 5
  • Немного сдвиньте выделенные кости. Сетка цилиндра будет деформирована. Поскольку вы находитесь в режиме Auto Key, будет создан ключевой кадр
  • 3dsmax-7

  • Создайте несколько дополнительных ключевых кадров. Вы также можете выбирать другие кости для этого и двигать или поворачивать их. Я создал 25 кадров, и последний ключевой кадр равен первому, так что анимация получается цикличной.
  • После того как вы закончите создание анимации отключите режим Auto Key.

Настройка OgreMax

  • Откройте OgreMax Scene Settings из меню
  • На вкладке Meshes включите Export XML Files и отключите Export Binary Files, а также Export Vertex Colors,
  • 3dsmax-8

  • Перейдите на вкладку Environment и уберите галочку с Export Environment Settings. В противном случае импортер JME выдаст исключение NullPointerException
  • 3dsmax-9

  • Если вы текстурировали свою модель, вы также можете поставить галочку Copy Bitmaps to Export Directory на вкладке Bitmaps.
  • Разблокируйте цилиндр, щелкнув вкладку Display ▸ Freeze ▸ Unfreeze All
  • Пока цилиндр выбран, откройте в меню диалоговое окно OgreMax Object Settings
  • Откройте вкладку Mesh Animations и выберите Skeleton, Export Skeleton : Yes,
  • Ниже Mesh Animations нажмите кнопку Add…
  • Назначьте Name для track например как, wobble. Тип Track должен быть Skin. Задайте правильно Start/End Frames для вашей анимации
  • 3dsmax-10

  • Нажмите [ОК], и вы увидите анимацию в таблице. Вы можете добавить дополнительные анимации, выбрав другие диапазоны кадров, если хотите
  • 3dsmax-11

Экспорт и импорт

  • Когда все анимации находятся в списке, выберите OgreMax ▸ Export ▸ Export Scene и назовите файл worm.scene,
  • Создайте тестовый класс JME, который импортирует файл, получает контроллер анимации и запускает анимацию wobble
import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.animation.Skeleton;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.plugins.FileLocator;
import com.jme3.light.AmbientLight;
import com.jme3.light.PointLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.LodControl;
import com.jme3.scene.debug.SkeletonDebugger;

/**
 * Это тестовый класс для загрузки Ogre XML сцены, экспортируемой OgreMax.
 *
 * @author Stephan Dreyer
 *
 */
public class TestOgreMaxImport extends SimpleApplication {

  @Override
  public void simpleInitApp() {
    assetManager.registerLocator("Assets/model/ogre/test/", FileLocator.class);

    // создадим геометрию и прикрепим ее
    final Node model = (Node) assetManager.loadModel("worm.scene");
    // изменим её размер, из-за большого масштаба в 3dsmax
    model.setLocalScale(.001f);

    // прикрепим к корневому узлу
    rootNode.attachChild(model);
    addLodControl(model);

    final AnimControl ac = findAnimControl(model);

    try {
      // добавим отладчик(debugger) скелета, чтобы сделать кости видимыми
      final Skeleton skel = ac.getSkeleton();
      final SkeletonDebugger skeletonDebug = new SkeletonDebugger("skeleton",
          skel);
      final Material mat = new Material(assetManager,
          "Common/MatDefs/Misc/Unshaded.j3md");
      mat.setColor("Color", ColorRGBA.Green);
      mat.getAdditionalRenderState().setDepthTest(false);
      skeletonDebug.setMaterial(mat);
      ((Node) ac.getSpatial()).attachChild(skeletonDebug);

      // создадим канал и запустим анимацию wobble
      final AnimChannel channel = ac.createChannel();
      channel.setAnim("wobble");
    } catch (final Exception e) {
      e.printStackTrace();
    }

    // добавим немного освещения
    rootNode.addLight(new AmbientLight());
    rootNode.addLight(new PointLight());
  }

  public void addLodControl(final Spatial parent) {
    if (parent instanceof Node) {
      for (final Spatial s : ((Node) parent).getChildren()) {
        addLodControl(s);
      }
    } else if (parent instanceof Geometry) {
      final LodControl lc = new LodControl();
      lc.setDistTolerance(1f);
      parent.addControl(lc);
    }
  }

  /**
   * Метод поиска animation control, поскольку он не находится на корневом узле
   * моделей.
   *
   * @param parent
   *          Поиск spatial.
   * @return {@link AnimControl} или null, если он не существует.
   */
  public AnimControl findAnimControl(final Spatial parent) {
    final AnimControl animControl = parent.getControl(AnimControl.class);
    if (animControl != null) {
      return animControl;
    }

    if (parent instanceof Node) {
      for (final Spatial s : ((Node) parent).getChildren()) {
        final AnimControl animControl2 = findAnimControl(s);
        if (animControl2 != null) {
          return animControl2;
        }
      }
    }

    return null;
  }

  public static void main(final String[] args) {
    new TestOgreMaxImport().start();
  }
}

Вы увидите странные движения червя. Повеселитесь!

3dsmax-12

3ds Max Двуножная Анимация для JME3(3ds Max Biped Animation to JME3)

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

Создание персонажа в 3dsMax

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

  • Вы можете создать biped, перед тем как приступать к моделированию, потому что довольно легко подгонять пропорции двуногих.
  • После создания модели и biped я получил что-то вроде этого:
  • 1

  • Я добавил модификатор Meshmooth с Iterations 2 и получил этот результат:
  • 3dsmax_biped_2

  • После сглаживания вашей сетки вы можете откорректировать вершины с помощью модификатора Edit Mesh. Наконец, вы добавляете модификатор Physique .
  • Теперь вы можете редактировать свои envelopes в соответствии с вашей моделью.

Создание простой анимации ходьбы

  • Выберите сундук вашего biped, выберите вкладку Motion (1) ▸ Foot Step Mode (2) ▸ Create Multiple Footsteps (3)
  • Вам нужно выбрать In Place Mode (4), чтобы персонаж двигался на месте, не меняя своего местоположения.
  • 3dsmax_biped_3_1

  • Теперь вы можете немного поиграть с настройками, я скорректировал Actual Stride Length и Actual Stride Height.
  • Для Number of Footsteps(Колличеста шагов), 6 будет достаточно, потому что циклическая анимация будет позже.
  • Вы также можете создавать или редактировать шаги вручную и перемещать или поворачивать их.
  • После того, как все шаги будут созданы, нажмите кнопку Create Keys for Inactive Footsteps на панели Footstep Operations
  • Теперь вы можете проверить свою анимацию, нажав кнопку Play на временной шкале.

Подготовка экспорта и настройка OgreMax

  • OgreMax Scene Settings должны быть такими же, как показано выше.
  • Поскольку вы хотите, чтобы ваша анимация была зациклена, вам нужно найти два ключевых кадра, где ноги находятся почти в одном положении. Для моих настроек я выбрал кадры 48-78 для анимации ходьбы.
  • Выберите сетку(mesh) персоонажа и откройте диалоговое окно OgreMax Scene Settings.
  • Откройте вкладку Mesh Animations и выберите тип Skeleton, Export Skeleton: Yes,
  • Ниже Mesh Animations нажмите кнопку Add…
  • 3dsmax_biped_4

  • Введите Name для track, например walk.
  • Убедитесь, что для типа Track задано значение Physique.
  • Задайте Start/End Frames, в моём случае это 48-78.
  • Закройте диалоговое окно, нажав [Ok].
  • Было бы полезно создать также track start_run, который совмещал бы остановку с анимацией ходьбы. Я бы использовал для этого кадры 0-47.
  • Поскольку ваша модель сглажена и от того с большим количеством полигонов, может быть полезно создать уровни детализации (LOD). Что бы когда камера будет отдалятся, от вашего персонажа будет рендерится(визуализироваться) низко полигональная сетка(mesh) вашего персонажа.
  • 3dsmax_biped_5

  • Откройте вкладку Mesh LOD в настройках объекта.
  • Достаточно выбрать Automatic setting, но если ваша анимация будет выглядеть странно, вы можете создать его вручную.
  • Я использовал 4 уровня LOD с расстоянием 1. Не беспокойтесь о настройке расстояния, вы можете изменить её позже в JME.
  • Для Reduction Each Lavel By я использовал 20 percent, которые дают хорошие результаты. Вы можете отрегулировать все настройки под ваших потребности.
  • Закройте диалоговое окно, нажав [Ok].

Фиксирование местоположения

  • Перед экспортом вам нужно сделать небольшое исправление, потому что ваша модель на самом деле не находится там, где вы ее видите. В JME будет масса неприятностей, если вы не измените это.
  • Обеспечьте сохранение максимального файла. Иногда OgreMax вызывает сбой всего приложения при экспорте. Если вы хотите изменить анимацию после экспорта, вы должны перезагрузить весь этот файл, потому что исправление чего либо меняет местоположения, почему так я не знаю.
  • 3dsmax_biped_6

  • Щелкните [ПК Мыши] инструмент Select and Move на верхней панели инструментов. Появится диалоговое окно.
  • Задайте X и Y в положение 0 и закройте диалоговое окно.
  • Есть еще один способ добиться этого. Если вы масштабировали, перемещали или поворачивали свою модель, просто откройте вкладку Hierarchy и нажмите Transform и Scale на панели Reset.

Экспорт и импорт

  • Теперь вы можете экспортировать свою сцену. Выберите только сетку(mesh) и используйте Export selected objects. Вам не нужна вся сцена, включая biped объект, но кости создаются автоматически во время экспорта.
  • Создайте тестовый класс JME для импорта сцены.

Для этого я расширил первый класс:

import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.animation.Skeleton;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.plugins.FileLocator;
import com.jme3.light.AmbientLight;
import com.jme3.light.PointLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.LodControl;
import com.jme3.scene.debug.SkeletonDebugger;
import com.jme3.scene.shape.Box;

/**
 * Это тестовый класс для загрузки Ogre XML сцены, экспортируемой OgreMax.
 *
 * @author Stephan Dreyer
 *
 */
public class TestOgreMaxImport extends SimpleApplication {

  @Override
  public void simpleInitApp() {
    assetManager.registerLocator("Assets/model/ogre/test/", FileLocator.class);

    // создадим геометрию и прикрепим ее
    final Node model = (Node) assetManager.loadModel("guy.scene");
    // изменим её размер, из-за большого масштаба в 3dsmax
    model.setLocalScale(.02f);

    // прикрепим к корневому узлу
    rootNode.attachChild(model);
    addLodControl(model);

    final AnimControl ac = findAnimControl(model);

    try {
      // добавим отладчик(debugger) скелета, чтобы сделать кости видимыми
      final Skeleton skel = ac.getSkeleton();
      final SkeletonDebugger skeletonDebug = new SkeletonDebugger("skeleton",
          skel);
      final Material mat = new Material(assetManager,
          "Common/MatDefs/Misc/Unshaded.j3md");
      mat.setColor("Color", ColorRGBA.Green);
      mat.getAdditionalRenderState().setDepthTest(false);
      skeletonDebug.setMaterial(mat);
      ((Node) ac.getSpatial()).attachChild(skeletonDebug);

      // создадим канал и запустим анимацию walk
      final AnimChannel channel = ac.createChannel();
      channel.setAnim("walk");
    } catch (final Exception e) {
      e.printStackTrace();
    }

    flyCam.setMoveSpeed(40f);
    cam.setLocation(new Vector3f(15, 10, 15));
    cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
    cam.setFrustumNear(1f);

    // добавим немного освещения
    rootNode.addLight(new AmbientLight());

    final PointLight pl = new PointLight();
    pl.setPosition(new Vector3f(-3f, 3f, 1f));
    rootNode.addLight(pl);

    // добавим куб в качестве пола
    final Box b = new Box(100f, 0.1f, 100f);
    final Geometry geo = new Geometry("floor", b);

    final Material mat = new Material(assetManager,
        "Common/MatDefs/Misc/Unshaded.j3md");
    mat.setColor("Color", ColorRGBA.LightGray);
    geo.setMaterial(mat);

    rootNode.attachChild(geo);
  }

  /**
   * Метод перемещения по графу сцены и добавление {@link LodControl} 
   * в сетку(mesh).
   *
   * @param parent
   *          Узел для добавления control.
   */
  public void addLodControl(final Spatial parent) {
    if (parent instanceof Node) {
      for (final Spatial s : ((Node) parent).getChildren()) {
        addLodControl(s);
      }
    } else if (parent instanceof Geometry) {
      final LodControl lc = new LodControl();

      // здесь задано расстояние для изменений LOD, вы можете отрегулировать это
      lc.setDistTolerance(1f);
      parent.addControl(lc);
    }
  }

  /**
   * Метод поиска animation control, поскольку он не находится на корневом узле
   * моделей.
   *
   * @param parent
   *          Поиск spatial.
   * @return {@link AnimControl} или null, если он не существует.
   */
  public AnimControl findAnimControl(final Spatial parent) {
    final AnimControl animControl = parent.getControl(AnimControl.class);
    if (animControl != null) {
      return animControl;
    }

    if (parent instanceof Node) {
      for (final Spatial s : ((Node) parent).getChildren()) {
        final AnimControl animControl2 = findAnimControl(s);
        if (animControl2 != null) {
          return animControl2;
        }
      }
    }

    return null;
  }

  public static void main(final String[] args) {
    new TestOgreMaxImport().start();
  }
}

После запуска класса вы можете увидеть приятную плавную анимацию (если она не плавная, вам нужно настроить кадры дорожки(track frames)):

3dsmax_biped_7

Как вы можете видеть, LOD работает:

3dsmax_biped_8

Смотрите так же:


Переведено для jmonkeyengine.ru, оригинал
Автор перевода: Andry

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

jMonkeyEngine.ru © 2017. Все права сохранены.