changed: gcc8 base update
[opensg.git] / Source / System / State / Base / OSGMultiLightChunk.cpp
blobfc38806b5c0b80d0e597b56ef4c3f5367eab5733
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2013 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, carsten_neumann@gmx.net *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
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. *
18 * *
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. *
23 * *
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. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
40 // Includes
41 //---------------------------------------------------------------------------
43 #include <cstdlib>
44 #include <cstdio>
46 #include <boost/bind.hpp>
48 #include "OSGConfig.h"
50 #include "OSGGL.h"
51 #include "OSGGLU.h"
52 #include "OSGGLEXT.h"
53 #include "OSGWindow.h"
55 #include "OSGMatrix.h"
56 #include "OSGMatrixUtility.h"
57 #include "OSGQuaternion.h"
59 #include "OSGGLFuncProtos.h"
60 #include "OSGBaseFunctions.h"
62 #include "OSGDrawEnv.h"
63 #include "OSGNode.h"
65 #include "OSGMultiLightChunk.h"
67 OSG_BEGIN_NAMESPACE
69 // Documentation for this class is emitted in the
70 // OSGMultiLightChunkBase.cpp file.
71 // To modify it, please change the .fcd file (OSGMultiLightChunk.fcd) and
72 // regenerate the base file.
74 /***************************************************************************\
75 * Class variables *
76 \***************************************************************************/
78 typedef OSG::Window Win;
80 /***************************************************************************\
81 * Class methods *
82 \***************************************************************************/
84 void MultiLightChunk::initMethod(InitPhase ePhase)
86 Inherited::initMethod(ePhase);
88 if(ePhase == TypeObject::SystemPost)
94 /***************************************************************************\
95 * Instance methods *
96 \***************************************************************************/
98 MultiLight::MultiLight(Type e)
99 : position(0.f,0.f,0.f)
100 , direction(0.f,0.f,1.f)
101 , color(1.f,1.f,1.f)
102 , intensity(1.f)
103 , ambientIntensity(1.f,1.f,1.f)
104 , diffuseIntensity(1.f,1.f,1.f)
105 , specularIntensity(1.f,1.f,1.f)
106 , attenuation(1.f, 0.0001f, 0.000001f)
107 , spotlightAngle(20.f)
108 , spotExponent(1.f)
109 , innerSuperEllipsesWidth(1.f)
110 , innerSuperEllipsesHeight(1.f)
111 , outerSuperEllipsesWidth(1.3f)
112 , outerSuperEllipsesHeight(1.3f)
113 , superEllipsesRoundness(1.f)
114 , superEllipsesTwist(0.f)
115 , rangeCutOn(0.f)
116 , rangeCutOff(1.f)
117 , rangeNearZone(0.f)
118 , rangeFarZone(0.f)
119 , type(e)
120 , enabled(true)
121 , beacon(NULL)
125 /*-------------------------------------------------------------------------*\
126 - private -
127 \*-------------------------------------------------------------------------*/
129 /*----------------------- constructors & destructors ----------------------*/
131 MultiLightChunk::MultiLightChunk(void) :
132 Inherited(),
133 _bUpdateBuffer(false),
134 _cameraCB()
138 MultiLightChunk::MultiLightChunk(const MultiLightChunk &source) :
139 Inherited(source),
140 _bUpdateBuffer(false),
141 _cameraCB()
145 MultiLightChunk::~MultiLightChunk(void)
147 clearLights();
150 /*----------------------------- class specific ----------------------------*/
152 void MultiLightChunk::changed(ConstFieldMaskArg whichField,
153 UInt32 origin,
154 BitVector details)
157 // The BeaconMatrixFieldMask is deliberately omitted
159 if((whichField & ( HasWorldToLightSpaceMatrixFieldMask |
160 HasLightToWorldSpaceMatrixFieldMask |
161 HasEyeToLightSpaceMatrixFieldMask |
162 HasLightToEyeSpaceMatrixFieldMask |
163 HasLightPerspectiveMatrixFieldMask |
164 HasInvLightPerspectiveMatrixFieldMask |
165 HasColorFieldMask |
166 HasIntensityFieldMask |
167 HasSeparateIntensitiesFieldMask |
168 HasAttenuationFieldMask |
169 HasRangeCutOnFieldMask |
170 HasRangeCutOffFieldMask |
171 HasRangeNearZoneFieldMask |
172 HasRangeFarZoneFieldMask |
173 HasCosSpotlightAngleFieldMask |
174 HasSpotlightAngleFieldMask |
175 HasSpotExponentFieldMask |
176 HasCinemaLightFieldMask |
177 AutoCalcRangesFieldMask |
178 PositionFieldMask |
179 DirectionFieldMask |
180 ColorFieldMask |
181 IntensityFieldMask |
182 AmbientIntensityFieldMask |
183 DiffuseIntensityFieldMask |
184 SpecularIntensityFieldMask |
185 AttenuationFieldMask |
186 RangeCutOnFieldMask |
187 RangeCutOffFieldMask |
188 RangeNearZoneFieldMask |
189 RangeFarZoneFieldMask |
190 SpotlightAngleFieldMask |
191 SpotExponentFieldMask |
192 InnerSuperEllipsesWidthFieldMask |
193 InnerSuperEllipsesHeightFieldMask |
194 OuterSuperEllipsesWidthFieldMask |
195 OuterSuperEllipsesHeightFieldMask |
196 SuperEllipsesRoundnessFieldMask |
197 SuperEllipsesTwistFieldMask |
198 TypeFieldMask |
199 EnabledFieldMask |
200 BeaconFieldMask |
201 EyeSpaceFieldMask )) != 0)
203 _bUpdateBuffer = true;
206 Inherited::changed(whichField, origin, details);
209 /*----------------------------- onCreate --------------------------------*/
211 void MultiLightChunk::onCreate(const MultiLightChunk *source)
213 Inherited::onCreate(source);
215 if(GlobalSystemState == Startup)
216 return;
219 void MultiLightChunk::onCreateAspect(
220 const MultiLightChunk *createAspect,
221 const MultiLightChunk *source )
223 Inherited::onCreateAspect(createAspect, source);
226 void MultiLightChunk::onDestroy(UInt32 uiContainerId)
228 Inherited::onDestroy(uiContainerId);
231 /*------------------------------ Output -------------------------------------*/
233 void MultiLightChunk::dump( UInt32 ,
234 const BitVector ) const
236 SLOG << "Dump MultiLightChunk NI" << std::endl;
239 /*------------------------------ buffer -------------------------------------*/
241 void MultiLightChunk::transformToWorldSpace(
242 DrawEnv* pEnv,
243 Node* beacon,
244 const Pnt3f& position_bs,
245 const Vec3f& direction_bs,
246 Pnt3f& position_ws,
247 Vec3f& direction_ws) const
249 Matrix matWsFromBS;
250 matWsFromBS.identity();
252 if(beacon != NULL)
254 beacon->getToWorld(matWsFromBS);
256 else
258 matWsFromBS.setIdentity();
261 matWsFromBS.multFull( position_bs, position_ws);
262 matWsFromBS.multFull(direction_bs, direction_ws);
265 void MultiLightChunk::transformToEyeSpace(
266 DrawEnv* pEnv,
267 Node* beacon,
268 const Pnt3f& position_bs,
269 const Vec3f& direction_bs,
270 Pnt3f& position_es,
271 Vec3f& direction_es) const
273 Matrix matWsFromBS;
275 if(beacon != NULL)
277 beacon->getToWorld(matWsFromBS);
279 else
281 matWsFromBS.setIdentity();
284 Matrix mat = pEnv->getCameraViewing(); // matEsFromWs
285 mat.mult(matWsFromBS); // matEsFromBs
287 mat.multFull( position_bs, position_es);
288 mat.multFull(direction_bs, direction_es);
291 void MultiLightChunk::calcDirectionalLightMatrices(
292 DrawEnv* pEnv,
293 Node* beacon,
294 const Vec3f& direction_bs,
295 Matrix& matLSFromWS,
296 Matrix& matLSFromES) const
298 if(beacon)
299 beacon->getToWorld(matLSFromWS); // matWsFromBS;
301 Matrix matLightDir;
302 Quaternion rotLightDir(Vec3f(0.f, 0.f, 1.f), direction_bs);
303 matLightDir.setRotate(rotLightDir);
305 matLSFromWS.mult (matLightDir);
306 matLSFromWS.invert ( ); // WS -> LS
308 Matrix matWsFromEs = pEnv->getCameraToWorld();
309 matLSFromES = matLSFromWS;
310 matLSFromES.mult(matWsFromEs);
313 void MultiLightChunk::calcPointLightMatrices(
314 DrawEnv* pEnv,
315 Node* beacon,
316 const Pnt3f& position_bs,
317 Matrix& matLSFromWS,
318 Matrix& matLSFromES) const
320 if(beacon)
321 beacon->getToWorld(matLSFromWS); // matWsFromBS;
323 Matrix matLightPos;
324 matLightPos.setTranslate(position_bs);
326 matLSFromWS.mult (matLightPos);
327 matLSFromWS.invert ( ); // WS -> LS
329 Matrix matWsFromEs = pEnv->getCameraToWorld();
330 matLSFromES = matLSFromWS;
331 matLSFromES.mult(matWsFromEs);
334 void MultiLightChunk::calcSpotLightMatrices(
335 DrawEnv* pEnv,
336 Node* beacon,
337 const Pnt3f& position_bs,
338 const Vec3f& direction_bs,
339 Matrix& matLSFromWS,
340 Matrix& matLSFromES) const
342 if(beacon)
343 beacon->getToWorld(matLSFromWS); // matWsFromBS;
345 Matrix matLightPos;
346 matLightPos.setTranslate(position_bs);
348 Matrix matLightDir;
349 Quaternion rotLightDir(Vec3f(0.f, 0.f, 1.f), -direction_bs);
350 matLightDir.setRotate(rotLightDir);
352 matLSFromWS.mult (matLightPos);
353 matLSFromWS.mult (matLightDir);
354 matLSFromWS.invert ( ); // WS -> LS
356 Matrix matWsFromEs = pEnv->getCameraToWorld();
357 matLSFromES = matLSFromWS;
358 matLSFromES.mult(matWsFromEs);
361 void MultiLightChunk::calcPointLightRange(
362 DrawEnv* pEnv,
363 const Vec3f attenuation,
364 Real32 threshold,
365 Real32& outNear,
366 Real32& outFar) const
368 Real32 defaultNear = pEnv->getCameraNear();
369 Real32 defaultFar = pEnv->getCameraFar();
371 outNear = defaultNear;
372 outFar = defaultFar;
374 Real32 q = attenuation[2];
375 Real32 l = attenuation[1];
376 Real32 c = attenuation[0];
378 if (osgAbs(q) > TypeTraits<Real32>::getDefaultEps())
380 Real32 D = l*l - 4.f * q * (c - 1.f/threshold);
382 if (D >= 0)
384 D = osgSqrt(D);
386 Real32 r1 = - l + D / (2.f * q);
387 Real32 r2 = - l - D / (2.f * q);
389 if (r1 > 0.f && r2 > 0.f)
391 outFar = osgMin(r1, r2);
393 else if (r1 > 0.f)
395 outFar = r1;
397 else if (r2 > 0.f)
399 outFar = r2;
403 else if(osgAbs(l) > TypeTraits<Real32>::getDefaultEps())
405 Real32 r = (1.f/threshold - c)/l;
407 if (r > 0.f)
409 outFar = r;
414 std::size_t MultiLightChunk::calcLightBufferSize() const
416 std::size_t ao = 0; // aligned offset
417 std::size_t bo = 0; // base offset
419 OSG_ASSERT(check_invariant());
421 //struct Light
423 // mat4 worldToLightSpaceMatrix;
424 // mat4 lightToWorldSpaceMatrix;
425 // mat4 eyeToLightSpaceMatrix;
426 // mat4 lightToEyeSpaceMatrix;
427 // mat4 lightPerspectiveMatrix
428 // mat4 InvLightPerspectiveMatrix;
429 // vec3 position;
430 // vec3 direction;
431 // vec3 color;
432 // vec3 ambientIntensity;
433 // vec3 diffuseIntensity;
434 // vec3 specularIntensity;
435 // float intensity;
436 // float constantAttenuation;
437 // float linearAttenuation;
438 // float quadraticAttenuation;
439 // float rangeCutOn;
440 // float rangeCutOff;
441 // float rangeNearZone;
442 // float rangeFarZone;
443 // float cosSpotlightAngle;
444 // float spotlightAngle;
445 // float spotExponent;
446 // float innerSuperEllipsesWidth;
447 // float innerSuperEllipsesHeight;
448 // float outerSuperEllipsesWidth;
449 // float outerSuperEllipsesHeight;
450 // float superEllipsesRoundness;
451 // float superEllipsesTwist;
452 // int type;
453 // bool enabled;
454 //};
456 if (getHasWorldToLightSpaceMatrix())
458 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f); // Matrix worldToLightSpaceMatrix
459 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f);
460 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f);
461 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f);
462 ao = alignOffset(16, bo); bo = ao;
465 if (getHasLightToWorldSpaceMatrix())
467 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f); // Matrix lightToWorldSpaceMatrix
468 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f);
469 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f);
470 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f);
471 ao = alignOffset(16, bo); bo = ao;
474 if (getHasEyeToLightSpaceMatrix())
476 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f); // Matrix eyeToLightSpaceMatrix
477 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f);
478 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f);
479 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f);
480 ao = alignOffset(16, bo); bo = ao;
483 if (getHasLightToEyeSpaceMatrix())
485 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f); // Matrix lightToEyeSpaceMatrix
486 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f);
487 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f);
488 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f);
489 ao = alignOffset(16, bo); bo = ao;
492 if (getHasLightPerspectiveMatrix())
494 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f); // Matrix lightPerspectiveMatrix
495 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f);
496 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f);
497 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f);
498 ao = alignOffset(16, bo); bo = ao;
501 if (getHasInvLightPerspectiveMatrix())
503 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f); // Matrix invLightPerspectiveMatrix
504 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f);
505 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f);
506 ao = alignOffset(16, bo); bo = ao + sizeof(OSG::Vec4f);
507 ao = alignOffset(16, bo); bo = ao;
510 ao = alignOffset(16, bo); bo = ao + sizeof(Pnt3f); // Pnt3f position
511 ao = alignOffset(16, bo); bo = ao + sizeof(Vec3f); // Vec3f direction
513 if (getHasColor())
515 ao = alignOffset(16, bo); bo = ao + sizeof(Color3f); // Color3f color
518 if (getHasSeparateIntensities())
520 ao = alignOffset(16, bo); bo = ao + sizeof(Vec3f); // Vec3f ambientIntensity
521 ao = alignOffset(16, bo); bo = ao + sizeof(Vec3f); // Vec3f diffuseIntensity
522 ao = alignOffset(16, bo); bo = ao + sizeof(Vec3f); // Vec3f specularIntensity
525 if (getHasIntensity())
527 ao = alignOffset( 4, bo); bo = ao + sizeof(Real32); // Real32 intensity
530 if (getHasAttenuation())
532 ao = alignOffset( 4, bo); bo = ao + sizeof(Real32); // Real32 constantAttenuation
533 ao = alignOffset( 4, bo); bo = ao + sizeof(Real32); // Real32 linearAttenuation
534 ao = alignOffset( 4, bo); bo = ao + sizeof(Real32); // Real32 quadraticAttenuation
537 if (getHasRangeCutOn())
539 ao = alignOffset( 4, bo); bo = ao + sizeof(Real32); // Real32 rangeCutOn
542 if (getHasRangeCutOff())
544 ao = alignOffset( 4, bo); bo = ao + sizeof(Real32); // Real32 rangeCutOff
547 if (getHasRangeNearZone())
549 ao = alignOffset( 4, bo); bo = ao + sizeof(Real32); // Real32 rangeNearZone
552 if (getHasRangeFarZone())
554 ao = alignOffset( 4, bo); bo = ao + sizeof(Real32); // Real32 rangeFarZone
557 if (getHasCosSpotlightAngle() || (!getHasCosSpotlightAngle() && !getHasSpotlightAngle()))
559 ao = alignOffset( 4, bo); bo = ao + sizeof(Real32); // Real32 cosSpotlightAngle
562 if (getHasSpotlightAngle())
564 ao = alignOffset( 4, bo); bo = ao + sizeof(Real32); // Real32 spotlightAngle
567 if (getHasSpotExponent())
569 ao = alignOffset( 4, bo); bo = ao + sizeof(Real32); // Real32 spotExponent
572 if (getHasCinemaLight())
574 ao = alignOffset( 4, bo); bo = ao + sizeof(Real32); // Real32 innerSuperEllipsesWidth
575 ao = alignOffset( 4, bo); bo = ao + sizeof(Real32); // Real32 innerSuperEllipsesHeight
576 ao = alignOffset( 4, bo); bo = ao + sizeof(Real32); // Real32 outerSuperEllipsesWidth
577 ao = alignOffset( 4, bo); bo = ao + sizeof(Real32); // Real32 outerSuperEllipsesHeight
578 ao = alignOffset( 4, bo); bo = ao + sizeof(Real32); // Real32 superEllipsesRoundness
579 ao = alignOffset( 4, bo); bo = ao + sizeof(Real32); // Real32 superEllipsesTwist
582 ao = alignOffset( 4, bo); bo = ao + sizeof(Int32); // UInt8 type
583 ao = alignOffset( 4, bo); bo = ao + sizeof(Int32); // bool enabled
585 ao = alignOffset(16, bo); bo = ao; // padding
587 ao *= numLights(); bo = ao; // array
588 ao = alignOffset(16, bo); bo = ao; // padding
590 return ao;
593 std::vector<UInt8> MultiLightChunk::createLightBuffer(DrawEnv* pEnv) const
595 std::size_t size = calcLightBufferSize();
597 std::vector<UInt8> buffer(size);
599 UInt32 num_lights = numLights();
601 std::size_t ao = 0; // aligned offset
602 std::size_t bo = 0; // base offset
604 for (UInt32 idx = 0; idx < num_lights; ++idx)
606 Pnt3f position;
607 Vec3f direction;
609 Real32 cosSpotlightAngle = 1.f;
610 Real32 spotlightAngle = 0.f;
612 switch (getType(idx))
614 case MultiLight::POINT_LIGHT:
615 break;
616 case MultiLight::DIRECTIONAL_LIGHT:
617 break;
618 case MultiLight::SPOT_LIGHT:
619 cosSpotlightAngle = osgCos(osgDegree2Rad(getSpotlightAngle(idx)));
620 spotlightAngle = osgDegree2Rad(getSpotlightAngle(idx));
621 break;
622 case MultiLight::CINEMA_LIGHT:
623 break;
626 Real32 cutOnRange = getHasRangeCutOn () ? getRangeCutOn (idx) : pEnv->getCameraNear();
627 Real32 cutOffRange = getHasRangeCutOff() ? getRangeCutOff(idx) : pEnv->getCameraFar();
629 if (getAutoCalcRanges() && getHasAttenuation())
631 const Real32 threshold = 0.001f;
632 calcPointLightRange(pEnv, getAttenuation(idx), threshold, cutOnRange, cutOffRange);
635 if (getEyeSpace())
637 transformToEyeSpace(
638 pEnv, getBeacon(idx),
639 getPosition(idx), getDirection(idx),
640 position, direction);
642 else
644 transformToWorldSpace(
645 pEnv, getBeacon(idx),
646 getPosition(idx), getDirection(idx),
647 position, direction);
650 Matrix matLSFromWS, matWSFromLS, matLSFromES, matESFromLS;
651 if (getHasWorldToLightSpaceMatrix() || getHasLightToWorldSpaceMatrix() || getHasEyeToLightSpaceMatrix() || getHasLightToEyeSpaceMatrix())
653 switch (getType(idx))
655 case MultiLight::POINT_LIGHT:
656 calcPointLightMatrices(pEnv, getBeacon(idx), getPosition(idx), matLSFromWS, matLSFromES);
657 break;
658 case MultiLight::DIRECTIONAL_LIGHT:
659 calcDirectionalLightMatrices(pEnv, getBeacon(idx), getDirection(idx), matLSFromWS, matLSFromES);
660 break;
661 case MultiLight::SPOT_LIGHT:
662 case MultiLight::CINEMA_LIGHT:
663 calcSpotLightMatrices(pEnv, getBeacon(idx), getPosition(idx), getDirection(idx), matLSFromWS, matLSFromES);
664 break;
668 if (getHasWorldToLightSpaceMatrix())
670 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matLSFromWS[0][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
671 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matLSFromWS[1][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
672 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matLSFromWS[2][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
673 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matLSFromWS[3][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
674 ao = alignOffset(16, bo); bo = ao;
677 if (getHasLightToWorldSpaceMatrix())
679 matLSFromWS.inverse(matWSFromLS);
681 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matWSFromLS[0][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
682 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matWSFromLS[1][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
683 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matWSFromLS[2][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
684 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matWSFromLS[3][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
685 ao = alignOffset(16, bo); bo = ao;
688 if (getHasEyeToLightSpaceMatrix())
690 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matLSFromES[0][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
691 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matLSFromES[1][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
692 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matLSFromES[2][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
693 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matLSFromES[3][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
694 ao = alignOffset(16, bo); bo = ao;
697 if (getHasLightToEyeSpaceMatrix())
699 matLSFromES.inverse(matESFromLS);
700 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matESFromLS[0][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
701 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matESFromLS[1][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
702 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matESFromLS[2][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
703 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matESFromLS[3][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
704 ao = alignOffset(16, bo); bo = ao;
707 Matrix matLightPerspProj, matInvLightPerspProj;
708 if (getHasLightPerspectiveMatrix() || getHasInvLightPerspectiveMatrix())
710 switch (getType(idx))
712 case MultiLight::POINT_LIGHT:
713 MatrixPerspective(matLightPerspProj, Pi / 4.f, 1.f, cutOnRange, cutOffRange);
714 break;
715 case MultiLight::DIRECTIONAL_LIGHT:
716 break;
717 case MultiLight::SPOT_LIGHT:
718 MatrixPerspective(matLightPerspProj, cosSpotlightAngle, 1.f, cutOnRange, cutOffRange);
719 break;
720 case MultiLight::CINEMA_LIGHT:
722 Real32 s = osgMax(osgMax(getInnerSuperEllipsesWidth(idx), getInnerSuperEllipsesHeight(idx)),
723 osgMax(getOuterSuperEllipsesWidth(idx), getOuterSuperEllipsesHeight(idx)));
725 Real32 a = osgATan(s/1.f);
726 cosSpotlightAngle = cos(a);
727 spotlightAngle = a;
729 MatrixPerspective(matLightPerspProj, cosSpotlightAngle, 1.f, cutOnRange, cutOffRange);
731 break;
735 if (getHasLightPerspectiveMatrix())
737 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matLightPerspProj[0][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
738 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matLightPerspProj[1][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
739 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matLightPerspProj[2][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
740 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matLightPerspProj[3][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
741 ao = alignOffset(16, bo); bo = ao;
744 if (getHasInvLightPerspectiveMatrix())
746 matLightPerspProj.inverse(matInvLightPerspProj);
748 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matInvLightPerspProj[0][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
749 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matInvLightPerspProj[1][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
750 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matInvLightPerspProj[2][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
751 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &matInvLightPerspProj[3][0], sizeof(Vec4f)); bo = ao + sizeof(Vec4f);
752 ao = alignOffset(16, bo); bo = ao;
755 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &position [0], sizeof(Pnt3f)); bo = ao + sizeof(Pnt3f);
756 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &direction[0], sizeof(Vec3f)); bo = ao + sizeof(Vec3f);
758 if (getHasColor())
760 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &getColor(idx)[0], sizeof(Color3f)); bo = ao + sizeof(Color3f);
763 if (getHasSeparateIntensities())
765 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &getAmbientIntensity (idx)[0], sizeof(Vec3f)); bo = ao + sizeof(Vec3f);
766 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &getDiffuseIntensity (idx)[0], sizeof(Vec3f)); bo = ao + sizeof(Vec3f);
767 ao = alignOffset(16, bo); memcpy(&buffer[0] + ao, &getSpecularIntensity(idx)[0], sizeof(Vec3f)); bo = ao + sizeof(Vec3f);
770 if (getHasIntensity())
772 ao = alignOffset( 4, bo); *(reinterpret_cast<Real32*>(&buffer[0] + ao)) = getIntensity(idx); bo = ao + sizeof(Real32);
775 if (getHasAttenuation())
777 ao = alignOffset( 4, bo); *(reinterpret_cast<Real32*>(&buffer[0] + ao)) = getAttenuation(idx)[0]; bo = ao + sizeof(Real32);
778 ao = alignOffset( 4, bo); *(reinterpret_cast<Real32*>(&buffer[0] + ao)) = getAttenuation(idx)[1]; bo = ao + sizeof(Real32);
779 ao = alignOffset( 4, bo); *(reinterpret_cast<Real32*>(&buffer[0] + ao)) = getAttenuation(idx)[2]; bo = ao + sizeof(Real32);
782 if (getHasRangeCutOn())
784 ao = alignOffset( 4, bo); *(reinterpret_cast<Real32*>(&buffer[0] + ao)) = cutOnRange; bo = ao + sizeof(Real32);
787 if (getHasRangeCutOff())
789 ao = alignOffset( 4, bo); *(reinterpret_cast<Real32*>(&buffer[0] + ao)) = cutOffRange; bo = ao + sizeof(Real32);
792 if (getHasRangeNearZone())
794 ao = alignOffset( 4, bo); *(reinterpret_cast<Real32*>(&buffer[0] + ao)) = getRangeNearZone(idx); bo = ao + sizeof(Real32);
797 if (getHasRangeFarZone())
799 ao = alignOffset( 4, bo); *(reinterpret_cast<Real32*>(&buffer[0] + ao)) = getRangeFarZone (idx); bo = ao + sizeof(Real32);
802 if (getHasCosSpotlightAngle() || (!getHasCosSpotlightAngle() && !getHasSpotlightAngle()))
804 ao = alignOffset( 4, bo); *(reinterpret_cast<Real32*>(&buffer[0] + ao)) = cosSpotlightAngle; bo = ao + sizeof(Real32);
807 if (getHasSpotlightAngle())
809 ao = alignOffset( 4, bo); *(reinterpret_cast<Real32*>(&buffer[0] + ao)) = spotlightAngle; bo = ao + sizeof(Real32);
812 if (getHasSpotExponent())
814 ao = alignOffset( 4, bo); *(reinterpret_cast<Real32*>(&buffer[0] + ao)) = getSpotExponent(idx); bo = ao + sizeof(Real32);
817 if (getHasCinemaLight())
819 OSG::Real32 twistAngle = osgDegree2Rad(getSuperEllipsesTwist(idx));
821 ao = alignOffset( 4, bo); *(reinterpret_cast<Real32*>(&buffer[0] + ao)) = getInnerSuperEllipsesWidth (idx); bo = ao + sizeof(Real32);
822 ao = alignOffset( 4, bo); *(reinterpret_cast<Real32*>(&buffer[0] + ao)) = getInnerSuperEllipsesHeight(idx); bo = ao + sizeof(Real32);
823 ao = alignOffset( 4, bo); *(reinterpret_cast<Real32*>(&buffer[0] + ao)) = getOuterSuperEllipsesWidth (idx); bo = ao + sizeof(Real32);
824 ao = alignOffset( 4, bo); *(reinterpret_cast<Real32*>(&buffer[0] + ao)) = getOuterSuperEllipsesHeight(idx); bo = ao + sizeof(Real32);
825 ao = alignOffset( 4, bo); *(reinterpret_cast<Real32*>(&buffer[0] + ao)) = getSuperEllipsesRoundness (idx); bo = ao + sizeof(Real32);
826 ao = alignOffset( 4, bo); *(reinterpret_cast<Real32*>(&buffer[0] + ao)) = twistAngle; bo = ao + sizeof(Real32);
829 ao = alignOffset( 4, bo); *(reinterpret_cast<Int32*>(&buffer[0] + ao)) = Int32(getType(idx)); bo = ao + sizeof(Int32);
830 ao = alignOffset( 4, bo); *(reinterpret_cast<bool* >(&buffer[0] + ao)) = getEnabled(idx); bo = ao + sizeof(Int32);
832 ao = alignOffset(16, bo); bo = ao; // padding
835 return buffer;
838 void MultiLightChunk::createLightState(DrawEnv* pEnv)
840 std::vector<UInt8> buffer = createLightBuffer(pEnv);
841 editMFBuffer()->setValues(buffer);
844 void MultiLightChunk::updateLightState(DrawEnv* pEnv)
846 std::vector<UInt8> buffer = createLightBuffer(pEnv);
847 editMFBuffer()->setValues(buffer);
849 setLastCamNear (pEnv->getCameraNear());
850 setLastCamFar (pEnv->getCameraFar());
851 setLastCamToWorld(pEnv->getCameraToWorld());
853 for (std::size_t idx = 0; idx < _mfBeacon.size(); ++idx)
855 Matrix matWsFromBS;
856 Node* beacon = getBeacon(UInt32(idx));
857 if (beacon)
859 beacon->getToWorld(matWsFromBS);
861 editMField(BeaconMatrixFieldMask, _mfBeaconMatrix);
862 _mfBeaconMatrix[idx] = matWsFromBS;
866 _bUpdateBuffer = false;
869 /*------------------------------ activate -----------------------------------*/
871 void MultiLightChunk::activate(DrawEnv *pEnv, UInt32 index)
873 if (getLastCamNear () != pEnv->getCameraNear() ||
874 getLastCamFar () != pEnv->getCameraFar() ||
875 getLastCamToWorld() != pEnv->getCameraToWorld())
877 _bUpdateBuffer = true;
879 else
881 for (std::size_t idx = 0; idx < _mfBeacon.size(); ++idx)
883 Matrix matWsFromBS;
884 Node* beacon = getBeacon(UInt32(idx));
885 if (beacon)
887 beacon->getToWorld(matWsFromBS);
889 if (matWsFromBS != _mfBeaconMatrix[idx])
891 _bUpdateBuffer = true;
892 break;
898 if (_bUpdateBuffer)
899 updateLightState(pEnv);
901 Inherited::activate(pEnv, index);
904 /*------------------------------ deactivate ---------------------------------*/
906 void MultiLightChunk::deactivate(DrawEnv *pEnv, UInt32 index)
908 Inherited::deactivate(pEnv, index);
911 /*------------------------------ changeFrom ---------------------------------*/
913 void MultiLightChunk::changeFrom(DrawEnv *pEnv,
914 StateChunk *old,
915 UInt32 index )
917 Inherited::changeFrom(pEnv, old, index);
920 /*------------------------------ interface ----------------------------------*/
922 UInt32 MultiLightChunk::addLight(MultiLight::Type eType)
924 if (!check_invariant())
925 clearLights();
927 editMField(PositionFieldMask, _mfPosition);
928 editMField(DirectionFieldMask, _mfDirection);
929 editMField(SpotlightAngleFieldMask, _mfSpotlightAngle);
930 editMField(TypeFieldMask, _mfType);
931 editMField(EnabledFieldMask, _mfEnabled);
932 editMField(BeaconFieldMask, _mfBeacon);
933 editMField(BeaconMatrixFieldMask, _mfBeaconMatrix);
935 _mfPosition. push_back(Pnt3f(0.f,0.f,0.f));
936 _mfDirection. push_back(Vec3f(0.f,0.f,1.f));
937 _mfSpotlightAngle. push_back(45.f);
938 _mfType. push_back(eType);
939 _mfEnabled. push_back(false);
940 pushToBeacon(NULL);
941 _mfBeaconMatrix. push_back(Matrix());
943 if (getHasSeparateIntensities())
945 editMField(AmbientIntensityFieldMask, _mfAmbientIntensity);
946 editMField(DiffuseIntensityFieldMask, _mfDiffuseIntensity);
947 editMField(SpecularIntensityFieldMask, _mfSpecularIntensity);
949 _mfAmbientIntensity. push_back(Vec3f(1.f,1.f,1.f));
950 _mfDiffuseIntensity. push_back(Vec3f(1.f,1.f,1.f));
951 _mfSpecularIntensity.push_back(Vec3f(1.f,1.f,1.f));
954 if (getHasColor())
956 editMField(ColorFieldMask, _mfColor);
957 _mfColor.push_back(Vec3f(1.f,1.f,1.f));
960 if (getHasIntensity())
962 editMField(IntensityFieldMask, _mfIntensity);
963 _mfIntensity.push_back(1.f);
966 if (getHasAttenuation())
968 editMField(AttenuationFieldMask, _mfAttenuation);
969 _mfAttenuation.push_back(Vec3f(1.f,0.f,0.f));
972 if (getHasRangeCutOn())
974 editMField(RangeCutOnFieldMask, _mfRangeCutOn);
975 _mfRangeCutOn.push_back(0.f);
978 if (getHasRangeCutOff())
980 editMField(RangeCutOffFieldMask, _mfRangeCutOff);
981 _mfRangeCutOff.push_back(0.f);
984 if (getHasRangeNearZone())
986 editMField(RangeNearZoneFieldMask, _mfRangeNearZone);
987 _mfRangeNearZone.push_back(0.f);
990 if (getHasRangeFarZone())
992 editMField(RangeFarZoneFieldMask, _mfRangeFarZone);
993 _mfRangeFarZone.push_back(0.f);
996 if (getHasSpotExponent())
998 editMField(SpotExponentFieldMask, _mfSpotExponent);
999 _mfSpotExponent.push_back(1.f);
1002 if (getHasCinemaLight())
1004 editMField(InnerSuperEllipsesWidthFieldMask, _mfInnerSuperEllipsesWidth);
1005 editMField(InnerSuperEllipsesHeightFieldMask, _mfInnerSuperEllipsesHeight);
1006 editMField(OuterSuperEllipsesWidthFieldMask, _mfOuterSuperEllipsesWidth);
1007 editMField(OuterSuperEllipsesHeightFieldMask, _mfOuterSuperEllipsesHeight);
1008 editMField(SuperEllipsesRoundnessFieldMask, _mfSuperEllipsesRoundness);
1009 editMField(SuperEllipsesTwistFieldMask, _mfSuperEllipsesTwist);
1011 _mfInnerSuperEllipsesWidth. push_back(1.f);
1012 _mfInnerSuperEllipsesHeight.push_back(1.f);
1013 _mfOuterSuperEllipsesWidth. push_back(1.f);
1014 _mfOuterSuperEllipsesHeight.push_back(1.f);
1015 _mfSuperEllipsesRoundness. push_back(0.f);
1016 _mfSuperEllipsesTwist. push_back(0.f);
1019 OSG_ASSERT(check_invariant());
1021 return UInt32(_mfPosition.size() - 1);
1024 UInt32 MultiLightChunk::addLight(const MultiLight& light)
1026 if (!check_invariant())
1027 clearLights();
1029 editMField(PositionFieldMask, _mfPosition);
1030 editMField(DirectionFieldMask, _mfDirection);
1031 editMField(SpotlightAngleFieldMask, _mfSpotlightAngle);
1032 editMField(TypeFieldMask, _mfType);
1033 editMField(EnabledFieldMask, _mfEnabled);
1034 editMField(BeaconFieldMask, _mfBeacon);
1035 editMField(BeaconMatrixFieldMask, _mfBeaconMatrix);
1037 _mfPosition. push_back(light.position);
1038 _mfDirection. push_back(light.direction);
1039 _mfSpotlightAngle. push_back(light.spotlightAngle);
1040 _mfType. push_back(light.type);
1041 _mfEnabled. push_back(light.enabled);
1042 pushToBeacon(light.beacon);
1043 _mfBeaconMatrix. push_back(Matrix());
1045 if (getHasSeparateIntensities())
1047 editMField(AmbientIntensityFieldMask, _mfAmbientIntensity);
1048 editMField(DiffuseIntensityFieldMask, _mfDiffuseIntensity);
1049 editMField(SpecularIntensityFieldMask, _mfSpecularIntensity);
1051 _mfAmbientIntensity. push_back(light.ambientIntensity);
1052 _mfDiffuseIntensity. push_back(light.diffuseIntensity);
1053 _mfSpecularIntensity.push_back(light.specularIntensity);
1056 if (getHasColor())
1058 editMField(ColorFieldMask, _mfColor);
1059 _mfColor.push_back(light.color);
1062 if (getHasIntensity())
1064 editMField(IntensityFieldMask, _mfIntensity);
1065 _mfIntensity.push_back(light.intensity);
1068 if (getHasAttenuation())
1070 editMField(AttenuationFieldMask, _mfAttenuation);
1071 _mfAttenuation.push_back(light.attenuation);
1074 if (getHasRangeCutOn())
1076 editMField(RangeCutOnFieldMask, _mfRangeCutOn);
1077 _mfRangeCutOn.push_back(light.rangeCutOn);
1080 if (getHasRangeCutOff())
1082 editMField(RangeCutOffFieldMask, _mfRangeCutOff);
1083 _mfRangeCutOff.push_back(light.rangeCutOff);
1086 if (getHasRangeNearZone())
1088 editMField(RangeNearZoneFieldMask, _mfRangeNearZone);
1089 _mfRangeNearZone.push_back(light.rangeNearZone);
1092 if (getHasRangeFarZone())
1094 editMField(RangeFarZoneFieldMask, _mfRangeFarZone);
1095 _mfRangeFarZone.push_back(light.rangeFarZone);
1098 if (getHasSpotExponent())
1100 editMField(SpotExponentFieldMask, _mfSpotExponent);
1101 _mfSpotExponent.push_back(light.spotExponent);
1104 if (getHasCinemaLight())
1106 editMField(InnerSuperEllipsesWidthFieldMask, _mfInnerSuperEllipsesWidth);
1107 editMField(InnerSuperEllipsesHeightFieldMask, _mfInnerSuperEllipsesHeight);
1108 editMField(OuterSuperEllipsesWidthFieldMask, _mfOuterSuperEllipsesWidth);
1109 editMField(OuterSuperEllipsesHeightFieldMask, _mfOuterSuperEllipsesHeight);
1110 editMField(SuperEllipsesRoundnessFieldMask, _mfSuperEllipsesRoundness);
1111 editMField(SuperEllipsesTwistFieldMask, _mfSuperEllipsesTwist);
1113 _mfInnerSuperEllipsesWidth. push_back(light.innerSuperEllipsesWidth);
1114 _mfInnerSuperEllipsesHeight.push_back(light.innerSuperEllipsesHeight);
1115 _mfOuterSuperEllipsesWidth. push_back(light.outerSuperEllipsesWidth);
1116 _mfOuterSuperEllipsesHeight.push_back(light.outerSuperEllipsesHeight);
1117 _mfSuperEllipsesRoundness. push_back(light.superEllipsesRoundness);
1118 _mfSuperEllipsesTwist. push_back(light.superEllipsesTwist);
1121 OSG_ASSERT(check_invariant());
1123 return UInt32(_mfPosition.size() - 1);
1126 void MultiLightChunk::updateLight(const UInt32 idx, const MultiLight& light)
1128 setPosition (idx, light.position);
1129 setDirection (idx, light.direction);
1130 setSpotlightAngle (idx, light.spotlightAngle);
1131 setType (idx, light.type);
1132 setEnabled (idx, light.enabled);
1133 setBeacon (idx, light.beacon);
1135 if (getHasSeparateIntensities())
1137 setAmbientIntensity (idx, light.ambientIntensity);
1138 setDiffuseIntensity (idx, light.diffuseIntensity);
1139 setSpecularIntensity(idx, light.specularIntensity);
1142 if (getHasColor())
1144 setColor(idx, light.color);
1147 if (getHasIntensity())
1149 setIntensity(idx, light.intensity);
1152 if (getHasAttenuation())
1154 setAttenuation(idx, light.attenuation);
1157 if (getHasRangeCutOn())
1159 setRangeCutOn(idx, light.rangeCutOn);
1162 if (getHasRangeCutOff())
1164 setRangeCutOff(idx, light.rangeCutOff);
1167 if (getHasRangeNearZone())
1169 setRangeNearZone(idx, light.rangeNearZone);
1172 if (getHasRangeFarZone())
1174 setRangeFarZone(idx, light.rangeFarZone);
1177 if (getHasSpotExponent())
1179 setSpotExponent(idx, light.spotExponent);
1182 if (getHasCinemaLight())
1184 setInnerSuperEllipsesWidth (idx, light.innerSuperEllipsesWidth);
1185 setInnerSuperEllipsesHeight (idx, light.innerSuperEllipsesHeight);
1186 setOuterSuperEllipsesWidth (idx, light.outerSuperEllipsesWidth);
1187 setOuterSuperEllipsesHeight (idx, light.outerSuperEllipsesHeight);
1188 setSuperEllipsesRoundness (idx, light.superEllipsesRoundness);
1189 setSuperEllipsesTwist (idx, light.superEllipsesTwist);
1193 void MultiLightChunk::removeLight(const UInt32 idx)
1195 OSG_ASSERT(check_invariant());
1197 if (idx >= _mfPosition.size())
1198 return;
1200 editMField(PositionFieldMask, _mfPosition);
1201 editMField(DirectionFieldMask, _mfDirection);
1202 editMField(SpotlightAngleFieldMask, _mfSpotlightAngle);
1203 editMField(TypeFieldMask, _mfType);
1204 editMField(EnabledFieldMask, _mfEnabled);
1205 editMField(BeaconFieldMask, _mfBeacon);
1206 editMField(BeaconMatrixFieldMask, _mfBeaconMatrix);
1208 _mfPosition. erase(idx);
1209 _mfDirection. erase(idx);
1210 _mfSpotlightAngle. erase(idx);
1211 _mfType. erase(idx);
1212 _mfEnabled. erase(idx);
1213 _mfBeacon. erase(idx);
1214 _mfBeaconMatrix. erase(idx);
1216 if (getHasSeparateIntensities())
1218 editMField(AmbientIntensityFieldMask, _mfAmbientIntensity);
1219 editMField(DiffuseIntensityFieldMask, _mfDiffuseIntensity);
1220 editMField(SpecularIntensityFieldMask, _mfSpecularIntensity);
1222 _mfAmbientIntensity. erase(idx);
1223 _mfDiffuseIntensity. erase(idx);
1224 _mfSpecularIntensity.erase(idx);
1227 if (getHasColor())
1229 editMField(ColorFieldMask, _mfColor);
1230 _mfColor.erase(idx);
1233 if (getHasIntensity())
1235 editMField(IntensityFieldMask, _mfIntensity);
1236 _mfIntensity.erase(idx);
1239 if (getHasAttenuation())
1241 editMField(AttenuationFieldMask, _mfAttenuation);
1242 _mfAttenuation.erase(idx);
1245 if (getHasRangeCutOn())
1247 editMField(RangeCutOnFieldMask, _mfRangeCutOn);
1248 _mfRangeCutOn.erase(idx);
1251 if (getHasRangeCutOff())
1253 editMField(RangeCutOffFieldMask, _mfRangeCutOff);
1254 _mfRangeCutOff.erase(idx);
1257 if (getHasRangeNearZone())
1259 editMField(RangeNearZoneFieldMask, _mfRangeNearZone);
1260 _mfRangeNearZone.erase(idx);
1263 if (getHasRangeFarZone())
1265 editMField(RangeFarZoneFieldMask, _mfRangeFarZone);
1266 _mfRangeFarZone.erase(idx);
1269 if (getHasSpotExponent())
1271 editMField(SpotExponentFieldMask, _mfSpotExponent);
1272 _mfSpotExponent.erase(idx);
1275 if (getHasCinemaLight())
1277 editMField(InnerSuperEllipsesWidthFieldMask, _mfInnerSuperEllipsesWidth);
1278 editMField(InnerSuperEllipsesHeightFieldMask, _mfInnerSuperEllipsesHeight);
1279 editMField(OuterSuperEllipsesWidthFieldMask, _mfOuterSuperEllipsesWidth);
1280 editMField(OuterSuperEllipsesHeightFieldMask, _mfOuterSuperEllipsesHeight);
1281 editMField(SuperEllipsesRoundnessFieldMask, _mfSuperEllipsesRoundness);
1282 editMField(SuperEllipsesTwistFieldMask, _mfSuperEllipsesTwist);
1284 _mfInnerSuperEllipsesWidth. erase(idx);
1285 _mfInnerSuperEllipsesHeight.erase(idx);
1286 _mfOuterSuperEllipsesWidth. erase(idx);
1287 _mfOuterSuperEllipsesHeight.erase(idx);
1288 _mfSuperEllipsesRoundness. erase(idx);
1289 _mfSuperEllipsesTwist. erase(idx);
1292 OSG_ASSERT(check_invariant());
1295 void MultiLightChunk::clearLights()
1297 editMField(PositionFieldMask, _mfPosition);
1298 editMField(DirectionFieldMask, _mfDirection);
1299 editMField(ColorFieldMask, _mfColor);
1300 editMField(IntensityFieldMask, _mfIntensity);
1301 editMField(AmbientIntensityFieldMask, _mfAmbientIntensity);
1302 editMField(DiffuseIntensityFieldMask, _mfDiffuseIntensity);
1303 editMField(SpecularIntensityFieldMask, _mfSpecularIntensity);
1304 editMField(AttenuationFieldMask, _mfAttenuation);
1305 editMField(RangeCutOnFieldMask, _mfRangeCutOn);
1306 editMField(RangeCutOffFieldMask, _mfRangeCutOff);
1307 editMField(RangeNearZoneFieldMask, _mfRangeNearZone);
1308 editMField(RangeFarZoneFieldMask, _mfRangeFarZone);
1309 editMField(SpotlightAngleFieldMask, _mfSpotlightAngle);
1310 editMField(SpotExponentFieldMask, _mfSpotExponent);
1311 editMField(InnerSuperEllipsesWidthFieldMask, _mfInnerSuperEllipsesWidth);
1312 editMField(InnerSuperEllipsesHeightFieldMask, _mfInnerSuperEllipsesHeight);
1313 editMField(OuterSuperEllipsesWidthFieldMask, _mfOuterSuperEllipsesWidth);
1314 editMField(OuterSuperEllipsesHeightFieldMask, _mfOuterSuperEllipsesHeight);
1315 editMField(SuperEllipsesRoundnessFieldMask, _mfSuperEllipsesRoundness);
1316 editMField(SuperEllipsesTwistFieldMask, _mfSuperEllipsesTwist);
1317 editMField(TypeFieldMask, _mfType);
1318 editMField(EnabledFieldMask, _mfEnabled);
1319 editMField(BeaconFieldMask, _mfBeacon);
1320 editMField(BeaconMatrixFieldMask, _mfBeaconMatrix);
1322 _mfPosition. clear();
1323 _mfDirection. clear();
1324 _mfColor. clear();
1325 _mfIntensity. clear();
1326 _mfAmbientIntensity. clear();
1327 _mfDiffuseIntensity. clear();
1328 _mfSpecularIntensity. clear();
1329 _mfAttenuation. clear();
1330 _mfRangeCutOn. clear();
1331 _mfRangeCutOff. clear();
1332 _mfRangeNearZone. clear();
1333 _mfRangeFarZone. clear();
1334 _mfSpotlightAngle. clear();
1335 _mfSpotExponent. clear();
1336 _mfInnerSuperEllipsesWidth. clear();
1337 _mfInnerSuperEllipsesHeight.clear();
1338 _mfOuterSuperEllipsesWidth. clear();
1339 _mfOuterSuperEllipsesHeight.clear();
1340 _mfSuperEllipsesRoundness. clear();
1341 _mfSuperEllipsesTwist. clear();
1342 _mfType. clear();
1343 _mfEnabled. clear();
1344 _mfBeacon. clear();
1345 _mfBeaconMatrix. clear();
1348 void MultiLightChunk::setLayoutType(UInt32 layout)
1350 setHasColor (false);
1351 setHasIntensity (false);
1352 setHasSeparateIntensities (false);
1353 setHasAttenuation (false);
1354 setHasRangeCutOn (false);
1355 setHasRangeCutOff (false);
1356 setHasRangeNearZone (false);
1357 setHasRangeFarZone (false);
1358 setHasCosSpotlightAngle (true);
1359 setHasSpotlightAngle (false);
1360 setHasSpotExponent (false);
1361 setHasCinemaLight (false);
1363 if (layout & MultiLight::SIMPLE_LAYOUT)
1365 setHasColor (true);
1366 setHasIntensity (true);
1367 setHasRangeCutOff (true);
1370 if (layout & MultiLight::RANGE_LAYOUT)
1372 setHasRangeCutOn (true);
1373 setHasRangeCutOff (true);
1376 if (layout & MultiLight::ZONE_LAYOUT)
1378 setHasRangeNearZone (true);
1379 setHasRangeFarZone (true);
1382 if (layout & MultiLight::OPENGL_LAYOUT)
1384 setHasSeparateIntensities (true);
1385 setHasAttenuation (true);
1386 setHasSpotExponent (true);
1389 if (layout & MultiLight::CINEMA_LAYOUT)
1391 setHasCinemaLight (true);
1394 clearLights();
1397 std::string MultiLightChunk::getLightProgSnippet() const
1399 using namespace std;
1401 stringstream ost;
1404 << endl << "//"
1405 << endl << "// The supported light types"
1406 << endl << "//"
1407 << endl << "const int POINT_LIGHT = " << MultiLight::POINT_LIGHT << ";"
1408 << endl << "const int DIRECTIONAL_LIGHT = " << MultiLight::DIRECTIONAL_LIGHT << ";"
1409 << endl << "const int SPOT_LIGHT = " << MultiLight::SPOT_LIGHT << ";"
1410 << endl << "const int CINEMA_LIGHT = " << MultiLight::CINEMA_LIGHT << ";"
1411 << endl << ""
1412 << endl << "//"
1413 << endl << "// The multi light type declaration"
1414 << endl << "//"
1415 << endl << "struct Light"
1416 << endl << "{"
1418 if (getHasWorldToLightSpaceMatrix())
1421 << endl << " mat4 worldToLightSpaceMatrix;"
1425 if (getHasLightToWorldSpaceMatrix())
1428 << endl << " mat4 lightToWorldSpaceMatrix;"
1432 if (getHasEyeToLightSpaceMatrix())
1435 << endl << " mat4 eyeToLightSpaceMatrix;"
1439 if (getHasLightToEyeSpaceMatrix())
1442 << endl << " mat4 lightToEyeSpaceMatrix;"
1446 if (getHasLightPerspectiveMatrix())
1449 << endl << " mat4 lightPerspectiveMatrix;"
1453 if (getHasInvLightPerspectiveMatrix())
1456 << endl << " mat4 invLightPerspectiveMatrix;"
1459 ost
1460 << endl << " vec3 position; // in " << (getEyeSpace() ? "eye" : "world") << " space"
1461 << endl << " vec3 direction; // in " << (getEyeSpace() ? "eye" : "world") << " space"
1463 if (getHasColor())
1466 << endl << " vec3 color;"
1470 if (getHasSeparateIntensities())
1473 << endl << " vec3 ambientIntensity;"
1474 << endl << " vec3 diffuseIntensity;"
1475 << endl << " vec3 specularIntensity;"
1479 if (getHasIntensity())
1482 << endl << " float intensity;"
1486 if (getHasAttenuation())
1489 << endl << " float constantAttenuation;"
1490 << endl << " float linearAttenuation;"
1491 << endl << " float quadraticAttenuation;"
1495 if (getHasRangeCutOn())
1498 << endl << " float rangeCutOn;"
1502 if (getHasRangeCutOff())
1505 << endl << " float rangeCutOff;"
1509 if (getHasRangeNearZone())
1512 << endl << " float rangeNearZone;"
1516 if (getHasRangeFarZone())
1519 << endl << " float rangeFarZone;"
1523 if (getHasCosSpotlightAngle() || (!getHasCosSpotlightAngle() && !getHasSpotlightAngle()))
1526 << endl << " float cosSpotlightAngle;"
1530 if (getHasSpotlightAngle())
1533 << endl << " float spotlightAngle; // in radians"
1537 if (getHasSpotExponent())
1540 << endl << " float spotExponent;"
1544 if (getHasCinemaLight())
1547 << endl << " float innerSuperEllipsesWidth; // a"
1548 << endl << " float innerSuperEllipsesHeight; // b"
1549 << endl << " float outerSuperEllipsesWidth; // A"
1550 << endl << " float outerSuperEllipsesHeight; // B"
1551 << endl << " float superEllipsesRoundness; // r"
1552 << endl << " float superEllipsesTwist; // // twist angle theta in radians"
1556 << endl << " int type; // specific type of light: POINT_LIGHT, DIRECTIONAL_LIGHT, SPOT_LIGHT or CINEMA_LIGHT"
1557 << endl << " bool enabled; // on/off state of light"
1558 << endl << "};"
1559 << endl << ""
1560 << endl << "layout (std430) buffer " << getLightBlockName()
1561 << endl << "{"
1562 << endl << " Light light[];"
1563 << endl << "} " << getLightVariableName() << ";"
1564 << endl
1567 return ost.str();
1570 OSG_END_NAMESPACE