1 |
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.0//EN" "https://www.web3d.org/specifications/x3d-3.0.dtd">
|
3 | <X3D profile='Immersive' version='3.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-3.0.xsd'> |
4 | <head> |
5 | <meta name='title' content=' SimpleBuildingConstructionPrototypes.x3d '/> |
6 | <meta name='creator' content='Don Brutzman'/> |
7 | <meta name='created' content='17 October 2001'/> |
8 | <meta name='modified' content='20 October 2019'/> |
9 | <meta name='description' content='Prototypes for simple building construction: Floor, Wall, Level and Building.'/> |
10 | <meta name='identifier' content=' https://www.web3d.org/x3d/content/examples/Savage/Buildings/UHRB/SimpleBuildingConstructionPrototypes.x3d '/> |
11 | <meta name='generator' content='X3D-Edit 3.2, https://www.web3d.org/x3d/tools/X3D-Edit'/> |
12 | <meta name='license' content='../../license.html'/> |
13 | </head> |
14 | <Scene> |
15 | <WorldInfo title='SimpleBuildingConstructionPrototypes.x3d'/> |
16 | <ProtoDeclare name='Floor' appinfo='Each Floor cantains the current floor surface plus a ceiling surface for the floor immediately underneath. A Floor does not include exterior or interior wall polygons.'> |
17 | <ProtoInterface> |
18 |
<field name='name' type='SFString' accessType='initializeOnly'
appinfo='Identifying name for this Floor.'/> |
19 |
<field name='description' type='MFString' accessType='initializeOnly'
appinfo='Description info for this construction.'/> |
20 |
<field name='size' type='SFNode' accessType='initializeOnly'
appinfo='single-value Coordinate node with dimension x=width y=height z=depth in meters'> |
21 | <Coordinate/> |
22 | </field> |
23 |
<field name='floorAppearance' type='SFNode' accessType='initializeOnly'
appinfo='Appearance node with Material colors ImageTexture etc. for this construction.'> |
24 | <Appearance DEF='DefaultFloorAppearance'> |
25 | <Material diffuseColor='0.2 0.2 0.2'/> |
26 | </Appearance> |
27 | </field> |
28 |
<field name='ceilingAppearance' type='SFNode' accessType='initializeOnly'
appinfo='Appearance node with Material colors ImageTexture etc. for this construction.'> |
29 | <Appearance DEF='DefaultCeilingAppearance'> |
30 | <Material/> |
31 | </Appearance> |
32 | </field> |
33 |
<field name='showSides' type='SFBool' value='false' accessType='initializeOnly'
appinfo='Whether sides are visible.'/> |
34 |
<field name='width' type='SFFloat' accessType='outputOnly'
appinfo='width of front side of floor aligned with local X axis.'/> |
35 |
<field name='height' type='SFFloat' accessType='outputOnly'
appinfo='height of vertical distance between floor and ceiling directly underneath aligned with local Y axis.'/> |
36 |
<field name='depth' type='SFFloat' accessType='outputOnly'
appinfo='depth of horizontal side of floor aligned with local -Z axis.'/> |
37 |
<field name='built' type='SFBool' accessType='outputOnly'
appinfo='Indicate whether initialization complete.'/> |
38 | </ProtoInterface> |
39 | <ProtoBody> |
40 | <Group DEF='FloorRoot'> |
41 | <Transform DEF='LowerLeftOutsideCornerLocation'> |
42 | <Shape DEF='Floor'> |
43 | <IS> |
44 | <connect nodeField='appearance' protoField='floorAppearance'/> |
45 | </IS> |
46 | <IndexedFaceSet coordIndex='0 1 2 3 0 -1'> |
47 |
<!-- Coordinate
FloorCoordinate is a DEF node that has 2 USE nodes: USE_1, USE_2
<!-- ROUTE information for FloorCoordinate node: [from FloorConstructionScript.floorPoints to point ] --> <Coordinate DEF='FloorCoordinate'/> |
48 | </IndexedFaceSet> |
49 | </Shape> |
50 | <Shape DEF='Ceiling'> |
51 | <IS> |
52 | <connect nodeField='appearance' protoField='ceilingAppearance'/> |
53 | </IS> |
54 | <IndexedFaceSet coordIndex='4 7 6 5 4 -1'> |
55 | <Coordinate USE='FloorCoordinate'/> |
56 | </IndexedFaceSet> |
57 | </Shape> |
58 |
<!-- ROUTE information for FloorSidesSwitch node:
[from FloorConstructionScript.wallsVisible to whichChoice
]
-->
<Switch DEF='FloorSidesSwitch' whichChoice='-1'> |
59 | <Shape DEF='FloorSides'> |
60 | <IS> |
61 | <connect nodeField='appearance' protoField='floorAppearance'/> |
62 | </IS> |
63 | <IndexedFaceSet solid='false' coordIndex='0 3 7 4 -1 3 2 6 7 -1 1 5 6 2 -1 0 4 5 1 -1'> |
64 | <Coordinate USE='FloorCoordinate'/> |
65 | </IndexedFaceSet> |
66 | </Shape> |
67 | </Switch> |
68 | </Transform> |
69 |
<!-- ROUTE information for FloorConstructionScript node:
[from floorPoints to FloorCoordinate.point
]
[from wallsVisible to FloorSidesSwitch.whichChoice
]
-->
<Script DEF='FloorConstructionScript' directOutput='true'> |
70 | <field name='name' type='SFString' accessType='initializeOnly'/> |
71 | <field name='description' type='MFString' accessType='initializeOnly'/> |
72 | <field name='size' type='SFNode' accessType='initializeOnly'/> |
73 | <field name='showSides' type='SFBool' accessType='initializeOnly'/> |
74 | <field name='wallsVisible' type='SFInt32' accessType='outputOnly'/> |
75 | <field name='floorPoints' type='MFVec3f' accessType='outputOnly'/> |
76 | <field name='width' type='SFFloat' accessType='outputOnly'/> |
77 | <field name='height' type='SFFloat' accessType='outputOnly'/> |
78 | <field name='depth' type='SFFloat' accessType='outputOnly'/> |
79 | <field name='traceEnabled' type='SFBool' value='true' accessType='initializeOnly'/> |
80 | <field name='built' type='SFBool' accessType='outputOnly'/> |
81 | <IS> |
82 | <connect nodeField='name' protoField='name'/> |
83 | <connect nodeField='description' protoField='description'/> |
84 | <connect nodeField='size' protoField='size'/> |
85 | <connect nodeField='showSides' protoField='showSides'/> |
86 | <connect nodeField='width' protoField='width'/> |
87 | <connect nodeField='height' protoField='height'/> |
88 | <connect nodeField='depth' protoField='depth'/> |
89 | <connect nodeField='built' protoField='built'/> |
90 | </IS> |
<![CDATA[
ecmascript: function tracePrint (outputString) { if (traceEnabled) Browser.println ('[Floor' + name + ']' + outputString); } function alwaysPrint (outputString) { Browser.println ('[Floor' + name + ']' + outputString); } function initialize () { built = false; tracePrint ('description=' + description); tracePrint ('showSides=' + showSides); if (showSides == true) wallsVisible = 0; // goes to Switch whichChoice tracePrint ('wallsVisible=' + wallsVisible); if ((size.point.length == 0) || (size.point.length > 1)) alwaysPrint ('** warning, size.point.length =' + size.point.length + ' rather than 1'); width = size.point[0].x; height = size.point[0].y; depth = size.point[0].z; tracePrint ('(width, height, depth)=(' + width + ',' + height + ',' + depth + ')'); // floor is immediately above ceiling floorPoints = new MFVec3f ( new SFVec3f (0, 0, 0), new SFVec3f (width, 0, 0), new SFVec3f (width, 0, -depth), new SFVec3f (0, 0, -depth), new SFVec3f (0, -height, 0), new SFVec3f (width, -height, 0), new SFVec3f (width, -height, -depth), new SFVec3f (0, -height, -depth)); tracePrint ('floorPoints=' + floorPoints); built = true; tracePrint ('built=' + built); }
]]>
|
|
92 | </Script> |
93 | < ROUTE fromNode='FloorConstructionScript' fromField='floorPoints' toNode='FloorCoordinate' toField='point'/> |
94 | < ROUTE fromNode='FloorConstructionScript' fromField='wallsVisible' toNode='FloorSidesSwitch' toField='whichChoice'/> |
95 | </Group> |
96 | </ProtoBody> |
97 | </ProtoDeclare> |
98 | <ProtoDeclare name='Wall' appinfo='Each Wall contains exterior and interior walls.'> |
99 | <ProtoInterface> |
100 |
<field name='name' type='SFString' accessType='initializeOnly'
appinfo='Identifying name for this Wall.'/> |
101 |
<field name='description' type='MFString' accessType='initializeOnly'
appinfo='Description info for this construction.'/> |
102 |
<field name='size' type='SFNode' accessType='initializeOnly'
appinfo='single-value Coordinate node with dimension x=width y=height z=depth in meters'> |
103 | <Coordinate point='0 0 0'/> |
104 | </field> |
105 |
<field name='interiorAppearance' type='SFNode' accessType='initializeOnly'
appinfo='Appearance node with Material colors ImageTexture etc. for this construction.'> |
106 | <Appearance DEF='DefaultInteriorAppearance'> |
107 | <Material diffuseColor='0.4 0.4 0.4'/> |
108 | </Appearance> |
109 | </field> |
110 |
<field name='exteriorAppearance' type='SFNode' accessType='initializeOnly'
appinfo='Appearance node with Material colors ImageTexture etc. for this construction.'> |
111 | <Appearance DEF='DefaultExteriorAppearance'> |
112 | <Material diffuseColor='0.6 0.6 0.6'/> |
113 | </Appearance> |
114 | </field> |
115 |
<field name='showSides' type='SFBool' value='false' accessType='initializeOnly'
appinfo='Whether sides are visible.'/> |
116 |
<field name='width' type='SFFloat' accessType='outputOnly'
appinfo='width of horizontal side of wall aligned with local X axis.'/> |
117 |
<field name='height' type='SFFloat' accessType='outputOnly'
appinfo='height of Wall aligned with local Y axis.'/> |
118 |
<field name='depth' type='SFFloat' accessType='outputOnly'
appinfo='depth of horizontal thickness of Wall aligned with local -Z axis.'/> |
119 |
<field name='built' type='SFBool' accessType='outputOnly'
appinfo='Indicate whether initialization complete.'/> |
120 | </ProtoInterface> |
121 | <ProtoBody> |
122 | <Group DEF='WallRoot'> |
123 | <Transform DEF='LowerLeftOutsideCornerLocationWall'> |
124 | <Shape DEF='InteriorWall'> |
125 | <IS> |
126 | <connect nodeField='appearance' protoField='interiorAppearance'/> |
127 | </IS> |
128 | <!-- only draw interior-facing side for efficiency, and also so that view piercing external wall immediately sees interior --> |
129 | <IndexedFaceSet coordIndex='4 7 6 5 4 -1'> |
130 |
<!-- Coordinate
WallCoordinate is a DEF node that has 2 USE nodes: USE_1, USE_2
<!-- ROUTE information for WallCoordinate node: [from WallConstructionScript.coordinatePoints to point ] --> <Coordinate DEF='WallCoordinate'/> |
131 | </IndexedFaceSet> |
132 | </Shape> |
133 | <Shape DEF='ExteriorWall'> |
134 | <IS> |
135 | <connect nodeField='appearance' protoField='exteriorAppearance'/> |
136 | </IS> |
137 | <IndexedFaceSet coordIndex='0 1 2 3 0 -1'> |
138 | <Coordinate USE='WallCoordinate'/> |
139 | </IndexedFaceSet> |
140 | </Shape> |
141 |
<!-- ROUTE information for WallSidesSwitch node:
[from WallConstructionScript.wallsVisible to whichChoice
]
-->
<Switch DEF='WallSidesSwitch' whichChoice='-1'> |
142 | <Shape DEF='WallSides'> |
143 | <IS> |
144 | <connect nodeField='appearance' protoField='exteriorAppearance'/> |
145 | </IS> |
146 | <IndexedFaceSet coordIndex='0 3 7 4 -1 3 2 6 7 -1 1 5 6 2 -1 0 4 5 1 -1'> |
147 | <Coordinate USE='WallCoordinate'/> |
148 | </IndexedFaceSet> |
149 | </Shape> |
150 | </Switch> |
151 | </Transform> |
152 |
<!-- ROUTE information for WallConstructionScript node:
[from coordinatePoints to WallCoordinate.point
]
[from wallsVisible to WallSidesSwitch.whichChoice
]
-->
<Script DEF='WallConstructionScript' directOutput='true'> |
153 | <field name='name' type='SFString' accessType='initializeOnly'/> |
154 | <field name='description' type='MFString' accessType='initializeOnly'/> |
155 | <field name='size' type='SFNode' accessType='initializeOnly'/> |
156 | <field name='showSides' type='SFBool' accessType='initializeOnly'/> |
157 | <field name='wallsVisible' type='SFInt32' accessType='outputOnly'/> |
158 | <field name='coordinatePoints' type='MFVec3f' accessType='outputOnly'/> |
159 | <field name='width' type='SFFloat' accessType='outputOnly'/> |
160 | <field name='height' type='SFFloat' accessType='outputOnly'/> |
161 | <field name='depth' type='SFFloat' accessType='outputOnly'/> |
162 | <field name='traceEnabled' type='SFBool' value='true' accessType='initializeOnly'/> |
163 | <field name='built' type='SFBool' accessType='outputOnly'/> |
164 | <IS> |
165 | <connect nodeField='name' protoField='name'/> |
166 | <connect nodeField='description' protoField='description'/> |
167 | <connect nodeField='size' protoField='size'/> |
168 | <connect nodeField='showSides' protoField='showSides'/> |
169 | <connect nodeField='width' protoField='width'/> |
170 | <connect nodeField='height' protoField='height'/> |
171 | <connect nodeField='depth' protoField='depth'/> |
172 | <connect nodeField='built' protoField='built'/> |
173 | </IS> |
<![CDATA[
ecmascript: function tracePrint (outputString) { if (traceEnabled) Browser.println ('[Wall' + name + ']' + outputString); } function alwaysPrint (outputString) { Browser.println ('[Wall' + name + ']' + outputString); } function initialize () { built = false; tracePrint ('description=' + description); tracePrint ('showSides=' + showSides); if (showSides == true) wallsVisible = 0; // goes to Switch whichChoice tracePrint ('wallsVisible=' + wallsVisible); if ((size.point.length == 0) || (size.point.length > 1)) alwaysPrint ('** warning, size.point.length =' + size.point.length + ' rather than 1'); width = size.point[0].x; height = size.point[0].y; depth = size.point[0].z; tracePrint ('(width, height, depth)=(' + width + ',' + height + ',' + depth + ')'); coordinatePoints = new MFVec3f ( new SFVec3f (0, 0, 0), new SFVec3f (width, 0, 0), new SFVec3f (width, height, 0), new SFVec3f (0, height, 0), new SFVec3f (0, 0, -depth), new SFVec3f (width, 0, -depth), new SFVec3f (width, height, -depth), new SFVec3f (0, height, -depth)); tracePrint ('coordinatePoints=' + coordinatePoints); built = true; tracePrint ('built=' + built); }
]]>
|
|
175 | </Script> |
176 | < ROUTE fromNode='WallConstructionScript' fromField='coordinatePoints' toNode='WallCoordinate' toField='point'/> |
177 | < ROUTE fromNode='WallConstructionScript' fromField='wallsVisible' toNode='WallSidesSwitch' toField='whichChoice'/> |
178 | </Group> |
179 | </ProtoBody> |
180 | </ProtoDeclare> |
181 | <ProtoDeclare name='Level' appinfo='collection of a Floor and four Walls working in order up from lowest level (i.e. story) of the Building'> |
182 | <ProtoInterface> |
183 |
<field name='name' type='SFString' accessType='initializeOnly'
appinfo='Identifying name for this Level.'/> |
184 |
<field name='description' type='MFString' accessType='initializeOnly'
appinfo='Description info for this construction.'/> |
185 |
<field name='floor' type='MFNode' accessType='initializeOnly'
appinfo='contains single Floor node'> |
186 | <Group/> |
187 | </field> |
188 |
<field name='frontWall' type='MFNode' accessType='initializeOnly'
appinfo='contains single front Wall node'> |
189 | <ProtoInstance name='Wall'/> |
190 | </field> |
191 |
<field name='rightWall' type='MFNode' accessType='initializeOnly'
appinfo='contains single right-side Wall node'> |
192 | <ProtoInstance name='Wall'/> |
193 | </field> |
194 |
<field name='rearWall' type='MFNode' accessType='initializeOnly'
appinfo='contains single rear Wall node'> |
195 | <ProtoInstance name='Wall'/> |
196 | </field> |
197 |
<field name='leftWall' type='MFNode' accessType='initializeOnly'
appinfo='contains single left-side Wall node'> |
198 | <ProtoInstance name='Wall'/> |
199 | </field> |
200 |
<field name='width' type='SFFloat' accessType='outputOnly'
appinfo='Calculated width of horizontal side of Level aligned with local X axis.'/> |
201 |
<field name='height' type='SFFloat' accessType='outputOnly'
appinfo='Calculated height of Level aligned with local Y axis.'/> |
202 |
<field name='depth' type='SFFloat' accessType='outputOnly'
appinfo='Calculated depth of horizontal thickness of Level aligned with local -Z axis.'/> |
203 |
<field name='built' type='SFBool' accessType='outputOnly'
appinfo='Indicate whether initialization complete.'/> |
204 | </ProtoInterface> |
205 | <ProtoBody> |
206 | <Group DEF='LevelRoot'> |
207 | <Transform DEF='FloorTransform'> |
208 | <IS> |
209 | <connect nodeField='children' protoField='floor'/> |
210 | </IS> |
211 | </Transform> |
212 | <Transform DEF='FrontWallTransform'> |
213 | <IS> |
214 | <connect nodeField='children' protoField='frontWall'/> |
215 | </IS> |
216 | </Transform> |
217 |
<!-- ROUTE information for RightWallTransform node:
[from LevelConstructionScript.rightTranslation to translation
]
-->
<Transform DEF='RightWallTransform' rotation='0 1 0 1.57079'> |
218 | <IS> |
219 | <connect nodeField='children' protoField='rightWall'/> |
220 | </IS> |
221 | </Transform> |
222 |
<!-- ROUTE information for RearWallTransform node:
[from LevelConstructionScript.rearTranslation to translation
]
-->
<Transform DEF='RearWallTransform' rotation='0 1 0 3.1416'> |
223 | <IS> |
224 | <connect nodeField='children' protoField='rearWall'/> |
225 | </IS> |
226 | </Transform> |
227 |
<!-- ROUTE information for LeftWallTransform node:
[from LevelConstructionScript.leftTranslation to translation
]
-->
<Transform DEF='LeftWallTransform' rotation='0 1 0 4.7124'> |
228 | <IS> |
229 | <connect nodeField='children' protoField='leftWall'/> |
230 | </IS> |
231 | </Transform> |
232 |
<!-- ROUTE information for LevelConstructionScript node:
[from LevelRecalculateUntilBuilt.cycleTime to recheckUntilBuilt
]
[from rightTranslation to RightWallTransform.translation
]
[from rearTranslation to RearWallTransform.translation
]
[from leftTranslation to LeftWallTransform.translation
]
[from built to LevelBuiltFilter.set_boolean
]
-->
<Script DEF='LevelConstructionScript' directOutput='true'> |
233 | <field name='name' type='SFString' accessType='initializeOnly'/> |
234 | <field name='description' type='MFString' accessType='initializeOnly'/> |
235 | <field name='floor' type='MFNode' accessType='initializeOnly'/> |
236 | <field name='frontWall' type='MFNode' accessType='initializeOnly'/> |
237 | <field name='rightWall' type='MFNode' accessType='initializeOnly'/> |
238 | <field name='rearWall' type='MFNode' accessType='initializeOnly'/> |
239 | <field name='leftWall' type='MFNode' accessType='initializeOnly'/> |
240 | <field name='width' type='SFFloat' accessType='outputOnly'/> |
241 | <field name='height' type='SFFloat' accessType='outputOnly'/> |
242 | <field name='depth' type='SFFloat' accessType='outputOnly'/> |
243 | <field name='rightTranslation' type='SFVec3f' accessType='outputOnly'/> |
244 | <field name='rearTranslation' type='SFVec3f' accessType='outputOnly'/> |
245 | <field name='leftTranslation' type='SFVec3f' accessType='outputOnly'/> |
246 | <field name='traceEnabled' type='SFBool' value='true' accessType='initializeOnly'/> |
247 |
<field name='recheckUntilBuilt' type='SFTime' accessType='inputOnly'
appinfo='New floor or wall initialization may be complete check and recalculate until built'/> |
248 | <field name='built' type='SFBool' accessType='outputOnly'/> |
249 | <IS> |
250 | <connect nodeField='name' protoField='name'/> |
251 | <connect nodeField='description' protoField='description'/> |
252 | <connect nodeField='floor' protoField='floor'/> |
253 | <connect nodeField='frontWall' protoField='frontWall'/> |
254 | <connect nodeField='rightWall' protoField='rightWall'/> |
255 | <connect nodeField='rearWall' protoField='rearWall'/> |
256 | <connect nodeField='leftWall' protoField='leftWall'/> |
257 | <connect nodeField='width' protoField='width'/> |
258 | <connect nodeField='height' protoField='height'/> |
259 | <connect nodeField='depth' protoField='depth'/> |
260 | <connect nodeField='built' protoField='built'/> |
261 | </IS> |
<![CDATA[
ecmascript: var firstLoopWhileTrueCompleted; function tracePrint (outputString) { if (traceEnabled) Browser.println ('[Level' + name + ']' + outputString); } function alwaysPrint (outputString) { Browser.println ('[Level' + name + ']' + outputString); } function initialize () { built = false; firstLoopWhileTrueCompleted = false; alwaysPrint ('initialize, built=' + built); } function recheckUntilBuilt (value) { if (built == true) { built = true; // resend to trigger cancellation event for TimeSensor if (firstLoopWhileTrueCompleted) alwaysPrint ('recheckUntilBuilt() continuous built=true indicates internal error'); else firstLoopWhileTrueCompleted = true; return; // done } alwaysPrint ('recheckUntilBuilt testing...'); // following are single nodes, cast as MFNode type for IS/connect matchups if (floor[0].built == false) return; // not yet ready else if (frontWall[0].built == false) return; else if (rightWall[0].built == false) return; else if (rearWall[0].built == false) return; else if (leftWall[0].built == false) return; alwaysPrint ('recheckUntilBuilt ready, initializing Level...'); alwaysPrint ('description=' + description); if (floor) { // tracePrint ('floor found'); if (floor.length > 1) alwaysPrint ('** warning, more than one floor found (' + floor.length + ' nodes total)'); tracePrint ('floor (width, height, depth)=(' + floor[0].width + ',' + floor[0].height + ',' + floor[0].depth + ')'); } else tracePrint ('floor not found'); if (frontWall) { // tracePrint ('frontWall found'); if (frontWall > 1) alwaysPrint ('** warning, more than one frontWall found (' + frontWall.length + ' nodes total)'); tracePrint ('frontWall (width, height, depth)=(' + frontWall[0].width + ',' + frontWall[0].height + ',' + frontWall[0].depth + ')'); } else tracePrint ('frontWall not found'); if (rightWall) { // tracePrint ('rightWall found'); if (rightWall > 1) alwaysPrint ('** warning, more than one rightWall found (' + frontWall.length + ' nodes total)'); tracePrint ('rightWall (width, height, depth)=(' + rightWall[0].width + ',' + rightWall[0].height + ',' + rightWall[0].depth + ')'); } else tracePrint ('rightWall not found'); if (rearWall) { // tracePrint ('rearWall found'); if (frontWall > 1) alwaysPrint ('** warning, more than one rearWall found (' + rearWall + ' nodes total)'); tracePrint ('rearWall (width, height, depth)=(' + rearWall[0].width + ',' + rearWall[0].height + ',' + rearWall[0].depth + ')'); } else tracePrint ('rearWall not found'); if (leftWall) { // tracePrint ('leftWall found'); if (frontWall > 1) alwaysPrint ('** warning, more than one leftWall found (' + leftWall.length + ' nodes total)'); tracePrint ('leftWall (width, height, depth)=(' + leftWall[0].width + ',' + leftWall[0].height + ',' + leftWall[0].depth + ')'); } else tracePrint ('leftWall not found'); if (floor && frontWall) { if ((floor[0].width != frontWall[0].width) && (floor[0].width != 0) && (frontWall[0].width != 0)) alwaysPrint ('** warning, floor/frontWall width mismatch'); } if (floor && rearWall) { if ((floor[0].width != rearWall[0].width) && (floor[0].width != 0) && (rearWall[0].width != 0)) alwaysPrint ('** warning, floor/rearWall width mismatch'); } if (floor && rightWall) { if ((floor[0].depth != rightWall[0].width) && (floor[0].depth != 0) && (rightWall[0].width != 0)) alwaysPrint ('** warning, floor.depth/rightWall.width mismatch'); } if (floor && leftWall) { if ((floor[0].depth != leftWall[0].width) && (floor[0].depth != 0) && (leftWall[0].width != 0)) alwaysPrint ('** warning, floor.depth/leftWall.width mismatch'); } if (frontWall && rearWall) { if ((frontWall[0].width != rearWall[0].width) && (frontWall[0].width != 0) && (rearWall[0].width != 0)) alwaysPrint ('** warning, frontWall/rearWall width mismatch'); } if (leftWall && rightWall) { if ((leftWall[0].width != rightWall[0].width) && (leftWall[0].width != 0) && (rightWall[0].width != 0)) alwaysPrint ('** warning, leftWall/rightWall width mismatch'); } // find first nonzero values width = 0; if (floor) width = floor[0].width; if (frontWall && (width == 0)) width = frontWall[0].width; if (rearWall && (width == 0)) width = rearWall[0].width; height = 0; if (frontWall) height = frontWall[0].height; if (rightWall && (height == 0)) height = rightWall[0].height; else if (rearWall && (height == 0)) height = rearWall[0].height; else if (leftWall && (height == 0)) height = leftWall[0].height; depth = 0; if (floor) depth = floor[0].depth; if (rightWall && (depth == 0)) depth = rightWall[0].depth; if (leftWall && (depth == 0)) depth = leftWall[0].depth; tracePrint ('(width, height, depth)=(' + width + ',' + height + ',' + depth + ')'); // translate wall centers (not corners) rightTranslation = new SFVec3f (width, 0, 0); tracePrint ('rightTranslation=' + rightTranslation); rearTranslation = new SFVec3f (width, 0, -depth); tracePrint ('rearTranslation=' + rearTranslation); leftTranslation = new SFVec3f (0, 0, -width/2); tracePrint ('leftTranslation=' + leftTranslation); built = true; tracePrint ('built=' + built); }
]]>
|
|
263 | </Script> |
264 | < ROUTE fromNode='LevelConstructionScript' fromField='rightTranslation' toNode='RightWallTransform' toField='translation'/> |
265 | < ROUTE fromNode='LevelConstructionScript' fromField='rearTranslation' toNode='RearWallTransform' toField='translation'/> |
266 | < ROUTE fromNode='LevelConstructionScript' fromField='leftTranslation' toNode='LeftWallTransform' toField='translation'/> |
267 | <Group DEF='LevelInitializeAfterChildrenReady'> |
268 |
<!-- ROUTE information for LevelBuiltFilter node:
[from LevelConstructionScript.built to set_boolean
]
[from inputTrue to LevelBuiltNegation.set_boolean
]
-->
<BooleanFilter DEF='LevelBuiltFilter'/> |
269 |
<!-- ROUTE information for LevelBuiltNegation node:
[from LevelBuiltFilter.inputTrue to set_boolean
]
[from inputNegate to LevelRecalculateUntilBuilt.enabled
]
-->
<BooleanFilter DEF='LevelBuiltNegation'/> |
270 |
<!-- ROUTE information for LevelRecalculateUntilBuilt node:
[from LevelBuiltNegation.inputNegate to enabled
]
[from cycleTime to LevelConstructionScript.recheckUntilBuilt
]
-->
<TimeSensor DEF='LevelRecalculateUntilBuilt' cycleInterval='0.1' loop='true'/> |
271 | < ROUTE fromNode='LevelConstructionScript' fromField='built' toNode='LevelBuiltFilter' toField='set_boolean'/> |
272 | < ROUTE fromNode='LevelBuiltFilter' fromField='inputTrue' toNode='LevelBuiltNegation' toField='set_boolean'/> |
273 | < ROUTE fromNode='LevelBuiltNegation' fromField='inputNegate' toNode='LevelRecalculateUntilBuilt' toField='enabled'/> |
274 | < ROUTE fromNode='LevelRecalculateUntilBuilt' fromField='cycleTime' toNode='LevelConstructionScript' toField='recheckUntilBuilt'/> |
275 | </Group> |
276 | </Group> |
277 | </ProtoBody> |
278 | </ProtoDeclare> |
279 | <ProtoDeclare name='Building' appinfo='Collect prototypes for levels floors and walls to create a simple Building.'> |
280 | <ProtoInterface> |
281 |
<field name='name' type='SFString' accessType='initializeOnly'
appinfo='Identifying name of this Building.'/> |
282 |
<field name='description' type='MFString' accessType='initializeOnly'
appinfo='Description info for this construction.'/> |
283 |
<field name='authorAssist' type='SFBool' value='true' accessType='initializeOnly'
appinfo='whether or not to display author assist tools such as coordinate axes measuring grids etc.'/> |
284 |
<field name='xHeading' type='SFFloat' value='0.0' accessType='initializeOnly'
appinfo='compass direction in degrees of building X axis as seen when regarding front face of building pointing from left side to right side.'/> |
285 |
<field name='orientation' type='SFRotation' accessType='outputOnly'
appinfo='output rotation value calculated from xHeading as (0 1 0 xHeading * 2pi / 360)'/> |
286 |
<field name='latitude' type='SFString' accessType='initializeOnly'
appinfo='example value: 120.30 E'/> |
287 |
<field name='longitude' type='SFString' accessType='initializeOnly'
appinfo='example value: 20.45 N'/> |
288 |
<field name='levels' type='MFNode' accessType='initializeOnly'
appinfo='contains array of Level nodes'> |
289 | <ProtoInstance name='Level'/> |
290 | </field> |
291 |
<field name='roof' type='SFNode' accessType='initializeOnly'
appinfo='Geometry for Roof positioned above topmost Level'> |
292 | <Group/> |
293 | </field> |
294 |
<field name='roofHeight' type='SFFloat' value='0' accessType='initializeOnly'
appinfo='height value for provided Roof geometry.'/> |
295 |
<field name='width' type='SFFloat' accessType='outputOnly'
appinfo='Calculated width of horizontal side of Building aligned with local X axis.'/> |
296 |
<field name='height' type='SFFloat' accessType='outputOnly'
appinfo='Calculated height of Building aligned with local Y axis.'/> |
297 |
<field name='depth' type='SFFloat' accessType='outputOnly'
appinfo='Calculated depth of horizontal thickness of Building aligned with local -Z axis.'/> |
298 |
<field name='built' type='SFBool' accessType='outputOnly'
appinfo='Indicate whether initialization complete.'/> |
299 | </ProtoInterface> |
300 | <ProtoBody> |
301 | <Group> |
302 |
<!-- ROUTE information for AuthorAssist1 node:
[from BuildingConstructionScript.authorAssistChoice to whichChoice
]
-->
<Switch DEF='AuthorAssist1' whichChoice='-1'> |
303 |
<!-- ROUTE information for CoordinateAxesTransform node:
[from BuildingConstructionScript.scale to scale
]
-->
<Transform DEF='CoordinateAxesTransform'> |
304 | <Inline DEF='CoordinateAxes' url=' "../../X3dForWebAuthors/Chapter03Grouping/CoordinateAxes.x3d" "https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter03Grouping/CoordinateAxes.x3d" "https://www.web3d.org/x3d/content/examples/Savage/Tools/Authoring/CoordinateAxes.x3d" "../../X3dForWebAuthors/Chapter03Grouping/CoordinateAxes.wrl" "https://www.web3d.org/x3d/content/examples/X3dForWebAuthors/Chapter03Grouping/CoordinateAxes.wrl" "https://www.web3d.org/x3d/content/examples/Savage/Tools/Authoring/CoordinateAxes.wrl" '/> |
305 | </Transform> |
306 | </Switch> |
307 | <Group DEF='BuildingRoot'> |
308 |
<!-- Transform
LevelsRoot is a DEF node that has 1 USE node: USE_1 -->
<Transform DEF='LevelsRoot'> |
309 |
<!-- ROUTE information for AuthorAssist2 node:
[from BuildingConstructionScript.authorAssistChoice to whichChoice
]
-->
<Switch DEF='AuthorAssist2' whichChoice='-1'> |
310 | <Transform DEF='AuthorAssistTransform2'> |
311 | <Inline url=' "GridXY_20x20Movable.wrl" "https://www.web3d.org/x3d/content/examples/Basic/course/GridXY_20x20Movable.wrl" "https://www.web3d.org/x3d/content/examples/Savage/Tools/Authoring/GridXY_20x20Movable.wrl" "GridXY_20x20Movable.x3d" "https://www.web3d.org/x3d/content/examples/Basic/course/GridXY_20x20Movable.x3d" "https://www.web3d.org/x3d/content/examples/Savage/Tools/Authoring/GridXY_20x20Movable.x3d" '/> |
312 | <Inline url=' "GridXZ_20x20Movable.wrl" "https://www.web3d.org/x3d/content/examples/Basic/course/GridXZ_20x20Movable.wrl" "https://www.web3d.org/x3d/content/examples/Savage/Tools/Authoring/GridXZ_20x20Movable.wrl" "GridXZ_20x20Movable.x3d" "https://www.web3d.org/x3d/content/examples/Basic/course/GridXZ_20x20Movable.x3d" "https://www.web3d.org/x3d/content/examples/Savage/Tools/Authoring/GridXZ_20x20Movable.x3d" '/> |
313 | <Inline url=' "GridYZ_20x20Movable.wrl" "https://www.web3d.org/x3d/content/examples/Basic/course/GridYZ_20x20Movable.wrl" "https://www.web3d.org/x3d/content/examples/Savage/Tools/Authoring/GridYZ_20x20Movable.wrl" "GridYZ_20x20Movable.x3d" "https://www.web3d.org/x3d/content/examples/Basic/course/GridYZ_20x20Movable.x3d" "https://www.web3d.org/x3d/content/examples/Savage/Tools/Authoring/GridYZ_20x20Movable.x3d" '/> |
314 | </Transform> |
315 | </Switch> |
316 | </Transform> |
317 |
<!-- ROUTE information for BuildingConstructionScript node:
[from BuildingRecalculateUntilBuilt.cycleTime to recheckUntilBuilt
]
[from authorAssistChoice to AuthorAssist1.whichChoice
]
[from authorAssistChoice to AuthorAssist2.whichChoice
]
[from scale to CoordinateAxesTransform.scale
]
[from built to BuildingBuiltFilter.set_boolean
]
-->
<Script DEF='BuildingConstructionScript' directOutput='true'> |
318 | <field name='name' type='SFString' accessType='initializeOnly'/> |
319 | <field name='description' type='MFString' accessType='initializeOnly'/> |
320 | <field name='xHeading' type='SFFloat' accessType='initializeOnly'/> |
321 | <field name='orientation' type='SFRotation' accessType='outputOnly'/> |
322 | <field name='latitude' type='SFString' accessType='initializeOnly'/> |
323 | <field name='longitude' type='SFString' accessType='initializeOnly'/> |
324 | <field name='authorAssist' type='SFBool' accessType='initializeOnly'/> |
325 | <field name='levels' type='MFNode' accessType='initializeOnly'/> |
326 | <field name='roof' type='SFNode' accessType='initializeOnly'/> |
327 | <field name='roofHeight' type='SFFloat' accessType='initializeOnly'/> |
328 | <field name='LevelsRoot' type='SFNode' accessType='initializeOnly'> |
329 | <Transform USE='LevelsRoot'/> |
330 | </field> |
331 | <field name='width' type='SFFloat' accessType='outputOnly'/> |
332 | <field name='height' type='SFFloat' accessType='outputOnly'/> |
333 | <field name='depth' type='SFFloat' accessType='outputOnly'/> |
334 | <field name='scale' type='SFVec3f' accessType='outputOnly'/> |
335 | <field name='authorAssistChoice' type='SFInt32' accessType='outputOnly'/> |
336 | <field name='traceEnabled' type='SFBool' value='true' accessType='initializeOnly'/> |
337 |
<field name='recheckUntilBuilt' type='SFTime' accessType='inputOnly'
appinfo='New floor or wall initialization may be complete check and recalculate until built'/> |
338 | <field name='built' type='SFBool' accessType='outputOnly'/> |
339 | <IS> |
340 | <connect nodeField='name' protoField='name'/> |
341 | <connect nodeField='description' protoField='description'/> |
342 | <connect nodeField='authorAssist' protoField='authorAssist'/> |
343 | <connect nodeField='xHeading' protoField='xHeading'/> |
344 | <connect nodeField='orientation' protoField='orientation'/> |
345 | <connect nodeField='latitude' protoField='latitude'/> |
346 | <connect nodeField='longitude' protoField='longitude'/> |
347 | <connect nodeField='levels' protoField='levels'/> |
348 | <connect nodeField='roof' protoField='roof'/> |
349 | <connect nodeField='roofHeight' protoField='roofHeight'/> |
350 | <connect nodeField='width' protoField='width'/> |
351 | <connect nodeField='height' protoField='height'/> |
352 | <connect nodeField='depth' protoField='depth'/> |
353 | <connect nodeField='built' protoField='built'/> |
354 | </IS> |
<![CDATA[
ecmascript: var firstLoopWhileTrueCompleted; function tracePrint (outputString) { if (traceEnabled) Browser.println ('[Building' + name + ']' + outputString); } function alwaysPrint (outputString) { Browser.println ('[Building' + name + ']' + outputString); } function initialize () { built = false; firstLoopWhileTrueCompleted = false; alwaysPrint ('initialize, built=' + built); } function recheckUntilBuilt (value) { if (built == true) { built = true; // resend to trigger cancellation event for TimeSensor if (firstLoopWhileTrueCompleted) alwaysPrint ('recheckUntilBuilt() continuous built=true indicates internal error'); else firstLoopWhileTrueCompleted = true; return; // done } tracePrint ('recheckUntilBuilt testing...'); if (built == true) return; // done for (i=0; i < levels.length; i++) { if (levels[i].built == false) return; // not yet ready } tracePrint ('recheckUntilBuilt ready!'); alwaysPrint ('description=' + description); if (levels.length == 0) { alwaysPrint ('** warning, no levels found'); return; } orientation = new SFRotation (0, 1, 0, -xHeading * 3.14159 / 180.0); LevelsRoot.rotation = orientation; tracePrint ('xHeading=' + xHeading + ' degrees,' + 'orientation=' + orientation); width = 0; depth = 0; incrementalHeight = 0; // first child of LevelsRoot is oriented AuthorAssist2 Switch for (i=0; i < levels.length; i++) { tracePrint ('level[' + i + ']'); // compute max values for width, height, depth if (width < levels[i].width) width = levels[i].width; if (depth < levels[i].depth) depth = levels[i].depth; newTransform ='Transform {' + 'translation 0' + incrementalHeight + ' 0' + '}'; tracePrint ('newTransform=' + newTransform); newTransformNode = Browser.createVrmlFromString (newTransform); // returns MFNode // append newTransformNode to LevelsRoot.children LevelsRoot.children[i+1] = newTransformNode[0]; // append current Level to current newTransformNode newTransformNode[0].children[0] = levels[i]; incrementalHeight += levels[i].height; tracePrint ('incrementalHeight=' + incrementalHeight); } childCount = levels.length + 1; if (roof) { tracePrint ('roof'); newTransform ='Transform {' + 'translation 0' + incrementalHeight + ' 0' + '}'; tracePrint ('newTransform=' + newTransform); newTransformNode = Browser.createVrmlFromString (newTransform); // returns MFNode // append newTransformNode to LevelsRoot.children LevelsRoot.children[childCount] = newTransformNode[0]; childCount++; // append roof to current newTransformNode newTransformNode[0].children[0] = roof; incrementalHeight += roofHeight; } else alwaysPrint ('** warning, no roof found'); height = incrementalHeight; tracePrint ('(width, height, depth)=(' + width + ',' + height + ',' + depth + ')'); maxDimension = width; if (maxDimension < height) maxDimension = height; if (maxDimension < depth) maxDimension = depth; scale = new SFVec3f (maxDimension * 1.1, maxDimension * 1.1, maxDimension * 1.1); newView ='Viewpoint {' + 'description \"' + name + ' (' + latitude + ',' + longitude + ')\"' + 'position' + (width/2) + ' ' + (height*2.0/3.0) + ' ' + (depth*3) + ' ' + '}'; tracePrint ('newView=' + newView); newViewNode = Browser.createVrmlFromString (newView); // returns MFNode // append newViewNode to LevelsRoot.children LevelsRoot.children[childCount] = newViewNode[0]; childCount++; newView ='Viewpoint {' + 'description \"' + name + ' (above)\"' + 'position' + (width/2) + ' ' + (height*3.0) + ' ' + (-depth/2) + ' ' + 'orientation 1 0 0 -1.57' + '}'; tracePrint ('newView=' + newView); newViewNode = Browser.createVrmlFromString (newView); // returns MFNode // append newViewNode to LevelsRoot.children LevelsRoot.children[childCount] = newViewNode[0]; childCount++; if (authorAssist) { tracePrint ('authorAssist'); authorAssistChoice = 0; } else authorAssistChoice = -1; tracePrint ('LevelsRoot childCount=' + childCount + ' (Switch + # levels + [roof] + Viewpoint*2)'); built = true; tracePrint ('built=' + built); }
]]>
|
|
356 | </Script> |
357 | < ROUTE fromNode='BuildingConstructionScript' fromField='authorAssistChoice' toNode='AuthorAssist1' toField='whichChoice'/> |
358 | < ROUTE fromNode='BuildingConstructionScript' fromField='authorAssistChoice' toNode='AuthorAssist2' toField='whichChoice'/> |
359 | < ROUTE fromNode='BuildingConstructionScript' fromField='scale' toNode='CoordinateAxesTransform' toField='scale'/> |
360 | <Group DEF='BuildingInitializeAfterChildrenReady'> |
361 |
<!-- ROUTE information for BuildingBuiltFilter node:
[from BuildingConstructionScript.built to set_boolean
]
[from inputTrue to BuildingBuiltNegation.set_boolean
]
-->
<BooleanFilter DEF='BuildingBuiltFilter'/> |
362 |
<!-- ROUTE information for BuildingBuiltNegation node:
[from BuildingBuiltFilter.inputTrue to set_boolean
]
[from inputNegate to BuildingRecalculateUntilBuilt.enabled
]
-->
<BooleanFilter DEF='BuildingBuiltNegation'/> |
363 |
<!-- ROUTE information for BuildingRecalculateUntilBuilt node:
[from BuildingBuiltNegation.inputNegate to enabled
]
[from cycleTime to BuildingConstructionScript.recheckUntilBuilt
]
-->
<TimeSensor DEF='BuildingRecalculateUntilBuilt' cycleInterval='0.1' loop='true'/> |
364 | < ROUTE fromNode='BuildingConstructionScript' fromField='built' toNode='BuildingBuiltFilter' toField='set_boolean'/> |
365 | < ROUTE fromNode='BuildingBuiltFilter' fromField='inputTrue' toNode='BuildingBuiltNegation' toField='set_boolean'/> |
366 | < ROUTE fromNode='BuildingBuiltNegation' fromField='inputNegate' toNode='BuildingRecalculateUntilBuilt' toField='enabled'/> |
367 | < ROUTE fromNode='BuildingRecalculateUntilBuilt' fromField='cycleTime' toNode='BuildingConstructionScript' toField='recheckUntilBuilt'/> |
368 | </Group> |
369 | </Group> |
370 | </Group> |
371 | </ProtoBody> |
372 | </ProtoDeclare> |
373 | <!-- ============================ --> |
374 | <Viewpoint description='SimpleBuildingConstructionPrototypes' position='0 0 12'/> |
375 | <Background groundAngle='1.57' groundColor='0.6 0.9 0.6 0.6 0.9 0.6' skyColor='0.6 0.6 0.9'/> |
376 | <Anchor description='SimpleBuildingConstructionExample' parameter='"target=_blank"' url=' "SimpleBuildingConstructionExample.wrl" "https://www.web3d.org/x3d/content/examples/Savage/Buildings/UHRB/SimpleBuildingConstructionExample.wrl" "SimpleBuildingConstructionExample.x3d" "https://www.web3d.org/x3d/content/examples/Savage/Buildings/UHRB/SimpleBuildingConstructionExample.x3d" '> |
377 | <Shape> |
378 | <Text string='"SimpleBuildingConstructionPrototypes" "is a prototype definition file" "" "Click this text to see" "SimpleBuildingConstructionExample"'> |
379 | <FontStyle justify='"MIDDLE" "MIDDLE"'/> |
380 | </Text> |
381 | <Appearance> |
382 | <Material diffuseColor='0.2 0.2 0.8'/> |
383 | </Appearance> |
384 | </Shape> |
385 | </Anchor> |
386 | </Scene> |
387 | </X3D> |
Event Graph ROUTE Table entries with 18 ROUTE connections total, showing X3D event-model relationships for this scene.
Each row shows an event cascade that may occur during a single timestamp interval between frame renderings, as part of the X3D execution model.
FloorConstructionScript
Script floorPoints MFVec3f |
FloorCoordinate
Coordinate point MFVec3f |
|
FloorConstructionScript
Script wallsVisible SFInt32 |
FloorSidesSwitch
Switch whichChoice SFInt32 |
WallConstructionScript
Script coordinatePoints MFVec3f |
WallCoordinate
Coordinate point MFVec3f |
|
WallConstructionScript
Script wallsVisible SFInt32 |
WallSidesSwitch
Switch whichChoice SFInt32 |
line 189
ProtoInstance Wall |
No direct ROUTE connection found for events to/from this node. This ProtoInstance contains SFNode/MFNode fieldValue declarations with direct access to other nodes, and thus has potential to produce run-time animation. |
line 192
ProtoInstance Wall |
No direct ROUTE connection found for events to/from this node. This ProtoInstance contains SFNode/MFNode fieldValue declarations with direct access to other nodes, and thus has potential to produce run-time animation. |
line 195
ProtoInstance Wall |
No direct ROUTE connection found for events to/from this node. This ProtoInstance contains SFNode/MFNode fieldValue declarations with direct access to other nodes, and thus has potential to produce run-time animation. |
line 198
ProtoInstance Wall |
No direct ROUTE connection found for events to/from this node. This ProtoInstance contains SFNode/MFNode fieldValue declarations with direct access to other nodes, and thus has potential to produce run-time animation. |
line 289
ProtoInstance Level |
No direct ROUTE connection found for events to/from this node. This ProtoInstance contains SFNode/MFNode fieldValue declarations with direct access to other nodes, and thus has potential to produce run-time animation. |
line 376
Anchor |
description='SimpleBuildingConstructionExample' User-interaction hint for this node. |
<!--
Color-coding legend: X3D terminology
<X3dNode
DEF='idName' field='value'/>
matches XML terminology
<XmlElement
DEF='idName' attribute='value'/>
(Light-blue background: event-based behavior node or statement)
(Grey background inside box: inserted documentation)
(Magenta background: X3D Extensibility)
<ProtoInstance name='ProtoName'>
<field
name='fieldName'/> </ProtoInstance>
-->
<!--
For additional help information about X3D scenes, please see X3D Tooltips, X3D Resources, and X3D Scene Authoring Hints.
-->