1 /*
2 Open Asset Import Library (assimp)
3 ----------------------------------------------------------------------
4
5 Copyright (c) 2006-2019, assimp team
6
7
8 All rights reserved.
9
10 Redistribution and use of this software in source and binary forms,
11 with or without modification, are permitted provided that the
12 following conditions are met:
13
14 * Redistributions of source code must retain the above
15 copyright notice, this list of conditions and the
16 following disclaimer.
17
18 * Redistributions in binary form must reproduce the above
19 copyright notice, this list of conditions and the
20 following disclaimer in the documentation and/or other
21 materials provided with the distribution.
22
23 * Neither the name of the assimp team, nor the names of its
24 contributors may be used to endorse or promote products
25 derived from this software without specific prior
26 written permission of the assimp team.
27
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
40 ----------------------------------------------------------------------
41 */
42 /// \file X3DImporter_Light.cpp
43 /// \brief Parsing data from nodes of "Lighting" set of X3D.
44 /// date 2015-2016
45 /// author smal.root@gmail.com
46
47 #ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
48
49 #include "X3DImporter.hpp"
50 #include "X3DImporter_Macro.hpp"
51 #include "X3DXmlHelper.h"
52 #include <assimp/StringUtils.h>
53
54 namespace Assimp {
55
56 // <DirectionalLight
57 // DEF="" ID
58 // USE="" IDREF
59 // ambientIntensity="0" SFFloat [inputOutput]
60 // color="1 1 1" SFColor [inputOutput]
61 // direction="0 0 -1" SFVec3f [inputOutput]
62 // global="false" SFBool [inputOutput]
63 // intensity="1" SFFloat [inputOutput]
64 // on="true" SFBool [inputOutput]
65 // />
readDirectionalLight(XmlNode & node)66 void X3DImporter::readDirectionalLight(XmlNode &node) {
67 std::string def, use;
68 float ambientIntensity = 0;
69 aiColor3D color(1, 1, 1);
70 aiVector3D direction(0, 0, -1);
71 bool global = false;
72 float intensity = 1;
73 bool on = true;
74 X3DNodeElementBase *ne(nullptr);
75
76 MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use);
77 XmlParser::getFloatAttribute(node, "ambientIntensity", ambientIntensity);
78 X3DXmlHelper::getColor3DAttribute(node, "color", color);
79 X3DXmlHelper::getVector3DAttribute(node, "direction", direction);
80 XmlParser::getBoolAttribute(node, "global", global);
81 XmlParser::getFloatAttribute(node, "intensity", intensity);
82 XmlParser::getBoolAttribute(node, "on", on);
83
84 // if "USE" defined then find already defined element.
85 if (!use.empty()) {
86 ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_DirectionalLight, ne);
87 } else {
88 if (on) {
89 // create and if needed - define new geometry object.
90 ne = new X3DNodeElementLight(X3DElemType::ENET_DirectionalLight, mNodeElementCur);
91 if (!def.empty())
92 ne->ID = def;
93 else
94 ne->ID = "DirectionalLight_" + ai_to_string((size_t)ne); // make random name
95
96 ((X3DNodeElementLight *)ne)->AmbientIntensity = ambientIntensity;
97 ((X3DNodeElementLight *)ne)->Color = color;
98 ((X3DNodeElementLight *)ne)->Direction = direction;
99 ((X3DNodeElementLight *)ne)->Global = global;
100 ((X3DNodeElementLight *)ne)->Intensity = intensity;
101 // Assimp want a node with name similar to a light. "Why? I don't no." )
102 ParseHelper_Group_Begin(false);
103
104 mNodeElementCur->ID = ne->ID; // assign name to node and return to light element.
105 ParseHelper_Node_Exit();
106 // check for child nodes
107 if (!isNodeEmpty(node))
108 childrenReadMetadata(node, ne, "DirectionalLight");
109 else
110 mNodeElementCur->Children.push_back(ne); // add made object as child to current element
111
112 NodeElement_List.push_back(ne); // add element to node element list because its a new object in graph
113 } // if(on)
114 } // if(!use.empty()) else
115 }
116
117 // <PointLight
118 // DEF="" ID
119 // USE="" IDREF
120 // ambientIntensity="0" SFFloat [inputOutput]
121 // attenuation="1 0 0" SFVec3f [inputOutput]
122 // color="1 1 1" SFColor [inputOutput]
123 // global="true" SFBool [inputOutput]
124 // intensity="1" SFFloat [inputOutput]
125 // location="0 0 0" SFVec3f [inputOutput]
126 // on="true" SFBool [inputOutput]
127 // radius="100" SFFloat [inputOutput]
128 // />
readPointLight(XmlNode & node)129 void X3DImporter::readPointLight(XmlNode &node) {
130 std::string def, use;
131 float ambientIntensity = 0;
132 aiVector3D attenuation(1, 0, 0);
133 aiColor3D color(1, 1, 1);
134 bool global = true;
135 float intensity = 1;
136 aiVector3D location(0, 0, 0);
137 bool on = true;
138 float radius = 100;
139 X3DNodeElementBase *ne(nullptr);
140
141 MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use);
142 XmlParser::getFloatAttribute(node, "ambientIntensity", ambientIntensity);
143 X3DXmlHelper::getVector3DAttribute(node, "attenuation", attenuation);
144 X3DXmlHelper::getColor3DAttribute(node, "color", color);
145 XmlParser::getBoolAttribute(node, "global", global);
146 XmlParser::getFloatAttribute(node, "intensity", intensity);
147 X3DXmlHelper::getVector3DAttribute(node, "location", location);
148 XmlParser::getBoolAttribute(node, "on", on);
149 XmlParser::getFloatAttribute(node, "radius", radius);
150
151 // if "USE" defined then find already defined element.
152 if (!use.empty()) {
153 ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_PointLight, ne);
154 } else {
155 if (on) {
156 // create and if needed - define new geometry object.
157 ne = new X3DNodeElementLight(X3DElemType::ENET_PointLight, mNodeElementCur);
158 if (!def.empty()) ne->ID = def;
159
160 ((X3DNodeElementLight *)ne)->AmbientIntensity = ambientIntensity;
161 ((X3DNodeElementLight *)ne)->Attenuation = attenuation;
162 ((X3DNodeElementLight *)ne)->Color = color;
163 ((X3DNodeElementLight *)ne)->Global = global;
164 ((X3DNodeElementLight *)ne)->Intensity = intensity;
165 ((X3DNodeElementLight *)ne)->Location = location;
166 ((X3DNodeElementLight *)ne)->Radius = radius;
167 // Assimp want a node with name similar to a light. "Why? I don't no." )
168 ParseHelper_Group_Begin(false);
169 // make random name
170 if (ne->ID.empty()) ne->ID = "PointLight_" + ai_to_string((size_t)ne);
171
172 mNodeElementCur->ID = ne->ID; // assign name to node and return to light element.
173 ParseHelper_Node_Exit();
174 // check for child nodes
175 if (!isNodeEmpty(node))
176 childrenReadMetadata(node, ne, "PointLight");
177 else
178 mNodeElementCur->Children.push_back(ne); // add made object as child to current element
179
180 NodeElement_List.push_back(ne); // add element to node element list because its a new object in graph
181 } // if(on)
182 } // if(!use.empty()) else
183 }
184
185 // <SpotLight
186 // DEF="" ID
187 // USE="" IDREF
188 // ambientIntensity="0" SFFloat [inputOutput]
189 // attenuation="1 0 0" SFVec3f [inputOutput]
190 // beamWidth="0.7854" SFFloat [inputOutput]
191 // color="1 1 1" SFColor [inputOutput]
192 // cutOffAngle="1.570796" SFFloat [inputOutput]
193 // direction="0 0 -1" SFVec3f [inputOutput]
194 // global="true" SFBool [inputOutput]
195 // intensity="1" SFFloat [inputOutput]
196 // location="0 0 0" SFVec3f [inputOutput]
197 // on="true" SFBool [inputOutput]
198 // radius="100" SFFloat [inputOutput]
199 // />
readSpotLight(XmlNode & node)200 void X3DImporter::readSpotLight(XmlNode &node) {
201 std::string def, use;
202 float ambientIntensity = 0;
203 aiVector3D attenuation(1, 0, 0);
204 float beamWidth = 0.7854f;
205 aiColor3D color(1, 1, 1);
206 float cutOffAngle = 1.570796f;
207 aiVector3D direction(0, 0, -1);
208 bool global = true;
209 float intensity = 1;
210 aiVector3D location(0, 0, 0);
211 bool on = true;
212 float radius = 100;
213 X3DNodeElementBase *ne(nullptr);
214
215 MACRO_ATTRREAD_CHECKUSEDEF_RET(node, def, use);
216 XmlParser::getFloatAttribute(node, "ambientIntensity", ambientIntensity);
217 X3DXmlHelper::getVector3DAttribute(node, "attenuation", attenuation);
218 XmlParser::getFloatAttribute(node, "beamWidth", beamWidth);
219 X3DXmlHelper::getColor3DAttribute(node, "color", color);
220 XmlParser::getFloatAttribute(node, "cutOffAngle", cutOffAngle);
221 X3DXmlHelper::getVector3DAttribute(node, "direction", direction);
222 XmlParser::getBoolAttribute(node, "global", global);
223 XmlParser::getFloatAttribute(node, "intensity", intensity);
224 X3DXmlHelper::getVector3DAttribute(node, "location", location);
225 XmlParser::getBoolAttribute(node, "on", on);
226 XmlParser::getFloatAttribute(node, "radius", radius);
227
228 // if "USE" defined then find already defined element.
229 if (!use.empty()) {
230 ne = MACRO_USE_CHECKANDAPPLY(node, def, use, ENET_SpotLight, ne);
231 } else {
232 if (on) {
233 // create and if needed - define new geometry object.
234 ne = new X3DNodeElementLight(X3DElemType::ENET_SpotLight, mNodeElementCur);
235 if (!def.empty()) ne->ID = def;
236
237 if (beamWidth > cutOffAngle) beamWidth = cutOffAngle;
238
239 ((X3DNodeElementLight *)ne)->AmbientIntensity = ambientIntensity;
240 ((X3DNodeElementLight *)ne)->Attenuation = attenuation;
241 ((X3DNodeElementLight *)ne)->BeamWidth = beamWidth;
242 ((X3DNodeElementLight *)ne)->Color = color;
243 ((X3DNodeElementLight *)ne)->CutOffAngle = cutOffAngle;
244 ((X3DNodeElementLight *)ne)->Direction = direction;
245 ((X3DNodeElementLight *)ne)->Global = global;
246 ((X3DNodeElementLight *)ne)->Intensity = intensity;
247 ((X3DNodeElementLight *)ne)->Location = location;
248 ((X3DNodeElementLight *)ne)->Radius = radius;
249
250 // Assimp want a node with name similar to a light. "Why? I don't no." )
251 ParseHelper_Group_Begin(false);
252 // make random name
253 if (ne->ID.empty()) ne->ID = "SpotLight_" + ai_to_string((size_t)ne);
254
255 mNodeElementCur->ID = ne->ID; // assign name to node and return to light element.
256 ParseHelper_Node_Exit();
257 // check for child nodes
258 if (!isNodeEmpty(node))
259 childrenReadMetadata(node, ne, "SpotLight");
260 else
261 mNodeElementCur->Children.push_back(ne); // add made object as child to current element
262
263 NodeElement_List.push_back(ne); // add element to node element list because its a new object in graph
264 } // if(on)
265 } // if(!use.empty()) else
266 }
267
268 } // namespace Assimp
269
270 #endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
271