1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2013 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, carsten_neumann@gmx.net *
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 <boost/bind.hpp>
48 #include "OSGConfig.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"
65 #include "OSGMultiLightChunk.h"
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 /***************************************************************************\
76 \***************************************************************************/
78 typedef OSG::Window Win
;
80 /***************************************************************************\
82 \***************************************************************************/
84 void MultiLightChunk::initMethod(InitPhase ePhase
)
86 Inherited::initMethod(ePhase
);
88 if(ePhase
== TypeObject::SystemPost
)
94 /***************************************************************************\
96 \***************************************************************************/
98 MultiLight::MultiLight(Type e
)
99 : position(0.f
,0.f
,0.f
)
100 , direction(0.f
,0.f
,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
)
109 , innerSuperEllipsesWidth(1.f
)
110 , innerSuperEllipsesHeight(1.f
)
111 , outerSuperEllipsesWidth(1.3f
)
112 , outerSuperEllipsesHeight(1.3f
)
113 , superEllipsesRoundness(1.f
)
114 , superEllipsesTwist(0.f
)
125 /*-------------------------------------------------------------------------*\
127 \*-------------------------------------------------------------------------*/
129 /*----------------------- constructors & destructors ----------------------*/
131 MultiLightChunk::MultiLightChunk(void) :
133 _bUpdateBuffer(false),
138 MultiLightChunk::MultiLightChunk(const MultiLightChunk
&source
) :
140 _bUpdateBuffer(false),
145 MultiLightChunk::~MultiLightChunk(void)
150 /*----------------------------- class specific ----------------------------*/
152 void MultiLightChunk::changed(ConstFieldMaskArg whichField
,
157 // The BeaconMatrixFieldMask is deliberately omitted
159 if((whichField
& ( HasWorldToLightSpaceMatrixFieldMask
|
160 HasLightToWorldSpaceMatrixFieldMask
|
161 HasEyeToLightSpaceMatrixFieldMask
|
162 HasLightToEyeSpaceMatrixFieldMask
|
163 HasLightPerspectiveMatrixFieldMask
|
164 HasInvLightPerspectiveMatrixFieldMask
|
166 HasIntensityFieldMask
|
167 HasSeparateIntensitiesFieldMask
|
168 HasAttenuationFieldMask
|
169 HasRangeCutOnFieldMask
|
170 HasRangeCutOffFieldMask
|
171 HasRangeNearZoneFieldMask
|
172 HasRangeFarZoneFieldMask
|
173 HasCosSpotlightAngleFieldMask
|
174 HasSpotlightAngleFieldMask
|
175 HasSpotExponentFieldMask
|
176 HasCinemaLightFieldMask
|
177 AutoCalcRangesFieldMask
|
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
|
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
)
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(
244 const Pnt3f
& position_bs
,
245 const Vec3f
& direction_bs
,
247 Vec3f
& direction_ws
) const
250 matWsFromBS
.identity();
254 beacon
->getToWorld(matWsFromBS
);
258 matWsFromBS
.setIdentity();
261 matWsFromBS
.multFull( position_bs
, position_ws
);
262 matWsFromBS
.multFull(direction_bs
, direction_ws
);
265 void MultiLightChunk::transformToEyeSpace(
268 const Pnt3f
& position_bs
,
269 const Vec3f
& direction_bs
,
271 Vec3f
& direction_es
) const
277 beacon
->getToWorld(matWsFromBS
);
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(
294 const Vec3f
& direction_bs
,
296 Matrix
& matLSFromES
) const
299 beacon
->getToWorld(matLSFromWS
); // matWsFromBS;
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(
316 const Pnt3f
& position_bs
,
318 Matrix
& matLSFromES
) const
321 beacon
->getToWorld(matLSFromWS
); // matWsFromBS;
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(
337 const Pnt3f
& position_bs
,
338 const Vec3f
& direction_bs
,
340 Matrix
& matLSFromES
) const
343 beacon
->getToWorld(matLSFromWS
); // matWsFromBS;
346 matLightPos
.setTranslate(position_bs
);
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(
363 const Vec3f attenuation
,
366 Real32
& outFar
) const
368 Real32 defaultNear
= pEnv
->getCameraNear();
369 Real32 defaultFar
= pEnv
->getCameraFar();
371 outNear
= defaultNear
;
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
);
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
);
403 else if(osgAbs(l
) > TypeTraits
<Real32
>::getDefaultEps())
405 Real32 r
= (1.f
/threshold
- c
)/l
;
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());
423 // mat4 worldToLightSpaceMatrix;
424 // mat4 lightToWorldSpaceMatrix;
425 // mat4 eyeToLightSpaceMatrix;
426 // mat4 lightToEyeSpaceMatrix;
427 // mat4 lightPerspectiveMatrix
428 // mat4 InvLightPerspectiveMatrix;
432 // vec3 ambientIntensity;
433 // vec3 diffuseIntensity;
434 // vec3 specularIntensity;
436 // float constantAttenuation;
437 // float linearAttenuation;
438 // float quadraticAttenuation;
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;
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
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
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
)
609 Real32 cosSpotlightAngle
= 1.f
;
610 Real32 spotlightAngle
= 0.f
;
612 switch (getType(idx
))
614 case MultiLight::POINT_LIGHT
:
616 case MultiLight::DIRECTIONAL_LIGHT
:
618 case MultiLight::SPOT_LIGHT
:
619 cosSpotlightAngle
= osgCos(osgDegree2Rad(getSpotlightAngle(idx
)));
620 spotlightAngle
= osgDegree2Rad(getSpotlightAngle(idx
));
622 case MultiLight::CINEMA_LIGHT
:
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
);
638 pEnv
, getBeacon(idx
),
639 getPosition(idx
), getDirection(idx
),
640 position
, direction
);
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
);
658 case MultiLight::DIRECTIONAL_LIGHT
:
659 calcDirectionalLightMatrices(pEnv
, getBeacon(idx
), getDirection(idx
), matLSFromWS
, matLSFromES
);
661 case MultiLight::SPOT_LIGHT
:
662 case MultiLight::CINEMA_LIGHT
:
663 calcSpotLightMatrices(pEnv
, getBeacon(idx
), getPosition(idx
), getDirection(idx
), matLSFromWS
, matLSFromES
);
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
);
715 case MultiLight::DIRECTIONAL_LIGHT
:
717 case MultiLight::SPOT_LIGHT
:
718 MatrixPerspective(matLightPerspProj
, cosSpotlightAngle
, 1.f
, cutOnRange
, cutOffRange
);
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
);
729 MatrixPerspective(matLightPerspProj
, cosSpotlightAngle
, 1.f
, cutOnRange
, cutOffRange
);
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
);
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
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
)
856 Node
* beacon
= getBeacon(UInt32(idx
));
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;
881 for (std::size_t idx
= 0; idx
< _mfBeacon
.size(); ++idx
)
884 Node
* beacon
= getBeacon(UInt32(idx
));
887 beacon
->getToWorld(matWsFromBS
);
889 if (matWsFromBS
!= _mfBeaconMatrix
[idx
])
891 _bUpdateBuffer
= true;
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
,
917 Inherited::changeFrom(pEnv
, old
, index
);
920 /*------------------------------ interface ----------------------------------*/
922 UInt32
MultiLightChunk::addLight(MultiLight::Type eType
)
924 if (!check_invariant())
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);
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
));
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())
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
);
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
);
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())
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
);
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();
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();
1343 _mfEnabled
. 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
)
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);
1397 std::string
MultiLightChunk::getLightProgSnippet() const
1399 using namespace std
;
1405 << endl
<< "// The supported light types"
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
<< ";"
1413 << endl
<< "// The multi light type declaration"
1415 << endl
<< "struct Light"
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;"
1460 << endl
<< " vec3 position; // in " << (getEyeSpace() ? "eye" : "world") << " space"
1461 << endl
<< " vec3 direction; // in " << (getEyeSpace() ? "eye" : "world") << " space"
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"
1560 << endl
<< "layout (std430) buffer " << getLightBlockName()
1562 << endl
<< " Light light[];"
1563 << endl
<< "} " << getLightVariableName() << ";"