1 | /* |
2 | Open Asset Import Library (assimp) |
3 | ---------------------------------------------------------------------- |
4 | |
5 | Copyright (c) 2006-2017, assimp team |
6 | |
7 | All rights reserved. |
8 | |
9 | Redistribution and use of this software in source and binary forms, |
10 | with or without modification, are permitted provided that the |
11 | following conditions are met: |
12 | |
13 | * Redistributions of source code must retain the above |
14 | copyright notice, this list of conditions and the |
15 | following disclaimer. |
16 | |
17 | * Redistributions in binary form must reproduce the above |
18 | copyright notice, this list of conditions and the |
19 | following disclaimer in the documentation and/or other |
20 | materials provided with the distribution. |
21 | |
22 | * Neither the name of the assimp team, nor the names of its |
23 | contributors may be used to endorse or promote products |
24 | derived from this software without specific prior |
25 | written permission of the assimp team. |
26 | |
27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
28 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
29 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
30 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
31 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
32 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
33 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
34 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
35 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
36 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
37 | OF 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 | |
52 | namespace 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 | // /> |
64 | void 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 | // /> |
134 | void 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 | // /> |
212 | void 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 | |