Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/src/OgreBillboardParticleRenderer.cpp @ 3

Last change on this file since 3 was 3, checked in by anonymous, 17 years ago

=update

File size: 19.8 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29#include "OgreStableHeaders.h"
30
31#include "OgreBillboardParticleRenderer.h"
32#include "OgreParticle.h"
33#include "OgreStringConverter.h"
34
35namespace Ogre {
36    String rendererTypeName = "billboard";
37
38    //-----------------------------------------------------------------------
39    BillboardParticleRenderer::CmdBillboardType BillboardParticleRenderer::msBillboardTypeCmd;
40    BillboardParticleRenderer::CmdBillboardOrigin BillboardParticleRenderer::msBillboardOriginCmd;
41    BillboardParticleRenderer::CmdBillboardRotationType BillboardParticleRenderer::msBillboardRotationTypeCmd;
42    BillboardParticleRenderer::CmdCommonDirection BillboardParticleRenderer::msCommonDirectionCmd;
43    BillboardParticleRenderer::CmdCommonUpVector BillboardParticleRenderer::msCommonUpVectorCmd;
44    BillboardParticleRenderer::CmdPointRendering BillboardParticleRenderer::msPointRenderingCmd;
45        BillboardParticleRenderer::CmdAccurateFacing BillboardParticleRenderer::msAccurateFacingCmd;
46    //-----------------------------------------------------------------------
47    BillboardParticleRenderer::BillboardParticleRenderer()
48    {
49        if (createParamDictionary("BillboardParticleRenderer"))
50        {
51            ParamDictionary* dict = getParamDictionary();
52            dict->addParameter(ParameterDef("billboard_type", 
53                "The type of billboard to use. 'point' means a simulated spherical particle, " 
54                "'oriented_common' means all particles in the set are oriented around common_direction, "
55                "'oriented_self' means particles are oriented around their own direction, "
56                "'perpendicular_common' means all particles are perpendicular to common_direction, "
57                "and 'perpendicular_self' means particles are perpendicular to their own direction.",
58                PT_STRING),
59                &msBillboardTypeCmd);
60
61            dict->addParameter(ParameterDef("billboard_origin", 
62                "This setting controls the fine tuning of where a billboard appears in relation to it's position. "
63                "Possible value are: 'top_left', 'top_center', 'top_right', 'center_left', 'center', 'center_right', "
64                "'bottom_left', 'bottom_center' and 'bottom_right'. Default value is 'center'.",
65                PT_STRING),
66                &msBillboardOriginCmd);
67
68            dict->addParameter(ParameterDef("billboard_rotation_type", 
69                "This setting controls the billboard rotation type. "
70                                "'vertex' means rotate the billboard's vertices around their facing direction."
71                "'texcoord' means rotate the billboard's texture coordinates. Default value is 'texcoord'.",
72                PT_STRING),
73                &msBillboardRotationTypeCmd);
74
75            dict->addParameter(ParameterDef("common_direction", 
76                "Only useful when billboard_type is oriented_common or perpendicular_common. "
77                                "When billboard_type is oriented_common, this parameter sets the common orientation for "
78                                "all particles in the set (e.g. raindrops may all be oriented downwards). "
79                                "When billboard_type is perpendicular_common, this parameter sets the perpendicular vector for "
80                                "all particles in the set (e.g. an aureola around the player and parallel to the ground).",
81                PT_VECTOR3),
82                &msCommonDirectionCmd);
83
84            dict->addParameter(ParameterDef("common_up_vector",
85                "Only useful when billboard_type is perpendicular_self or perpendicular_common. This "
86                                "parameter sets the common up-vector for all particles in the set (e.g. an aureola around "
87                                "the player and parallel to the ground).",
88                PT_VECTOR3),
89                &msCommonUpVectorCmd);
90            dict->addParameter(ParameterDef("point_rendering",
91                "Set whether or not particles will use point rendering "
92                                "rather than manually generated quads. This allows for faster "
93                                "rendering of point-oriented particles although introduces some "
94                                "limitations too such as requiring a common particle size."
95                                "Possible values are 'true' or 'false'.",
96                PT_BOOL),
97                &msPointRenderingCmd);
98                        dict->addParameter(ParameterDef("accurate_facing",
99                                "Set whether or not particles will be oriented to the camera "
100                                "based on the relative position to the camera rather than just "
101                                "the camera direction. This is more accurate but less optimal. "
102                                "Cannot be combined with point rendering.",
103                                PT_BOOL),
104                                &msAccurateFacingCmd);
105        }
106
107        // Create billboard set
108        mBillboardSet = new BillboardSet("", 0, true);
109        // World-relative axes
110        mBillboardSet->setBillboardsInWorldSpace(true);
111    }
112    //-----------------------------------------------------------------------
113    BillboardParticleRenderer::~BillboardParticleRenderer()
114    {
115        delete mBillboardSet;
116    }
117    //-----------------------------------------------------------------------
118    const String& BillboardParticleRenderer::getType(void) const
119    {
120        return rendererTypeName;
121    }
122    //-----------------------------------------------------------------------
123    void BillboardParticleRenderer::_updateRenderQueue(RenderQueue* queue, 
124        std::list<Particle*>& currentParticles, bool cullIndividually)
125    {
126        mBillboardSet->setCullIndividually(cullIndividually);
127
128        // Update billboard set geometry
129        mBillboardSet->beginBillboards(currentParticles.size());
130        Billboard bb;
131        for (std::list<Particle*>::iterator i = currentParticles.begin();
132            i != currentParticles.end(); ++i)
133        {
134            Particle* p = *i;
135            bb.mPosition = p->position;
136                        if (mBillboardSet->getBillboardType() == BBT_ORIENTED_SELF ||
137                                mBillboardSet->getBillboardType() == BBT_PERPENDICULAR_SELF)
138                        {
139                                // Normalise direction vector
140                                bb.mDirection = p->direction;
141                                bb.mDirection.normalise();
142                        }
143            bb.mColour = p->colour;
144            bb.mRotation = p->rotation;
145            // Assign and compare at the same time
146            if (bb.mOwnDimensions = p->mOwnDimensions)
147            {
148                bb.mWidth = p->mWidth;
149                bb.mHeight = p->mHeight;
150            }
151            mBillboardSet->injectBillboard(bb);
152
153        }
154       
155        mBillboardSet->endBillboards();
156
157        // Update the queue
158        mBillboardSet->_updateRenderQueue(queue);
159    }
160    //-----------------------------------------------------------------------
161    void BillboardParticleRenderer::_setMaterial(MaterialPtr& mat)
162    {
163        mBillboardSet->setMaterialName(mat->getName());
164    }
165    //-----------------------------------------------------------------------
166    void BillboardParticleRenderer::setBillboardType(BillboardType bbt)
167    {
168        mBillboardSet->setBillboardType(bbt);
169    }
170        //-----------------------------------------------------------------------
171        void BillboardParticleRenderer::setUseAccurateFacing(bool acc)
172        {
173                mBillboardSet->setUseAccurateFacing(acc);
174        }
175        //-----------------------------------------------------------------------
176        bool BillboardParticleRenderer::getUseAccurateFacing(void) const
177        {
178                return mBillboardSet->getUseAccurateFacing();
179        }
180    //-----------------------------------------------------------------------
181    BillboardType BillboardParticleRenderer::getBillboardType(void) const
182    {
183        return mBillboardSet->getBillboardType();
184    }
185    //-----------------------------------------------------------------------
186    void BillboardParticleRenderer::setBillboardRotationType(BillboardRotationType rotationType)
187    {
188        mBillboardSet->setBillboardRotationType(rotationType);
189    }
190    //-----------------------------------------------------------------------
191    BillboardRotationType BillboardParticleRenderer::getBillboardRotationType(void) const
192    {
193        return mBillboardSet->getBillboardRotationType();
194    }
195    //-----------------------------------------------------------------------
196    void BillboardParticleRenderer::setCommonDirection(const Vector3& vec)
197    {
198        mBillboardSet->setCommonDirection(vec);
199    }
200    //-----------------------------------------------------------------------
201    const Vector3& BillboardParticleRenderer::getCommonDirection(void) const
202    {
203        return mBillboardSet->getCommonDirection();
204    }
205    //-----------------------------------------------------------------------
206    void BillboardParticleRenderer::setCommonUpVector(const Vector3& vec)
207    {
208        mBillboardSet->setCommonUpVector(vec);
209    }
210    //-----------------------------------------------------------------------
211    const Vector3& BillboardParticleRenderer::getCommonUpVector(void) const
212    {
213        return mBillboardSet->getCommonUpVector();
214    }
215    //-----------------------------------------------------------------------
216    void BillboardParticleRenderer::_notifyCurrentCamera(Camera* cam)
217    {
218        mBillboardSet->_notifyCurrentCamera(cam);
219    }
220    //-----------------------------------------------------------------------
221    void BillboardParticleRenderer::_notifyParticleRotated(void)
222    {
223        mBillboardSet->_notifyBillboardRotated();
224    }
225    //-----------------------------------------------------------------------
226    void BillboardParticleRenderer::_notifyDefaultDimensions(Real width, Real height)
227    {
228        mBillboardSet->setDefaultDimensions(width, height);
229    }
230    //-----------------------------------------------------------------------
231    void BillboardParticleRenderer::_notifyParticleResized(void)
232    {
233        mBillboardSet->_notifyBillboardResized();
234    }
235    //-----------------------------------------------------------------------
236    void BillboardParticleRenderer::_notifyParticleQuota(size_t quota)
237    {
238        mBillboardSet->setPoolSize(quota);
239    }
240    //-----------------------------------------------------------------------
241    void BillboardParticleRenderer::_notifyAttached(Node* parent, bool isTagPoint)
242    {
243        mBillboardSet->_notifyAttached(parent, isTagPoint);
244    }
245        //-----------------------------------------------------------------------
246        void BillboardParticleRenderer::setRenderQueueGroup(uint8 queueID)
247        {
248                assert(queueID <= RENDER_QUEUE_MAX && "Render queue out of range!");
249                mBillboardSet->setRenderQueueGroup(queueID);
250        }
251        //-----------------------------------------------------------------------
252        void BillboardParticleRenderer::setKeepParticlesInLocalSpace(bool keepLocal)
253        {
254                mBillboardSet->setBillboardsInWorldSpace(!keepLocal);
255        }
256    //-----------------------------------------------------------------------
257    SortMode BillboardParticleRenderer::_getSortMode(void) const
258    {
259        return mBillboardSet->_getSortMode();
260    }
261        //-----------------------------------------------------------------------
262        void BillboardParticleRenderer::setPointRenderingEnabled(bool enabled)
263        {
264                mBillboardSet->setPointRenderingEnabled(enabled);
265        }
266        //-----------------------------------------------------------------------
267        bool BillboardParticleRenderer::isPointRenderingEnabled(void) const
268        {
269                return mBillboardSet->isPointRenderingEnabled();
270        }
271    //-----------------------------------------------------------------------
272    //-----------------------------------------------------------------------
273    //-----------------------------------------------------------------------
274    const String& BillboardParticleRendererFactory::getType() const
275    {
276        return rendererTypeName;
277    }
278    //-----------------------------------------------------------------------
279    ParticleSystemRenderer* BillboardParticleRendererFactory::createInstance( 
280        const String& name )
281    {
282        return new BillboardParticleRenderer();
283    }
284    //-----------------------------------------------------------------------
285    void BillboardParticleRendererFactory::destroyInstance( 
286        ParticleSystemRenderer* inst)
287    {
288        delete inst;
289    }
290    //-----------------------------------------------------------------------
291    //-----------------------------------------------------------------------
292    String BillboardParticleRenderer::CmdBillboardType::doGet(const void* target) const
293    {
294        BillboardType t = static_cast<const BillboardParticleRenderer*>(target)->getBillboardType();
295        switch(t)
296        {
297        case BBT_POINT:
298            return "point";
299            break;
300        case BBT_ORIENTED_COMMON:
301            return "oriented_common";
302            break;
303        case BBT_ORIENTED_SELF:
304            return "oriented_self";
305            break;
306        case BBT_PERPENDICULAR_COMMON:
307            return "perpendicular_common";
308        case BBT_PERPENDICULAR_SELF:
309            return "perpendicular_self";
310        }
311        // Compiler nicety
312        return "";
313    }
314    void BillboardParticleRenderer::CmdBillboardType::doSet(void* target, const String& val)
315    {
316        BillboardType t;
317        if (val == "point")
318        {
319            t = BBT_POINT;
320        }
321        else if (val == "oriented_common")
322        {
323            t = BBT_ORIENTED_COMMON;
324        }
325        else if (val == "oriented_self")
326        {
327            t = BBT_ORIENTED_SELF;
328        }
329        else if (val == "perpendicular_common")
330        {
331            t = BBT_PERPENDICULAR_COMMON;
332        }
333        else if (val == "perpendicular_self")
334        {
335            t = BBT_PERPENDICULAR_SELF;
336        }
337        else
338        {
339            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
340                "Invalid billboard_type '" + val + "'", 
341                "ParticleSystem::CmdBillboardType::doSet");
342        }
343
344        static_cast<BillboardParticleRenderer*>(target)->setBillboardType(t);
345    }
346    //-----------------------------------------------------------------------
347    String BillboardParticleRenderer::CmdBillboardOrigin::doGet(const void* target) const
348    {
349        BillboardOrigin o = static_cast<const BillboardParticleRenderer*>(target)->getBillboardOrigin();
350        switch (o)
351        {
352        case BBO_TOP_LEFT:
353            return "top_left";
354        case BBO_TOP_CENTER:
355            return "top_center";
356        case BBO_TOP_RIGHT:
357            return "top_right";
358        case BBO_CENTER_LEFT:
359            return "center_left";
360        case BBO_CENTER:
361            return "center";
362        case BBO_CENTER_RIGHT:
363            return "center_right";
364        case BBO_BOTTOM_LEFT:
365            return "bottom_left";
366        case BBO_BOTTOM_CENTER:
367            return "bottom_center";
368        case BBO_BOTTOM_RIGHT:
369            return "bottom_right";
370        }
371        // Compiler nicety
372        return StringUtil::BLANK;
373    }
374    void BillboardParticleRenderer::CmdBillboardOrigin::doSet(void* target, const String& val)
375    {
376        BillboardOrigin o;
377        if (val == "top_left")
378            o = BBO_TOP_LEFT;
379        else if (val =="top_center")
380            o = BBO_TOP_CENTER;
381        else if (val =="top_right")
382            o = BBO_TOP_RIGHT;
383        else if (val =="center_left")
384            o = BBO_CENTER_LEFT;
385        else if (val =="center")
386            o = BBO_CENTER;
387        else if (val =="center_right")
388            o = BBO_CENTER_RIGHT;
389        else if (val =="bottom_left")
390            o = BBO_BOTTOM_LEFT;
391        else if (val =="bottom_center")
392            o = BBO_BOTTOM_CENTER;
393        else if (val =="bottom_right")
394            o = BBO_BOTTOM_RIGHT;
395        else
396        {
397            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
398                "Invalid billboard_origin '" + val + "'", 
399                "ParticleSystem::CmdBillboardOrigin::doSet");
400        }
401
402        static_cast<BillboardParticleRenderer*>(target)->setBillboardOrigin(o);
403    }
404    //-----------------------------------------------------------------------
405    String BillboardParticleRenderer::CmdBillboardRotationType::doGet(const void* target) const
406    {
407        BillboardRotationType r = static_cast<const BillboardParticleRenderer*>(target)->getBillboardRotationType();
408        switch(r)
409        {
410        case BBR_VERTEX:
411            return "vertex";
412        case BBR_TEXCOORD:
413            return "texcoord";
414        }
415        // Compiler nicety
416        return StringUtil::BLANK;
417    }
418    void BillboardParticleRenderer::CmdBillboardRotationType::doSet(void* target, const String& val)
419    {
420        BillboardRotationType r;
421        if (val == "vertex")
422            r = BBR_VERTEX;
423        else if (val == "texcoord")
424            r = BBR_TEXCOORD;
425        else
426        {
427            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
428                "Invalid billboard_rotation_type '" + val + "'", 
429                "ParticleSystem::CmdBillboardRotationType::doSet");
430        }
431
432        static_cast<BillboardParticleRenderer*>(target)->setBillboardRotationType(r);
433    }
434    //-----------------------------------------------------------------------
435    String BillboardParticleRenderer::CmdCommonDirection::doGet(const void* target) const
436    {
437        return StringConverter::toString(
438            static_cast<const BillboardParticleRenderer*>(target)->getCommonDirection() );
439    }
440    void BillboardParticleRenderer::CmdCommonDirection::doSet(void* target, const String& val)
441    {
442        static_cast<BillboardParticleRenderer*>(target)->setCommonDirection(
443            StringConverter::parseVector3(val));
444    }
445    //-----------------------------------------------------------------------
446    String BillboardParticleRenderer::CmdCommonUpVector::doGet(const void* target) const
447    {
448        return StringConverter::toString(
449            static_cast<const BillboardParticleRenderer*>(target)->getCommonUpVector() );
450    }
451    void BillboardParticleRenderer::CmdCommonUpVector::doSet(void* target, const String& val)
452    {
453        static_cast<BillboardParticleRenderer*>(target)->setCommonUpVector(
454            StringConverter::parseVector3(val));
455    }
456    //-----------------------------------------------------------------------
457    String BillboardParticleRenderer::CmdPointRendering::doGet(const void* target) const
458    {
459        return StringConverter::toString(
460            static_cast<const BillboardParticleRenderer*>(target)->isPointRenderingEnabled() );
461    }
462    void BillboardParticleRenderer::CmdPointRendering::doSet(void* target, const String& val)
463    {
464        static_cast<BillboardParticleRenderer*>(target)->setPointRenderingEnabled(
465            StringConverter::parseBool(val));
466    }
467        //-----------------------------------------------------------------------
468        String BillboardParticleRenderer::CmdAccurateFacing::doGet(const void* target) const
469        {
470                return StringConverter::toString(
471                        static_cast<const BillboardParticleRenderer*>(target)->getUseAccurateFacing() );
472        }
473        void BillboardParticleRenderer::CmdAccurateFacing::doSet(void* target, const String& val)
474        {
475                static_cast<BillboardParticleRenderer*>(target)->setUseAccurateFacing(
476                        StringConverter::parseBool(val));
477        }
478
479}
480
Note: See TracBrowser for help on using the repository browser.