scenejs_on_rails 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -5
- data/app/controllers/scenejs_controller.rb +53 -0
- data/app/views/scenejs/get_scenejs_data.html.erb +3 -0
- data/lib/scenejs_on_rails.rb +1 -1
- data/lib/scenejs_on_rails/rails.rb +5 -0
- data/lib/scenejs_on_rails/version.rb +1 -1
- data/vendor/assets/javascripts/scenejs.js +17307 -0
- data/vendor/assets/javascripts/scenejs_extras/gui.js +478 -0
- data/vendor/assets/javascripts/scenejs_extras/gui/README.md +4 -0
- data/vendor/assets/javascripts/scenejs_extras/gui/dat.gui.min.js +94 -0
- data/vendor/assets/javascripts/scenejs_extras/gui/gui.js +385 -0
- data/vendor/assets/javascripts/scenejs_lib/cityBuilder.js +457 -0
- data/vendor/assets/javascripts/scenejs_lib/dat.gui.min.js +94 -0
- data/vendor/assets/javascripts/scenejs_lib/gl-matrix-min.js +28 -0
- data/vendor/assets/javascripts/scenejs_lib/gl-matrix.js +4078 -0
- data/vendor/assets/javascripts/scenejs_lib/require.js +36 -0
- data/vendor/assets/javascripts/scenejs_lib/requireConfig.js +18 -0
- data/vendor/assets/javascripts/scenejs_lib/requireWrapperEnd.js +1 -0
- data/vendor/assets/javascripts/scenejs_lib/requireWrapperStart.js +2 -0
- data/vendor/assets/javascripts/scenejs_lib/stats.min.js +6 -0
- data/vendor/assets/javascripts/scenejs_lib/sylvester.js +1 -0
- data/vendor/assets/javascripts/scenejs_lib/webgl-debug-utils.js +839 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/boundary.js +59 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/box.js +72 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/plane.js +126 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/quad.js +37 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/skybox.js +86 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/sphere.js +82 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/teapot.js +5853 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/torus.js +139 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/vectorText.js +1499 -0
- data/vendor/assets/javascripts/scenejs_plugins/geometry/wobblyBox.js +44 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/canvas2image.js +198 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/frustum/frustumCullEngine.js +810 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/frustum/frustumCullSystem.js +185 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/frustum/frustumCullSystemPool.js +174 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/frustum/frustumCullWorker.js +142 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/gl-matrix-min.js +28 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/jquery-1.8.3.min.js +2 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/k3d.js +1029 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/physics/jiglib.all.min.js +3 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/physics/physics.js +223 -0
- data/vendor/assets/javascripts/scenejs_plugins/lib/physics/worker.js +330 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/alpha/orbitTracking.js +295 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/alpha/orbitTrackingTarget.js +43 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/backgrounds/gradient.js +148 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/cameras/orbit.js +172 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/cameras/pickFlyOrbit.js +409 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/canvas/capture.js +107 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/demos/color.js +30 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/demos/redTeapot.js +52 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/demos/spinningTeapot.js +43 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/effects/crt.js +36 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/effects/fog.js +159 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/effects/snowyPeaks.js +50 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/effects/wobble.js +42 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/effects/xray.js +126 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/frustum/body.js +112 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/frustum/cull.js +42 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/frustum/lod.js +125 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/heightmaps/custom.js +185 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/import/3ds.js +91 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/import/md2.js +139 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/import/obj.js +100 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/buildings/building.js +352 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/buildings/building/HighRiseGlass.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/buildings/building/HighRiseGlassSpecular.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/buildings/building/highrise-windows.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/buildings/building/pixelcity_windows7.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/buildings/city.js +26 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/plants/ghostTree.js +387 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/space/planets/earth.js +168 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/space/planets/earth/earth-lights.gif +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/space/planets/earth/earth-specular.gif +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/space/planets/earth/earth-specular.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/space/planets/earth/earth.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/space/planets/earth/earthbump.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/space/planets/earth/earthclouds.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/toys/drinkingBird.js +632 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/vehicles/tank.js +77670 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/objects/vehicles/tank.js~ +77636 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/physics/body.js +85 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/physics/box.js +30 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/physics/material.js +35 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/physics/plane.js +47 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/physics/sphere.js +32 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/physics/system.js +44 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/physics/teapot.js +29 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/boundary.js +73 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/box.js +87 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/cylinder.js +186 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/grid.js +47 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/plane.js +137 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/quad.js +43 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/sphere.js +107 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/teapot.js +5846 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/torus.js +149 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/prims/vectorText.js +1508 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/clouds.js +19 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/cloudySea.js +19 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/custom.js +150 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/grimmNight.js +19 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/interstellarClouds.js +19 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/miramarClouds.js +19 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/stormyDays.js +19 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/textures/clouds.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/textures/cloudySea.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/textures/grimmNight.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/textures/interstellarClouds.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/textures/miramarClouds.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/textures/stormyDays.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/textures/violentDays.jpg +0 -0
- data/vendor/assets/javascripts/scenejs_plugins/node/skyboxes/violentDays.js +19 -0
- data/vendor/assets/javascripts/scenejs_plugins/texture/image.js +67 -0
- data/vendor/assets/javascripts/scenejs_plugins/texture/video.js +105 -0
- metadata +113 -1
@@ -0,0 +1,352 @@
|
|
1
|
+
(function () {
|
2
|
+
|
3
|
+
var buildingTypes = initBuildingTypes();
|
4
|
+
|
5
|
+
SceneJS.Types.addType("objects/buildings/building", {
|
6
|
+
|
7
|
+
construct:function (params) {
|
8
|
+
var type = params.buildingType || 0;
|
9
|
+
var buildingType = buildingTypes[type];
|
10
|
+
if (!buildingType) {
|
11
|
+
throw "unsupported building type: " + type;
|
12
|
+
}
|
13
|
+
var pos = params.pos || {};
|
14
|
+
createBuilding(buildingType, this, {
|
15
|
+
xmin:(pos.x || 0) - 10,
|
16
|
+
zmin:(pos.z || 0) - 10,
|
17
|
+
xmax:(pos.x || 0) + 10,
|
18
|
+
zmax:(pos.z || 0) + 10
|
19
|
+
});
|
20
|
+
}
|
21
|
+
});
|
22
|
+
|
23
|
+
function initBuildingTypes() {
|
24
|
+
|
25
|
+
var texturePath = SceneJS.getConfigs("pluginPath") + "/node/objects/buildings/building/";
|
26
|
+
|
27
|
+
return [
|
28
|
+
// Building 1
|
29
|
+
{
|
30
|
+
freq:50,
|
31
|
+
material:{
|
32
|
+
type:"material",
|
33
|
+
coreId:"building.1.material",
|
34
|
+
baseColor:{
|
35
|
+
r:1.0,
|
36
|
+
g:1.0,
|
37
|
+
b:1.0
|
38
|
+
},
|
39
|
+
specularColor:[ 1.0, 1.0, 1.0 ],
|
40
|
+
specular:0.4,
|
41
|
+
shine:20.0
|
42
|
+
},
|
43
|
+
texture:{
|
44
|
+
type:"texture",
|
45
|
+
coreId:"building.1.texture",
|
46
|
+
layers:[
|
47
|
+
{
|
48
|
+
src:texturePath + "highrise-windows.jpg",
|
49
|
+
applyTo:"baseColor",
|
50
|
+
blendMode:"multiply",
|
51
|
+
wrapS:"repeat",
|
52
|
+
wrapT:"repeat",
|
53
|
+
scale:{
|
54
|
+
x:0.04,
|
55
|
+
y:0.05
|
56
|
+
}
|
57
|
+
}
|
58
|
+
]
|
59
|
+
},
|
60
|
+
roof:{
|
61
|
+
height:1,
|
62
|
+
material:{
|
63
|
+
type:"material",
|
64
|
+
coreId:"building.1.roof",
|
65
|
+
baseColor:{
|
66
|
+
r:1.0,
|
67
|
+
g:1.0,
|
68
|
+
b:1.0
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
72
|
+
},
|
73
|
+
// Building 2
|
74
|
+
{
|
75
|
+
freq:30,
|
76
|
+
material:{
|
77
|
+
type:"material",
|
78
|
+
coreId:"building.2.material",
|
79
|
+
baseColor:{
|
80
|
+
r:1.0,
|
81
|
+
g:1.0,
|
82
|
+
b:1.0
|
83
|
+
},
|
84
|
+
specularColor:[ 1.0, 1.0, 1.0 ],
|
85
|
+
specular:1.0,
|
86
|
+
shine:5.0
|
87
|
+
},
|
88
|
+
texture:{
|
89
|
+
type:"texture",
|
90
|
+
coreId:"building.2.texture",
|
91
|
+
layers:[
|
92
|
+
{
|
93
|
+
src:texturePath + "HighRiseGlass.jpg",
|
94
|
+
applyTo:"baseColor",
|
95
|
+
blendMode:"multiply",
|
96
|
+
wrapS:"repeat",
|
97
|
+
wrapT:"repeat",
|
98
|
+
scale:{
|
99
|
+
x:0.25,
|
100
|
+
y:0.2
|
101
|
+
}
|
102
|
+
},
|
103
|
+
{
|
104
|
+
src:texturePath + "HighRiseGlassSpecular.jpg",
|
105
|
+
applyTo:"specular",
|
106
|
+
blendMode:"multiply",
|
107
|
+
wrapS:"repeat",
|
108
|
+
wrapT:"repeat",
|
109
|
+
scale:{
|
110
|
+
x:0.25,
|
111
|
+
y:0.2
|
112
|
+
}
|
113
|
+
}
|
114
|
+
]
|
115
|
+
},
|
116
|
+
roof:{
|
117
|
+
height:1,
|
118
|
+
material:{
|
119
|
+
type:"material",
|
120
|
+
coreId:"building.2.roof",
|
121
|
+
baseColor:{
|
122
|
+
r:0.4,
|
123
|
+
g:0.4,
|
124
|
+
b:0.4
|
125
|
+
}
|
126
|
+
}
|
127
|
+
}
|
128
|
+
},
|
129
|
+
// Building 3
|
130
|
+
{
|
131
|
+
freq:20,
|
132
|
+
material:{
|
133
|
+
type:"material",
|
134
|
+
coreId:"building.3.material",
|
135
|
+
baseColor:{
|
136
|
+
r:1.0,
|
137
|
+
g:1.0,
|
138
|
+
b:1.0
|
139
|
+
},
|
140
|
+
specularColor:[ 1.0, 1.0, 1.0 ],
|
141
|
+
specular:0.4,
|
142
|
+
shine:20.0
|
143
|
+
},
|
144
|
+
texture:{
|
145
|
+
type:"texture",
|
146
|
+
coreId:"building.3.texture",
|
147
|
+
layers:[
|
148
|
+
{
|
149
|
+
src:texturePath + "pixelcity_windows7.jpg",
|
150
|
+
applyTo:"baseColor",
|
151
|
+
blendMode:"multiply",
|
152
|
+
wrapS:"repeat",
|
153
|
+
wrapT:"repeat",
|
154
|
+
scale:{
|
155
|
+
x:0.015,
|
156
|
+
y:0.01
|
157
|
+
}
|
158
|
+
}
|
159
|
+
]
|
160
|
+
},
|
161
|
+
roof:{
|
162
|
+
height:1,
|
163
|
+
material:{
|
164
|
+
type:"material",
|
165
|
+
coreId:"building.3.roof",
|
166
|
+
baseColor:{
|
167
|
+
r:0.0,
|
168
|
+
g:0.0,
|
169
|
+
b:0.0
|
170
|
+
}
|
171
|
+
}
|
172
|
+
}
|
173
|
+
}
|
174
|
+
];
|
175
|
+
}
|
176
|
+
|
177
|
+
function createBuilding(buildingType, node, footprint) {
|
178
|
+
|
179
|
+
var xpos = (footprint.xmin + footprint.xmax) * 0.5;
|
180
|
+
var ypos = 0;
|
181
|
+
var zpos = (footprint.zmin + footprint.zmax) * 0.5;
|
182
|
+
|
183
|
+
/* Base
|
184
|
+
*/
|
185
|
+
|
186
|
+
var baseWidth = 0.6;
|
187
|
+
|
188
|
+
addBase(
|
189
|
+
buildingType,
|
190
|
+
node,
|
191
|
+
xpos, zpos,
|
192
|
+
footprint.xmax - footprint.xmin,
|
193
|
+
baseWidth / 2,
|
194
|
+
footprint.zmax - footprint.zmin);
|
195
|
+
|
196
|
+
var xmin;
|
197
|
+
var ymin;
|
198
|
+
var zmin;
|
199
|
+
var xmax;
|
200
|
+
var ymax;
|
201
|
+
var zmax;
|
202
|
+
|
203
|
+
var width;
|
204
|
+
var axis;
|
205
|
+
var sign;
|
206
|
+
|
207
|
+
var yMaxSize = (Math.random() * 30) + 15;
|
208
|
+
var ySize = yMaxSize + baseWidth;
|
209
|
+
|
210
|
+
while (ySize > 5) {
|
211
|
+
|
212
|
+
width = (Math.random() * 3) + 2;
|
213
|
+
|
214
|
+
axis = Math.round(Math.random());
|
215
|
+
sign = Math.round(Math.random());
|
216
|
+
|
217
|
+
ymin = baseWidth;
|
218
|
+
ymax = ySize;
|
219
|
+
|
220
|
+
switch (axis) {
|
221
|
+
|
222
|
+
case 0:
|
223
|
+
|
224
|
+
if (sign == 0) {
|
225
|
+
|
226
|
+
xmin = footprint.xmin;
|
227
|
+
zmin = zpos - width;
|
228
|
+
|
229
|
+
xmax = xpos + width;
|
230
|
+
zmax = zpos + width;
|
231
|
+
|
232
|
+
} else {
|
233
|
+
|
234
|
+
xmin = xpos - width;
|
235
|
+
zmin = zpos - width;
|
236
|
+
|
237
|
+
xmax = footprint.xmax;
|
238
|
+
zmax = zpos + width;
|
239
|
+
}
|
240
|
+
|
241
|
+
break;
|
242
|
+
|
243
|
+
case 1:
|
244
|
+
|
245
|
+
|
246
|
+
if (sign == 0) {
|
247
|
+
|
248
|
+
xmin = xpos - width;
|
249
|
+
zmin = footprint.zmin;
|
250
|
+
|
251
|
+
xmax = xpos + width;
|
252
|
+
zmax = zpos + width;
|
253
|
+
|
254
|
+
} else {
|
255
|
+
|
256
|
+
xmin = xpos - width;
|
257
|
+
zmin = zpos - width;
|
258
|
+
|
259
|
+
xmax = xpos + width;
|
260
|
+
zmax = footprint.zmax;
|
261
|
+
}
|
262
|
+
|
263
|
+
break;
|
264
|
+
}
|
265
|
+
|
266
|
+
addBox(
|
267
|
+
buildingType,
|
268
|
+
node,
|
269
|
+
(xmin + xmax) * 0.5,
|
270
|
+
ySize + baseWidth,
|
271
|
+
(zmin + zmax) * 0.5,
|
272
|
+
|
273
|
+
xmax - xmin,
|
274
|
+
ySize,
|
275
|
+
zmax - zmin);
|
276
|
+
|
277
|
+
ySize -= (Math.random() * 5) + 2;
|
278
|
+
}
|
279
|
+
}
|
280
|
+
|
281
|
+
|
282
|
+
function addBase(buildingType, node, xpos, zpos, xsize, ysize, zsize) {
|
283
|
+
node.addNode({
|
284
|
+
type:"translate",
|
285
|
+
x:xpos,
|
286
|
+
y:ysize,
|
287
|
+
z:zpos,
|
288
|
+
nodes:[
|
289
|
+
{
|
290
|
+
type:"material",
|
291
|
+
baseColor:{
|
292
|
+
r:0.6, g:.6, b:0.6
|
293
|
+
},
|
294
|
+
coreId:"building.base",
|
295
|
+
nodes:[
|
296
|
+
{
|
297
|
+
type:"geometry",
|
298
|
+
source:{
|
299
|
+
type:"box",
|
300
|
+
xSize:xsize,
|
301
|
+
ySize:ysize,
|
302
|
+
zSize:zsize
|
303
|
+
}
|
304
|
+
}
|
305
|
+
]
|
306
|
+
}
|
307
|
+
]
|
308
|
+
});
|
309
|
+
}
|
310
|
+
|
311
|
+
function addBox(buildingType, node, xpos, ypos, zpos, xsize, ysize, zsize) {
|
312
|
+
|
313
|
+
/* Roof cap
|
314
|
+
*/
|
315
|
+
node.addNode(buildingType.roof.material)
|
316
|
+
.addNode({
|
317
|
+
type:"translate",
|
318
|
+
x:xpos,
|
319
|
+
y:ypos + ysize + buildingType.roof.height,
|
320
|
+
z:zpos
|
321
|
+
})
|
322
|
+
.addNode({
|
323
|
+
type:"geometry",
|
324
|
+
source:{
|
325
|
+
type:"box",
|
326
|
+
xSize:xsize,
|
327
|
+
ySize:buildingType.roof.height,
|
328
|
+
zSize:zsize
|
329
|
+
}
|
330
|
+
});
|
331
|
+
|
332
|
+
/* Body with texture
|
333
|
+
*/
|
334
|
+
node.addNode(buildingType.material)// Current material
|
335
|
+
.addNode(buildingType.texture)// Current texture
|
336
|
+
.addNode({
|
337
|
+
type:"translate",
|
338
|
+
x:xpos,
|
339
|
+
y:ypos,
|
340
|
+
z:zpos
|
341
|
+
})
|
342
|
+
.addNode({
|
343
|
+
type:"geometry",
|
344
|
+
source:{
|
345
|
+
type:"box",
|
346
|
+
xSize:xsize,
|
347
|
+
ySize:ysize,
|
348
|
+
zSize:zsize
|
349
|
+
}
|
350
|
+
});
|
351
|
+
}
|
352
|
+
})();
|
data/vendor/assets/javascripts/scenejs_plugins/node/objects/buildings/building/HighRiseGlass.jpg
ADDED
Binary file
|
Binary file
|
data/vendor/assets/javascripts/scenejs_plugins/node/objects/buildings/building/highrise-windows.jpg
ADDED
Binary file
|
Binary file
|
@@ -0,0 +1,26 @@
|
|
1
|
+
SceneJS.Types.addType("objects/buildings/city", {
|
2
|
+
|
3
|
+
construct:function (params) {
|
4
|
+
|
5
|
+
var width = params.width || 600;
|
6
|
+
if (width < 100) {
|
7
|
+
throw "city width must be at least 100";
|
8
|
+
}
|
9
|
+
var halfWidth = width / 2;
|
10
|
+
|
11
|
+
// Add a grid of buildings
|
12
|
+
for (var x = -halfWidth; x < halfWidth; x += 50) {
|
13
|
+
for (var z = -halfWidth; z < halfWidth; z += 50) {
|
14
|
+
this.addNode({
|
15
|
+
type:"objects/buildings/building",
|
16
|
+
buildingType:Math.floor(Math.random() * 3), // Three building types
|
17
|
+
pos:{
|
18
|
+
x:x,
|
19
|
+
y:0,
|
20
|
+
z:z
|
21
|
+
}
|
22
|
+
});
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
});
|
@@ -0,0 +1,387 @@
|
|
1
|
+
/**
|
2
|
+
* A procedurally-generated tree
|
3
|
+
*
|
4
|
+
* This is a quick bit of fun that borrows the procedural tree generation
|
5
|
+
* code from the "Ghost Trees" Chrome Experiment by Marek Kapolka:
|
6
|
+
*
|
7
|
+
* http://www.chromeexperiments.com/detail/ghost-trees/
|
8
|
+
*
|
9
|
+
* Tree generation code is wrapped in a custom SceneJS node type defined in:
|
10
|
+
* http://scenejs.org/api/latest/plugins/node/objects/plants/ghostTree.js
|
11
|
+
*
|
12
|
+
* All the parameters for the tree generator are exposed as configurations
|
13
|
+
* for the node type.
|
14
|
+
*
|
15
|
+
*/
|
16
|
+
|
17
|
+
(function () {
|
18
|
+
|
19
|
+
require([
|
20
|
+
SceneJS.getConfigs("pluginPath") + "/lib/gl-matrix-min.js"
|
21
|
+
],
|
22
|
+
function (glmat) {
|
23
|
+
|
24
|
+
SceneJS.Types.addType("objects/plants/ghostTree", {
|
25
|
+
|
26
|
+
construct:function (params) {
|
27
|
+
|
28
|
+
if (params.minSegmentLength == undefined) params.minSegmentLength = 1;
|
29
|
+
if (params.maxSegmentLength == undefined) params.maxSegmentLength = 2;
|
30
|
+
if (params.minSegmentAngle == undefined) params.minSegmentAngle = Math.PI / 16;
|
31
|
+
if (params.maxSegmentAngle == undefined) params.maxSegmentAngle = Math.PI / 8;
|
32
|
+
if (params.minNumBranches == undefined) params.minNumBranches = 1;
|
33
|
+
if (params.maxNumBranches == undefined) params.maxNumBranches = 4;
|
34
|
+
if (params.segments == undefined) params.segments = 9;
|
35
|
+
if (params.branchLengthFactor == undefined) params.branchLengthFactor = 2;
|
36
|
+
if (params.branchAngleFactor == undefined) params.branchAngleFactor = 1.5;
|
37
|
+
if (params.branchSegmentFactor == undefined) params.branchSegmentFactor = 1;
|
38
|
+
if (params.branchBranchFactor == undefined) params.branchBranchFactor = .5;
|
39
|
+
if (params.color == undefined) params.color = [1, 1, 1];
|
40
|
+
|
41
|
+
var segment = generateSegment(null, params);
|
42
|
+
var height = countSegmentMaxHeight(segment);
|
43
|
+
|
44
|
+
this.addNode(buildGeometry(segment));
|
45
|
+
}
|
46
|
+
});
|
47
|
+
|
48
|
+
function buildGeometry(segment) {
|
49
|
+
|
50
|
+
var templateVertices = [];
|
51
|
+
|
52
|
+
for (var i = 0; i < 6; i++) {
|
53
|
+
var v = glmat.vec3.create();
|
54
|
+
glmat.vec3.set(v, Math.cos(i * Math.PI / 3), 0, Math.sin(i * Math.PI / 3));
|
55
|
+
templateVertices.push(v);
|
56
|
+
}
|
57
|
+
|
58
|
+
var vertexArray = templateVertices.slice(0);
|
59
|
+
var elementArray = [];
|
60
|
+
var colorArray = [];
|
61
|
+
//Initialize color array
|
62
|
+
for (var i = 0; i < vertexArray.length; i++) {
|
63
|
+
colorArray.push([1, 1, 1, 1]);
|
64
|
+
}
|
65
|
+
var rootMatrix = glmat.mat4.create();
|
66
|
+
glmat.mat4.identity(rootMatrix);
|
67
|
+
|
68
|
+
addSegmentToRenderable(vertexArray, elementArray, colorArray, 0, templateVertices, segment, rootMatrix, 0);
|
69
|
+
|
70
|
+
return {
|
71
|
+
type:"geometry",
|
72
|
+
primitive:"triangle-strip",
|
73
|
+
positions:unpackArray(vertexArray),
|
74
|
+
indices:elementArray,
|
75
|
+
colors:unpackArray(colorArray)
|
76
|
+
};
|
77
|
+
}
|
78
|
+
|
79
|
+
function Segment() {
|
80
|
+
|
81
|
+
//type: Segment
|
82
|
+
//The segment that precedes this one
|
83
|
+
this.prevSegment = null;
|
84
|
+
|
85
|
+
//type: Segment
|
86
|
+
//The segment that succeeds this one
|
87
|
+
this.nextSegment = null;
|
88
|
+
|
89
|
+
//Type: Array (of Segments)
|
90
|
+
//Contains the root segments of the branches connected to this Segment.
|
91
|
+
this.branches = [];
|
92
|
+
|
93
|
+
//Type: float
|
94
|
+
//The length of this segment in distance units
|
95
|
+
this.segmentLength = 1;
|
96
|
+
|
97
|
+
//Type: float (radians)
|
98
|
+
//The angle of this segment's rotation along the X/Y axis
|
99
|
+
this.angle = 0;
|
100
|
+
|
101
|
+
//Type: float (radians)
|
102
|
+
//The angle of this segment's rotation along the local Z axis
|
103
|
+
this.direction = 0;
|
104
|
+
}
|
105
|
+
|
106
|
+
function SegmentParameters() {
|
107
|
+
|
108
|
+
//Type: float
|
109
|
+
//The minimum and maximum lengths of a segment to use
|
110
|
+
//when generating a new segment
|
111
|
+
this.minSegmentLength = 1;
|
112
|
+
this.maxSegmentLength = 1;
|
113
|
+
|
114
|
+
//Type: float (radians)
|
115
|
+
//The minimum and maximum values of a segment's angle
|
116
|
+
//when generating a new segment
|
117
|
+
this.minSegmentAngle = 0;
|
118
|
+
this.maxSegmentAngle = 0;
|
119
|
+
|
120
|
+
//Type: int
|
121
|
+
//The minimum and maxiumum amount of branches to have on this segment
|
122
|
+
this.minNumBranches = 0;
|
123
|
+
this.maxNumBranches = 0;
|
124
|
+
|
125
|
+
//Type: int
|
126
|
+
//This value represents how many segments are left to be generated
|
127
|
+
//along this particular length of tree.
|
128
|
+
this.segments = 0;
|
129
|
+
|
130
|
+
//Type: float
|
131
|
+
//When generating a branch, the the min and max values of the branch's length
|
132
|
+
//will be multiplied by this value.
|
133
|
+
this.branchLengthFactor = 1;
|
134
|
+
|
135
|
+
//Type: float
|
136
|
+
//When generating a branch, the min and max value of the branch's angle will be
|
137
|
+
//multiplied by this factor
|
138
|
+
this.branchAngleFactor = 1;
|
139
|
+
|
140
|
+
//Type: float
|
141
|
+
//When generating a branch, the number of segments in the branch will be taken
|
142
|
+
//from it's root and multiplied by this factor.
|
143
|
+
this.branchSegmentFactor = 1;
|
144
|
+
|
145
|
+
//Type: float
|
146
|
+
//When generating a branch, the number of branches branching out from that branch
|
147
|
+
//Will be multiplied by this factor.
|
148
|
+
this.branchBranchFactor = 1;
|
149
|
+
}
|
150
|
+
|
151
|
+
//Generates a random value between min and max (inclusive)
|
152
|
+
|
153
|
+
function randomRange(min, max) {
|
154
|
+
return min + Math.random() * (max - min);
|
155
|
+
}
|
156
|
+
|
157
|
+
//Parameters:
|
158
|
+
//--root--
|
159
|
+
//Type: Segment
|
160
|
+
//The generated segment will stem from this segment
|
161
|
+
//--params--
|
162
|
+
//Type: SegmentParameters
|
163
|
+
//The values to use when generating this Segment
|
164
|
+
|
165
|
+
function generateSegment(root, params) {
|
166
|
+
var segment = new Segment();
|
167
|
+
segment.previousSegment = root;
|
168
|
+
segment.segmentLength = randomRange(params.minSegmentLength, params.maxSegmentLength);
|
169
|
+
segment.angle = randomRange(params.minSegmentAngle, params.maxSegmentAngle);
|
170
|
+
segment.direction = Math.random() * Math.PI * 2;
|
171
|
+
|
172
|
+
var numBranches = Math.floor(randomRange(params.minNumBranches, params.maxNumBranches));
|
173
|
+
var branchParams = branchSegmentParams(params);
|
174
|
+
for (var i = 0; i < numBranches; i++) {
|
175
|
+
var branch = generateSegment(segment, branchParams);
|
176
|
+
branch.prevSegment = segment;
|
177
|
+
segment.branches.push(branch);
|
178
|
+
}
|
179
|
+
|
180
|
+
if (params.segments > 1) {
|
181
|
+
//params.segments -= 1;
|
182
|
+
segment.nextSegment = generateSegment(segment, branchParams);
|
183
|
+
segment.nextSegment.prevSegment = segment;
|
184
|
+
}
|
185
|
+
|
186
|
+
return segment;
|
187
|
+
}
|
188
|
+
|
189
|
+
//Returns the root-most segment connected to the input Segment
|
190
|
+
|
191
|
+
function getBaseSegment(segment) {
|
192
|
+
if (segment.prevSegment === null) {
|
193
|
+
return segment;
|
194
|
+
} else {
|
195
|
+
return getBaseSegment(segment.prevSegment);
|
196
|
+
}
|
197
|
+
}
|
198
|
+
|
199
|
+
//Creates a new SegmentParameters object
|
200
|
+
//by shrinking the min and max values of the
|
201
|
+
//given SegmentParameters object by the factors specified
|
202
|
+
//in that object.
|
203
|
+
//Parameters:
|
204
|
+
//--params--
|
205
|
+
//Type: SegmentParameters
|
206
|
+
//The input SegmentParameters object that will have its values
|
207
|
+
//shrunk
|
208
|
+
|
209
|
+
function branchSegmentParams(params) {
|
210
|
+
var sp2 = new SegmentParameters();
|
211
|
+
sp2.minSegmentLength = params.minSegmentLength * params.branchLengthFactor;
|
212
|
+
sp2.maxSegmentLength = params.maxSegmentLength * params.branchLengthFactor;
|
213
|
+
|
214
|
+
sp2.minSegmentAngle = params.minSegmentAngle * params.branchAngleFactor;
|
215
|
+
sp2.maxSegmentAngle = params.maxSegmentAngle * params.branchAngleFactor;
|
216
|
+
|
217
|
+
sp2.minNumBranches = Math.floor(params.minNumBranches * params.branchBranchFactor);
|
218
|
+
sp2.maxNumBranches = Math.floor(params.maxNumBranches * params.branchBranchFactor);
|
219
|
+
|
220
|
+
sp2.segments = Math.floor(params.segments * params.branchSegmentFactor);
|
221
|
+
sp2.segments -= 1;
|
222
|
+
|
223
|
+
return sp2;
|
224
|
+
}
|
225
|
+
|
226
|
+
//Unpacks an array of vectors into an array of values.
|
227
|
+
//This is useful because the addSegmentToRenderable method
|
228
|
+
//expects the values in its vertexArray to be glMatrix vec3s, but
|
229
|
+
//WebGL buffers should be filled with primative values
|
230
|
+
|
231
|
+
function unpackArray(input) {
|
232
|
+
var output = [];
|
233
|
+
|
234
|
+
for (var child in input) {
|
235
|
+
for (var i = 0; i < input[child].length; i++) {
|
236
|
+
output.push(input[child][i]);
|
237
|
+
}
|
238
|
+
}
|
239
|
+
|
240
|
+
return output;
|
241
|
+
}
|
242
|
+
|
243
|
+
//Generates the vertex, element, and color array data for a tree segment
|
244
|
+
//and its children recursively.
|
245
|
+
|
246
|
+
function addSegmentToRenderable(vertexArray, elementArray, colorArray, rootIndexStart, templateVertices, segment, rootMatrix, level) {
|
247
|
+
var m = glmat.mat4.clone(rootMatrix);
|
248
|
+
|
249
|
+
var vUp = glmat.vec3.create();
|
250
|
+
glmat.vec3.set(vUp, 0, 1, 0);
|
251
|
+
var vFor = glmat.vec3.create();
|
252
|
+
glmat.vec3.set(vFor, Math.cos(segment.direction), 0, Math.sin(segment.direction));
|
253
|
+
var vRot = glmat.vec3.create();
|
254
|
+
vRot = glmat.vec3.cross(vRot, vUp, vFor);
|
255
|
+
|
256
|
+
glmat.mat4.rotate(m, m, segment.angle, vRot);
|
257
|
+
glmat.mat4.translate(m, m, [0, segment.segmentLength, 0]);
|
258
|
+
|
259
|
+
var startIndex = vertexArray.length;
|
260
|
+
|
261
|
+
var scaleMatrix = glmat.mat4.create();
|
262
|
+
glmat.mat4.identity(scaleMatrix);
|
263
|
+
//var dist = countSegmentMaxHeight(getBaseSegment(segment)) - countSegmentMaxHeight(segment);
|
264
|
+
var dist = getBaseSegment(segment).maxHeight - segment.maxHeight;
|
265
|
+
glmat.mat4.scale(scaleMatrix, scaleMatrix, [Math.pow(.6, dist), 1, Math.pow(.6, dist)]);
|
266
|
+
//Add vertices
|
267
|
+
for (var i in templateVertices) {
|
268
|
+
//Vertex Location
|
269
|
+
var v = glmat.vec3.clone(templateVertices[i]);
|
270
|
+
glmat.vec3.transformMat4(v, v, scaleMatrix);
|
271
|
+
glmat.vec3.transformMat4(v, v, m);
|
272
|
+
vertexArray.push(v);
|
273
|
+
|
274
|
+
//Color
|
275
|
+
var c = Math.pow(.8, level);
|
276
|
+
colorArray.push([c, c, c, 1]);
|
277
|
+
}
|
278
|
+
|
279
|
+
//Elements
|
280
|
+
for (var i = 0; i < templateVertices.length; i++) {
|
281
|
+
elementArray.push(rootIndexStart + i);
|
282
|
+
elementArray.push(startIndex + i);
|
283
|
+
}
|
284
|
+
//loop around
|
285
|
+
elementArray.push(rootIndexStart);
|
286
|
+
elementArray.push(startIndex);
|
287
|
+
//Degenerate
|
288
|
+
elementArray.push(startIndex);
|
289
|
+
|
290
|
+
//Up first
|
291
|
+
if (segment.nextSegment != null) {
|
292
|
+
addSegmentToRenderable(vertexArray, elementArray, colorArray, startIndex, templateVertices, segment.nextSegment, m, level + 1);
|
293
|
+
}
|
294
|
+
|
295
|
+
for (var branch in segment.branches) {
|
296
|
+
//discontinuous degenerate
|
297
|
+
elementArray.push(rootIndexStart);
|
298
|
+
elementArray.push(rootIndexStart);
|
299
|
+
addSegmentToRenderable(vertexArray, elementArray, colorArray, rootIndexStart, templateVertices, segment.branches[branch], rootMatrix, level);
|
300
|
+
}
|
301
|
+
}
|
302
|
+
|
303
|
+
//Generates the pattern of vertices that will be used for each ring of the tree
|
304
|
+
|
305
|
+
function makeTemplateVertices() {
|
306
|
+
var templateVertices = [];
|
307
|
+
|
308
|
+
for (var i = 0; i < 6; i++) {
|
309
|
+
var v = glmat.vec3.create();
|
310
|
+
glmat.vec3.set(v, Math.cos(i * Math.PI / 3), 0, Math.sin(i * Math.PI / 3));
|
311
|
+
templateVertices.push(v);
|
312
|
+
}
|
313
|
+
|
314
|
+
return templateVertices;
|
315
|
+
}
|
316
|
+
|
317
|
+
//Generates a Renderable tree from this segment and its children.
|
318
|
+
|
319
|
+
function makeSegmentRenderable(segment, glContext) {
|
320
|
+
var templateVertices = makeTemplateVertices();
|
321
|
+
|
322
|
+
var vertexArray = templateVertices.slice(0);
|
323
|
+
var elementArray = [];
|
324
|
+
var colorArray = [];
|
325
|
+
//Initialize color array
|
326
|
+
for (var i = 0; i < vertexArray.length; i++) {
|
327
|
+
colorArray.push([1, 1, 1, 1]);
|
328
|
+
}
|
329
|
+
var rootMatrix = glmat.mat4.create();
|
330
|
+
mat4.identity(rootMatrix);
|
331
|
+
|
332
|
+
var renderable = new Renderable(glContext);
|
333
|
+
renderable.mvMatrix = rootMatrix;
|
334
|
+
|
335
|
+
addSegmentToRenderable(vertexArray, elementArray, colorArray, 0, templateVertices, segment, rootMatrix, 0);
|
336
|
+
|
337
|
+
var upColors = unpackArray(colorArray);
|
338
|
+
var upVerts = unpackArray(vertexArray);
|
339
|
+
var upElements = elementArray;
|
340
|
+
|
341
|
+
renderable.setVertices(upVerts);
|
342
|
+
renderable.setElements(upElements);
|
343
|
+
renderable.setColors(upColors);
|
344
|
+
|
345
|
+
return renderable;
|
346
|
+
}
|
347
|
+
|
348
|
+
//Returns the maxiumum number of segments that follow this one
|
349
|
+
//Before a leaf segment is found
|
350
|
+
|
351
|
+
function countSegmentMaxHeight(segment) {
|
352
|
+
if (segment.nextSegment === null && segment.branches.length === 0) {
|
353
|
+
return 1;
|
354
|
+
} else {
|
355
|
+
var max = 0;
|
356
|
+
if (segment.nextSegment != null) {
|
357
|
+
max = countSegmentMaxHeight(segment.nextSegment) + 1;
|
358
|
+
} else {
|
359
|
+
max = 1;
|
360
|
+
}
|
361
|
+
for (var child in segment.branches) {
|
362
|
+
var ch = countSegmentMaxHeight(segment.branches[child]);
|
363
|
+
if (ch > max) {
|
364
|
+
max = ch;
|
365
|
+
}
|
366
|
+
}
|
367
|
+
segment.maxHeight = max;
|
368
|
+
return max;
|
369
|
+
}
|
370
|
+
}
|
371
|
+
|
372
|
+
//Counts the total number of segments below this segment in a tree.
|
373
|
+
|
374
|
+
function countNumSegments(segment) {
|
375
|
+
var output;
|
376
|
+
if (segment.nextSegment != null) {
|
377
|
+
output = countNumSegments(segment.nextSegment) + 1;
|
378
|
+
} else {
|
379
|
+
output = 1;
|
380
|
+
}
|
381
|
+
for (var branch in segment.branches) {
|
382
|
+
output += countNumSegments(branch);
|
383
|
+
}
|
384
|
+
return output;
|
385
|
+
}
|
386
|
+
});
|
387
|
+
})();
|