1 /** @file material.cpp Material definition accessor.
2 *
3 * @authors Copyright © 2015 Daniel Swanson <danij@dengine.net>
4 *
5 * @par License
6 * GPL: http://www.gnu.org/licenses/gpl.html
7 *
8 * <small>This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. This program is distributed in the hope that it
12 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14 * Public License for more details. You should have received a copy of the GNU
15 * General Public License along with this program; if not, see:
16 * http://www.gnu.org/licenses</small>
17 */
18
19 #include "doomsday/defs/material.h"
20 #include "doomsday/defs/ded.h"
21
22 #include <de/Record>
23 #include <de/RecordValue>
24
25 using namespace de;
26
27 namespace defn {
28
resetToDefaults()29 void MaterialDecoration::resetToDefaults()
30 {
31 Definition::resetToDefaults();
32
33 // Add all expected fields with their default values.
34 def().addArray("patternOffset", new ArrayValue(Vector2i()));
35 def().addArray("patternSkip", new ArrayValue(Vector2i()));
36 def().addArray("stage", new ArrayValue);
37 }
38
addStage()39 Record &MaterialDecoration::addStage()
40 {
41 auto *stage = new Record;
42
43 stage->addNumber("tics", 0);
44 stage->addNumber("variance", 0); // Time.
45 stage->addArray ("origin", new ArrayValue(Vector2f())); // Surface-relative offset.
46 stage->addNumber("elevation", 1); // Distance from the surface.
47 stage->addArray ("color", new ArrayValue(Vector3f())); // Light color. (0,0,0) means not visible during this stage.
48 stage->addNumber("radius", 1); // Dynamic light radius (-1 = no light).
49 stage->addArray ("lightLevels", new ArrayValue(Vector2f())); // Fade by sector lightlevel.
50
51 stage->addText ("lightmapUp", ""); // Uri. None.
52 stage->addText ("lightmapDown", ""); // Uri. None.
53 stage->addText ("lightmapSide", ""); // Uri. None.
54
55 stage->addNumber("haloRadius", 0); // Halo radius (zero = no halo).
56 stage->addText ("haloTexture", ""); // Uri. None.
57 stage->addNumber("haloTextureIndex", 0); // Overrides haloTexture
58
59 def()["stage"].array().add(new RecordValue(stage, RecordValue::OwnsRecord));
60
61 return *stage;
62 }
63
stageCount() const64 int MaterialDecoration::stageCount() const
65 {
66 return int(geta("stage").size());
67 }
68
hasStage(int index) const69 bool MaterialDecoration::hasStage(int index) const
70 {
71 return index >= 0 && index < stageCount();
72 }
73
stage(int index)74 Record &MaterialDecoration::stage(int index)
75 {
76 return *def().geta("stage")[index].as<RecordValue>().record();
77 }
78
stage(int index) const79 Record const &MaterialDecoration::stage(int index) const
80 {
81 return *geta("stage")[index].as<RecordValue>().record();
82 }
83
84 // ------------------------------------------------------------------------------------
85
resetToDefaults()86 void MaterialLayer::resetToDefaults()
87 {
88 Definition::resetToDefaults();
89
90 // Add all expected fields with their default values.
91 def().addArray("stage", new ArrayValue);
92 }
93
addStage()94 Record &MaterialLayer::addStage()
95 {
96 auto *stage = new Record;
97
98 stage->addText ("texture", ""); // Uri. None.
99 stage->addNumber("tics", 0);
100 stage->addNumber("variance", 0); // Time.
101 stage->addNumber("glowStrength", 0);
102 stage->addNumber("glowStrengthVariance", 0);
103 stage->addArray ("texOrigin", new ArrayValue(Vector2f()));
104
105 def()["stage"].array().add(new RecordValue(stage, RecordValue::OwnsRecord));
106
107 return *stage;
108 }
109
stageCount() const110 int MaterialLayer::stageCount() const
111 {
112 return int(geta("stage").size());
113 }
114
hasStage(int index) const115 bool MaterialLayer::hasStage(int index) const
116 {
117 return index >= 0 && index < stageCount();
118 }
119
stage(int index)120 Record &MaterialLayer::stage(int index)
121 {
122 return *def().geta("stage")[index].as<RecordValue>().record();
123 }
124
stage(int index) const125 Record const &MaterialLayer::stage(int index) const
126 {
127 return *geta("stage")[index].as<RecordValue>().record();
128 }
129
130 // ------------------------------------------------------------------------------------
131
resetToDefaults()132 void Material::resetToDefaults()
133 {
134 Definition::resetToDefaults();
135
136 // Add all expected fields with their default values.
137 def().addText (VAR_ID, ""); // URI. Unknown.
138 def().addBoolean("autoGenerated", false);
139 def().addNumber ("flags", 0);
140 def().addArray ("dimensions", new ArrayValue(Vector2i()));
141 def().addArray ("decoration", new ArrayValue);
142 def().addArray ("layer", new ArrayValue);
143 }
144
addDecoration()145 Record &Material::addDecoration()
146 {
147 auto *decor = new Record;
148 MaterialDecoration(*decor).resetToDefaults();
149 def()["decoration"].array().add(new RecordValue(decor, RecordValue::OwnsRecord));
150 return *decor;
151 }
152
decorationCount() const153 int Material::decorationCount() const
154 {
155 return int(geta("decoration").size());
156 }
157
hasDecoration(int index) const158 bool Material::hasDecoration(int index) const
159 {
160 return index >= 0 && index < decorationCount();
161 }
162
decoration(int index)163 Record &Material::decoration(int index)
164 {
165 return *def().geta("decoration")[index].as<RecordValue>().record();
166 }
167
decoration(int index) const168 Record const &Material::decoration(int index) const
169 {
170 return *geta("decoration")[index].as<RecordValue>().record();
171 }
172
addLayer()173 Record &Material::addLayer()
174 {
175 auto *layer = new Record;
176 MaterialLayer(*layer).resetToDefaults();
177 def()["layer"].array().add(new RecordValue(layer, RecordValue::OwnsRecord));
178 return *layer;
179 }
180
layerCount() const181 int Material::layerCount() const
182 {
183 return int(geta("layer").size());
184 }
185
hasLayer(int index) const186 bool Material::hasLayer(int index) const
187 {
188 return index >= 0 && index < layerCount();
189 }
190
layer(int index)191 Record &Material::layer(int index)
192 {
193 return *def().geta("layer")[index].as<RecordValue>().record();
194 }
195
layer(int index) const196 Record const &Material::layer(int index) const
197 {
198 return *geta("layer")[index].as<RecordValue>().record();
199 }
200
201 } // namespace defn
202