1 // Copyright (c) 2017 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <Graphic3d_LightSet.hxx>
16 #include <NCollection_LocalArray.hxx>
18 IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_LightSet, Standard_Transient)
22 //! Suffixes identifying light source type.
23 static const char THE_LIGHT_KEY_LETTERS[Graphic3d_TypeOfLightSource_NB] =
25 'a', // Graphic3d_TOLS_AMBIENT
26 'd', // Graphic3d_TOLS_DIRECTIONAL
27 'p', // Graphic3d_TOLS_POSITIONAL
28 's' // Graphic3d_TOLS_SPOT
32 // =======================================================================
33 // function : Graphic3d_LightSet
35 // =======================================================================
36 Graphic3d_LightSet::Graphic3d_LightSet()
37 : myAmbient (0.0f, 0.0f, 0.0f, 0.0f),
43 memset (myLightTypes, 0, sizeof(myLightTypes));
44 memset (myLightTypesEnabled, 0, sizeof(myLightTypesEnabled));
47 // =======================================================================
50 // =======================================================================
51 Standard_Boolean Graphic3d_LightSet::Add (const Handle(Graphic3d_CLight)& theLight)
53 if (theLight.IsNull())
55 throw Standard_ProgramError ("Graphic3d_LightSet::Add(), NULL argument");
58 const Standard_Integer anOldExtent = myLights.Extent();
59 const Standard_Integer anIndex = myLights.Add (theLight, 0);
60 if (anIndex <= anOldExtent)
62 return Standard_False;
65 myLightTypes[theLight->Type()] += 1;
66 myLights.ChangeFromIndex (anIndex) = theLight->Revision();
71 // =======================================================================
74 // =======================================================================
75 Standard_Boolean Graphic3d_LightSet::Remove (const Handle(Graphic3d_CLight)& theLight)
77 const Standard_Integer anIndToRemove = myLights.FindIndex (theLight);
78 if (anIndToRemove <= 0)
80 return Standard_False;
84 myLights.RemoveFromIndex (anIndToRemove);
85 myLightTypes[theLight->Type()] -= 1;
89 // =======================================================================
90 // function : UpdateRevision
92 // =======================================================================
93 Standard_Size Graphic3d_LightSet::UpdateRevision()
95 if (myCacheRevision == myRevision)
97 // check implicit updates of light sources
98 for (NCollection_IndexedDataMap<Handle(Graphic3d_CLight), Standard_Size>::Iterator aLightIter (myLights); aLightIter.More(); aLightIter.Next())
100 const Handle(Graphic3d_CLight)& aLight = aLightIter.Key();
101 if (aLightIter.Value() != aLight->Revision())
108 if (myCacheRevision == myRevision)
113 myCacheRevision = myRevision;
115 myAmbient.SetValues (0.0f, 0.0f, 0.0f, 0.0f);
116 memset (myLightTypesEnabled, 0, sizeof(myLightTypesEnabled));
117 NCollection_LocalArray<char, 32> aKeyLong (myLights.Extent() + 1);
118 Standard_Integer aLightLast = 0;
119 for (NCollection_IndexedDataMap<Handle(Graphic3d_CLight), Standard_Size>::Iterator aLightIter (myLights); aLightIter.More(); aLightIter.Next())
121 const Handle(Graphic3d_CLight)& aLight = aLightIter.Key();
122 aLightIter.ChangeValue() = aLight->Revision();
123 if (!aLight->IsEnabled())
128 myLightTypesEnabled[aLight->Type()] += 1;
129 if (aLight->Type() == Graphic3d_TOLS_AMBIENT)
131 myAmbient += aLight->PackedColor() * aLight->Intensity();
135 if (aLight->ToCastShadows())
138 aKeyLong[aLightLast++] = UpperCase (THE_LIGHT_KEY_LETTERS[aLight->Type()]);
142 aKeyLong[aLightLast++] = THE_LIGHT_KEY_LETTERS[aLight->Type()];
146 aKeyLong[aLightLast] = '\0';
147 myAmbient.a() = 1.0f;
148 myNbEnabled = myLightTypesEnabled[Graphic3d_TOLS_DIRECTIONAL]
149 + myLightTypesEnabled[Graphic3d_TOLS_POSITIONAL]
150 + myLightTypesEnabled[Graphic3d_TOLS_SPOT];
151 myKeyEnabledLong = aKeyLong;
152 myKeyEnabledShort = TCollection_AsciiString (myLightTypesEnabled[Graphic3d_TOLS_DIRECTIONAL] > 0 ? THE_LIGHT_KEY_LETTERS[Graphic3d_TOLS_DIRECTIONAL] : '\0')
153 + TCollection_AsciiString (myLightTypesEnabled[Graphic3d_TOLS_POSITIONAL] > 0 ? THE_LIGHT_KEY_LETTERS[Graphic3d_TOLS_POSITIONAL] : '\0')
154 + TCollection_AsciiString (myLightTypesEnabled[Graphic3d_TOLS_SPOT] > 0 ? THE_LIGHT_KEY_LETTERS[Graphic3d_TOLS_SPOT] : '\0');