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