1 /*
2 * NodeAppearance.cpp
3 *
4 * Copyright (C) 1999 Stephen F. White
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program (see the file "COPYING" for details); if
18 * not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19 * Cambridge, MA 02139, USA.
20 */
21
22 #include <stdio.h>
23 #include "stdafx.h"
24
25 #include "NodeAppearance.h"
26 #include "Proto.h"
27 #include "FieldValue.h"
28 #include "SFFloat.h"
29 #include "SFNode.h"
30 #include "Node.h"
31 #include "NodeMaterial.h"
32 #include "NodeTwoSidedMaterial.h"
33 #include "Util.h"
34
ProtoAppearance(Scene * scene)35 ProtoAppearance::ProtoAppearance(Scene *scene)
36 : WonderlandExportProto(scene, "Appearance")
37 {
38 addElements();
39 }
40
ProtoAppearance(Scene * scene,const char * name)41 ProtoAppearance::ProtoAppearance(Scene *scene, const char* name)
42 : WonderlandExportProto(scene, name)
43 {
44 addElements();
45 }
46
47 void
addElements(void)48 ProtoAppearance::addElements(void)
49 {
50 material.set(
51 addExposedField(SFNODE, "material", new SFNode(NULL), MATERIAL_NODE));
52
53 texture.set(
54 addExposedField(SFNODE, "texture", new SFNode(NULL), TEXTURE_NODE));
55
56 textureTransform.set(
57 addExposedField(SFNODE, "textureTransform", new SFNode(NULL),
58 TEXTURE_TRANSFORM_NODE));
59
60 fillProperties.set(
61 addExposedField(SFNODE, "fillProperties", new SFNode(NULL),
62 X3D_FILL_PROPERTIES));
63 setFieldFlags(fillProperties, FF_X3D_ONLY);
64
65 lineProperties.set(
66 addExposedField(SFNODE, "lineProperties", new SFNode(NULL),
67 X3D_LINE_PROPERTIES));
68 setFieldFlags(lineProperties, FF_X3D_ONLY);
69
70 pointProperties.set(
71 addExposedField(SFNODE, "pointProperties", new SFNode(NULL),
72 X3D_POINT_PROPERTIES));
73 setFieldFlags(pointProperties, FF_X3D_ONLY);
74
75 shaders.set(
76 addExposedField(MFNODE, "shaders", new MFNode(), SHADER_NODE));
77 setFieldFlags(shaders, FF_X3D_ONLY);
78
79 receiveShadows.set(
80 addField(MFNODE, "receiveShadows", new MFNode(), LIGHT_NODE));
81 setFieldFlags(receiveShadows, FF_KAMBI_ONLY);
82
83 shadowCaster.set(
84 addField(SFBOOL, "shadowCaster", new SFBool(TRUE)));
85 setFieldFlags(shadowCaster, FF_KAMBI_ONLY);
86
87 normalMap.set(
88 addExposedField(SFNODE, "normalMap", new SFNode(NULL), TEXTURE_NODE));
89 setFieldFlags(normalMap, FF_KAMBI_ONLY);
90
91 heightMap.set(
92 addExposedField(SFNODE, "heightMap", new SFNode(NULL), TEXTURE_NODE));
93 setFieldFlags(heightMap, FF_KAMBI_ONLY);
94
95 heightMapScale.set(
96 addExposedField(SFFLOAT, "heightMapScale", new SFFloat(0.01f),
97 new SFFloat(0.0f)));
98 setFieldFlags(heightMapScale, FF_KAMBI_ONLY);
99
100 blendMode.set(
101 addExposedField(SFNODE, "blendMode", new SFNode(), KAMBI_BLEND_MODE));
102 setFieldFlags(blendMode, FF_KAMBI_ONLY | FF_X3DOM_ONLY);
103
104 effects.set(
105 addField(MFNODE, "effects", new MFNode(), KAMBI_EFFECT));
106 setFieldFlags(effects, FF_KAMBI_ONLY);
107
108 if (TheApp->getCoverMode()) {
109 // non standard Covise/COVER extensions
110 texture2.set(
111 addExposedField(SFNODE, "texture2", new SFNode(NULL), TEXTURE_NODE));
112 setFieldFlags(texture2, FF_COVER_ONLY);
113
114 textureTransform2.set(
115 addExposedField(SFNODE, "textureTransform2", new SFNode(NULL),
116 TEXTURE_TRANSFORM_NODE));
117 setFieldFlags(textureTransform2, FF_COVER_ONLY);
118
119 texture3.set(
120 addExposedField(SFNODE, "texture3", new SFNode(NULL), TEXTURE_NODE));
121 setFieldFlags(texture3, FF_COVER_ONLY);
122
123 textureTransform3.set(
124 addExposedField(SFNODE, "textureTransform3", new SFNode(NULL),
125 TEXTURE_TRANSFORM_NODE));
126 setFieldFlags(textureTransform3, FF_COVER_ONLY);
127
128 texture4.set(
129 addExposedField(SFNODE, "texture4", new SFNode(NULL), TEXTURE_NODE));
130 setFieldFlags(texture4, FF_COVER_ONLY);
131
132 textureTransform4.set(
133 addExposedField(SFNODE, "textureTransform4", new SFNode(NULL),
134 TEXTURE_TRANSFORM_NODE));
135 setFieldFlags(textureTransform4, FF_COVER_ONLY);
136 }
137
138 alphaClipThreshold.set(
139 addExposedField(SFFLOAT, "alphaClipThreshold", new SFFloat(1)));
140 setFieldFlags(alphaClipThreshold, FF_X3DOM_ONLY);
141
142 colorMaskMode.set(
143 addExposedField(SFNODE, "colorMaskMode", new SFNode(NULL),
144 X3DOM_COLOR_MASK_MODE));
145 setFieldFlags(colorMaskMode, FF_X3DOM_ONLY);
146
147 depthMode.set(
148 addExposedField(SFNODE, "depthMode", new SFNode(NULL),
149 X3DOM_DEPTH_MODE));
150 setFieldFlags(depthMode, FF_X3DOM_ONLY);
151
152 sortKey.set(
153 addExposedField(SFINT32, "sortKey", new SFInt32(0)));
154 setFieldFlags(sortKey, FF_X3DOM_ONLY);
155
156 sortType.set(
157 addExposedField(SFSTRING, "sortType", new SFString("auto")));
158 setFieldFlags(sortType, FF_X3DOM_ONLY);
159 }
160
161 Node *
create(Scene * scene)162 ProtoAppearance::create(Scene *scene)
163 {
164 return new NodeAppearance(scene, this);
165 }
166
NodeAppearance(Scene * scene,Proto * def)167 NodeAppearance::NodeAppearance(Scene *scene, Proto *def)
168 : Node(scene, def)
169 {
170 }
171
bind()172 void NodeAppearance::bind()
173 {
174 if (material() == NULL)
175 return;
176 if (texture() == NULL)
177 return;
178 if (textureTransform() == NULL)
179 return;
180
181 Node *nMaterial = ((SFNode *) getField(material_Field()))->getValue();
182 Node *nTexture = ((SFNode *) getField(texture_Field()))->getValue();
183 Node *nTextureTransform = ((SFNode *) getField(textureTransform_Field()))
184 ->getValue();
185 float ftransparency = 0.0f;
186 float fBackTransparency = 0.0f;
187
188 while (nMaterial && (nMaterial->getType() == VRML_MATERIAL) &&
189 nMaterial->isPROTO())
190 nMaterial = ((NodePROTO *)nMaterial)->getProtoNode(0);
191 if (nMaterial && (nMaterial->getType() == VRML_MATERIAL) &&
192 ((NodeMaterial *)nMaterial)->transparency()) {
193 nMaterial->bind();
194 ftransparency = ((NodeMaterial *)
195 nMaterial)->transparency()->getValue();
196 fBackTransparency = ftransparency;
197 }
198 if (nMaterial && (nMaterial->getType() == X3D_TWO_SIDED_MATERIAL)) {
199 nMaterial->bind();
200 ftransparency = ((NodeTwoSidedMaterial *)
201 nMaterial)->transparency()->getValue();
202 if (((NodeTwoSidedMaterial *)
203 nMaterial)->separateBackColor()->getValue())
204 fBackTransparency = ((NodeTwoSidedMaterial *)
205 nMaterial)->backTransparency()->getValue();
206 else
207 fBackTransparency = ftransparency;
208 }
209 if (nTexture) {
210 nTexture->bind();
211 if ((nTexture->textureGlColorMode() == GL_RGBA) ||
212 (nTexture->textureGlColorMode() == GL_LUMINANCE_ALPHA)) {
213 ftransparency = 0;
214 fBackTransparency = 0;
215 }
216 float dc[4];
217 dc[0] = dc[1] = dc[2] = 1.0f; dc[3] = 1.0f - ftransparency;
218 Util::myGlMaterialfv(GL_FRONT, GL_DIFFUSE, dc);
219 float bdc[4];
220 bdc[0] = bdc[1] = bdc[2] = 1.0f; bdc[3] = 1.0f - fBackTransparency;
221 Util::myGlMaterialfv(GL_BACK, GL_DIFFUSE, bdc);
222 }
223 if (nTextureTransform) nTextureTransform->bind();
224 }
225
unbind()226 void NodeAppearance::unbind()
227 {
228 if (material() == NULL)
229 return;
230 if (texture() == NULL)
231 return;
232 if (textureTransform() == NULL)
233 return;
234
235 Node *nMaterial = ((SFNode *) getField(material_Field()))->getValue();
236 Node *nTexture = ((SFNode *) getField(texture_Field()))->getValue();
237 Node *nTextureTransform = ((SFNode *) getField(textureTransform_Field()))
238 ->getValue();
239
240 if (nMaterial) nMaterial->unbind();
241 if (nTexture) nTexture->unbind();
242 if (nTextureTransform) nTextureTransform->unbind();
243 }
244
isTransparent(void)245 bool NodeAppearance::isTransparent(void)
246 {
247 if (getField(material_Field())) {
248 Node *nMaterial = ((SFNode *) getField(material_Field()))->getValue();
249 if (nMaterial)
250 if (nMaterial->isTransparent())
251 return true;
252 }
253
254 if (getField(texture_Field())) {
255 Node *nTexture = ((SFNode *) getField(texture_Field()))->getValue();
256 if (nTexture)
257 return nTexture->isTransparent();
258 }
259 return false;
260 }
261
getTransparency(void)262 float NodeAppearance::getTransparency(void)
263 {
264 float ret = 0;
265 if (material()) {
266 Node *nMaterial = material()->getValue();
267 if (nMaterial)
268 ret = nMaterial->getTransparency();
269 }
270 return ret;
271 }
272
getProfile(void) const273 int NodeAppearance::getProfile(void) const
274 {
275 // if (!isDefault(fillProperties_Field()))
276 // return PROFILE_FULL;
277 if (!isDefault(textureTransform_Field()))
278 return PROFILE_IMMERSIVE;
279 // if (!isDefault(lineProperties_Field()))
280 // return PROFILE_IMMERSIVE;
281 return PROFILE_INTERCHANGE;
282 }
283
284
285