1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
/******************************************************************/
/* This file is part of the homework assignments for CSCI-427/527 */
/* at The College of William & Mary and authored by Pieter Peers. */
/* No part of this file, whether altered or in original form, can */
/* be distributed or used outside the context of CSCI-427/527 */
/* without consent of either the College of William & Mary or */
/* Pieter Peers. */
/******************************************************************/
#include <cassert>
#include "errorMessage.h"
#include "random_number.h"
#include "sceneIO_core.h"
#include "sceneIO_basis.h"
#include "sceneIO_light.h"
#include "sceneIO_texture.h"
#include "sceneIO_material.h"
#include "sceneIO_geometry.h"
#include "spotLightsource.h"
#include "areaLightsource.h"
#include "pointLightsource.h"
#include "directionalLightsource.h"
#include "lightsourceGeometry.h"
static std::shared_ptr<const lightsource_base> importDirectionalLight(const XMLNode& node)
{
// get properties
vec3d direction = getVec3d(node, "direction", vec3d(0.0f, 0.0f, 1.0f));
color power = getColor(node, "power", color(1.0f, 1.0f, 1.0f));
// Done.
return std::shared_ptr<const lightsource_base>( new directionalLightsource( direction, power));
}
static std::shared_ptr<const lightsource_base> importPointLight(const XMLNode& node)
{
// get properties
vec3d position = getVec3d(node, "position", vec3d(0.0f, 0.0f, 0.0f));
color power = getColor(node, "power", color(1.0f, 1.0f, 1.0f));
vec3d attenuation = getVec3d(node, "attenuation", vec3d(0.0f, 0.0f, 1.0f));
// Done
return std::shared_ptr<const lightsource_base>( new pointLightsource(position, power, attenuation));
}
static std::shared_ptr<const lightsource_base> importSpotLight(const XMLNode& node)
{
// Get properties
vec3d position = getVec3d(node, "position", vec3d(0.0f, 0.0f, 0.0f));
vec3d direction = getVec3d(node, "direction", vec3d(0.0f, 0.0f, 1.0f));
float cutoff = getFloat(node, "cutoff", 30.0f);
float sharpness = getFloat(node, "sharpness", 1.0f);
color power = getColor(node, "power", color(1.0f, 1.0f, 1.0f));
vec3d attenuation = getVec3d(node, "attenuation", vec3d(0.0f, 0.0f, 1.0f));
// Done.
return std::shared_ptr<const lightsource_base>(new spotLightsource( position, direction, cutoff, sharpness, power, attenuation ));
}
static std::shared_ptr<const lightsource_base> importAreaLight(const XMLNode& node, nodeCache<boundedPrimitive>& shape_cache, nodeCache<shader_base>& shader_cache, nodeCache<texture_base>& texture_cache, const std::string& rootDir)
{
// get properties
color power = getColor(node, "power", color(1.0f, 1.0f, 1.0f));
vec3d attenuation = getVec3d(node, "attenuation", vec3d(0.0f, 0.0f, 1.0f));
// node properties
std::shared_ptr<const shader_base> reflectanceMaterial;
std::shared_ptr<const boundedPrimitive> geometry;
// get children
for(XMLNode child = node.firstChild(); child.isValid(); child++)
{
std::string name = child.name();
// general child nodes
auto tempMat = importMaterial(child, shader_cache, texture_cache, rootDir);
auto tempGeom = importGeometry(child, shape_cache, shader_cache, texture_cache, rootDir);
// specific child nodes
if(tempMat) reflectanceMaterial = tempMat;
else if(tempGeom) geometry = tempGeom;
else errorMessage("Unknown child-node in areaLightsource (%s).", name.c_str());
}
// produce warning if shader defined on the geometry
if(geometry && geometry->hasShader() && !reflectanceMaterial)
warningMessage("Any shader defined on the geometry are ignored in AreaLightsource. Define a reflectance material explicitely in AreaLightsource instead.");
// Create
// 1) light source
// 2) light source geometry
std::shared_ptr<const lightsource_base> ls( new areaLightsource(power, geometry, attenuation) );
std::shared_ptr<boundedPrimitive> lsShape( new lightsourceGeometry(geometry, ls, reflectanceMaterial) );
// Add lsShape to shape_cache
char id[32]; sprintf(id, "lightgeometry-%u", random_int());
shape_cache.add(std::string(id), lsShape);
// Done.
return ls;
}
std::shared_ptr<const lightsource_base> importLight(const XMLNode& node, nodeCache<boundedPrimitive>& shape_cache, nodeCache<shader_base>& shader_cache, nodeCache<texture_base>& texture_cache, const std::string& rootDir)
{
// sanity check
assert(node.name() == "light");
// get light source type
std::string type = getString(node, "type", "directional");
// create light source
std::shared_ptr<const lightsource_base> ls;
if(type == "directional") ls = importDirectionalLight(node);
else if(type == "point") ls = importPointLight(node);
else if(type == "spot") ls = importSpotLight(node);
else if(type == "area") ls = importAreaLight(node, shape_cache, shader_cache, texture_cache, rootDir);
else errorMessage("Unknown light source type (%s)", type.c_str());
// Done.
return ls;
}
|