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