source: OGRE/trunk/ogrenew/OgreMain/src/OgreBillboardChain.cpp @ 692

Revision 692, 22.4 KB checked in by mattausch, 19 years ago (diff)

adding ogre 1.2 and dependencies

RevLine 
[692]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-2005 The OGRE Team
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-----------------------------------------------------------------------------
24*/
25
26// Thanks to Vincent Cantin (karmaGfa) for the original implementation of this
27// class, although it has now been mostly rewritten
28
29#include "OgreStableHeaders.h"
30#include "OgreBillboardChain.h"
31
32#include "OgreSimpleRenderable.h"
33#include "OgreHardwareBufferManager.h"
34#include "OgreNode.h"
35#include "OgreCamera.h"
36#include "OgreRoot.h"
37#include "OgreMaterialManager.h"
38#include "OgreLogManager.h"
39#include "OgreStringConverter.h"
40
41namespace Ogre {
42        const size_t BillboardChain::SEGMENT_EMPTY = 0xffffffff;
43        //-----------------------------------------------------------------------
44        BillboardChain::Element::Element()
45        {
46        }
47        //-----------------------------------------------------------------------
48        BillboardChain::Element::Element(Vector3 _position,
49                Real _width,
50                Real _texCoord,
51                ColourValue _colour) :
52        position(_position),
53                width(_width),
54                texCoord(_texCoord),
55                colour(_colour)
56        {
57        }
58        //-----------------------------------------------------------------------
59        BillboardChain::BillboardChain(const String& name, size_t maxElements,
60                size_t numberOfChains, bool useTextureCoords, bool useColours, bool dynamic)
61                :MovableObject(name),
62                mMaxElementsPerChain(maxElements),
63                mChainCount(numberOfChains),
64                mUseTexCoords(useTextureCoords),
65                mUseVertexColour(useColours),
66                mDynamic(dynamic),
67                mVertexDeclDirty(true),
68                mBuffersNeedRecreating(true),
69                mBoundsDirty(true),
70                mIndexContentDirty(true),
71                mRadius(0.0f),
72                mTexCoordDir(TCD_U)
73        {
74                mVertexData = new VertexData();
75                mIndexData = new IndexData();
76
77                mOtherTexCoordRange[0] = 0.0f;
78                mOtherTexCoordRange[1] = 1.0f;
79
80                setupChainContainers();
81
82                mVertexData->vertexStart = 0;
83                // index data set up later
84                // set basic white material
85                this->setMaterialName("BaseWhiteNoLighting");
86
87        }
88        //-----------------------------------------------------------------------
89        BillboardChain::~BillboardChain()
90        {
91                delete mVertexData;
92                delete mIndexData;
93        }
94        //-----------------------------------------------------------------------
95        void BillboardChain::setupChainContainers(void)
96        {
97                // Allocate enough space for everything
98                mChainElementList.resize(mChainCount * mMaxElementsPerChain);
99                mVertexData->vertexCount = mChainElementList.size() * 2;
100
101                // Configure chains
102                mChainSegmentList.resize(mChainCount);
103                for (size_t i = 0; i < mChainCount; ++i)
104                {
105                        ChainSegment& seg = mChainSegmentList[i];
106                        seg.start = i * mMaxElementsPerChain;
107                        seg.tail = seg.head = SEGMENT_EMPTY;
108
109                }
110
111
112        }
113        //-----------------------------------------------------------------------
114        void BillboardChain::setupVertexDeclaration(void)
115        {
116                if (mVertexDeclDirty)
117                {
118                        VertexDeclaration* decl = mVertexData->vertexDeclaration;
119                        decl->removeAllElements();
120
121                        size_t offset = 0;
122                        // Add a description for the buffer of the positions of the vertices
123                        decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
124                        offset += VertexElement::getTypeSize(VET_FLOAT3);
125
126                        if (mUseVertexColour)
127                        {
128                                decl->addElement(0, offset, VET_COLOUR, VES_DIFFUSE);
129                                offset += VertexElement::getTypeSize(VET_COLOUR);
130                        }
131
132                        if (mUseTexCoords)
133                        {
134                                decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES);
135                                offset += VertexElement::getTypeSize(VET_FLOAT2);
136                        }
137
138                        if (!mUseTexCoords && !mUseVertexColour)
139                        {
140                                LogManager::getSingleton().logMessage(
141                                        "Error - BillboardChain '" + mName + "' is using neither "
142                                        "texture coordinates or vertex colours; it will not be "
143                                        "visible on some rendering APIs so you should change this "
144                                        "so you use one or the other.");
145                        }
146                        mVertexDeclDirty = false;
147                }
148        }
149        //-----------------------------------------------------------------------
150        void BillboardChain::setupBuffers(void)
151        {
152                setupVertexDeclaration();
153                if (mBuffersNeedRecreating)
154                {
155                        // Create the vertex buffer (always dynamic due to the camera adjust)
156                        HardwareVertexBufferSharedPtr pBuffer =
157                                HardwareBufferManager::getSingleton().createVertexBuffer(
158                                mVertexData->vertexDeclaration->getVertexSize(0),
159                                mVertexData->vertexCount,
160                                HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE);
161
162                        // (re)Bind the buffer
163                        // Any existing buffer will lose its reference count and be destroyed
164                        mVertexData->vertexBufferBinding->setBinding(0, pBuffer);
165
166                        mIndexData->indexBuffer =
167                                HardwareBufferManager::getSingleton().createIndexBuffer(
168                                        HardwareIndexBuffer::IT_16BIT,
169                                        mChainCount * mMaxElementsPerChain * 6, // max we can use
170                                        mDynamic? HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY : HardwareBuffer::HBU_STATIC_WRITE_ONLY);
171                        // NB we don't set the indexCount on IndexData here since we will
172                        // probably use less than the maximum number of indices
173
174                        mBuffersNeedRecreating = false;
175                }
176        }
177        //-----------------------------------------------------------------------
178        void BillboardChain::setMaxChainElements(size_t maxElements)
179        {
180                mMaxElementsPerChain = maxElements;
181                setupChainContainers();
182        }
183        //-----------------------------------------------------------------------
184        void BillboardChain::setNumberOfChains(size_t numChains)
185        {
186                mChainCount = numChains;
187                setupChainContainers();
188        }
189        //-----------------------------------------------------------------------
190        void BillboardChain::setUseTextureCoords(bool use)
191        {
192                mUseTexCoords = use;
193                mVertexDeclDirty = mBuffersNeedRecreating = true;
194        }
195        //-----------------------------------------------------------------------
196        void BillboardChain::setTextureCoordDirection(BillboardChain::TexCoordDirection dir)
197        {
198                mTexCoordDir = dir;
199        }
200        //-----------------------------------------------------------------------
201        void BillboardChain::setOtherTextureCoordRange(Real start, Real end)
202        {
203                mOtherTexCoordRange[0] = start;
204                mOtherTexCoordRange[1] = end;
205        }
206        //-----------------------------------------------------------------------
207        void BillboardChain::setUseVertexColours(bool use)
208        {
209                mUseVertexColour = use;
210                mVertexDeclDirty = mBuffersNeedRecreating = true;
211        }
212        //-----------------------------------------------------------------------
213        void BillboardChain::setDynamic(bool dyn)
214        {
215                mDynamic = dyn;
216                mBuffersNeedRecreating = mIndexContentDirty = true;
217        }
218        //-----------------------------------------------------------------------
219        void BillboardChain::addChainElement(size_t chainIndex,
220                const BillboardChain::Element& dtls)
221        {
222
223                if (chainIndex >= mChainCount)
224                {
225                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
226                                "chainIndex out of bounds",
227                                "BillboardChain::addChainElement");
228                }
229                ChainSegment& seg = mChainSegmentList[chainIndex];
230                if (seg.head == SEGMENT_EMPTY)
231                {
232                        // Tail starts at end, head grows backwards
233                        seg.tail = mMaxElementsPerChain - 1;
234                        seg.head = seg.tail;
235                        mIndexContentDirty = true;
236                }
237                else
238                {
239                        if (seg.head == 0)
240                        {
241                                // Wrap backwards
242                                seg.head = mMaxElementsPerChain - 1;
243                        }
244                        else
245                        {
246                                // Just step backward
247                                --seg.head;
248                        }
249                        // Run out of elements?
250                        if (seg.head == seg.tail)
251                        {
252                                // Move tail backwards too, losing the end of the segment and re-using
253                                // it in the head
254                                if (seg.tail == 0)
255                                        seg.tail = mMaxElementsPerChain - 1;
256                                else
257                                        --seg.tail;
258                        }
259                }
260
261                // Set the details
262                mChainElementList[seg.start + seg.head] = dtls;
263
264                mIndexContentDirty = true;
265                mBoundsDirty = true;
266                // tell parent node to update bounds
267                if (mParentNode)
268                        mParentNode->needUpdate();
269
270        }
271        //-----------------------------------------------------------------------
272        void BillboardChain::removeChainElement(size_t chainIndex)
273        {
274                if (chainIndex >= mChainCount)
275                {
276                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
277                                "chainIndex out of bounds",
278                                "BillboardChain::removeChainElement");
279                }
280                ChainSegment& seg = mChainSegmentList[chainIndex];
281                if (seg.head == SEGMENT_EMPTY)
282                        return; // do nothing, nothing to remove
283
284
285                if (seg.tail == seg.head)
286                {
287                        // last item
288                        seg.head = seg.tail = SEGMENT_EMPTY;
289                }
290                else if (seg.tail == 0)
291                {
292                        seg.tail = mMaxElementsPerChain - 1;
293                }
294                else
295                {
296                        --seg.tail;
297                }
298
299                // we removed an entry so indexes need updating
300                mIndexContentDirty = true;
301                mBoundsDirty = true;
302                // tell parent node to update bounds
303                if (mParentNode)
304                        mParentNode->needUpdate();
305
306        }
307        //-----------------------------------------------------------------------
308        void BillboardChain::updateChainElement(size_t chainIndex, size_t elementIndex,
309                const BillboardChain::Element& dtls)
310        {
311                if (chainIndex >= mChainCount)
312                {
313                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
314                                "chainIndex out of bounds",
315                                "BillboardChain::updateChainElement");
316                }
317                ChainSegment& seg = mChainSegmentList[chainIndex];
318                if (seg.head == SEGMENT_EMPTY)
319                {
320                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
321                                "Chain segment is empty",
322                                "BillboardChain::updateChainElement");
323                }
324
325                size_t idx = seg.head + elementIndex;
326                // adjust for the edge and start
327                idx = (idx % mMaxElementsPerChain) + seg.start;
328
329                mChainElementList[idx] = dtls;
330
331                mBoundsDirty = true;
332                // tell parent node to update bounds
333                if (mParentNode)
334                        mParentNode->needUpdate();
335
336
337        }
338        //-----------------------------------------------------------------------
339        const BillboardChain::Element&
340        BillboardChain::getChainElement(size_t chainIndex, size_t elementIndex) const
341        {
342
343                if (chainIndex >= mChainCount)
344                {
345                        OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND,
346                                "chainIndex out of bounds",
347                                "BillboardChain::updateChainElement");
348                }
349                const ChainSegment& seg = mChainSegmentList[chainIndex];
350
351                size_t idx = seg.head + elementIndex;
352                // adjust for the edge and start
353                idx = (idx % mMaxElementsPerChain) + seg.start;
354
355                return mChainElementList[idx];
356        }
357        //-----------------------------------------------------------------------
358        void BillboardChain::updateBoundingBox(void) const
359        {
360                if (mBoundsDirty)
361                {
362                        mAABB.setNull();
363                        Vector3 widthVector;
364                        for (ChainSegmentList::const_iterator segi = mChainSegmentList.begin();
365                                segi != mChainSegmentList.end(); ++segi)
366                        {
367                                const ChainSegment& seg = *segi;
368
369                                if (seg.head != SEGMENT_EMPTY)
370                                {
371
372                                        for(size_t e = seg.head; ; ++e) // until break
373                                        {
374                                                // Wrap forwards
375                                                if (e == mMaxElementsPerChain)
376                                                        e = 0;
377
378                                                const Element& elem = mChainElementList[seg.start + e];
379
380                                                widthVector.x = widthVector.y = widthVector.z = elem.width;
381                                                mAABB.merge(elem.position - widthVector);
382                                                mAABB.merge(elem.position + widthVector);
383
384                                                if (e == seg.tail)
385                                                        break;
386
387                                        }
388                                }
389
390                        }
391
392                        // Set the current radius
393                        if (mAABB.isNull())
394                        {
395                                mRadius = 0.0f;
396                        }
397                        else
398                        {
399                                mRadius = Math::Sqrt(
400                                        std::max(mAABB.getMinimum().squaredLength(),
401                                        mAABB.getMaximum().squaredLength()));
402                        }
403
404                        mBoundsDirty = false;
405                }
406        }
407        //-----------------------------------------------------------------------
408        void BillboardChain::updateVertexBuffer(Camera* cam)
409        {
410                setupBuffers();
411                HardwareVertexBufferSharedPtr pBuffer =
412                        mVertexData->vertexBufferBinding->getBuffer(0);
413                void* pBufferStart = pBuffer->lock(HardwareBuffer::HBL_DISCARD);
414
415                const Vector3& camPos = cam->getDerivedPosition();
416                Vector3 eyePos = mParentNode->_getDerivedOrientation().Inverse() *
417                        (camPos - mParentNode->_getDerivedPosition()) / mParentNode->_getDerivedScale();
418
419                Vector3 chainTangent;
420                for (ChainSegmentList::iterator segi = mChainSegmentList.begin();
421                        segi != mChainSegmentList.end(); ++segi)
422                {
423                        ChainSegment& seg = *segi;
424
425                        // Skip 0 or 1 element segment counts
426                        if (seg.head != SEGMENT_EMPTY && seg.head != seg.tail)
427                        {
428                                size_t laste = seg.head;
429                                for (size_t e = seg.head; ; ++e) // until break
430                                {
431                                        // Wrap forwards
432                                        if (e == mMaxElementsPerChain)
433                                                e = 0;
434
435                                        Element& elem = mChainElementList[e + seg.start];
436                                        uint16 baseIdx = (e + seg.start) * 2;
437
438                                        // Determine base pointer to vertex #1
439                                        void* pBase = static_cast<void*>(
440                                                static_cast<char*>(pBufferStart) +
441                                                        pBuffer->getVertexSize() * baseIdx);
442
443                                        // Get index of next item
444                                        size_t nexte = e + 1;
445                                        if (nexte == mMaxElementsPerChain)
446                                                nexte = 0;
447
448                                        if (e == seg.head)
449                                        {
450                                                // No laste, use next item
451                                                chainTangent = mChainElementList[nexte + seg.start].position - elem.position;
452                                        }
453                                        else if (e == seg.tail)
454                                        {
455                                                // No nexte, use only last item
456                                                chainTangent = elem.position - mChainElementList[laste + seg.start].position;
457                                        }
458                                        else
459                                        {
460                                                // A mid position, use tangent across both prev and next
461                                                chainTangent = mChainElementList[nexte + seg.start].position - mChainElementList[laste + seg.start].position;
462
463                                        }
464
465                                        Vector3 vP1ToEye = eyePos - elem.position;
466                                        Vector3 vPerpendicular = chainTangent.crossProduct(vP1ToEye);
467                                        vPerpendicular.normalise();
468                                        vPerpendicular *= (elem.width * 0.5);
469
470                                        Vector3 pos0 = elem.position - vPerpendicular;
471                                        Vector3 pos1 = elem.position + vPerpendicular;
472
473                                        float* pFloat = static_cast<float*>(pBase);
474                                        // pos1
475                                        *pFloat++ = pos0.x;
476                                        *pFloat++ = pos0.y;
477                                        *pFloat++ = pos0.z;
478
479                                        pBase = static_cast<void*>(pFloat);
480
481                                        if (mUseVertexColour)
482                                        {
483                                                RGBA* pCol = static_cast<RGBA*>(pBase);
484                                                Root::getSingleton().convertColourValue(elem.colour, pCol);
485                                                pCol++;
486                                                pBase = static_cast<void*>(pCol);
487                                        }
488
489                                        if (mUseTexCoords)
490                                        {
491                                                pFloat = static_cast<float*>(pBase);
492                                                if (mTexCoordDir == TCD_U)
493                                                {
494                                                        *pFloat++ = elem.texCoord;
495                                                        *pFloat++ = mOtherTexCoordRange[0];
496                                                }
497                                                else
498                                                {
499                                                        *pFloat++ = mOtherTexCoordRange[0];
500                                                        *pFloat++ = elem.texCoord;
501                                                }
502                                                pBase = static_cast<void*>(pFloat);
503                                        }
504
505                                        // pos2
506                                        pFloat = static_cast<float*>(pBase);
507                                        *pFloat++ = pos1.x;
508                                        *pFloat++ = pos1.y;
509                                        *pFloat++ = pos1.z;
510                                        pBase = static_cast<void*>(pFloat);
511
512                                        if (mUseVertexColour)
513                                        {
514                                                RGBA* pCol = static_cast<RGBA*>(pBase);
515                                                Root::getSingleton().convertColourValue(elem.colour, pCol);
516                                                pCol++;
517                                                pBase = static_cast<void*>(pCol);
518                                        }
519
520                                        if (mUseTexCoords)
521                                        {
522                                                pFloat = static_cast<float*>(pBase);
523                                                if (mTexCoordDir == TCD_U)
524                                                {
525                                                        *pFloat++ = elem.texCoord;
526                                                        *pFloat++ = mOtherTexCoordRange[1];
527                                                }
528                                                else
529                                                {
530                                                        *pFloat++ = mOtherTexCoordRange[1];
531                                                        *pFloat++ = elem.texCoord;
532                                                }
533                                                pBase = static_cast<void*>(pFloat);
534                                        }
535
536                                        if (e == seg.tail)
537                                                break; // last one
538
539                                        laste = e;
540
541                                } // element
542                        } // segment valid?
543
544                } // each segment
545
546
547
548                pBuffer->unlock();
549
550
551        }
552        //-----------------------------------------------------------------------
553        void BillboardChain::updateIndexBuffer(void)
554        {
555
556                setupBuffers();
557                if (mIndexContentDirty)
558                {
559
560                        uint16* pShort = static_cast<uint16*>(
561                                mIndexData->indexBuffer->lock(HardwareBuffer::HBL_DISCARD));
562                        mIndexData->indexCount = 0;
563                        // indexes
564                        for (ChainSegmentList::iterator segi = mChainSegmentList.begin();
565                                segi != mChainSegmentList.end(); ++segi)
566                        {
567                                ChainSegment& seg = *segi;
568
569                                // Skip 0 or 1 element segment counts
570                                if (seg.head != SEGMENT_EMPTY && seg.head != seg.tail)
571                                {
572                                        // Start from head + 1 since it's only useful in pairs
573                                        size_t laste = seg.head;
574                                        while(1) // until break
575                                        {
576                                                size_t e = laste + 1;
577                                                // Wrap forwards
578                                                if (e == mMaxElementsPerChain)
579                                                        e = 0;
580                                                // indexes of this element are (e * 2) and (e * 2) + 1
581                                                // indexes of the last element are the same, -2
582                                                uint16 baseIdx = (e + seg.start) * 2;
583                                                uint16 lastBaseIdx = (laste + seg.start) * 2;
584                                                *pShort++ = lastBaseIdx;
585                                                *pShort++ = lastBaseIdx + 1;
586                                                *pShort++ = baseIdx;
587                                                *pShort++ = lastBaseIdx + 1;
588                                                *pShort++ = baseIdx + 1;
589                                                *pShort++ = baseIdx;
590
591                                                mIndexData->indexCount += 6;
592
593
594                                                if (e == seg.tail)
595                                                        break; // last one
596
597                                                laste = e;
598
599                                        }
600                                }
601
602                        }
603                        mIndexData->indexBuffer->unlock();
604
605                        mIndexContentDirty = false;
606                }
607
608        }
609        //-----------------------------------------------------------------------
610        void BillboardChain::_notifyCurrentCamera(Camera* cam)
611        {
612                updateVertexBuffer(cam);
613        }
614        //-----------------------------------------------------------------------
615        Real BillboardChain::getSquaredViewDepth(const Camera* cam) const
616        {
617                Vector3 min, max, mid, dist;
618                min = mAABB.getMinimum();
619                max = mAABB.getMaximum();
620                mid = ((max - min) * 0.5) + min;
621                dist = cam->getDerivedPosition() - mid;
622
623                return dist.squaredLength();
624        }
625        //-----------------------------------------------------------------------
626        Real BillboardChain::getBoundingRadius(void) const
627        {
628                return mRadius;
629        }
630        //-----------------------------------------------------------------------
631        const AxisAlignedBox& BillboardChain::getBoundingBox(void) const
632        {
633                updateBoundingBox();
634                return mAABB;
635        }
636        //-----------------------------------------------------------------------
637        const MaterialPtr& BillboardChain::getMaterial(void) const
638        {
639                return mMaterial;
640        }
641        //-----------------------------------------------------------------------
642        void BillboardChain::setMaterialName(const String& name)
643        {
644                mMaterialName = name;
645                mMaterial = MaterialManager::getSingleton().getByName(mMaterialName);
646
647                if (mMaterial.isNull())
648                {
649                        LogManager::getSingleton().logMessage("Can't assign material " + name +
650                                " to BillboardChain " + mName + " because this "
651                                "Material does not exist. Have you forgotten to define it in a "
652                                ".material script?");
653                        mMaterial = MaterialManager::getSingleton().getByName("BaseWhiteNoLighting");
654                        if (mMaterial.isNull())
655                        {
656                                OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Can't assign default material "
657                                        "to BillboardChain of " + mName + ". Did "
658                                        "you forget to call MaterialManager::initialise()?",
659                                        "BillboardChain.setMaterialName");
660                        }
661                }
662                // Ensure new material loaded (will not load again if already loaded)
663                mMaterial->load();
664        }
665        //-----------------------------------------------------------------------
666        const String& BillboardChain::getMovableType(void) const
667        {
668                return BillboardChainFactory::FACTORY_TYPE_NAME;
669        }
670        //-----------------------------------------------------------------------
671        void BillboardChain::_updateRenderQueue(RenderQueue* queue)
672        {
673                updateIndexBuffer();
674
675                if (mIndexData->indexCount > 0)
676                {
677                        queue->addRenderable(this);
678                }
679
680        }
681        //-----------------------------------------------------------------------
682        void BillboardChain::getRenderOperation(RenderOperation& op)
683        {
684                op.indexData = mIndexData;
685                op.operationType = RenderOperation::OT_TRIANGLE_LIST;
686                op.srcRenderable = this;
687                op.useIndexes = true;
688                op.vertexData = mVertexData;
689        }
690        //-----------------------------------------------------------------------
691        void BillboardChain::getWorldTransforms(Matrix4* xform) const
692        {
693                *xform = _getParentNodeFullTransform();
694        }
695        //-----------------------------------------------------------------------
696        const Quaternion& BillboardChain::getWorldOrientation(void) const
697        {
698                return getParentNode()->_getDerivedOrientation();
699        }
700        //-----------------------------------------------------------------------
701        const Vector3& BillboardChain::getWorldPosition(void) const
702        {
703                return getParentNode()->_getDerivedPosition();
704        }
705        //-----------------------------------------------------------------------
706        const LightList& BillboardChain::getLights(void) const
707        {
708                return getParentSceneNode()->findLights(getBoundingRadius());
709        }
710        //-----------------------------------------------------------------------
711        //-----------------------------------------------------------------------
712        String BillboardChainFactory::FACTORY_TYPE_NAME = "BillboardChain";
713        //-----------------------------------------------------------------------
714        const String& BillboardChainFactory::getType(void) const
715        {
716                return FACTORY_TYPE_NAME;
717        }
718        //-----------------------------------------------------------------------
719        MovableObject* BillboardChainFactory::createInstanceImpl( const String& name,
720                const NameValuePairList* params)
721        {
722                size_t maxElements = 20;
723                size_t numberOfChains = 1;
724                bool useTex = true;
725                bool useCol = true;
726                bool dynamic = true;
727                // optional params
728                if (params != 0)
729                {
730                        NameValuePairList::const_iterator ni = params->find("maxElements");
731                        if (ni != params->end())
732                        {
733                                maxElements = StringConverter::parseUnsignedLong(ni->second);
734                        }
735                        ni = params->find("numberOfChains");
736                        if (ni != params->end())
737                        {
738                                numberOfChains = StringConverter::parseUnsignedLong(ni->second);
739                        }
740                        ni = params->find("useTextureCoords");
741                        if (ni != params->end())
742                        {
743                                useTex = StringConverter::parseBool(ni->second);
744                        }
745                        ni = params->find("useVertexColours");
746                        if (ni != params->end())
747                        {
748                                useCol = StringConverter::parseBool(ni->second);
749                        }
750                        ni = params->find("dynamic");
751                        if (ni != params->end())
752                        {
753                                dynamic = StringConverter::parseBool(ni->second);
754                        }
755
756                }
757
758                return new BillboardChain(name, maxElements, numberOfChains, useTex, useCol, dynamic);
759
760        }
761        //-----------------------------------------------------------------------
762        void BillboardChainFactory::destroyInstance( MovableObject* obj)
763        {
764                delete obj;
765        }
766
767}
768
Note: See TracBrowser for help on using the repository browser.