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
- Ogre的WeaponTrail
- Ogre的WeaponTrail (刀光)
- Ogre的WeaponTrail (刀光)
- Ogre的WeaponTrail (刀光)
- Ogre的WeaponTrail (刀光)
- Ogre的API:Ogre::RenderOperation
- Ogre的骨骼动画
- Ogre 学习的历程
- Ogre 的文档系统
- Ogre的MaterialSystem分析
- Ogre的SceneManager分析
- Ogre的官僚主义批判
- Ogre的状态框架
- Ogre 的 四元数quaternion
- Ogre Mesh的加载
- Ogre的UML类图
- Ogre的消息机制
- Ogre的渲染系统
- C++菱形继承面试题
- WebService学习总结(三)--WebServic发布
- SylixOS中间件移植方法总结
- php求两个文件的相对路径
- Nginx负载均衡配置
- Ogre的WeaponTrail
- AngularJS简单介绍
- 002_Windows程序设计--Unicode
- 面向对象的三个基本特征是:封装、继承、多态及其五大原则
- 【BZOJ 2440】[中山市选2011]完全平方数 莫比乌斯反演+容斥
- 贝叶斯模型比较
- 优秀Java程序员的编程风格
- CCF之最优灌溉(java)
- 三年计划