1 /*
2 * NodeSwitch.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 "NodeSwitch.h"
26 #include "Proto.h"
27 #include "Scene.h"
28 #include "FieldValue.h"
29 #include "MFNode.h"
30 #include "SFInt32.h"
31
ProtoSwitch(Scene * scene)32 ProtoSwitch::ProtoSwitch(Scene *scene)
33 : WonderlandExportProto(scene, "Switch")
34 {
35 bboxCenter.set(
36 addField(SFVEC3F, "bboxCenter", new SFVec3f(0.0f, 0.0f, 0.0f)));
37 setFieldFlags(bboxCenter, FF_X3D_ONLY);
38 bboxSize.set(
39 addField(SFVEC3F, "bboxSize", new SFVec3f(-1.0f, -1.0f, -1.0f),
40 new SFFloat(-1.0f)));
41 setFieldFlags(bboxSize, FF_X3D_ONLY);
42 choice.set(
43 addExposedField(MFNODE, "choice", new MFNode(), CHILD_NODE,
44 "children"));
45 whichChoice.set(
46 addExposedField(SFINT32, "whichChoice", new SFInt32(-1),
47 new SFInt32(-1)));
48
49 render.set(
50 addExposedField(SFBOOL, "render", new SFBool(true)));
51 setFieldFlags(render, FF_X3DOM_ONLY);
52
53 addEventIn(MFNODE, "addChildren", FF_X3D_ONLY);
54 addEventIn(MFNODE, "removeChildren", FF_X3D_ONLY);
55 }
56
57 Node *
create(Scene * scene)58 ProtoSwitch::create(Scene *scene)
59 {
60 return new NodeSwitch(scene, this);
61 }
62
NodeSwitch(Scene * scene,Proto * def)63 NodeSwitch::NodeSwitch(Scene *scene, Proto *def)
64 : Node(scene, def)
65 {
66 }
67
accountWhich()68 int NodeSwitch::accountWhich()
69 {
70 NodeList *choiceList = choice()->getValues();
71
72 int which = whichChoice()->getValue();
73
74 int whichCount = 0;
75 for (long i = 0; i < choiceList->size(); i++)
76 if (choiceList->get(i)->getType() != VRML_COMMENT) {
77 if (whichCount == which)
78 return i;
79 else
80 whichCount++;
81 }
82 return which;
83 }
84
85 void
preDraw()86 NodeSwitch::preDraw()
87 {
88 NodeList *choiceList = choice()->getValues();
89
90 int which = accountWhich();
91
92 if (which < 0 || which >= (int)choiceList->size()) return;
93
94 choiceList->get(which)->preDraw();
95 }
96
97 void
draw(int pass)98 NodeSwitch::draw(int pass)
99 {
100 NodeList *choiceList = choice()->getValues();
101
102 int which = accountWhich();
103
104 if (which < 0 || which >= (int)choiceList->size()) return;
105
106 glPushName(choice_Field());
107 glPushName(which);
108 choiceList->get(which)->draw(pass);
109 glPopName();
110 glPopName();
111 }
112
113 void
flip(int index)114 NodeSwitch::flip(int index)
115 {
116 if (m_scene->isX3d())
117 bboxCenter()->flip(index);
118 choice()->flip(index);
119 }
120
121 void
swap(int fromTo)122 NodeSwitch::swap(int fromTo)
123 {
124 if (m_scene->isX3d()) {
125 bboxCenter()->swap(fromTo);
126 bboxSize()->swap(fromTo);
127 }
128 choice()->swap(fromTo);
129 }
130
131 // writing of file formats, which do not support switch-like constructs:
132 // if a valid choice is selected, write this choice, else write all in choice field
133
134 int
writeAc3d(int filedes,int indent)135 NodeSwitch::writeAc3d(int filedes, int indent)
136 {
137 int which = accountWhich();
138 if (which < 0 || which >= (int)choice()->getValues()->size())
139 return choice()->writeAc3d(filedes, indent);
140 return choice()->getValues()->get(which)->writeAc3d(filedes, indent);
141 }
142
143 int
writeRib(int filedes,int indent)144 NodeSwitch::writeRib(int filedes, int indent)
145 {
146 int which = accountWhich();
147 if (which > -1 && which < (int)choice()->getValues()->size())
148 return choice()->getValues()->get(which)->writeRib(filedes, indent);
149 return 0;
150 }
151
152 int
writeCattGeo(int filedes,int indent)153 NodeSwitch::writeCattGeo(int filedes, int indent)
154 {
155 int which = accountWhich();
156 if (which < 0 || which >= (int)choice()->getValues()->size())
157 return choice()->getValues()->writeCattGeo(this, filedes, indent);
158 NodeList tempNode(choice()->getValue(which));
159 // The following is a dangerous construct.
160 // Works only, cause writeCattGeo gets only things like name, scene etc. from node
161 return tempNode.writeCattGeo(this, filedes, indent);
162 }
163
164