Ejemplo n.º 1
0
//-----------------------------------------------------------------------------------------
bool CBillboardSetEditor::load(bool async)
{
    if(mLoaded->get())
        return true;
    
    if(CNodeEditor::load())
    {
        mBillboardSetHandle = mOgitorsRoot->GetSceneManager()->createBillboardSet(mName->get());
        mHandle->attachObject(mBillboardSetHandle);
        
        mBillboardSetHandle->setBillboardType((Ogre::BillboardType)mBillboardType->get());
        mBillboardSetHandle->setSortingEnabled(mSorting->get());
        mBillboardSetHandle->setBillboardOrigin((Ogre::BillboardOrigin)mOrigin->get());
        mBillboardSetHandle->setBillboardRotationType((Ogre::BillboardRotationType)mRotation->get());
        mBillboardSetHandle->setDefaultWidth(mDefaultWidth->get());
        mBillboardSetHandle->setDefaultHeight(mDefaultHeight->get());
        mBillboardSetHandle->setVisibilityFlags(1 << mLayer->get());
        if(mMaterial->get() != "")
            mBillboardSetHandle->setMaterialName(mMaterial->get());
        
        mBillboardSetHandle->setPointRenderingEnabled(mPointRendering->get());
        mBillboardSetHandle->setRenderingDistance(mRenderDistance->get());

        Ogre::Vector2 v2val;
        Ogre::Vector3 v3val;
        Ogre::Vector4 v4val;
        Ogre::ColourValue cval;
        Ogre::Real rval;
        int ival;
        Ogre::String propname;

        int count = mBillboardCount->get();
        for(int ix = 0;ix < count;ix++)
        {
            propname = "billboard" + Ogre::StringConverter::toString(ix);

            Ogre::Billboard *pBillboard = mBillboardSetHandle->createBillboard(Ogre::Vector3::ZERO);
            mProperties.getValue(propname + "::position", v3val);
            pBillboard->setPosition(v3val);
            mProperties.getValue(propname + "::colour", cval);
            pBillboard->setColour(cval);
            mProperties.getValue(propname + "::dimensions", v2val);
             pBillboard->setDimensions(v2val.x, v2val.y);
            mProperties.getValue(propname + "::rotation", rval);
            pBillboard->setRotation(Ogre::Degree(rval));
            mProperties.getValue(propname + "::texcoordindex", ival);
            pBillboard->setTexcoordIndex(ival);
            mProperties.getValue(propname + "::texrect", v4val);
            pBillboard->setTexcoordRect(v4val.x, v4val.y, v4val.z, v4val.w);
        }

    }
    else
        return false;

    return true;
}
Ejemplo n.º 2
0
void CellDrawActor< C >::allDraw(
    const AllDrawMessage< C >& m
) {
    // Рисуем только если ещё не было нарисовано
    // или по просьбе "обновлять постоянно"
    const std::string sceneName = "CellDrawActor::allDraw::Scene";
    const std::string bsName = "CellDrawActor::allDraw::BillboardSet";

    // @test
    /*
    try {
        m.sm->getRootSceneNode()->removeAndDestroyChild( sceneName );
    } catch ( ... ) {
    }
    try {
        m.sm->destroyBillboardSet( bsName );
    } catch ( ... ) {
    }
    */

    if ( m.update || !m.sm->hasSceneNode( sceneName ) ) {

        // Каждому образу - свой холст (общая сцена)
        auto scene = m.sm->hasSceneNode( sceneName ) ?
            m.sm->getSceneNode( sceneName ) :
            m.sm->getRootSceneNode()->createChildSceneNode( sceneName );

        // Определяем общее кол-во элементов
        const size_t NM = m.N * m.M;

        // Готовим биллборды

        // Обращаются за отрисовкой первый раз?
        const bool virgin = m.sm->hasBillboardSet( bsName );
        Ogre::BillboardSet* bs = nullptr;
        if ( virgin ) {
            bs = m.sm->getBillboardSet( bsName );

        } else {
            // Один образ для всех ячеек
            // @todo Расширить кол-во образов.
            bs = m.sm->createBillboardSet( bsName, NM );
            bs->setAutoextend( true );
            const std::string nameMaterial = m.prefixMaterial + "0";
            bs->setMaterialName( nameMaterial );
            bs->setBillboardType( Ogre::BBT_PERPENDICULAR_COMMON );
            bs->setCommonUpVector( Ogre::Vector3::UNIT_Z );
            bs->setCommonDirection( -Ogre::Vector3::UNIT_Y );
            bs->setBillboardsInWorldSpace( true );
            bs->setBillboardOrigin( Ogre::BBO_CENTER );
            bs->setDefaultDimensions( m.scale, m.scale );
            bs->setUseAccurateFacing( false );
            scene->attachObject( bs );
        }

        // Визуализируем каждую ячейку

        /* - @todo Можно ускорить отрисовку > http://www.ogre3d.org/forums/viewtopic.php?f=2&t=11134&start=0
        Ogre::Billboard b = Ogre::Billboard( Ogre::Vector3::ZERO, bs );
        b.setColour( Ogre::ColourValue::White );
        b.setRotation( Ogre::Degree( (float)rand() ) );
        */

        //bs->beginBillboards();
        for (size_t z = 0; z < m.M; ++z) {
            for (size_t x = 0; x < m.N; ++x) {
                const coordInt2d_t coord( (int)x, (int)z );

                // Создадим образ ячейки с указанной координатой

                const int i = helper::ic( coord.get<0>(), coord.get<1>(), m.N, m.M );
                assert( (i != -1) && "Получена координата за пределами матрицы порта." );
                const C c = m.content[i];

                // Биллборд уже мог быть создан ранее
                const auto bi = helper::index( *bs, coord, m.scale );
                if (bi != -1) {
                    bs->removeBillboard( bi );
                }

                if (c.uid == 0) {
                    // Вакуум - отсутствие образа
                    continue;
                }
    
#if 0
                // - Медленно. Переписано через биллборды.
                /*
                const std::string name =
                    "smoke-pressure-"
                  + Ogre::StringConverter::toString( (int)c.pressure );
                */
                const std::string meshName = "sphere.mesh";
                /* - @todo Так ли каждый раз нужна новая сущность?
                const std::string entityName = meshName + ".entity";
                const bool has = sm->hasEntity( entityName );
                Ogre::Entity* image = has ?
                    sm->getEntity( entityName ) :
                    sm->createEntity( entityName, meshName );
                */
                Ogre::Entity* image = sm->createEntity( meshName );
                auto childScene = sn->createChildSceneNode();
                childScene->attachObject( image );
                // Координаты образа кратны масштабу
                childScene->setPosition(
                    (float)coord.get<0>() * scale,
                    0.0f,
                    (float)coord.get<1>() * scale
                );
                // Образ заполняет ячейку целиком
                //const Ogre::Vector3 fillScale( scale / image->getBoundingRadius() );
                //childScene->setScale( fillScale );
#endif

                // Работаем через биллборды
                // @source http://89.151.96.106/forums/viewtopic.php?f=10&t=60455

                // @todo Визаулизировать в зависимости от характеристики ячейки и соседей.

                // Позиционируем биллборд

                Ogre::Billboard* b = bs->createBillboard(
                    (float)coord.get<0>() * m.scale,
                    0.0f,
                    (float)coord.get<1>() * m.scale
                );
                b->setRotation( Ogre::Degree( (float)rand() ) );
                /*
                b.setPosition(
                    (float)coord.get<0>() * m.scale,
                    0.0f,
                    (float)coord.get<1>() * m.scale
                );
                bs->injectBillboard( b );
                */
                
                // @test
                //break;

            } // for (size_t x = 0; x < m.N; ++x)

        } // for (size_t z = 0; z < m.M; ++z)

        //bs->endBillboards();

    } // if ( m.update || !m.sm->hasSceneNode( sceneName ) )

}