Ogre的WeaponTrail

来源:互联网 发布:制作发光字软件 编辑:程序博客网 时间:2024/06/10 22:25

转载自:http://blog.sina.com.cn/s/blog_67b708440100ifa4.html

就是刀光拖尾效果,这个挺有意思,Ogre竟然单写了一个类来实现这个功能。名字叫做RibbonTrail。
不过这个类似乎并不太好用,实现的效果是从手握武器的位置沿相对衬的两个方向延伸出片,这样的话,如果手里是把剑,那么效果就不对了。如果手里的武器是长枪,因为手握得位置也不是正中间,所以也不对。。。。

于是又有人写了一个WeaponTrial类来解决这个问题。但是他没有处理缩放问题,所以在连接点从父节点带来的缩放矩阵影响下,刀光的宽度就会有问题,除非你的人物的骨骼完全没有缩放。

另外这个WeaponTrial的计算方法确实是相当费。需要重新更新整个的骨骼动画。

Ogre的一些周边代码的水平大抵都是如此,基本的意思有了,不过照工业标准总是差着一些。拿回来需要好好的修改才行。但用来玩玩还是足够的。

下面是修改后的截图和代码。
这里写图片描述

//.h#pragma once#include<list>#include "Ogre.h"using namespace Ogre;class WeaponTrail{public:    WeaponTrail(Ogre::String  name, SceneManager* s );    virtual ~WeaponTrail();    /// Set the weapon entity to which the trail is attached    void setWeaponEntity(Entity* p_WeaponEntity);    /// update the weapon trail    void onUpdate(float p_DeltaT);    /// Set the name of the material to use for the trail    void setMaterialName(const String& p_MaterialName);    /// set the initial color of the start of segments    void setSegmentStartInitialColor(const Ogre::ColourValue& p_Color);    /// get the initial color of the start of segments    const Ogre::ColourValue& getSegmentStartInitialColor() const;    /// set the initial color of the end of segments    void setSegmentEndInitialColor(const Ogre::ColourValue& p_Color);    /// get the initial color of the end of segments    const Ogre::ColourValue& getSegmentEndInitialColor() const;    /// set how the color of the start of segments will change over time    void setSegmentStartColorChange(const Ogre::ColourValue& p_ColorChange);    /// get how the color of the start of segments will change over time    const Ogre::ColourValue& getSegmentStartColorChange() const;    /// set how the color of the start of segments will change over time    void setSegmentEndColorChange(const Ogre::ColourValue& p_ColorChange);    /// get how the color of the start of segments will change over time    const Ogre::ColourValue& getSegmentEndColorChange() const;    /// Return the max vertex count of the trail    inline int getMaxSegmentCount() const {return m_MaxSegmentCount;}    /// set the width    void setWidth(float p_Width) {m_Width = p_Width;}    /// get the width    float getWidth() const {return m_Width;}    /// Set whether new segments are added    void setActive(bool p_Active = true);    /// Get whether new segments are added    bool isActive() const;    /// Get whether there are currently segments in the list    bool isVisible() const;protected:    /// a trail segment    struct TrailSegment    {        /// start position        Vector3 segmentStart;        /// end position        Vector3 segmentEnd;        /// current segment start color        Ogre::ColourValue segmentStartColor;        /// current segment end color        Ogre::ColourValue segmentEndColor;    }; // end TrailSegment struct declaration    /// typedef for a list of trail segments    typedef std::list<TrailSegment> TrailSegmentList;    /// the list of currently active trail segments    TrailSegmentList m_SegmentList;    /// Initializes the manual object    void init();    /// Uninitializes the manual object    void uninit();    ManualObject* m_TrailObject;    //!< the dynamically changed mesh representing the trail    Entity* m_WeaponEntity;         //!< the entity representing the weapon;    Node* m_WeaponNode;             //!< the node the tracked entity is attached to    SceneNode* m_TrailNode;         //!< the node the manual object is attached to    String m_MaterialName;          //!< the name of the material to use    const int m_MaxSegmentCount;    //!< the maximum number of segments the trail will consist of    Ogre::ColourValue m_SegmentStartInitialColor; //!< the initial color of start segments    Ogre::ColourValue m_SegmentEndInitialColor;   //!< the initial color of end segments    Ogre::ColourValue m_SegmentStartColorChange;  //!< how the color of start segments will change over time    Ogre::ColourValue m_SegmentEndColorChange;    //!< how the color of end segments will change over time    float m_Width;                      //!< the width of the trail    bool m_IsActive;                    //!< flag indicating whether new segments are generated    SceneManager* mSceneMgr;    Ogre::String  mName;}; // end of WeaponTrail class declaration//.cpp#include "WeaponTrail.h"//---------------------------------------------------------------------------//WeaponTrail::WeaponTrail(Ogre::String  name, SceneManager* s )    :m_TrailObject(0),    m_MaxSegmentCount(30),    mSceneMgr(s),    m_IsActive(true){     m_SegmentStartColorChange = Ogre::ColourValue(1.0,1.0,1.0,1.0);     m_SegmentEndColorChange = Ogre::ColourValue(1.0,1.0,1.0,1.0);     m_SegmentStartInitialColor = Ogre::ColourValue(0.6,0.5,0.8,1);     m_SegmentEndInitialColor = Ogre::ColourValue(1.0,0.2,1.0,1);     m_SegmentStartColorChange *= 3.0;     m_SegmentEndColorChange *= 3.0;     m_Width = 30.0;     setWeaponEntity(0);     init();}//---------------------------------------------------------------------------//WeaponTrail::~WeaponTrail(){     uninit();}//---------------------------------------------------------------------------//void WeaponTrail::init(){     // create object     m_TrailObject =mSceneMgr->createManualObject(mName);     m_TrailObject->estimateVertexCount(m_MaxSegmentCount * 2);     m_TrailObject->setDynamic(true);     m_TrailObject->begin("mat_trail", Ogre::RenderOperation::OT_TRIANGLE_STRIP);     // fill the object (the actual data does not matter here)     for(int i=0; i<m_MaxSegmentCount; ++i)     {          m_TrailObject->position(0, 0, -i*20);          m_TrailObject->textureCoord(0,0);          m_TrailObject->colour(1,0,0,1);          m_TrailObject->position(0, 30, -i*20);          m_TrailObject->textureCoord(1,0);          m_TrailObject->colour(1,0,0,1);     }     m_TrailObject->end();     // create node and attach object     m_TrailNode =mSceneMgr->getRootSceneNode()->createChildSceneNode();     m_TrailNode->attachObject(m_TrailObject);     m_TrailObject->setVisible(false);}//---------------------------------------------------------------------------//void WeaponTrail::uninit(){     m_IsActive = false;     // detach object and remove node     m_TrailNode->detachObject(m_TrailObject);     mSceneMgr->getRootSceneNode()->removeAndDestroyChild(m_TrailNode->getName());     // remove object     m_TrailObject->setVisible(false);     mSceneMgr->destroyManualObject(m_TrailObject);}//---------------------------------------------------------------------------//void WeaponTrail::setWeaponEntity(Entity* p_WeaponEntity){     m_WeaponEntity = p_WeaponEntity;     if (m_WeaponEntity)     {             m_WeaponNode = m_WeaponEntity->getParentNode();     }     else     {          m_WeaponNode = 0;     }}//---------------------------------------------------------------------------//void WeaponTrail::onUpdate(float p_DeltaT){     // early out     if(!isActive() && !isVisible())     {          return;     }     if (!m_WeaponEntity || !m_WeaponNode)     {          return;     }     if (!m_TrailObject)     {          return;     }     m_TrailObject->setVisible(true);     // iterate over the current segments, apply alpha change     for(TrailSegmentList::iterator it = m_SegmentList.begin();it != m_SegmentList.end();)     {          (*it).segmentStartColor -= m_SegmentStartColorChange * p_DeltaT;          (*it).segmentEndColor -= m_SegmentEndColorChange * p_DeltaT;          (*it).segmentStartColor.saturate();          (*it).segmentEndColor.saturate();          if((*it).segmentStartColor == Ogre::ColourValue::ZERO &&(*it).segmentEndColor == Ogre::ColourValue::ZERO)          {               it = m_SegmentList.erase(it);          }          else          {               ++it;          }     }     // throw away the last element if the maximum number of segments is used     if(m_SegmentList.size() >= m_MaxSegmentCount)     {          m_SegmentList.pop_back();     }     // only add a new segment if active     if(isActive())     {          // the segment to add to the trail          TrailSegment newSegment;          // initial the trail          newSegment.segmentStartColor = getSegmentStartInitialColor();          newSegment.segmentEndColor = getSegmentEndInitialColor();          newSegment.segmentStart  = m_WeaponNode->_getDerivedPosition();          Vector3 pos = m_WeaponNode->getPosition();          // probably quite costly way to get the second position          m_WeaponNode->translate(Vector3(0, m_Width, 0), SceneNode::TS_LOCAL);          newSegment.segmentEnd = m_WeaponNode->_getDerivedPosition();          m_WeaponNode->setPosition(pos);          Vector3 _verDir = newSegment.segmentEnd - newSegment.segmentStart;          _verDir.normalise();          newSegment.segmentEnd = newSegment.segmentStart + _verDir *  m_Width;          m_SegmentList.push_front(newSegment);     }     // update the manual object     m_TrailObject->beginUpdate(0);     int segmentCount = 0;     for(TrailSegmentList::iterator it = m_SegmentList.begin();it != m_SegmentList.end(); ++it)     {          m_TrailObject->position((*it).segmentStart);          m_TrailObject->textureCoord(0,0);          m_TrailObject->colour((*it).segmentStartColor);          m_TrailObject->position((*it).segmentEnd);          m_TrailObject->textureCoord(1,0);          m_TrailObject->colour((*it).segmentEndColor);          ++segmentCount;     }     // use the last position to render the invisible part of the trail     // as degenerate triangles     Vector3 lastPos = Vector3::ZERO;     if(!m_SegmentList.empty())     {          lastPos = m_SegmentList.back().segmentStart;     }     for(int i=segmentCount*2;i<m_MaxSegmentCount * 2;++i)     {          m_TrailObject->position(lastPos);     }     // end the update     m_TrailObject->end();}//---------------------------------------------------------------------------//void WeaponTrail::setMaterialName(const String& p_MaterialName){     m_MaterialName = p_MaterialName;     if(m_TrailObject)     {          m_TrailObject->setMaterialName(0, m_MaterialName);     }}//---------------------------------------------------------------------------//void WeaponTrail::setSegmentStartColorChange(const Ogre::ColourValue& p_ColorChange){     m_SegmentStartColorChange = p_ColorChange;}//---------------------------------------------------------------------------//const Ogre::ColourValue& WeaponTrail::getSegmentStartColorChange() const{     return m_SegmentStartColorChange;}//---------------------------------------------------------------------------//void WeaponTrail::setSegmentEndColorChange(const Ogre::ColourValue& p_ColorChange){     m_SegmentEndColorChange = p_ColorChange;}//---------------------------------------------------------------------------//const Ogre::ColourValue& WeaponTrail::getSegmentEndColorChange() const{     return m_SegmentEndColorChange;}//---------------------------------------------------------------------------//void WeaponTrail::setSegmentStartInitialColor(const Ogre::ColourValue& p_Color){     m_SegmentStartInitialColor = p_Color;}//---------------------------------------------------------------------------//const Ogre::ColourValue& WeaponTrail::getSegmentStartInitialColor() const{     return m_SegmentStartInitialColor;}//---------------------------------------------------------------------------//void WeaponTrail::setSegmentEndInitialColor(const Ogre::ColourValue& p_Color){     m_SegmentEndInitialColor = p_Color;}//---------------------------------------------------------------------------//const Ogre::ColourValue& WeaponTrail::getSegmentEndInitialColor() const{     return m_SegmentEndInitialColor;}//---------------------------------------------------------------------------//void WeaponTrail::setActive(bool p_Active){     m_IsActive = p_Active;}//---------------------------------------------------------------------------//bool WeaponTrail::isActive() const{     return m_IsActive;}//---------------------------------------------------------------------------//bool WeaponTrail::isVisible() const{     return !m_SegmentList.empty();}//---------------------------------------------------------------------------//
0 0
原创粉丝点击