Кодю генератор растительности. Собственно, сам генератор уже готов - теперь занимаюсь тем, чтобы мне не пришлось вручную указывать, какие модели грузить из архива. Они грузятся все :D
std::map< std::string, std::vector< Node*> >assets;
Bundle *b = Bundle::create( "res/assets/tree.gpb" );
_loader = b->loadScene();
for ( ; _loader->getFirstNode() != NULL; )
{
Node* asset = _loader->getFirstNode();
_scene->addNode(asset);
asset->getModel()->setMaterial("res/anim.material");
Animation* an = asset->getAnimation();
AnimationClip* cl = an->createClip("idle", 0, an->getDuration() );
cl->setSpeed(1);
cl->setRepeatCount(0);
cl->play();
assets["trees"].push_back(asset);
}
_loader->release();
SAFE_RELEASE(b);
for (size_t i = 0; i < dots.size(); i++)
{
dots[i].ID = rand() % assets["trees"].size();
}
Cхемка простейшая, но через полгода едва ли я смогу объяснить, как она работает, поэтому сейчас расскажу :D
В игре есть две сцены - _scene и _loader. Одна отвечает за отрисовку, а другая только за загрузку дополнительных ресурсов. А всё потому, что в этом движке невозможно заранее узнать, какие именно объекты хранятся в архиве, поэтому ресурсы из архивов я гружу целиком в _loader.
Открывается файл "tree.gpb" со скелетными моделями, из него все ресурсы грузятся во временную сцену _loader, а дальше начинается МАГИЯ. Если из сцены _loader добавить объект в сцену _scene, то из _loader он попросту удалится - поэтому цикл for организован таким странным образом (скорее всего лучше было бы обойтись while do).
Node* asset - это указатель на внутриигровой объект, у которого есть матрица трансформации, модель, материал, физический объект, источник звука и эмиттер системы частиц (аналог DummyCube из GLScene). Этому объектику в качестве мамы указываем совсем не родную сцену _scene, тем самым уменьшая счетчик объектов в сцене _loader.
Присваиваем модели объекта asset материал "aim.material", чтобы заработала скелетная анимация, рассчитываемая на GPU. Создаем анимационный клип длиной со всю анимацию, устанавливаем ему скорость, зацикливаем и запускаем.
А дальше - мое маленькое чудо (в любое другое время я вряд ли бы стал юзать такую страшную, но ужасно удобную конструкцию) - есть мап assets, в котором сразу же создастся раздел "trees", хранящий в себе вектор указателей на игровые объекты. В этот вектор и добавится наш объект.
Зачем это нужно: вместо того, чтобы создавать тысячу разных векторов под всякие нужды (для моделей персонажей, деревьев, предметов, других объектов), я аккуратно запаковал всё это дело в подобие словаря, где я могу обратиться к нужной странице ("tree") и отрисовать определенный объект ( assets["tree"][dots[i].ID]->getModel()->draw() ).
Днем таким же макаром буду запаковывать модели из другого архива в раздел "actors".
std::map< std::string, std::vector< Node*> >assets;
Bundle *b = Bundle::create( "res/assets/tree.gpb" );
_loader = b->loadScene();
for ( ; _loader->getFirstNode() != NULL; )
{
Node* asset = _loader->getFirstNode();
_scene->addNode(asset);
asset->getModel()->setMaterial("res/anim.material");
Animation* an = asset->getAnimation();
AnimationClip* cl = an->createClip("idle", 0, an->getDuration() );
cl->setSpeed(1);
cl->setRepeatCount(0);
cl->play();
assets["trees"].push_back(asset);
}
_loader->release();
SAFE_RELEASE(b);
for (size_t i = 0; i < dots.size(); i++)
{
dots[i].ID = rand() % assets["trees"].size();
}
Cхемка простейшая, но через полгода едва ли я смогу объяснить, как она работает, поэтому сейчас расскажу :D
В игре есть две сцены - _scene и _loader. Одна отвечает за отрисовку, а другая только за загрузку дополнительных ресурсов. А всё потому, что в этом движке невозможно заранее узнать, какие именно объекты хранятся в архиве, поэтому ресурсы из архивов я гружу целиком в _loader.
Открывается файл "tree.gpb" со скелетными моделями, из него все ресурсы грузятся во временную сцену _loader, а дальше начинается МАГИЯ. Если из сцены _loader добавить объект в сцену _scene, то из _loader он попросту удалится - поэтому цикл for организован таким странным образом (скорее всего лучше было бы обойтись while do).
Node* asset - это указатель на внутриигровой объект, у которого есть матрица трансформации, модель, материал, физический объект, источник звука и эмиттер системы частиц (аналог DummyCube из GLScene). Этому объектику в качестве мамы указываем совсем не родную сцену _scene, тем самым уменьшая счетчик объектов в сцене _loader.
Присваиваем модели объекта asset материал "aim.material", чтобы заработала скелетная анимация, рассчитываемая на GPU. Создаем анимационный клип длиной со всю анимацию, устанавливаем ему скорость, зацикливаем и запускаем.
А дальше - мое маленькое чудо (в любое другое время я вряд ли бы стал юзать такую страшную, но ужасно удобную конструкцию) - есть мап assets, в котором сразу же создастся раздел "trees", хранящий в себе вектор указателей на игровые объекты. В этот вектор и добавится наш объект.
Зачем это нужно: вместо того, чтобы создавать тысячу разных векторов под всякие нужды (для моделей персонажей, деревьев, предметов, других объектов), я аккуратно запаковал всё это дело в подобие словаря, где я могу обратиться к нужной странице ("tree") и отрисовать определенный объект ( assets["tree"][dots[i].ID]->getModel()->draw() ).
Днем таким же макаром буду запаковывать модели из другого архива в раздел "actors".




