1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
41 //---------------------------------------------------------------------------
46 #include "OSGConfig.h"
48 #include "OSGAction.h"
49 #include "OSGRenderAction.h"
50 #include "OSGMaterial.h"
51 //#include "OSGGeoPropPtrs.h"
52 #include "OSGCamera.h"
53 #include "OSGWindow.h"
54 #include "OSGDrawEnv.h"
56 #include "OSGParticles.h"
57 #include "OSGDrawableStatsAttachment.h"
59 #include "OSGGLFuncProtos.h"
60 #include "OSGConceptPropertyChecks.h"
66 // Documentation for this class is emited in the
67 // OSGParticlesBase.cpp file.
68 // To modify it, please change the .fcd file (OSGParticles.fcd) and
69 // regenerate the base file.
71 /***************************************************************************\
73 \***************************************************************************/
75 static UInt32 _extMultitexture
= Window::invalidExtensionID
;
77 static UInt32 _funcglMultiTexCoord3fvARB
= Window::invalidFunctionID
;
79 /***************************************************************************\
81 \***************************************************************************/
83 void Particles::initMethod(InitPhase ePhase
)
85 Inherited::initMethod(ePhase
);
87 if(ePhase
== TypeObject::SystemPost
)
89 RenderAction::registerEnterDefault(
90 Particles::getClassType(),
91 reinterpret_cast<Action::Callback
>(
92 &MaterialDrawable::renderEnter
));
94 RenderAction::registerLeaveDefault(
95 Particles::getClassType(),
96 reinterpret_cast<Action::Callback
>(
97 &MaterialDrawable::renderLeave
));
100 Window::registerExtension("GL_ARB_multitexture");
102 _funcglMultiTexCoord3fvARB
=
103 Window::registerFunction(
104 OSG_DLSYM_UNDERSCORE
"glMultiTexCoord3fvARB", _extMultitexture
);
108 /***************************************************************************\
110 \***************************************************************************/
112 /*-------------------------------------------------------------------------*\
114 \*-------------------------------------------------------------------------*/
116 Particles::Particles(void) :
121 Particles::Particles(const Particles
&source
) :
126 Particles::~Particles(void)
130 /*------------------------------- Sync -----------------------------------*/
132 void Particles::changed(ConstFieldMaskArg whichField
,
136 if(whichField
& PositionsFieldMask
)
138 for(UInt32 i
= 0; i
< _mfParents
.size(); i
++)
140 _mfParents
[i
]->invalidateVolume();
146 Inherited::changed(whichField
, origin
, details
);
149 /*------------------------------ Output ----------------------------------*/
151 void Particles::dump( UInt32
,
152 const BitVector
) const
154 SLOG
<< "Dump Particles NI" << std::endl
;
158 void Particles::adjustVolume( Volume
& volume
)
160 GeoVectorProperty
*pos
= getPositions();
163 return; // Node has no particles, no volume
168 const MFVec3f
*sizes
= getMFSizes();
170 if(sizes
->size() == pos
->size())
175 for(UInt32 i
= 0; i
< pos
->size(); i
++)
178 // make the size bigger to accomodate rotations
179 s
=(*sizes
)[i
][0]*Sqrt2
;
202 else if(sizes
->size() == 1)
206 // make the size bigger to accomodate rotations
207 s
=(*sizes
)[0][0]*Sqrt2
;
210 for(UInt32 i
= 0; i
< pos
->size(); i
++)
239 for(UInt32 i
= 0; i
< pos
->size32(); i
++)
248 void Particles::fill(DrawableStatsAttachment
*pStat
)
252 FINFO(("Particles::fill(DrawableStatsAttachment *): "
253 "No attachment given.\n"));
257 const GeoVectorProperty
*positions
= getPositions();
258 const MFInt32
*indices
= getMFIndices();
260 if(positions
== NULL
)
262 FINFO(("Particles::fill(DrawableStatsAttachment *): "
270 UInt32 triangles
= 0;
272 if(indices
->size() > 0)
274 verts
+= indices
->size32();
278 verts
+= positions
->size32();
300 triangles
+= verts
* 2;
307 triangles
+= verts
* 5;
313 triangles
+= verts
- 2;
319 FWARNING(("Particles::fill(DrawableStatsAttachment *): "
320 "Invalid sfMode value.\n"));
325 pStat
->setVertices (verts
);
326 pStat
->setPoints (points
);
327 pStat
->setLines (lines
);
328 pStat
->setTriangles(triangles
);
331 /*---------------------------- pumps -----------------------------------*/
333 /*! \name Drawing Pumps */
336 /*! The pumps use a trait system to create specialized code for important
337 cases. The general idea is to keep decision out of the inner loops
338 and make special versions for the most common data types. Not for
339 everything, as that creates big time code bloat.
342 /*! Base class for the particle rendering traits. Does nothing, just needed to
343 have a common base class.
346 /*! \ingroup GrpDrawablesParticlesHelpers
353 /*! Color trait base, keep the static data needed for color handling
354 \ingroup GrpDrawablesParticlesHelpers
357 struct ColTraitBase
: public ParticleTraits
359 typedef void (OSG_APIENTRY
*pumpFunc
)( GLubyte
* data
);
360 static const int formatBase
;
361 enum { numFormats
= GL_DOUBLE
- GL_BYTE
+ 1 };
363 static const char *formatNames
[];
365 static pumpFunc ColorFuncs
[numFormats
][4];
368 /*! The smallest enum for data types, used as a base for the formatNames map.
370 const int ColTraitBase::formatBase
= GL_BYTE
;
372 /*! A map from the OpenGL data type to the corresponding name
374 const char *ColTraitBase::formatNames
[] =
375 { "GL_BYTE", "GL_UNSIGNED_BYTE", "GL_SHORT", "GL_UNSIGNED_SHORT",
376 "GL_INT", "GL_UNSIGNED_INT", "GL_FLOAT", "GL_2_BYTES",
377 "GL_3_BYTES", "GL_4_BYTES", "GL_DOUBLE"
380 /*! The pump functions for colors, indexed by data type and dimensionality
382 ColTraitBase::pumpFunc
383 ColTraitBase::ColorFuncs
[ColTraitBase::numFormats
][4] = {
386 reinterpret_cast<pumpFunc
>(glColor3bv
),
387 reinterpret_cast<pumpFunc
>(glColor4bv
) }, // GL_BYTE
390 reinterpret_cast<pumpFunc
>(glColor3ubv
),
391 reinterpret_cast<pumpFunc
>(glColor4ubv
) }, // GL_UNSIGNED_BYTE
394 reinterpret_cast<pumpFunc
>(glColor3sv
),
395 reinterpret_cast<pumpFunc
>(glColor4sv
) }, // GL_SHORT
398 reinterpret_cast<pumpFunc
>(glColor3usv
),
399 reinterpret_cast<pumpFunc
>(glColor4usv
) }, // GL_UNSIGNED_SHORT
402 reinterpret_cast<pumpFunc
>(glColor3iv
),
403 reinterpret_cast<pumpFunc
>(glColor4iv
) }, // GL_INT
406 reinterpret_cast<pumpFunc
>(glColor3uiv
),
407 reinterpret_cast<pumpFunc
>(glColor4uiv
) }, // GL_UNSIGNED_INT
410 reinterpret_cast<pumpFunc
>(glColor3fv
),
411 reinterpret_cast<pumpFunc
>(glColor4fv
) }, // GL_FLOAT
412 { NULL
, NULL
, NULL
, NULL
}, // GL_2_BYTES
413 { NULL
, NULL
, NULL
, NULL
}, // GL_3_BYTES
414 { NULL
, NULL
, NULL
, NULL
}, // GL_4_BYTES
416 reinterpret_cast<pumpFunc
>(glColor3dv
),
417 reinterpret_cast<pumpFunc
>(glColor4dv
) }, // GL_DOUBLE
420 /*! \ingroup GrpDrawablesParticlesHelpers
423 struct ColTraitNone
: public ColTraitBase
425 typedef UInt8 dataType
; // no data needed, but can't instantiate void
427 static inline void init(Particles
*, DrawEnv
*, dataType
&)
431 static inline bool particle(dataType
&, UInt32
)
436 static inline void vertex(dataType
&, UInt32
, UInt32
)
441 /*! \ingroup GrpDrawablesParticlesHelpers
444 struct ColTraitSingle
: public ColTraitBase
446 typedef UInt8 dataType
; // no data needed, but can't instantiate void
448 static inline void init(Particles
*part
, DrawEnv
*, dataType
&)
450 GeoVectorProperty
*col
= part
->getColors();
456 col_func
= ColorFuncs
[ col
->getFormat() - formatBase
]
457 [ col
->getDimension() - 1 ];
461 SWARNING
<< "Particles " << part
<< "have illegal "
462 << "colors: " << col
->getDimension()
463 << "D " << formatNames
[col
->getFormat() - formatBase
]
469 col_func(const_cast<GLubyte
*>(col
->getData()));
474 static inline bool particle(dataType
&, UInt32
)
479 static inline void vertex(dataType
&, UInt32
, UInt32
)
484 /*! \ingroup GrpDrawablesParticlesHelpers
487 struct ColTraitParticle
: public ColTraitBase
499 static inline void init(Particles
*part
, DrawEnv
*, dataType
&data
)
501 GeoVectorProperty
*col
= part
->getColors();
503 data
.data
= col
->getData();
504 if((data
.stride
= col
->getStride()) == 0)
505 data
.stride
= col
->getFormatSize() * col
->getDimension();
507 data
.func
= ColorFuncs
[ col
->getFormat() - formatBase
]
508 [ col
->getDimension() - 1 ];
510 if(data
.func
== NULL
)
512 SWARNING
<< "Particles " << part
<< "have illegal "
513 << "colors: " << col
->getDimension()
514 << "D " << formatNames
[ col
->getFormat() - formatBase
]
520 static inline bool particle(dataType
&data
, UInt32 particle
)
522 data
.func(const_cast<GLubyte
*>(data
.data
+ particle
* data
.stride
));
527 static inline void vertex(dataType
&, UInt32
, UInt32
)
532 /*! \ingroup GrpDrawablesParticlesHelpers
535 struct ColTraitGeneric
: public ColTraitBase
547 static inline void init(Particles
*part
, DrawEnv
*, dataType
&data
)
549 GeoVectorProperty
*col
= part
->getColors();
551 data
.perParticle
= false;
555 data
.data
= col
->getData();
556 if((data
.stride
= col
->getStride()) == 0)
557 data
.stride
= col
->getFormatSize() * col
->getDimension();
559 data
.func
= ColorFuncs
[ col
->getFormat() - formatBase
]
560 [ col
->getDimension() - 1 ];
562 if(data
.func
== NULL
)
564 SWARNING
<< "Particles " << part
<< "have illegal "
565 << "colors: " << col
->getDimension()
566 << "D " << formatNames
[ col
->getFormat() - formatBase
]
573 data
.func(const_cast<GLubyte
*>(col
->getData()));
575 else if(col
->size() == part
->getPositions()->size())
577 data
.perParticle
= true;
582 static inline bool particle(dataType
&data
, UInt32 particle
)
584 if(data
.perParticle
== true)
587 const_cast<GLubyte
*>(data
.data
+ particle
* data
.stride
));
592 static inline void vertex(dataType
&, UInt32
, UInt32
)
597 /*! Position Particle Traits
598 \ingroup GrpDrawablesParticlesHelpers
601 struct PosTraitNone
: public ParticleTraits
610 static inline void init(Particles
*, DrawEnv
*, dataType
&data
,
611 GeoVectorProperty
*pos
)
615 static inline bool particle(dataType
&data
, UInt32 particle
)
620 static inline Pnt3f
&position(dataType
&data
)
622 static Pnt3f
null(0,0,0);
626 static inline void vertex(dataType
&data
, UInt32
, Vec4f
&dir
,
631 static inline void vertex(dataType
&data
)
636 /*! \ingroup GrpDrawablesParticlesHelpers
638 struct PosTraitGeneric
: public ParticleTraits
644 GeoVectorProperty
*pos
;
647 dataType(void) : pos(NULL
), p() {}
651 dataType(const dataType
&other
);
652 void operator =(const dataType
&rhs
);
655 static inline void init(Particles
*, DrawEnv
*, dataType
&data
,
656 GeoVectorProperty
*pos
)
661 static inline bool particle(dataType
&data
, UInt32 particle
)
663 data
.pos
->getValue(data
.p
, particle
);
668 static inline Pnt3f
&position(dataType
&data
)
673 static inline void vertex(dataType
&data
, UInt32
, Vec4f
&dir
,
676 glVertex3f( data
.p
[0] + dir
[0] * s
,
677 data
.p
[1] + dir
[1] * s
,
678 data
.p
[2] + dir
[2] * s
);
681 static inline void vertex(dataType
&data
)
683 glVertex3fv(static_cast<GLfloat
*>(data
.p
.getValues()));
687 /*! \ingroup GrpDrawablesParticlesHelpers
689 struct PosTrait3f
: public ParticleTraits
699 static inline void init(Particles
*,
702 GeoVectorProperty
*pos
)
704 GeoPnt3fProperty
*pos3f
= dynamic_cast<GeoPnt3fProperty
*>(pos
);
706 data
.pos
= pos3f
->getFieldPtr();
709 static inline bool particle(dataType
&data
, UInt32 particle
)
711 data
.p
= & (*(data
.pos
))[particle
];
715 static inline const Pnt3f
&position(dataType
&data
)
720 static inline void vertex(dataType
&data
, UInt32
, Vec4f
&dir
, Real32 s
)
722 glVertex3f( (*data
.p
)[0] + dir
[0] * s
,
723 (*data
.p
)[1] + dir
[1] * s
,
724 (*data
.p
)[2] + dir
[2] * s
);
727 static inline void vertex(dataType
&data
)
729 glVertex3fv(static_cast<const GLfloat
*>((*data
.p
).getValues()));
733 /*! Particle Size Traits
734 \ingroup GrpDrawablesParticlesHelpers
736 struct SizeTraitGeneric
: public ParticleTraits
742 const MFVec3f
*sizes
;
746 dataType(void): sizes(NULL
), s(), perParticle(true) {}
749 dataType(const dataType
&other
);
750 void operator =(const dataType
&rhs
);
753 static inline void init(Particles
*part
, DrawEnv
*, dataType
&data
)
755 data
.sizes
= part
->getMFSizes();
757 if(data
.sizes
!= NULL
)
759 if(data
.sizes
->size() == 1)
761 data
.s
= (*(data
.sizes
))[0];
762 data
.perParticle
= false;
764 else if(data
.sizes
->size() == part
->getPositions()->size())
766 data
.perParticle
= true;
770 data
.s
.setValues(1,1,1);
771 data
.perParticle
= false;
776 data
.s
.setValues(1,1,1);
777 data
.perParticle
= false;
781 static inline bool particle(dataType
&, UInt32
)
786 static inline const Vec3f
&size(dataType
&data
, UInt32 particle
)
789 return (*(data
.sizes
))[particle
];
794 /*! \ingroup GrpDrawablesParticlesHelpers
796 struct SizeTraitSingle
: public ParticleTraits
804 dataType(void) : s() {}
807 static inline void init(Particles
*part
, DrawEnv
*, dataType
&data
)
809 data
.s
= (*part
->getMFSizes())[0];
812 static inline bool particle(dataType
&, UInt32
)
817 static inline Vec3f
&size(dataType
&data
, UInt32
)
823 /*! \ingroup GrpDrawablesParticlesHelpers
825 struct SizeTraitParticle
: public ParticleTraits
831 const MFVec3f
*sizes
;
834 dataType(void) : sizes(NULL
), s(){}
837 dataType(const dataType
&other
);
838 void operator =(const dataType
&rhs
);
841 static inline void init(Particles
*part
, DrawEnv
*, dataType
&data
)
843 data
.sizes
= part
->getMFSizes();
846 static inline bool particle(dataType
&, UInt32
)
851 static inline const Vec3f
&size(dataType
&data
, UInt32 particle
)
853 return (*(data
.sizes
))[particle
];
857 /*! \ingroup GrpDrawablesParticlesHelpers
859 struct SizeTraitNone
: public ParticleTraits
861 typedef UInt8 dataType
;
863 static inline void init(Particles
*, DrawEnv
*, dataType
&)
867 static inline bool particle(dataType
&, UInt32
)
872 static inline Vec3f
&size(dataType
&, UInt32
)
874 static Vec3f
s(1,1,1);
879 /*! Particle Texture Traits
880 \ingroup GrpDrawablesParticlesHelpers
882 struct TexTraitGeneric
: public ParticleTraits
888 const MFReal32
*texzs
;
893 static inline void init(Particles
*part
, DrawEnv
*, dataType
&data
)
895 data
.texzs
= part
->getMFTextureZs();
897 data
.perParticle
= false;
899 if(data
.texzs
!= NULL
)
901 if(data
.texzs
->size() == 1)
903 data
.z
= (*(data
.texzs
))[0];
905 else if(data
.texzs
->size() == part
->getPositions()->size())
907 data
.perParticle
= true;
921 static inline bool particle(dataType
&data
, UInt32 particle
)
925 data
.z
= (*(data
.texzs
))[particle
];
930 static inline void vertex(dataType
&data
)
932 glTexCoord1f(data
.z
);
935 static inline void vertex(dataType
&data
, UInt32
, Real32 u
,
938 glTexCoord3f(u
, v
, data
.z
);
942 /*! \ingroup GrpDrawablesParticlesHelpers
944 struct TexTraitParticle
: public ParticleTraits
950 const MFReal32
*texzs
;
954 static inline void init(Particles
*part
, DrawEnv
*, dataType
&data
)
956 data
.texzs
= part
->getMFTextureZs();
959 static inline bool particle(dataType
&data
, UInt32 particle
)
961 data
.z
= (*(data
.texzs
))[particle
];
965 static inline void vertex(dataType
&data
)
967 glTexCoord1f(data
.z
);
970 static inline void vertex(dataType
&data
, UInt32
, Real32 u
,
973 glTexCoord3f(u
, v
, data
.z
);
977 /*! \ingroup GrpDrawablesParticlesHelpers
979 struct TexTraitSingle
: public ParticleTraits
989 static inline void init(Particles
*part
, DrawEnv
*, dataType
&data
)
991 data
.z
= (*(part
->getMFTextureZs()))[0];
994 static inline bool particle(dataType
&, UInt32
)
999 static inline void vertex(dataType
&data
)
1001 glTexCoord1f(data
.z
);
1004 static inline void vertex(dataType
&data
, UInt32
, Real32 u
,
1007 glTexCoord3f(u
, v
, data
.z
);
1011 /*! \ingroup GrpDrawablesParticlesHelpers
1013 struct TexTraitNone
: public ParticleTraits
1015 typedef UInt8 dataType
;
1017 static inline void init(Particles
*, DrawEnv
*, dataType
&)
1021 static inline bool particle(dataType
&, UInt32
)
1026 static inline void vertex(dataType
&, UInt32
)
1031 static inline void vertex(dataType
&, UInt32
, Real32 u
, Real32 v
)
1038 /*! Normal Particle Traits
1039 \ingroup GrpDrawablesParticlesHelpers
1041 struct NormalTraitGeneric
: public ParticleTraits
1047 GeoVectorProperty
*norms
;
1051 dataType(void) : norms(NULL
), n(), perParticle(true) {}
1055 dataType(const dataType
&other
);
1056 void operator =(const dataType
&rhs
);
1059 static inline void init(Particles
*part
, DrawEnv
*, dataType
&data
)
1061 data
.norms
= part
->getNormals();
1063 data
.perParticle
= false;
1065 if(data
.norms
!= NULL
)
1067 if(data
.norms
->size() == 1)
1069 data
.norms
->getValue(data
.n
, 0);
1071 else if(data
.norms
->size() == part
->getPositions()->size())
1073 data
.perParticle
= true;
1077 data
.n
.setValues(0,1,0);
1082 data
.n
.setValues(0,1,0);
1086 static inline bool particle(dataType
&data
, UInt32 particle
)
1088 if(data
.perParticle
)
1089 data
.norms
->getValue(data
.n
, particle
);
1094 static inline Vec3f
&normal(dataType
&data
)
1099 static inline void normal(dataType
&data
, UInt32
)
1101 glNormal3fv(static_cast<GLfloat
*>(data
.n
.getValues()));
1105 /*! \ingroup GrpDrawablesParticlesHelpers
1107 struct NormalTraitGeneric3f
: public ParticleTraits
1113 const MFVec3f
*norms
;
1119 static inline void init(Particles
*part
, DrawEnv
*, dataType
&data
)
1121 GeoVec3fProperty
*norms3f
=
1122 dynamic_cast<GeoVec3fProperty
*>(part
->getNormals());
1124 data
.norms
= norms3f
->getFieldPtr();
1126 data
.perParticle
= false;
1130 if(norms3f
->size() == 1)
1132 data
.n
= &(*(data
.norms
))[0];
1134 else if(data
.norms
->size() == part
->getPositions()->size())
1136 data
.perParticle
= true;
1140 data
.const_n
.setValues(0,1,0);
1141 data
.n
= &data
.const_n
;
1146 data
.const_n
.setValues(0,1,0);
1147 data
.n
= &data
.const_n
;
1151 static inline bool particle(dataType
&data
, UInt32 particle
)
1153 if(data
.perParticle
)
1154 data
.n
= &(*(data
.norms
))[particle
];
1159 static inline const Vec3f
&normal(dataType
&data
)
1164 static inline void normal(dataType
&data
, UInt32
)
1166 glNormal3fv(static_cast<const GLfloat
*>(data
.n
->getValues()));
1170 /*! ParticlesDrawer base classes, define the common interface(s)
1171 \ingroup GrpDrawablesParticlesHelpers
1173 struct ParticlesDrawer
1175 virtual void draw(Particles
*part
,
1179 virtual void drawIndexed( Particles
*part
,
1184 virtual ~ParticlesDrawer()
1189 /*! View-Dir aligned, indexed quad rendering
1190 \ingroup GrpDrawablesParticlesHelpers
1192 template <class posTrait
, class colTrait
, class texTrait
, class sizeTrait
>
1193 struct drawViewDirQuads
: public ParticlesDrawer
1195 virtual void drawIndexed( Particles
*part
,
1200 // get ModelView matrix to define the direction vectors
1201 Matrix camera
= pEnv
->getCameraToWorld();
1202 Matrix toworld
= pEnv
->getObjectToWorld();
1206 DrawActionBase *action = pEnv->getOldAction();
1208 RenderAction *ra = dynamic_cast<RenderAction *>(action);
1212 toworld = ra->top_matrix();
1216 action->getActNode()->getToWorld(toworld);
1220 // normalize them, we don't want to neutralize scales in toworld
1221 toworld
[0].normalize();
1222 toworld
[1].normalize();
1223 toworld
[2].normalize();
1224 toworld
.transpose();
1225 camera
.multLeft(toworld
);
1227 // Direction vectors
1228 Vec4f d1
, d2
, d3
, d4
;
1230 d1
= -1.0f
* camera
[0] + -1.0f
* camera
[1];
1231 d2
= 1.0f
* camera
[0] + -1.0f
* camera
[1];
1232 d3
= 1.0f
* camera
[0] + 1.0f
* camera
[1];
1233 d4
= -1.0f
* camera
[0] + 1.0f
* camera
[1];
1235 // some variables for faster access
1236 GeoVectorProperty
*pos
= part
->getPositions();
1239 typename
colTrait::dataType colData
;
1240 colTrait::init(part
, pEnv
, colData
);
1242 typename
texTrait::dataType texData
;
1243 texTrait::init(part
, pEnv
, texData
);
1245 typename
sizeTrait::dataType sizeData
;
1246 sizeTrait::init(part
, pEnv
, sizeData
);
1248 typename
posTrait::dataType posData
;
1249 posTrait::init(part
, pEnv
, posData
, part
->getPositions());
1255 for(UInt32 ii
= 0; ii
< length
; ++ii
)
1259 if(i
< 0 || i
> Int32(pos
->size32()))
1262 if(colTrait::particle (colData
, i
))
1265 if(texTrait::particle (texData
, i
))
1268 if(sizeTrait::particle(sizeData
, i
))
1271 if(posTrait::particle(posData
, i
))
1274 Real32 s
= sizeTrait::size(sizeData
, i
)[0] / 2.f
;
1279 colTrait::vertex(colData
, i
, 0);
1280 texTrait::vertex(texData
, 0, 0, 0);
1281 posTrait::vertex(posData
, 0, d1
, s
);
1283 colTrait::vertex(colData
, i
, 1);
1284 texTrait::vertex(texData
, 1, 1, 0);
1285 posTrait::vertex(posData
, 1, d2
, s
);
1287 colTrait::vertex(colData
, i
, 2);
1288 texTrait::vertex(texData
, 2, 1, 1);
1289 posTrait::vertex(posData
, 2, d3
, s
);
1291 colTrait::vertex(colData
, i
, 3);
1292 texTrait::vertex(texData
, 3, 0, 1);
1293 posTrait::vertex(posData
, 3, d4
, s
);
1299 virtual void draw(Particles
*part
, DrawEnv
*pEnv
, UInt32 length
)
1301 // get ModelView matrix to define the direction vectors
1303 Matrix camera
= pEnv
->getCameraToWorld();
1304 Matrix toworld
= pEnv
->getObjectToWorld();
1307 DrawActionBase *action = pEnv->getOldAction();
1309 RenderAction *ra = dynamic_cast<RenderAction *>(action);
1313 toworld = ra->top_matrix();
1317 action->getActNode()->getToWorld(toworld);
1321 // normalize them, we don't want to neutralize scales in toworld
1322 toworld
[0].normalize();
1323 toworld
[1].normalize();
1324 toworld
[2].normalize();
1325 toworld
.transpose();
1326 camera
.multLeft(toworld
);
1328 // Direction vectors
1329 Vec4f d1
, d2
, d3
, d4
;
1331 d1
= -1.0f
* camera
[0] + -1.0f
* camera
[1];
1332 d2
= 1.0f
* camera
[0] + -1.0f
* camera
[1];
1333 d3
= 1.0f
* camera
[0] + 1.0f
* camera
[1];
1334 d4
= -1.0f
* camera
[0] + 1.0f
* camera
[1];
1336 // some variables for faster access
1339 typename
colTrait::dataType colData
;
1340 colTrait::init(part
, pEnv
, colData
);
1342 typename
texTrait::dataType texData
;
1343 texTrait::init(part
, pEnv
, texData
);
1345 typename
sizeTrait::dataType sizeData
;
1346 sizeTrait::init(part
, pEnv
, sizeData
);
1348 typename
posTrait::dataType posData
;
1349 posTrait::init(part
, pEnv
, posData
, part
->getPositions());
1353 for(UInt32 i
= 0; i
< length
; ++i
)
1355 if(colTrait::particle (colData
, i
))
1358 if(texTrait::particle (texData
, i
))
1361 if(sizeTrait::particle(sizeData
, i
))
1364 if(posTrait::particle(posData
, i
))
1367 Real32 s
= sizeTrait::size(sizeData
, i
)[0] / 2.f
;
1372 colTrait::vertex(colData
, i
, 0);
1373 texTrait::vertex(texData
, 0, 0, 0);
1374 posTrait::vertex(posData
, 0, d1
, s
);
1376 colTrait::vertex(colData
, i
, 1);
1377 texTrait::vertex(texData
, 1, 1, 0);
1378 posTrait::vertex(posData
, 1, d2
, s
);
1380 colTrait::vertex(colData
, i
, 2);
1381 texTrait::vertex(texData
, 2, 1, 1);
1382 posTrait::vertex(posData
, 2, d3
, s
);
1384 colTrait::vertex(colData
, i
, 3);
1385 texTrait::vertex(texData
, 3, 0, 1);
1386 posTrait::vertex(posData
, 3, d4
, s
);
1394 /*! Viewer aligned, indexed quad rendering
1395 \ingroup GrpDrawablesParticlesHelpers
1397 template <class posTrait
, class colTrait
, class texTrait
, class sizeTrait
>
1398 struct drawViewerQuads
: public ParticlesDrawer
1400 virtual void drawIndexed(Particles
*part
, DrawEnv
*pEnv
,
1401 const Int32
*index
, UInt32 length
)
1403 // get ModelView matrix to define the direction vectors
1404 // Matrix camera,toworld;
1406 Matrix camera
= pEnv
->getCameraToWorld();
1407 Matrix toworld
= pEnv
->getObjectToWorld();
1410 DrawActionBase *action = pEnv->getOldAction();
1412 RenderAction *ra = dynamic_cast<RenderAction *>(action);
1416 toworld = ra->top_matrix();
1420 action->getActNode()->getToWorld(toworld);
1424 // normalize them, we don't want to neutralize scales in toworld
1425 toworld
[0].normalize();
1426 toworld
[1].normalize();
1427 toworld
[2].normalize();
1429 camera
.multLeft(toworld
);
1431 // Viewer position & up
1432 Pnt3f
vpos(camera
[3]);
1433 Vec3f
vup (camera
[1]);
1440 // some variables for faster access
1441 GeoVectorProperty
*pos
= part
->getPositions();
1444 typename
colTrait::dataType colData
;
1445 colTrait::init(part
, pEnv
, colData
);
1447 typename
texTrait::dataType texData
;
1448 texTrait::init(part
, pEnv
, texData
);
1450 typename
sizeTrait::dataType sizeData
;
1451 sizeTrait::init(part
, pEnv
, sizeData
);
1453 typename
posTrait::dataType posData
;
1454 posTrait::init(part
, pEnv
, posData
, part
->getPositions());
1460 for(UInt32 ii
= 0; ii
< length
; ++ii
)
1464 if(i
< 0 || i
> Int32(pos
->size32()))
1467 if(colTrait::particle (colData
, i
))
1470 if(texTrait::particle (texData
, i
))
1473 if(sizeTrait::particle(sizeData
, i
))
1476 if(posTrait::particle(posData
, i
))
1479 Real32 s
= sizeTrait::size(sizeData
, i
)[0] / 2.f
;
1484 // calc viewer-relative coord system
1486 Pnt3f p
= pos
->getValue
<Pnt3f
>(i
);
1489 vnorm
= vup
.cross(vdir
);
1491 d
.setValues( -vnorm
[0] - vup
[0],
1495 colTrait::vertex(colData
, i
, 0);
1496 texTrait::vertex(texData
, 0, 0, 0);
1497 posTrait::vertex(posData
, 0, d
, s
);
1499 d
.setValues( vnorm
[0] - vup
[0],
1503 colTrait::vertex(colData
, i
, 1);
1504 texTrait::vertex(texData
, 1, 1, 0);
1505 posTrait::vertex(posData
, 1, d
, s
);
1507 d
.setValues( vnorm
[0] + vup
[0],
1511 colTrait::vertex(colData
, i
, 2);
1512 texTrait::vertex(texData
, 2, 1, 1);
1513 posTrait::vertex(posData
, 2, d
, s
);
1515 d
.setValues( -vnorm
[0] + vup
[0],
1519 colTrait::vertex(colData
, i
, 3);
1520 texTrait::vertex(texData
, 3, 0, 1);
1521 posTrait::vertex(posData
, 3, d
, s
);
1527 virtual void draw(Particles
*part
, DrawEnv
*pEnv
, UInt32 length
)
1529 // get ModelView matrix to define the direction vectors
1531 Matrix camera
= pEnv
->getCameraToWorld();
1532 Matrix toworld
= pEnv
->getObjectToWorld();
1535 DrawActionBase *action = pEnv->getOldAction();
1537 RenderAction *ra = dynamic_cast<RenderAction *>(action);
1541 toworld = ra->top_matrix();
1545 action->getActNode()->getToWorld(toworld);
1549 // normalize them, we don't want to neutralize scales in toworld
1550 toworld
[0].normalize();
1551 toworld
[1].normalize();
1552 toworld
[2].normalize();
1554 camera
.multLeft(toworld
);
1556 // Viewer position & up
1557 Pnt3f
vpos(camera
[3]);
1558 Vec3f
vup (camera
[1]);
1565 // some variables for faster access
1566 GeoVectorProperty
*pos
= part
->getPositions();
1569 typename
colTrait::dataType colData
;
1570 colTrait::init(part
, pEnv
, colData
);
1572 typename
texTrait::dataType texData
;
1573 texTrait::init(part
, pEnv
, texData
);
1575 typename
sizeTrait::dataType sizeData
;
1576 sizeTrait::init(part
, pEnv
, sizeData
);
1578 typename
posTrait::dataType posData
;
1579 posTrait::init(part
, pEnv
, posData
, part
->getPositions());
1583 for(UInt32 i
= 0; i
< length
; ++i
)
1585 if(colTrait::particle (colData
, i
))
1588 if(texTrait::particle (texData
, i
))
1591 if(sizeTrait::particle(sizeData
, i
))
1594 if(posTrait::particle(posData
, i
))
1597 Real32 s
= sizeTrait::size(sizeData
, i
)[0] / 2.f
;
1602 // calc viewer-relative coord system
1604 Pnt3f p
= pos
->getValue
<Pnt3f
>(i
);
1607 vnorm
= vup
.cross(vdir
);
1609 d
.setValues( -vnorm
[0] - vup
[0],
1613 colTrait::vertex(colData
, i
, 0);
1614 texTrait::vertex(texData
, 0, 0, 0);
1615 posTrait::vertex(posData
, 0, d
, s
);
1617 d
.setValues( vnorm
[0] - vup
[0],
1621 colTrait::vertex(colData
, i
, 1);
1622 texTrait::vertex(texData
, 1, 1, 0);
1623 posTrait::vertex(posData
, 1, d
, s
);
1625 d
.setValues( vnorm
[0] + vup
[0],
1629 colTrait::vertex(colData
, i
, 2);
1630 texTrait::vertex(texData
, 2, 1, 1);
1631 posTrait::vertex(posData
, 2, d
, s
);
1633 d
.setValues( -vnorm
[0] + vup
[0],
1637 colTrait::vertex(colData
, i
, 3);
1638 texTrait::vertex(texData
, 3, 0, 1);
1639 posTrait::vertex(posData
, 3, d
, s
);
1648 /*! Single color lines between secPos and pos
1649 \ingroup GrpDrawablesParticlesHelpers
1653 template <class posTrait
, class colTrait
, class texTrait
, class sizeTrait
>
1654 struct drawLines
: public ParticlesDrawer
1656 virtual void draw(Particles
*part
, DrawEnv
*pEnv
, UInt32 length
)
1658 // some variables for faster access
1661 typename
colTrait::dataType colData
;
1662 colTrait::init(part
, pEnv
, colData
);
1664 typename
texTrait::dataType texData
;
1665 texTrait::init(part
, pEnv
, texData
);
1667 typename
sizeTrait::dataType sizeData
;
1668 sizeTrait::init(part
, pEnv
, sizeData
);
1670 typename
posTrait::dataType posData
;
1671 posTrait::init(part
, pEnv
, posData
, part
->getPositions());
1673 typename
posTrait::dataType secPosData
;
1674 posTrait::init(part
, pEnv
, secPosData
, part
->getSecPositions());
1676 Real32 s
= sizeTrait::size(sizeData
, 0)[0];
1678 glPushAttrib(GL_LINE_BIT
);
1683 for(UInt32 i
= 0; i
< length
; ++i
)
1685 if(colTrait::particle (colData
, i
))
1688 if(texTrait::particle (texData
, i
))
1691 if(sizeTrait::particle(sizeData
, i
))
1694 if(posTrait::particle(posData
, i
))
1697 if(posTrait::particle(secPosData
, i
))
1700 posTrait::vertex(posData
);
1701 posTrait::vertex(secPosData
);
1709 virtual void drawIndexed(Particles
*part
, DrawEnv
*pEnv
,
1710 const Int32
*index
, UInt32 length
)
1712 // some variables for faster access
1713 GeoVectorProperty
*pos
= part
->getPositions();
1716 typename
colTrait::dataType colData
;
1717 colTrait::init(part
, pEnv
, colData
);
1719 typename
texTrait::dataType texData
;
1720 texTrait::init(part
, pEnv
, texData
);
1722 typename
sizeTrait::dataType sizeData
;
1723 sizeTrait::init(part
, pEnv
, sizeData
);
1725 typename
posTrait::dataType posData
;
1726 posTrait::init(part
, pEnv
, posData
, part
->getPositions());
1728 typename
posTrait::dataType secPosData
;
1729 posTrait::init(part
, pEnv
, secPosData
, part
->getSecPositions());
1731 Real32 s
= sizeTrait::size(sizeData
, 0)[0];
1733 glPushAttrib(GL_LINE_BIT
);
1740 for(UInt32 ii
= 0; ii
< length
; ++ii
)
1744 if(i
< 0 || i
> Int32(pos
->size32()))
1747 if(colTrait::particle (colData
, i
))
1750 if(texTrait::particle (texData
, i
))
1753 if(sizeTrait::particle(sizeData
, i
))
1756 if(posTrait::particle(posData
, i
))
1759 if(posTrait::particle(secPosData
, i
))
1762 posTrait::vertex(posData
);
1763 posTrait::vertex(secPosData
);
1773 \ingroup GrpDrawablesParticlesHelpers
1775 template <class posTrait
, class colTrait
, class texTrait
, class sizeTrait
>
1776 struct drawPoints
: public ParticlesDrawer
1778 virtual void draw(Particles
*part
, DrawEnv
*pEnv
, UInt32 length
)
1780 // some variables for faster access
1782 typename
posTrait::dataType posData
;
1783 posTrait::init(part
, pEnv
, posData
, part
->getPositions());
1785 typename
colTrait::dataType colData
;
1786 colTrait::init(part
, pEnv
, colData
);
1788 typename
sizeTrait::dataType sizeData
;
1789 sizeTrait::init(part
, pEnv
, sizeData
);
1791 typename
texTrait::dataType texData
;
1792 texTrait::init(part
, pEnv
, texData
);
1794 sizeTrait::particle(sizeData
, 0);
1795 Real32 s
= sizeTrait::size(sizeData
, 0)[0];
1797 glPushAttrib(GL_POINT_BIT
);
1802 for(UInt32 i
= 0; i
< length
; ++i
)
1804 if(colTrait::particle(colData
, i
))
1807 if(posTrait::particle(posData
, i
))
1810 if(texTrait::particle(texData
, i
))
1813 texTrait::vertex(texData
);
1814 posTrait::vertex(posData
);
1822 virtual void drawIndexed(Particles
*part
, DrawEnv
*pEnv
,
1823 const Int32
*index
, UInt32 length
)
1825 // some variables for faster access
1826 GeoVectorProperty
*pos
= part
->getPositions();
1829 typename
posTrait::dataType posData
;
1830 posTrait::init(part
, pEnv
, posData
, part
->getPositions());
1832 typename
colTrait::dataType colData
;
1833 colTrait::init(part
, pEnv
, colData
);
1835 typename
sizeTrait::dataType sizeData
;
1836 sizeTrait::init(part
, pEnv
, sizeData
);
1838 sizeTrait::particle(sizeData
, 0);
1839 Real32 s
= sizeTrait::size(sizeData
, 0)[0];
1841 glPushAttrib(GL_POINT_BIT
);
1848 for(UInt32 ii
= 0; ii
< length
; ++ii
)
1852 if(i
< 0 || i
> Int32(pos
->size()))
1855 if(colTrait::particle(colData
, i
))
1858 if(posTrait::particle(posData
, i
))
1861 posTrait::vertex(posData
);
1870 /*! Geometry traits for drawing objects
1871 \ingroup GrpDrawablesParticlesHelpers
1873 struct GeoTraitArrow
: public ParticleTraits
1875 typedef UInt8 dataType
;
1877 static inline void init(Particles
*, DrawEnv
*, dataType
&)
1881 static inline void exit(Particles
*, DrawEnv
*, dataType
&)
1885 static inline bool particle(dataType
&, UInt32
)
1890 static inline void draw( dataType
&,
1901 glNormal3fv(static_cast<GLfloat
*>(dy
.getValues()));
1903 glBegin(GL_TRIANGLE_FAN
);
1905 glVertex3fv(static_cast<const GLfloat
*>(p
.getValues()));
1907 glVertex3f(p
[0] + dz
[0] * .5f
+ dx
[0] ,
1908 p
[1] + dz
[1] * .5f
+ dx
[1] ,
1909 p
[2] + dz
[2] * .5f
+ dx
[2] );
1911 glVertex3f(p
[0] + dz
[0] * .5f
+ dx
[0] * .5f
,
1912 p
[1] + dz
[1] * .5f
+ dx
[1] * .5f
,
1913 p
[2] + dz
[2] * .5f
+ dx
[2] * .5f
);
1915 glVertex3f(p
[0] + dz
[0] + dx
[0] * .5f
,
1916 p
[1] + dz
[1] + dx
[1] * .5f
,
1917 p
[2] + dz
[2] + dx
[2] * .5f
);
1919 glVertex3f(p
[0] + dz
[0] - dx
[0] * .5f
,
1920 p
[1] + dz
[1] - dx
[1] * .5f
,
1921 p
[2] + dz
[2] - dx
[2] * .5f
);
1923 glVertex3f(p
[0] + dz
[0] * .5f
- dx
[0] * .5f
,
1924 p
[1] + dz
[1] * .5f
- dx
[1] * .5f
,
1925 p
[2] + dz
[2] * .5f
- dx
[2] * .5f
);
1927 glVertex3f(p
[0] + dz
[0] * .5f
- dx
[0] ,
1928 p
[1] + dz
[1] * .5f
- dx
[1] ,
1929 p
[2] + dz
[2] * .5f
- dx
[2] );
1936 /*! Geometry traits for drawing rectangles
1937 \ingroup GrpDrawablesParticlesHelpers
1940 struct GeoTraitRectangle
: public ParticleTraits
1942 typedef UInt8 dataType
;
1944 static inline void init(Particles
*, DrawEnv
*, dataType
&)
1949 static inline void exit(Particles
*, DrawEnv
*, dataType
&)
1954 static inline bool particle(dataType
&, UInt32
)
1959 static inline void draw( dataType
&,
1969 glNormal3fv(static_cast<GLfloat
*>(dy
.getValues()));
1971 glVertex3f( p
[0] - dx
[0],
1975 glVertex3f( p
[0] + dx
[0],
1979 glVertex3f(sp
[0] + dx
[0],
1983 glVertex3f(sp
[0] - dx
[0],
1991 /*! Objects using the pos/secpos/normal coordinate system for rendering
1992 \ingroup GrpDrawablesParticlesHelpers
1994 template <class posTrait
, class colTrait
, class sizeTrait
, class normalTrait
,
1996 struct drawObjects
: public ParticlesDrawer
1998 virtual void draw(Particles
*part
, DrawEnv
*pEnv
, UInt32 length
)
2000 // some variables for faster access
2003 typename
geoTrait::dataType geoData
;
2004 geoTrait::init(part
, pEnv
, geoData
);
2006 typename
colTrait::dataType colData
;
2007 colTrait::init(part
, pEnv
, colData
);
2009 typename
sizeTrait::dataType sizeData
;
2010 sizeTrait::init(part
, pEnv
, sizeData
);
2012 typename
normalTrait::dataType normalData
;
2013 normalTrait::init(part
, pEnv
, normalData
);
2015 typename
posTrait::dataType posData
, secPosData
;
2016 posTrait::init(part
, pEnv
, posData
, part
->getPositions());
2017 posTrait::init(part
, pEnv
, secPosData
, part
->getSecPositions());
2019 for(UInt32 i
= 0; i
< length
; ++i
)
2021 if(geoTrait::particle (geoData
, i
))
2024 if(colTrait::particle (colData
, i
))
2027 if(sizeTrait::particle(sizeData
, i
))
2030 if(normalTrait::particle(normalData
, i
))
2033 if(posTrait::particle (posData
, i
))
2036 if(posTrait::particle (secPosData
, i
))
2039 // calc the coordinate system
2041 Pnt3f
&p
= posTrait ::position(posData
);
2042 Pnt3f
&sp
= posTrait ::position(secPosData
);
2043 Vec3f
&n
= normalTrait::normal (normalData
);
2048 Vec3f
dx(n
.cross(dz
));
2051 dx
=Vec3f(1,0,0).cross(dz
);
2054 dx
=Vec3f(0,1,0).cross(dz
);
2057 dx
=Vec3f(0,0,1).cross(dz
);
2061 dx
.setValues(0,0,0);
2067 Vec3f
dy(dx
.cross(dz
));
2069 // now draw the geometry;
2070 geoTrait::draw(geoData
, p
, sp
, dx
, dy
, dz
,
2071 sizeTrait::size(sizeData
, i
));
2074 geoTrait::exit(part
, pEnv
, geoData
);
2077 virtual void drawIndexed(Particles
*part
, DrawEnv
*pEnv
,
2078 const Int32
*index
, UInt32 length
)
2080 // some variables for faster access
2081 GeoVectorProperty
*pos
= part
->getPositions();
2084 typename
geoTrait::dataType geoData
;
2085 geoTrait::init(part
, pEnv
, geoData
);
2087 typename
colTrait::dataType colData
;
2088 colTrait::init(part
, pEnv
, colData
);
2090 typename
sizeTrait::dataType sizeData
;
2091 sizeTrait::init(part
, pEnv
, sizeData
);
2093 typename
normalTrait::dataType normalData
;
2094 normalTrait::init(part
, pEnv
, normalData
);
2096 typename
posTrait::dataType posData
, secPosData
;
2097 posTrait::init(part
, pEnv
, posData
, part
->getPositions());
2098 posTrait::init(part
, pEnv
, secPosData
, part
->getSecPositions());
2102 for(UInt32 ii
= 0; ii
< length
; ++ii
)
2106 if(i
< 0 || i
> Int32(pos
->size32()))
2109 if(geoTrait::particle (geoData
, i
))
2112 if(colTrait::particle (colData
, i
))
2115 if(sizeTrait::particle(sizeData
, i
))
2118 if(normalTrait::particle(normalData
, i
))
2121 if(posTrait::particle (posData
, i
))
2124 if(posTrait::particle (secPosData
, i
))
2127 // calc the coordinate system
2129 Pnt3f
&p
= posTrait ::position(posData
);
2130 Pnt3f
&sp
= posTrait ::position(secPosData
);
2131 Vec3f
&n
= normalTrait::normal (normalData
);
2136 Vec3f
dx(n
.cross(dz
));
2139 dx
=Vec3f(1,0,0).cross(dz
);
2142 dx
=Vec3f(0,1,0).cross(dz
);
2145 dx
=Vec3f(0,0,1).cross(dz
);
2149 dx
.setValues(0,0,0);
2155 Vec3f
dy(dx
.cross(dz
));
2157 // now draw the geometry;
2158 geoTrait::draw(geoData
, p
, sp
, dx
, dy
, dz
,
2159 sizeTrait::size(sizeData
, i
));
2162 geoTrait::exit(part
, pEnv
, geoData
);
2167 /*! Objects using the pos/secpos and viewer-directed coordinate system for
2169 \ingroup GrpDrawablesParticlesHelpers
2171 template <class posTrait
, class colTrait
, class sizeTrait
,
2173 struct drawViewerObjects
: public ParticlesDrawer
2175 virtual void draw(Particles
*part
, DrawEnv
*pEnv
, UInt32 length
)
2177 Matrix camera
= pEnv
->getCameraToWorld();
2178 Matrix toworld
= pEnv
->getObjectToWorld();
2180 // DrawActionBase *action = pEnv->getOldAction();
2181 // get ModelView matrix to define the direction vectors
2182 // Matrix camera,toworld;
2183 // action->getCamera()->getBeacon()->getToWorld(camera);
2184 // action->getActNode()->getToWorld(toworld);
2185 // normalize them, we don't want to neutralize scales in toworld
2186 toworld
[0].normalize();
2187 toworld
[1].normalize();
2188 toworld
[2].normalize();
2190 camera
.multLeft(toworld
);
2192 // Viewer position & up
2193 Pnt3f
vpos(camera
[3]);
2195 // some variables for faster access
2198 typename
geoTrait::dataType geoData
;
2199 geoTrait::init(part
, pEnv
, geoData
);
2201 typename
colTrait::dataType colData
;
2202 colTrait::init(part
, pEnv
, colData
);
2204 typename
sizeTrait::dataType sizeData
;
2205 sizeTrait::init(part
, pEnv
, sizeData
);
2207 typename
posTrait::dataType posData
, secPosData
;
2208 posTrait::init(part
, pEnv
, posData
, part
->getPositions());
2209 posTrait::init(part
, pEnv
, secPosData
, part
->getSecPositions());
2211 for(UInt32 i
= 0; i
< length
; ++i
)
2213 if(geoTrait::particle (geoData
, i
))
2216 if(colTrait::particle (colData
, i
))
2219 if(sizeTrait::particle(sizeData
, i
))
2222 if(posTrait::particle (posData
, i
))
2225 if(posTrait::particle (secPosData
, i
))
2228 // calc the coordinate system
2230 Pnt3f
&p
= posTrait::position(posData
);
2231 Pnt3f
&sp
= posTrait::position(secPosData
);
2237 Vec3f
dx(n
.cross(dz
));
2240 dx
=Vec3f(1,0,0).cross(dz
);
2243 dx
=Vec3f(0,1,0).cross(dz
);
2246 dx
=Vec3f(0,0,1).cross(dz
);
2250 dx
.setValues(0,0,0);
2256 Vec3f
dy(dx
.cross(dz
));
2258 // now draw the geometry;
2259 geoTrait::draw(geoData
, p
, sp
, dx
, dy
, dz
,
2260 sizeTrait::size(sizeData
, i
));
2263 geoTrait::exit(part
, pEnv
, geoData
);
2266 virtual void drawIndexed(Particles
*part
, DrawEnv
*pEnv
,
2267 const Int32
*index
, UInt32 length
)
2269 Matrix camera
= pEnv
->getCameraToWorld();
2270 Matrix toworld
= pEnv
->getObjectToWorld();
2272 // DrawActionBase *action = pEnv->getOldAction();
2273 // get ModelView matrix to define the direction vectors
2274 // Matrix camera,toworld;
2275 // action->getCamera()->getBeacon()->getToWorld(camera);
2276 // action->getActNode()->getToWorld(toworld);
2277 // normalize them, we don't want to neutralize scales in toworld
2278 toworld
[0].normalize();
2279 toworld
[1].normalize();
2280 toworld
[2].normalize();
2282 camera
.multLeft(toworld
);
2284 // Viewer position & up
2285 Pnt3f
vpos(camera
[3]);
2287 // some variables for faster access
2288 GeoVectorProperty
*pos
= part
->getPositions();
2291 typename
geoTrait::dataType geoData
;
2292 geoTrait::init(part
, pEnv
, geoData
);
2294 typename
colTrait::dataType colData
;
2295 colTrait::init(part
, pEnv
, colData
);
2297 typename
sizeTrait::dataType sizeData
;
2298 sizeTrait::init(part
, pEnv
, sizeData
);
2300 typename
posTrait::dataType posData
, secPosData
;
2301 posTrait::init(part
, pEnv
, posData
, part
->getPositions());
2302 posTrait::init(part
, pEnv
, secPosData
, part
->getSecPositions());
2306 for(UInt32 ii
= 0; ii
< length
; ++ii
)
2310 if(i
< 0 || i
> Int32(pos
->size32()))
2313 if(geoTrait::particle (geoData
, i
))
2316 if(colTrait::particle (colData
, i
))
2319 if(sizeTrait::particle(sizeData
, i
))
2322 if(posTrait::particle (posData
, i
))
2325 if(posTrait::particle (secPosData
, i
))
2328 // calc the coordinate system
2330 Pnt3f
&p
= posTrait ::position(posData
);
2331 Pnt3f
&sp
= posTrait ::position(secPosData
);
2337 Vec3f
dx(n
.cross(dz
));
2340 dx
=Vec3f(1,0,0).cross(dz
);
2343 dx
=Vec3f(0,1,0).cross(dz
);
2346 dx
=Vec3f(0,0,1).cross(dz
);
2350 dx
.setValues(0,0,0);
2356 Vec3f
dy(dx
.cross(dz
));
2358 // now draw the geometry;
2359 geoTrait::draw(geoData
, p
, sp
, dx
, dy
, dz
,
2360 sizeTrait::size(sizeData
, i
));
2363 geoTrait::exit(part
, pEnv
, geoData
);
2368 /*! Static coordinates quad, pass all parameters to shader
2369 \ingroup GrpDrawablesParticlesHelpers
2371 template <class posTrait
, class secPosTrait
, class colTrait
, class texTrait
,
2372 class sizeTrait
, class normalTrait
>
2373 struct drawShaderQuads
: public ParticlesDrawer
2375 virtual void drawIndexed(Particles
*part
, DrawEnv
*pEnv
,
2376 const Int32
*index
, UInt32 length
)
2378 Window
*win
= pEnv
->getWindow();
2380 osgSinkUnusedWarning(win
);
2382 OSGGETGLFUNCBYID_GL3( glMultiTexCoord3fv
,
2383 osgGlMultiTexCoord3fv
,
2384 _funcglMultiTexCoord3fvARB
,
2388 typename
colTrait::dataType colData
;
2389 colTrait::init(part
, pEnv
, colData
);
2391 typename
texTrait::dataType texData
;
2392 texTrait::init(part
, pEnv
, texData
);
2394 typename
sizeTrait::dataType sizeData
;
2395 sizeTrait::init(part
, pEnv
, sizeData
);
2397 typename
normalTrait::dataType normalData
;
2398 normalTrait::init(part
, pEnv
, normalData
);
2400 typename
posTrait::dataType posData
;
2401 posTrait::init(part
, pEnv
, posData
, part
->getPositions());
2403 typename
secPosTrait::dataType secPosData
;
2404 secPosTrait::init(part
, pEnv
, secPosData
, part
->getSecPositions());
2406 GeoVectorProperty
*pos
= part
->getPositions();
2412 for(UInt32 ii
= 0; ii
< length
; ++ii
)
2416 if(i
< 0 || i
> Int32(pos
->size32()))
2419 if(colTrait::particle (colData
, i
))
2422 if(texTrait::particle(texData
, i
))
2425 if(sizeTrait::particle(sizeData
, i
))
2428 if(normalTrait::particle(normalData
, i
))
2431 if(posTrait::particle(posData
, i
))
2434 if(secPosTrait::particle(secPosData
, i
))
2438 Vec3f s
= sizeTrait::size(sizeData
, i
);
2443 normalTrait::normal(normalData
, 0);
2445 osgGlMultiTexCoord3fv(GL_TEXTURE1_ARB
,
2446 posTrait::position(posData
).getValues());
2448 osgGlMultiTexCoord3fv(
2450 secPosTrait::position(secPosData
).getValues());
2452 osgGlMultiTexCoord3fv(GL_TEXTURE3_ARB
,
2455 texTrait::vertex(texData
, 0, 0, 0);
2456 glVertex2f (-.5f
, -.5f
);
2457 texTrait::vertex(texData
, 0, 1, 0);
2458 glVertex2f ( .5f
, -.5f
);
2459 texTrait::vertex(texData
, 0, 1, 1);
2460 glVertex2f ( .5f
, .5f
);
2461 texTrait::vertex(texData
, 0, 0, 1);
2462 glVertex2f (-.5f
, .5f
);
2468 virtual void draw(Particles
*part
, DrawEnv
*pEnv
, UInt32 length
)
2470 Window
*win
= pEnv
->getWindow();
2472 osgSinkUnusedWarning(win
);
2474 OSGGETGLFUNCBYID_GL3( glMultiTexCoord3fv
,
2475 osgGlMultiTexCoord3fv
,
2476 _funcglMultiTexCoord3fvARB
,
2480 typename
colTrait::dataType colData
;
2481 colTrait::init(part
, pEnv
, colData
);
2483 typename
texTrait::dataType texData
;
2484 texTrait::init(part
, pEnv
, texData
);
2486 typename
sizeTrait::dataType sizeData
;
2487 sizeTrait::init(part
, pEnv
, sizeData
);
2489 typename
normalTrait::dataType normalData
;
2490 normalTrait::init(part
, pEnv
, normalData
);
2492 typename
posTrait::dataType posData
;
2493 posTrait::init(part
, pEnv
, posData
, part
->getPositions());
2495 typename
secPosTrait::dataType secPosData
;
2496 secPosTrait::init(part
, pEnv
, secPosData
, part
->getSecPositions());
2500 for(UInt32 i
= 0; i
< length
; ++i
)
2502 if(colTrait::particle (colData
, i
))
2505 if(texTrait::particle(texData
, i
))
2508 if(sizeTrait::particle(sizeData
, i
))
2511 if(normalTrait::particle(normalData
, i
))
2514 if(posTrait::particle(posData
, i
))
2517 if(secPosTrait::particle(secPosData
, i
))
2521 Vec3f s
= sizeTrait::size(sizeData
, i
);
2526 normalTrait::normal(normalData
, 0);
2528 osgGlMultiTexCoord3fv(GL_TEXTURE1_ARB
,
2529 posTrait::position(posData
).getValues());
2531 osgGlMultiTexCoord3fv(
2533 secPosTrait::position(secPosData
).getValues());
2535 osgGlMultiTexCoord3fv(GL_TEXTURE3_ARB
,
2538 texTrait::vertex(texData
, 0, 0, 0);
2539 glVertex2f (-.5f
, -.5f
);
2540 texTrait::vertex(texData
, 0, 1, 0);
2541 glVertex2f ( .5f
, -.5f
);
2542 texTrait::vertex(texData
, 0, 1, 1);
2543 glVertex2f ( .5f
, .5f
);
2544 texTrait::vertex(texData
, 0, 0, 1);
2545 glVertex2f (-.5f
, .5f
);
2553 /*! Static coordinates strips with y coordinates between -.5 and .5, split
2554 into size[2] parts, pass all parameters to shader
2555 \ingroup GrpDrawablesParticlesHelpers
2557 template <class posTrait
, class secPosTrait
, class colTrait
, class texTrait
,
2558 class sizeTrait
, class normalTrait
>
2559 struct drawShaderStrips
: public ParticlesDrawer
2561 virtual void drawIndexed(Particles
*part
, DrawEnv
*pEnv
,
2562 const Int32
*index
, UInt32 length
)
2564 Window
*win
= pEnv
->getWindow();
2566 osgSinkUnusedWarning(win
);
2568 OSGGETGLFUNCBYID_GL3( glMultiTexCoord3fv
,
2569 osgGlMultiTexCoord3fv
,
2570 _funcglMultiTexCoord3fvARB
,
2574 typename
colTrait::dataType colData
;
2575 colTrait::init(part
, pEnv
, colData
);
2577 typename
texTrait::dataType texData
;
2578 texTrait::init(part
, pEnv
, texData
);
2580 typename
sizeTrait::dataType sizeData
;
2581 sizeTrait::init(part
, pEnv
, sizeData
);
2583 typename
normalTrait::dataType normalData
;
2584 normalTrait::init(part
, pEnv
, normalData
);
2586 typename
posTrait::dataType posData
;
2587 posTrait::init(part
, pEnv
, posData
, part
->getPositions());
2589 typename
secPosTrait::dataType secPosData
;
2590 secPosTrait::init(part
, pEnv
, secPosData
, part
->getSecPositions());
2592 GeoVectorProperty
*pos
= part
->getPositions();
2596 for(UInt32 ii
= 0; ii
< length
; ++ii
)
2600 if(i
< 0 || i
> Int32(pos
->size()))
2603 if(colTrait::particle (colData
, i
))
2606 if(texTrait::particle(texData
, i
))
2609 if(sizeTrait::particle(sizeData
, i
))
2612 if(normalTrait::particle(normalData
, i
))
2615 if(posTrait::particle(posData
, i
))
2618 if(secPosTrait::particle(secPosData
, i
))
2622 Vec3f s
= sizeTrait::size(sizeData
, i
);
2627 normalTrait::normal(normalData
, 0);
2629 osgGlMultiTexCoord3fv(GL_TEXTURE1_ARB
,
2630 posTrait::position(posData
).getValues());
2632 osgGlMultiTexCoord3fv(
2634 secPosTrait::position(secPosData
).getValues());
2636 osgGlMultiTexCoord3fv(GL_TEXTURE3_ARB
,
2639 glBegin(GL_QUAD_STRIP
);
2641 UInt32 n
= static_cast<UInt32
>(s
[2]);
2642 Real32 step
= 1.f
/ (n
-1);
2644 for(UInt32 y
= 0; y
< n
; ++y
, v
+= step
)
2646 texTrait::vertex(texData
, 0, 0, v
);
2647 glVertex2f (-.5f
, v
-.5f
);
2648 texTrait::vertex(texData
, 0, 1, v
);
2649 glVertex2f ( .5f
, v
-.5f
);
2657 virtual void draw(Particles
*part
, DrawEnv
*pEnv
, UInt32 length
)
2659 Window
*win
= pEnv
->getWindow();
2661 osgSinkUnusedWarning(win
);
2663 OSGGETGLFUNCBYID_GL3( glMultiTexCoord3fv
,
2664 osgGlMultiTexCoord3fv
,
2665 _funcglMultiTexCoord3fvARB
,
2669 typename
colTrait::dataType colData
;
2670 colTrait::init(part
, pEnv
, colData
);
2672 typename
texTrait::dataType texData
;
2673 texTrait::init(part
, pEnv
, texData
);
2675 typename
sizeTrait::dataType sizeData
;
2676 sizeTrait::init(part
, pEnv
, sizeData
);
2678 typename
normalTrait::dataType normalData
;
2679 normalTrait::init(part
, pEnv
, normalData
);
2681 typename
posTrait::dataType posData
;
2682 posTrait::init(part
, pEnv
, posData
, part
->getPositions());
2684 typename
secPosTrait::dataType secPosData
;
2685 secPosTrait::init(part
, pEnv
, secPosData
, part
->getSecPositions());
2687 for(UInt32 i
= 0; i
< length
; ++i
)
2689 if(colTrait::particle (colData
, i
))
2692 if(texTrait::particle(texData
, i
))
2695 if(sizeTrait::particle(sizeData
, i
))
2698 if(normalTrait::particle(normalData
, i
))
2701 if(posTrait::particle(posData
, i
))
2704 if(secPosTrait::particle(secPosData
, i
))
2708 Vec3f s
= sizeTrait::size(sizeData
, i
);
2713 normalTrait::normal(normalData
, 0);
2715 osgGlMultiTexCoord3fv(GL_TEXTURE1_ARB
,
2716 posTrait::position(posData
).getValues());
2718 osgGlMultiTexCoord3fv(
2720 secPosTrait::position(secPosData
).getValues());
2722 osgGlMultiTexCoord3fv(GL_TEXTURE3_ARB
,
2725 glBegin(GL_QUAD_STRIP
);
2727 UInt32 n
= static_cast<UInt32
>(s
[2]);
2728 Real32 step
= 1.f
/ (n
-1);
2730 for(UInt32 y
= 0; y
< n
; ++y
, v
+= step
)
2732 texTrait::vertex(texData
, 0, 0, v
);
2733 glVertex2f (-.5f
, v
-.5f
);
2734 texTrait::vertex(texData
, 0, 1, v
);
2735 glVertex2f ( .5f
, v
-.5f
);
2746 /* Sorting functions */
2748 /*! \ingroup GrpDrawablesParticlesHelpers
2754 sorter() : _value(0.f
), _index(0) {}
2756 sorter(Real32 value
, Int32 index
) :
2762 bool operator<(const sorter
&a
) const
2764 if(_value
< a
._value
)
2770 bool operator<=(const sorter
&a
) const
2772 if(_value
<= a
._value
)
2778 bool operator>(const sorter
&a
) const
2780 return ! (a
< *this);
2783 bool operator>=(const sorter
&a
) const
2785 return ! (a
<= *this);
2792 Int32
*Particles::calcIndex(DrawEnv
*pEnv
,
2796 // some variables for faster access
2797 GeoVectorProperty
*pos
= getPositions();
2798 const MFInt32
*indices
= getMFIndices();
2800 // get ModelView matrix to define the direction vectors
2801 // Matrix camera,toworld;
2803 Matrix camera
= pEnv
->getCameraToWorld();
2804 Matrix toworld
= pEnv
->getObjectToWorld();
2807 RenderAction *ra = dynamic_cast<RenderAction *>(pEnv->getOldAction());
2811 toworld = ra->top_matrix();
2816 camera
.multLeft(toworld
);
2818 Pnt3f
refpoint(camera
[3].getValues());
2820 if(getMode() == ViewDirQuads
)
2826 if(indices
->size() > 0)
2828 if(getNumParticles() == -1)
2830 size
= indices
->size32();
2834 size
= getNumParticles();
2839 if(getNumParticles() == -1)
2841 size
= pos
->size32();
2845 size
= getNumParticles();
2849 std::vector
<sorter
> sorterList(size
);
2854 if(getMode() == ViewDirQuads
)
2856 if(indices
->size() > 0)
2858 for(i
= 0; i
< size
; i
++)
2860 if((*(indices
))[i
] < 0 ||
2861 (*(indices
))[i
] > Int32(pos
->size()))
2864 sorterList
[len
]._index
= (*(indices
))[i
];
2868 sorterList
[len
]._value
= p
[2];
2875 for(i
= 0; i
< size
; i
++)
2877 sorterList
[len
]._index
= i
;
2881 sorterList
[len
]._value
= p
[2];
2889 if(indices
->size() > 0)
2891 for(i
= 0; i
< size
; i
++)
2893 if((*(indices
))[i
] < 0 ||
2894 (*(indices
))[i
] > Int32(pos
->size()))
2897 sorterList
[len
]._index
= (*(indices
))[i
];
2900 sorterList
[len
]._value
= - refpoint
.dist2(p
);
2907 for(i
= 0; i
< size
; i
++)
2909 sorterList
[len
]._index
= i
;
2912 sorterList
[len
]._value
= - refpoint
.dist2(p
);
2919 std::sort(sorterList
.begin(), sorterList
.begin() + len
);
2922 index
=new Int32
[len
];
2924 if(getDrawOrder() == FrontToBack
)
2926 for(i
= 0; i
<len
; i
++)
2928 index
[i
] = sorterList
[len
- 1 - i
]._index
;
2933 for(i
= 0; i
<len
; i
++)
2935 index
[i
] = sorterList
[i
]._index
;
2943 /*! Low-level Draw method that pumps OpenGL commands.
2945 void Particles::drawPrimitives(DrawEnv
*pEnv
)
2947 // some variables for faster access
2948 GeoVectorProperty
*pos
= getPositions();
2949 GeoVectorProperty
*col
= getColors();
2950 GeoVectorProperty
*norm
= getNormals();
2951 const MFVec3f
*size
= getMFSizes();
2953 if((size
->size() > 1 && size
->size() != pos
->size()) ||
2954 (col
!= NULL
&& col
->size() != 1 &&
2955 col
->size() != pos
->size()) ||
2956 (norm
!= NULL
&& norm
->size() != 1 &&
2957 norm
->size() != pos
->size())
2960 FWARNING(("Particles::draw: inconsistent attributes "
2961 "(p:%" PRISize
" s:%" PRISize
" c:%d)!\n",
2962 pos
->size(), size
->size(),
2963 (col
!= NULL
)? int(col
->size()) : -1));
2967 ParticlesDrawer
*drawer
= findDrawer();
2971 FWARNING(("Particles 0x%p: couldn't find drawer!\n",
2972 static_cast<void *>(this)));
2976 const Int32
*index
= NULL
;
2978 bool freeIndex
= false;
2980 if(_sfDrawOrder
.getValue() != Particles::Any
)
2984 index
= calcIndex(pEnv
,length
);
2988 if(!getBsp().created())
2990 editBsp().build(this);
2993 // Matrix modelview,toworld;
2995 Matrix modelview
= pEnv
->getCameraToWorld();
2996 Matrix toworld
= pEnv
->getObjectToWorld();
2999 RenderAction *ra = dynamic_cast<RenderAction *>(
3000 pEnv->getOldAction());
3004 toworld = ra->top_matrix();
3008 pEnv->getOldAction()->getActNode()->getToWorld(toworld);
3011 // action->getCamera()->getBeacon()->getToWorld(modelview);
3012 // action->getActNode()->getToWorld(toworld);
3015 modelview
.mult(toworld
);
3017 Pnt3f
ref(modelview
[3][0],modelview
[3][1],
3019 Vec3f
refvec( modelview
[2][0],modelview
[2][1],
3022 index
= getBsp().traverse(ref
,length
);
3026 else if (getMFIndices()->size() > 0)
3028 index
= &(getMFIndices()->getValues()[0]);
3029 if(getNumParticles() == -1)
3031 length
= getMFIndices()->size32();
3035 length
= getNumParticles();
3042 drawer
->drawIndexed(this,pEnv
,index
,length
);
3046 if(getNumParticles() == -1)
3048 drawer
->draw(this,pEnv
,pos
->size32());
3050 else if(getNumParticles() > 0)
3052 drawer
->draw(this,pEnv
,getNumParticles());
3062 /*! find the drawer object for the actual configuration of parameters */
3064 ParticlesDrawer
*Particles::findDrawer(void)
3066 if(getPositions() == NULL
)
3070 enum { part
= 0, sing
, none
} size
,normal
,color
,tex
,secpos
;
3074 // find the parameters' use
3076 size
= (getMFSizes()->size() == getPositions()->size()) ? part
:
3077 (getMFSizes()->size() == 1 ) ? sing
:
3079 normal
= (getNormals() != NULL
&&
3080 getNormals()->size() == getPositions()->size()) ? part
:
3081 (getNormals() != NULL
&&
3082 getNormals()->size() == 1 ) ? sing
:
3084 secpos
= (getSecPositions() != NULL
&&
3085 getSecPositions()->size()== getPositions()->size()) ? part
:
3086 (getSecPositions() != NULL
&&
3087 getSecPositions()->size()== 1 ) ? sing
:
3089 color
= (getColors() != NULL
&&
3090 getColors()->size() == getPositions()->size()) ? part
:
3091 (getColors() != NULL
&&
3092 getColors()->size() == 1 ) ? sing
:
3094 tex
= (getMFTextureZs()->size() == getPositions()->size()) ? part
:
3095 (getMFTextureZs()->size() == 1 ) ? sing
:
3098 // check if the used types are common cases
3101 bool normalIs3f = (getNormals() != NULL &&
3102 getNormals()->getFormat() == GL_FLOAT);
3104 bool colorIs3f = (getColors() != NULL &&
3105 getColors()->getFormat() == GL_FLOAT &&
3106 getColors()->getDimension() == 3);
3109 bool posIs3f
= (getPositions() != NULL
&&
3110 getPositions()->getFormat() == GL_FLOAT
&&
3111 getPositions()->getDimension() == 3);
3113 // now find the drawer
3115 // main difference: mode, as only a subset of the attributes is used
3116 // in the different modes
3118 // this is where to add fast pathes...
3119 // don't go overboard, as every path adds code, and code bloat is
3120 // easily obtained here.
3126 static ParticlesDrawer
*fallback
=
3127 new drawPoints
<PosTraitGeneric
,ColTraitGeneric
,
3128 TexTraitGeneric
,SizeTraitGeneric
>;
3137 FWARNING(("Particles::findDrawer: Need secondary positions for "
3142 static ParticlesDrawer
*fallback
=
3143 new drawLines
<PosTraitGeneric
,ColTraitGeneric
,
3144 TexTraitGeneric
,SizeTraitGeneric
>;
3151 static ParticlesDrawer
*fallback
=
3152 new drawViewDirQuads
<PosTraitGeneric
,ColTraitGeneric
,
3153 TexTraitGeneric
,SizeTraitGeneric
>;
3155 if(posIs3f
&& tex
== none
&& size
!= none
)
3157 static ParticlesDrawer
*pumps
[] = {
3158 new drawViewDirQuads
<PosTrait3f
,ColTraitParticle
,
3159 TexTraitNone
,SizeTraitParticle
>,
3160 new drawViewDirQuads
<PosTrait3f
,ColTraitSingle
,
3161 TexTraitNone
,SizeTraitParticle
>,
3162 new drawViewDirQuads
<PosTrait3f
,ColTraitNone
,
3163 TexTraitNone
,SizeTraitParticle
>,
3165 new drawViewDirQuads
<PosTrait3f
,ColTraitParticle
,
3166 TexTraitNone
,SizeTraitSingle
>,
3167 new drawViewDirQuads
<PosTrait3f
,ColTraitSingle
,
3168 TexTraitNone
,SizeTraitSingle
>,
3169 new drawViewDirQuads
<PosTrait3f
,ColTraitNone
,
3170 TexTraitNone
,SizeTraitSingle
>,
3173 return pumps
[size
* 3 + color
];
3181 static ParticlesDrawer
*fallback
=
3182 new drawViewerQuads
<PosTraitGeneric
,ColTraitGeneric
,
3183 TexTraitGeneric
,SizeTraitGeneric
>;
3185 if(posIs3f
&& tex
== none
&& size
!= none
)
3187 static ParticlesDrawer
*pumps
[] = {
3188 new drawViewerQuads
<PosTrait3f
,ColTraitParticle
,
3189 TexTraitNone
,SizeTraitParticle
>,
3190 new drawViewerQuads
<PosTrait3f
,ColTraitSingle
,
3191 TexTraitNone
,SizeTraitParticle
>,
3192 new drawViewerQuads
<PosTrait3f
,ColTraitNone
,
3193 TexTraitNone
,SizeTraitParticle
>,
3195 new drawViewerQuads
<PosTrait3f
,ColTraitParticle
,
3196 TexTraitNone
,SizeTraitSingle
>,
3197 new drawViewerQuads
<PosTrait3f
,ColTraitSingle
,
3198 TexTraitNone
,SizeTraitSingle
>,
3199 new drawViewerQuads
<PosTrait3f
,ColTraitNone
,
3200 TexTraitNone
,SizeTraitSingle
>,
3203 return pumps
[size
* 3 + color
];
3213 FWARNING(("Particles::findDrawer: Need secondary positions for "
3220 FWARNING(("Particles::findDrawer: Need normals for "
3225 static ParticlesDrawer
*fallback
=
3226 new drawObjects
<PosTraitGeneric
,ColTraitGeneric
,
3227 SizeTraitGeneric
,NormalTraitGeneric
,
3237 FWARNING(("Particles::findDrawer: Need secondary positions for "
3238 "type ViewerArrows!\n"));
3244 FWARNING(("Particles::findDrawer: Need normals for "
3245 "type ViewerArrows!\n"));
3249 static ParticlesDrawer
*fallback
=
3250 new drawViewerObjects
<PosTraitGeneric
,ColTraitGeneric
,
3251 SizeTraitGeneric
,GeoTraitArrow
>;
3260 FWARNING(("Particles::findDrawer: Need secondary positions for "
3261 "type Rectangles!\n"));
3267 FWARNING(("Particles::findDrawer: Need normals for "
3268 "type Rectangles!\n"));
3272 static ParticlesDrawer
*fallback
=
3273 new drawObjects
<PosTraitGeneric
,ColTraitGeneric
,
3274 SizeTraitGeneric
,NormalTraitGeneric
,
3282 static ParticlesDrawer
*fallback
=
3283 new drawShaderQuads
<PosTraitGeneric
,PosTraitGeneric
,
3284 ColTraitGeneric
, TexTraitGeneric
,
3285 SizeTraitGeneric
,NormalTraitGeneric
>,
3287 new drawShaderQuads
<PosTraitGeneric
,PosTraitNone
,
3288 ColTraitGeneric
, TexTraitGeneric
,
3289 SizeTraitGeneric
,NormalTraitGeneric
>;
3293 return nosecfallback
;
3303 static ParticlesDrawer
*fallback
=
3304 new drawShaderStrips
<PosTraitGeneric
,PosTraitGeneric
,
3305 ColTraitGeneric
, TexTraitGeneric
,
3306 SizeTraitGeneric
,NormalTraitGeneric
>,
3308 new drawShaderStrips
<PosTraitGeneric
,PosTraitNone
,
3309 ColTraitGeneric
, TexTraitGeneric
,
3310 SizeTraitGeneric
,NormalTraitGeneric
>;
3314 return nosecfallback
;
3325 if (normal
) return NULL
; // make picky compilers happy