移动模型后面跟随轨迹,模型和布告板之间的连线、布告板显示中文

参考地址:http://blog.csdn.net/flyingleo1981/article/details/39393821

// 画线、布告板显示中文
if (!m_pSceneManager->hasMovableObject("RibbonTrail1", "RibbonTrail"))
{
    Ogre::NameValuePairList params;
    params["numberOfChains"] = "1";
    params["maxElements"] = "500";

    Ogre::RibbonTrail* ribbonTrail = (Ogre::RibbonTrail*)m_pSceneManager
        ->createMovableObject("RibbonTrail1","RibbonTrail", &params);
    ribbonTrail->setTrailLength(100);
    ribbonTrail->setInitialColour(0, Ogre::ColourValue(128, 0, 255));
    ribbonTrail->setColourChange(0, Ogre::ColourValue(0, 0, 0));
    ribbonTrail->setInitialWidth(0, 0.2);
    m_pSceneManager->getRootSceneNode()->attachObject(ribbonTrail);

    Ogre::SceneNode* nodeTemp = m_pSceneManager->getRootSceneNode()
        ->createChildSceneNode("line");
    nodeTemp->setPosition(m_pCurrentObject->getPosition());
    ribbonTrail->addNode(nodeTemp);

    Ogre::Vector3 vt = nodeTemp->getPosition();
    nodeTemp->setPosition(vt.x-10, vt.y+10, vt.z);

    // 显示中文
    Ogre::ColourValue textColor = Ogre::ColourValue(0.5f, 0.0f, 1.0f);
    Ogre::DisplayString str = Ogre::DisplayString(L"食人魔");
    Ogre::MovableText* mt = 
        new Ogre::MovableText("TXT_001", str, "SdkTrays/Caption", 1, textColor);
    mt->showOnTop(true);
    mt->setTextAlignment(
        Ogre::MovableText::HorizontalAlignment::H_CENTER, 
        Ogre::MovableText::VerticalAlignment::V_ABOVE);
    nodeTemp->attachObject(mt);
}

// 移动模型跟随轨迹
if (!m_pSceneManager->hasMovableObject("RibbonTrail2", "RibbonTrail"))
{
    Ogre::NameValuePairList params2;
    params2["numberOfChains"] = "2";
    params2["maxElements"] = "500";
    Ogre::RibbonTrail* ribbonTrail2 = 
        (Ogre::RibbonTrail*)m_pSceneManager->
        createMovableObject("RibbonTrail2","RibbonTrail", &params2);
    ribbonTrail2->setTrailLength(100);
    ribbonTrail2->setInitialColour(0, Ogre::ColourValue(128, 0, 255));
    ribbonTrail2->setColourChange(0, Ogre::ColourValue(0, 0, 0));
    ribbonTrail2->setInitialWidth(0, 0.3);
    ribbonTrail2->setWidthChange(0, 1);
    m_pSceneManager->getRootSceneNode()->attachObject(ribbonTrail2);
    ribbonTrail2->addNode(m_pCurrentObject);
}

布告板显示中文类:

/*
 * .h 文件
 */

#ifndef __MovableText_H__
#define __MovableText_H__

#include <Ogre.h>
#include "OGRE\Overlay\OgreFont.h"
#include <OGRE\Overlay\OgreFontManager.h>
#include <OGRE\Overlay\OgreOverlayElement.h>

namespace Ogre
{
    class MovableText : public MovableObject, public Renderable
    {
    public:
        /// 水平对齐方式
        enum HorizontalAlignment
        {
            H_LEFT,     ///< 左对齐
            H_CENTER,   ///< 居中
            H_RIGHT     ///< 右对齐
        };

        /// 垂直对齐方式
        enum VerticalAlignment
        {
            V_BELOW,///< 低端对齐
            V_ABOVE,///< 顶端对齐
            V_CENTER///< 居中
        };

    protected:
        String              mFontName;
        String              mType;
        String              mName;
        DisplayString       mCaption;
        HorizontalAlignment mHorizontalAlignment;   ///< 水平对齐方式
        VerticalAlignment   mVerticalAlignment;     ///< 垂直对齐方式

        ColourValue         mColor;
        RenderOperation     mRenderOp;
        AxisAlignedBox      mAABB;
        LightList           mLList;

        Real                mCharHeight;
        Real                mSpaceWidth;

        bool                mNeedUpdate; 
        bool                mUpdateColors;
        bool                mOnTop;

        Real                mTimeUntilNextToggle;
        Real                mRadius;                ///< 包围半径
        Real                mAdditionalHeight;

        Camera*             mpCam;                  ///< 摄像机指针
        RenderWindow*       mpWin;                  ///< 渲染窗口指针
        FontPtr             mpFont;                 ///< 字体指针
        MaterialPtr         mpMaterial;
        MaterialPtr         mpBackgroundMaterial;   ///< 背景材质

        Vector3             mPositionOffset;
        Vector3             mScaleOffset;

    public:
        /// 构造函数
        /// @param[in] name 标识名
        /// @param[in] caption 字幕字符串
        /// @param[in] fontName 字体名
        /// @param[in] charHeight 字符高度
        /// @param[in] colour 字符颜色
        MovableText(const Ogre::String& name,
            const Ogre::DisplayString& caption,
            const Ogre::String& fontName = "BlueHighway",
            Ogre::Real charHeight = 1.0f,
            const Ogre::ColourValue& colour = Ogre::ColourValue::White);

        virtual ~MovableText(void);
        virtual void visitRenderables(
            Ogre::Renderable::Visitor* visitor, bool debugRenderables = false);
        /// 设置字体名
        void    setFontName(const String &fontName);

        /// 设置显示字幕
        void    setCaption(const DisplayString &caption);

        /// 设置文字颜色
        void    setColor(const ColourValue &color);

        /// 设置文字高度
        void    setCharacterHeight(Real height);

        /// 设置间隔宽度
        void    setSpaceWidth(Real width);

        /// 设置文字对齐方式
        void    setTextAlignment(const HorizontalAlignment& horizontalAlignment,
            const VerticalAlignment& verticalAlignment);

        /// 设置
        void    setAdditionalHeight( Real height );

        /// 是否最前方显示
        void    showOnTop(bool show=true);

        /// 
        void setPositionOffset(const Ogre::Vector3& offset);

        /// 
        Ogre::Vector3 getPositionOffset() const { return mPositionOffset; }

        /// 
        void setScaleOffset(const Ogre::Vector3& offset);

        /// 
        Ogre::Vector3 getScaleOffset() const { return mScaleOffset; }

        /// 获取字体名
        const   String&         getFontName() const {return mFontName;}

        /// 获取字幕字符串
        const   DisplayString&  getCaption() const {return mCaption;}

        /// 获取字体颜色
        const   ColourValue&    getColor() const {return mColor;}

        /// 获取字符高度
        Real    getCharacterHeight() const {return mCharHeight;}

        /// 获取间隔宽度
        Real    getSpaceWidth() const {return mSpaceWidth;}

        /// 
        Real    getAdditionalHeight() const {return mAdditionalHeight;}

        /// 获取是否在最前方显示
        bool    getShowOnTop() const {return mOnTop;}

        /// 获取包围盒
        AxisAlignedBox          GetAABB(void) { return mAABB; }
        /// 获取包围半径
        Real    getBoundingRadius(void) const {return mRadius;};

    protected:
        // from MovableText, create the object
        void    _setupGeometry();
        void    _updateColors();

        /// 获取世界坐标系中的变换
        void    getWorldTransforms(Matrix4 *xform) const;

        /// 获取摄像机的视深
        Real    getSquaredViewDepth(const Camera *cam) const {return 0;};

        /// 获取世界坐标系中的朝向
        /// @note 一直面朝摄像机
        const   Quaternion&         getWorldOrientation(void) const;

        /// 获取在世界坐标系中的坐标
        const   Vector3&            getWorldPosition(void) const;

        /// 获取包围盒
        const   AxisAlignedBox&     getBoundingBox(void) const {return mAABB;};

        /// 获取标识名
        const   String&             getName(void) const {return mName;};

        /// 获取类型名
        const   String&             getMovableType(void) const 
            {static Ogre::String movType = "MovableText"; return movType;};

        void    _notifyCurrentCamera(Camera *cam);
        void    _updateRenderQueue(RenderQueue* queue);

        // from renderable
        void    getRenderOperation(RenderOperation &op);
        const   MaterialPtr&    getMaterial(void) const {assert(!mpMaterial.isNull());return mpMaterial;};
        const   LightList&      getLights(void) const {return mLList;};
    };
}

#endif

/*
 * .cpp 文件
 */

#include "OgreMovableText.h"

using namespace Ogre;

#define POS_TEX_BINDING    0
#define COLOUR_BINDING     1
#define UNICODE_NEL        0x0085       ///< next line
#define UNICODE_CR         0x000D       ///< carriage return
#define UNICODE_LF         0x000A       ///< line feed
#define UNICODE_SPACE      0x0020       ///< space
#define UNICODE_ZERO       0x0030       ///< 0

MovableText::MovableText(const String &name,
                         const DisplayString &caption,
                         const String &fontName,
                         Real charHeight,
                         const ColourValue &color)
                         : mpCam(NULL)
                         , mpWin(NULL)
                         , mpFont(NULL)
                         , mName(name)
                         , mCaption(caption)
                         , mFontName(fontName)
                         , mCharHeight(charHeight)
                         , mColor(color)
                         , mType("MovableText")
                         , mTimeUntilNextToggle(0)
                         , mSpaceWidth(0)
                         , mUpdateColors(true)
                         , mOnTop(false)
                         , mHorizontalAlignment(H_LEFT)
                         , mVerticalAlignment(V_BELOW)
                         , mAdditionalHeight(0.0)
                         , mPositionOffset(Vector3::ZERO)
                         , mScaleOffset(Vector3::UNIT_SCALE)
{
    if (name == StringUtil::BLANK )
        throw Exception(Exception::ERR_INVALIDPARAMS, "Trying to create MovableText without name", "MovableText::MovableText");

    if (caption == StringUtil::BLANK )
        throw Exception(Exception::ERR_INVALIDPARAMS, "Trying to create MovableText without caption", "MovableText::MovableText");

    mRenderOp.vertexData = NULL;
    this->setFontName(mFontName);
    this->_setupGeometry();
}

MovableText::~MovableText()
{
    if (mRenderOp.vertexData)
        delete mRenderOp.vertexData;
}

void MovableText::setFontName(const String &fontName)
{
    if((Ogre::MaterialManager::getSingletonPtr()->resourceExists(mName + "Material"))) 
    { 
        Ogre::MaterialManager::getSingleton().remove(mName + "Material"); 
    }

    if (mFontName != fontName || mpMaterial.isNull() || mpFont.isNull())
    {
        mFontName = fontName;
        mpFont = FontManager::getSingleton().getByName(mFontName);
        if (mpFont.isNull())
            throw Exception(Exception::ERR_ITEM_NOT_FOUND, "Could not find font " + fontName, "MovableText::setFontName");

        mpFont->load();
        if (!mpMaterial.isNull())
        {
            MaterialManager::getSingletonPtr()->remove(mpMaterial->getName());
            mpMaterial.setNull();
        }

        mpMaterial = mpFont->getMaterial()->clone(mName + "Material");
        if (!mpMaterial->isLoaded())
            mpMaterial->load();


        mpMaterial->getTechnique(0)->getPass(0)->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA );//设置渲染通道和现有的渲染层内容混合方式
        mpMaterial->getTechnique(0)->getPass(0)->setAmbient(0.5,0.0,0.0);
        mpMaterial->getTechnique(0)->getPass(0)->setSpecular(0.6612,0.6612,0.6612,0.5);
        //Ogre::ColourValue curColorValue = mpMaterial->getTechnique(0)->getPass(0)->getDiffuse();
        mpMaterial->getTechnique(0)->getPass(0)->setDiffuse(0.5, 0.5, 0.5, 0);//设置透明度
        //mpMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setAlphaOperation(Ogre::LBX_MODULATE, Ogre::LBS_TEXTURE, Ogre::LBS_MANUAL, 1.0, 1 );
        mpMaterial->getTechnique(0)->getPass(0)->setDepthCheckEnabled(true);
        mpMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
        mpMaterial->setLightingEnabled(false);

//      mpMaterial->setDepthCheckEnabled(!mOnTop);
//#if 1
//      mpMaterial->setDepthBias(1.0,1.0);
//#else
//      mpMaterial->setDepthBias(1.0f);
//#endif
//      mpMaterial->setDepthWriteEnabled(mOnTop);
//            
//
//      mpMaterial->setLightingEnabled(false);
//      //
//      Ogre::Pass* pass=mpMaterial->getTechnique(0)->createPass();
//      pass->setSceneBlending(Ogre::SceneBlendType::SBT_TRANSPARENT_ALPHA);
//      pass->setAmbient(0.8,0.8,0.8);
//
//      pass->setDiffuse(0.5,0.5,0.5,1.0);
//      pass->setSpecular(0.6612,0.6612,0.6612,0.5);
//        
//        //pass->setEmissive(0,0,0);
//        //pass->setDepthCheckEnabled(true);
//  //      pass->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA );//设置渲染通道和现有的渲染层内容混合方式
//  //      pass->setAmbient(0.0,0.0,0.0);
//      //pass->setDiffuse(0.0,0.0,0.0,0.0);
//      //pass->setSpecular(0.6612,0.6612,0.6612,10);
//  //      pass->setEmissive(0,0,0);
//        //pass->setSceneBlending( Ogre::SBT_ADD );
//        //pass->getTextureUnitState(0)->setAlphaOperation(Ogre::LBX_MODULATE, Ogre::LBS_TEXTURE, Ogre::LBS_MANUAL, 1.0, 0.1 );
//      /*Ogre::TextureUnitState *tex=pass->createTextureUnitState("flare.png");
//        tex->setName("HighLight");
//      tex->setColourOperationEx(Ogre::LayerBlendOperationEx::LBX_ADD);
//      tex->setColourOpMultipassFallback(Ogre::SceneBlendFactor::SBF_ONE,Ogre::SceneBlendFactor::SBF_ONE);
//      tex->setEnvironmentMap(true);*/
        //unsigned short i=mpMaterial->getTechnique(0)->getPass(0)->getIndex();
        //mpMaterial->getTechnique(0)->movePass(i,0);
        //
        mNeedUpdate = true;
    }
}

void MovableText::setCaption(const DisplayString &caption)
{
    if (caption != mCaption)
    {
        mCaption = caption;
        mNeedUpdate = true;
    }
}
void MovableText::visitRenderables(Ogre::Renderable::Visitor* visitor, bool debugRenderables)
{
}
void MovableText::setColor(const ColourValue &color)
{
    if (color != mColor)
    {
        mColor = color;
        mUpdateColors = true;
    }
}

void MovableText::setCharacterHeight(Real height)
{
    if (height != mCharHeight)
    {
        mCharHeight = height;
        mSpaceWidth = 0;
        mNeedUpdate = true;
    }
}

void MovableText::setSpaceWidth(Real width)
{
    if (width != mSpaceWidth)
    {
        mSpaceWidth = width;
        mNeedUpdate = true;
    }
}

void MovableText::setTextAlignment(const HorizontalAlignment& horizontalAlignment,
                                   const VerticalAlignment& verticalAlignment)
{
    if(mHorizontalAlignment != horizontalAlignment)
    {
        mHorizontalAlignment = horizontalAlignment;
        mNeedUpdate = true;
    }
    if(mVerticalAlignment != verticalAlignment)
    {
        mVerticalAlignment = verticalAlignment;
        mNeedUpdate = true;
    }
}

void MovableText::setAdditionalHeight( Real height )
{
    if( mAdditionalHeight != height )
    {
        mAdditionalHeight = height;
        mNeedUpdate = true;
    }
}

void MovableText::showOnTop(bool show)
{
    if( mOnTop != show && !mpMaterial.isNull() )
    {
        mOnTop = show;
#if 1
        mpMaterial->setDepthBias(1.0f, 1.0f);
#else
        mpMaterial->setDepthBias(1.0f);
#endif
        mpMaterial->setDepthCheckEnabled(!mOnTop);
        mpMaterial->setDepthWriteEnabled(mOnTop);
    }
}

void MovableText::_setupGeometry()
{
    if (mpFont.isNull())
    {
        return;
    }

    if (mpMaterial.isNull())
    {
        return;
    }

    size_t charlen = mCaption.size();

    size_t vertexCount = charlen * 6;

    if (mRenderOp.vertexData)
    {
        // Removed this test as it causes problems when replacing a caption
        // of the same size: replacing "Hello" with "hello"
        // as well as when changing the text alignment
        //if (mRenderOp.vertexData->vertexCount != vertexCount)
        {
            delete mRenderOp.vertexData;
            mRenderOp.vertexData = NULL;
            mUpdateColors = true;
        }
    }

    if (!mRenderOp.vertexData)
        mRenderOp.vertexData = new VertexData();

    mRenderOp.indexData = 0;
    mRenderOp.vertexData->vertexStart = 0;
    mRenderOp.vertexData->vertexCount = vertexCount;
    mRenderOp.operationType = RenderOperation::OT_TRIANGLE_LIST; 
    mRenderOp.useIndexes = false; 

    VertexDeclaration  *decl = mRenderOp.vertexData->vertexDeclaration;
    VertexBufferBinding   *bind = mRenderOp.vertexData->vertexBufferBinding;
    size_t offset = 0;

    // create/bind positions/tex.ccord. buffer
    if (!decl->findElementBySemantic(VES_POSITION))
        decl->addElement(POS_TEX_BINDING, offset, VET_FLOAT3, VES_POSITION);

    offset += VertexElement::getTypeSize(VET_FLOAT3);

    if (!decl->findElementBySemantic(VES_TEXTURE_COORDINATES))
        decl->addElement(POS_TEX_BINDING, offset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);

    HardwareVertexBufferSharedPtr ptbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(POS_TEX_BINDING),
        mRenderOp.vertexData->vertexCount,
        HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
    bind->setBinding(POS_TEX_BINDING, ptbuf);

    // Colours - store these in a separate buffer because they change less often
    if (!decl->findElementBySemantic(VES_DIFFUSE))
        decl->addElement(COLOUR_BINDING, 0, VET_COLOUR, VES_DIFFUSE);

    HardwareVertexBufferSharedPtr cbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(COLOUR_BINDING),
        mRenderOp.vertexData->vertexCount,
        HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY);
    bind->setBinding(COLOUR_BINDING, cbuf);

    float *pPCBuff = static_cast<float*>(ptbuf->lock(HardwareBuffer::HBL_DISCARD));

    float largestWidth = 0;
    float left = 0 * 2.0 - 1.0;
    float top = -((0 * 2.0) - 1.0);

    // Derive space width from a capital A
    if (mSpaceWidth == 0)
        mSpaceWidth = mpFont->getGlyphAspectRatio('A') * mCharHeight * 2.0;

    // for calculation of AABB
    Ogre::Vector3 min, max, currPos;
    Ogre::Real maxSquaredRadius = 0;
    bool first = true;

    // Use iterator
    DisplayString::iterator i, iend;
    iend = mCaption.end();
    bool newLine = true;
    Real len = 0.0f;

    Real verticalOffset = 0;
    switch (mVerticalAlignment)
    {
    case MovableText::V_ABOVE:
        verticalOffset = mCharHeight;
        break;
    case MovableText::V_CENTER:
        verticalOffset = 0.5*mCharHeight;
        break;
    case MovableText::V_BELOW:
        verticalOffset = 0;
        break;
    }
    // Raise the first line of the caption
    top += verticalOffset;
    for (i = mCaption.begin(); i != iend; ++i)
    {
        Font::CodePoint character = OGRE_DEREF_DISPLAYSTRING_ITERATOR(i);
        if (character == UNICODE_CR
            || character == UNICODE_NEL
            || character == UNICODE_LF) 
        {
            top += verticalOffset * 2.0f;
        }
    }

    for (i = mCaption.begin(); i != iend; ++i)
    {
        Font::CodePoint character = OGRE_DEREF_DISPLAYSTRING_ITERATOR(i);

        if (newLine)
        {
            len = 0.0f;
            for (DisplayString::iterator j = i; j != iend; j++)
            {
                Font::CodePoint cr = OGRE_DEREF_DISPLAYSTRING_ITERATOR(j);

                if (cr == UNICODE_CR
                    || cr == UNICODE_NEL
                    || cr == UNICODE_LF) 
                {
                    break;
                }
                else if (cr == UNICODE_SPACE) // space
                {
                    len += mSpaceWidth;
                }
                else 
                {
                    len += mpFont->getGlyphAspectRatio(character) * mCharHeight * 2.0f;
                }
            }

            newLine = false;
        }

        if (character == UNICODE_CR
            || character == UNICODE_NEL
            || character == UNICODE_LF) 
        {
            left = 0 * 2.0 - 1.0;
            top -= mCharHeight * 2.0;
            newLine = true;
            continue;
        }

        if (character == UNICODE_SPACE)
        {
            // Just leave a gap, no tris
            left += mSpaceWidth;
            // Also reduce tri count
            mRenderOp.vertexData->vertexCount -= 6;
            continue;
        }

        Real horiz_height = mpFont->getGlyphAspectRatio(*i);
        Real u1, u2, v1, v2; 
        Ogre::Font::UVRect utmp;
        utmp = mpFont->getGlyphTexCoords(character);
        u1 = utmp.left;
        u2 = utmp.right;
        v1 = utmp.top;
        v2 = utmp.bottom;

        // each vert is (x, y, z, u, v)
        //-------------------------------------------------------------------------------------
        // First tri
        //
        // Upper left
        if(mHorizontalAlignment == MovableText::H_LEFT)
            *pPCBuff++ = left;
        else
            *pPCBuff++ = left - (len / 2);
        *pPCBuff++ = top;
        *pPCBuff++ = -1.0;
        *pPCBuff++ = u1;
        *pPCBuff++ = v1;

        // Deal with bounds
        if(mHorizontalAlignment == MovableText::H_LEFT)
            currPos = Ogre::Vector3(left, top, -1.0);
        else
            currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
        if (first)
        {
            min = max = currPos;
            maxSquaredRadius = currPos.squaredLength();
            first = false;
        }
        else
        {
            min.makeFloor(currPos);
            max.makeCeil(currPos);
            maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());
        }

        top -= mCharHeight * 2.0;

        // Bottom left
        if(mHorizontalAlignment == MovableText::H_LEFT)
            *pPCBuff++ = left;
        else
            *pPCBuff++ = left - (len / 2);
        *pPCBuff++ = top;
        *pPCBuff++ = -1.0;
        *pPCBuff++ = u1;
        *pPCBuff++ = v2;

        // Deal with bounds
        if(mHorizontalAlignment == MovableText::H_LEFT)
            currPos = Ogre::Vector3(left, top, -1.0);
        else
            currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
        min.makeFloor(currPos);
        max.makeCeil(currPos);
        maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

        top += mCharHeight * 2.0;
        left += horiz_height * mCharHeight * 2.0;

        // Top right
        if(mHorizontalAlignment == MovableText::H_LEFT)
            *pPCBuff++ = left;
        else
            *pPCBuff++ = left - (len / 2);
        *pPCBuff++ = top;
        *pPCBuff++ = -1.0;
        *pPCBuff++ = u2;
        *pPCBuff++ = v1;
        //-------------------------------------------------------------------------------------

        // Deal with bounds
        if(mHorizontalAlignment == MovableText::H_LEFT)
            currPos = Ogre::Vector3(left, top, -1.0);
        else
            currPos = Ogre::Vector3(left - (len / 2), top, -1.0);
        min.makeFloor(currPos);
        max.makeCeil(currPos);
        maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

        //-------------------------------------------------------------------------------------
        // Second tri
        //
        // Top right (again)
        if(mHorizontalAlignment == MovableText::H_LEFT)
            *pPCBuff++ = left;
        else
            *pPCBuff++ = left - (len / 2);
        *pPCBuff++ = top;
        *pPCBuff++ = -1.0;
        *pPCBuff++ = u2;
        *pPCBuff++ = v1;

        currPos = Ogre::Vector3(left, top, -1.0);
        min.makeFloor(currPos);
        max.makeCeil(currPos);
        maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

        top -= mCharHeight * 2.0;
        left -= horiz_height  * mCharHeight * 2.0;

        // Bottom left (again)
        if(mHorizontalAlignment == MovableText::H_LEFT)
            *pPCBuff++ = left;
        else
            *pPCBuff++ = left - (len / 2);
        *pPCBuff++ = top;
        *pPCBuff++ = -1.0;
        *pPCBuff++ = u1;
        *pPCBuff++ = v2;

        currPos = Ogre::Vector3(left, top, -1.0);
        min.makeFloor(currPos);
        max.makeCeil(currPos);
        maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

        left += horiz_height  * mCharHeight * 2.0;

        // Bottom right
        if(mHorizontalAlignment == MovableText::H_LEFT)
            *pPCBuff++ = left;
        else
            *pPCBuff++ = left - (len / 2);
        *pPCBuff++ = top;
        *pPCBuff++ = -1.0;
        *pPCBuff++ = u2;
        *pPCBuff++ = v2;
        //-------------------------------------------------------------------------------------

        currPos = Ogre::Vector3(left, top, -1.0);
        min.makeFloor(currPos);
        max.makeCeil(currPos);
        maxSquaredRadius = std::max(maxSquaredRadius, currPos.squaredLength());

        // Go back up with top
        top += mCharHeight * 2.0;

        float currentWidth = (left + 1)/2 - 0;
        if (currentWidth > largestWidth)
            largestWidth = currentWidth;
    }

    // Unlock vertex buffer
    ptbuf->unlock();

    min.makeFloor(max); //When only spaces are typed in min can exceed max, this rectifies this

    // update AABB/Sphere radius
    mAABB = Ogre::AxisAlignedBox(min, max);
    mRadius = Ogre::Math::Sqrt(maxSquaredRadius);

    if (mUpdateColors)
        this->_updateColors();

    mNeedUpdate = false;
}

void MovableText::_updateColors(void)
{
    assert(!mpFont.isNull());
    assert(!mpMaterial.isNull());

    if (mpFont.isNull())
    {
        return;
    }

    if (mpMaterial.isNull())
    {
        return;
    }

    // Convert to system-specific
    RGBA color;
    Root::getSingleton().convertColourValue(mColor, &color);
    HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(COLOUR_BINDING);
    RGBA *pDest = static_cast<RGBA*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
    for (uint i = 0; i < mRenderOp.vertexData->vertexCount; ++i)
        *pDest++ = color;
    vbuf->unlock();
    mUpdateColors = false;
}

const Quaternion& MovableText::getWorldOrientation(void) const
{
    assert(mpCam);
    return const_cast<Quaternion&>(mpCam->getDerivedOrientation());
}

const Vector3& MovableText::getWorldPosition(void) const
{
    assert(mParentNode);
    return mParentNode->_getDerivedPosition();
}

void MovableText::getWorldTransforms(Matrix4 *xform) const 
{
    if (this->isVisible() && mpCam)
    {
        Matrix3 rot3x3, scale3x3 = Matrix3::IDENTITY;

        // store rotation in a matrix
        mpCam->getDerivedOrientation().ToRotationMatrix(rot3x3);

        // parent node position
        Vector3 ppos = mParentNode->_getDerivedPosition() + Vector3::UNIT_Y*mAdditionalHeight;
        Quaternion pori = mParentNode->_getDerivedOrientation();
        Vector3 alignmentOffset = Vector3::ZERO;

        //ppos += pori * (mPositionOffset + alignmentOffset * 0.01);

        // apply scale
        scale3x3[0][0] = mParentNode->_getDerivedScale().x / 2;
        scale3x3[1][1] = mParentNode->_getDerivedScale().y / 2;
        scale3x3[2][2] = mParentNode->_getDerivedScale().z / 2;

        // apply all transforms to xform       
        *xform = (rot3x3 * scale3x3);
        xform->setTrans(ppos);
    }
}

void MovableText::getRenderOperation(RenderOperation &op)
{
    if (this->isVisible())
    {
        if (mNeedUpdate)
            this->_setupGeometry();
        if (mUpdateColors)
            this->_updateColors();
        op = mRenderOp;
    }
}

void MovableText::_notifyCurrentCamera(Camera *cam)
{
    mpCam = cam;
}

void MovableText::_updateRenderQueue(RenderQueue* queue)
{
    if (this->isVisible())
    {
        if (mNeedUpdate)
            this->_setupGeometry();
        if (mUpdateColors)
            this->_updateColors();

        queue->addRenderable(this, mRenderQueueID, OGRE_RENDERABLE_DEFAULT_PRIORITY);
    }
}

void Ogre::MovableText::setPositionOffset( const Ogre::Vector3& offset )
{
    mPositionOffset = offset;
}

void Ogre::MovableText::setScaleOffset( const Ogre::Vector3& offset )
{
    mScaleOffset = offset;
}

效果图:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值