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,185 @@
|
|
1
|
+
/**
|
2
|
+
* A frustum cuilling system, which manages a frustum culling worker implemented in frustumCullWorker.js
|
3
|
+
*/
|
4
|
+
(function () {
|
5
|
+
|
6
|
+
define(function () {
|
7
|
+
return System;
|
8
|
+
});
|
9
|
+
|
10
|
+
function System(systemId) {
|
11
|
+
|
12
|
+
this.systemId = systemId;
|
13
|
+
|
14
|
+
// Maximum number of bodies supported per system
|
15
|
+
var maxBodies = 1000;
|
16
|
+
|
17
|
+
var bodies = [];
|
18
|
+
var map = new Map(bodies);
|
19
|
+
|
20
|
+
// Create engine in worker
|
21
|
+
var workerPath = SceneJS.getConfigs().pluginPath + "/lib/frustum/frustumCullWorker.js";
|
22
|
+
var worker = new Worker(workerPath);
|
23
|
+
|
24
|
+
var workerOutputBuf = new ArrayBuffer(maxBodies * 3);
|
25
|
+
|
26
|
+
// True while worker is busy integrating
|
27
|
+
// We don't send integration requests to it while this is true
|
28
|
+
var integrating = false;
|
29
|
+
|
30
|
+
// System is integrating only when this true
|
31
|
+
var enabled = true;
|
32
|
+
|
33
|
+
// Schedules integration when true
|
34
|
+
var needIntegrate = true;
|
35
|
+
|
36
|
+
// Route updates from engine to bodies
|
37
|
+
worker.addEventListener('message',
|
38
|
+
function (e) {
|
39
|
+
|
40
|
+
var data = e.data;
|
41
|
+
workerOutputBuf = data.buffer; // Worker transfers ownership of buffer to us
|
42
|
+
var output = new Int16Array(workerOutputBuf);
|
43
|
+
var lenOutput = data.lenOutput;
|
44
|
+
var bodyId;
|
45
|
+
var body;
|
46
|
+
var intersect;
|
47
|
+
var canvasSize;
|
48
|
+
|
49
|
+
// The data buffer from the web worker contains a 3-element portion for
|
50
|
+
// each body, each of which contains the body ID, frustum intesection status
|
51
|
+
// and projected canvas size:
|
52
|
+
//
|
53
|
+
// [
|
54
|
+
// bodyId, intersect, canvasSize
|
55
|
+
// bodyId, intersect, canvasSize
|
56
|
+
// ...
|
57
|
+
// ]
|
58
|
+
for (var i = 0, len = lenOutput - 2; i < len; i += 3) {
|
59
|
+
bodyId = output[i]; // First element for body ID
|
60
|
+
body = bodies[bodyId];
|
61
|
+
intersect = output[i + 1];
|
62
|
+
canvasSize = output[i + 2];
|
63
|
+
if (body) { // May have been deleted
|
64
|
+
body.callback(intersect, canvasSize);
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
integrating = false;
|
69
|
+
|
70
|
+
}, false);
|
71
|
+
|
72
|
+
/**
|
73
|
+
* Configures this system
|
74
|
+
* @param configs Values for configs
|
75
|
+
*/
|
76
|
+
this.setConfigs = function (configs) {
|
77
|
+
needIntegrate = true;
|
78
|
+
worker.postMessage({ cmd:"setConfigs", configs:configs });
|
79
|
+
};
|
80
|
+
|
81
|
+
/**
|
82
|
+
* Enable or disable this system.
|
83
|
+
* To save on CPU, you would typically disable the system when its not in view.
|
84
|
+
* @param enable
|
85
|
+
*/
|
86
|
+
this.setEnabled = function (enable) {
|
87
|
+
enabled = enable;
|
88
|
+
if (enable) {
|
89
|
+
needIntegrate = true;
|
90
|
+
}
|
91
|
+
};
|
92
|
+
|
93
|
+
/**
|
94
|
+
* Creates a body, returns it's unique ID
|
95
|
+
* @param params Body params
|
96
|
+
* @param callback Callback fired whenever body updated
|
97
|
+
* @return Body ID
|
98
|
+
*/
|
99
|
+
this.createBody = function (params, callback) {
|
100
|
+
needIntegrate = true;
|
101
|
+
var bodyId = map.add({
|
102
|
+
callback:callback
|
103
|
+
});
|
104
|
+
worker.postMessage({ cmd:"createBody", bodyId:bodyId, bodyCfg:params });
|
105
|
+
return bodyId;
|
106
|
+
};
|
107
|
+
|
108
|
+
/**
|
109
|
+
* Updates an existing body
|
110
|
+
* @param bodyId Body ID
|
111
|
+
* @param params Body params
|
112
|
+
*/
|
113
|
+
this.updateBody = function (bodyId, params) {
|
114
|
+
needIntegrate = true;
|
115
|
+
worker.postMessage({ cmd:"updateBody", bodyId:bodyId, bodyCfg:params });
|
116
|
+
};
|
117
|
+
|
118
|
+
/**
|
119
|
+
* Removes a body
|
120
|
+
*/
|
121
|
+
this.removeBody = function (bodyId) {
|
122
|
+
worker.postMessage({ cmd:"removeBody", bodyId:bodyId });
|
123
|
+
map.remove(bodyId);
|
124
|
+
};
|
125
|
+
|
126
|
+
/**
|
127
|
+
* Integrates this system
|
128
|
+
* Does nothing when system is disabled with {@link System#setEnabled}.
|
129
|
+
*/
|
130
|
+
this.integrate = function () {
|
131
|
+
if (!enabled) {
|
132
|
+
return;
|
133
|
+
}
|
134
|
+
if (integrating) { // Don't choke worker
|
135
|
+
return;
|
136
|
+
}
|
137
|
+
if (needIntegrate) {
|
138
|
+
integrating = true;
|
139
|
+
needIntegrate = false;
|
140
|
+
// Transfer ownership of output buffer to the worker
|
141
|
+
var msg = {
|
142
|
+
cmd:"integrate",
|
143
|
+
buffer:workerOutputBuf
|
144
|
+
};
|
145
|
+
worker.postMessage(msg, [msg.buffer]);
|
146
|
+
}
|
147
|
+
};
|
148
|
+
|
149
|
+
/**
|
150
|
+
* Destroys system, terminating its worker
|
151
|
+
*/
|
152
|
+
this.destroy = function () {
|
153
|
+
worker.terminate();
|
154
|
+
};
|
155
|
+
}
|
156
|
+
|
157
|
+
/**
|
158
|
+
* Uniquely ID'd map of items
|
159
|
+
* @param items Array that will contain the items
|
160
|
+
*/
|
161
|
+
function Map(items) {
|
162
|
+
this.add = function (item) {
|
163
|
+
|
164
|
+
// Start looking from the beginning of the array
|
165
|
+
// because we don't want an infinitely-expanding
|
166
|
+
// sparse array as we remove then add nodes.
|
167
|
+
|
168
|
+
// We're trading insertion overhead for the benefit
|
169
|
+
// of a nicely packed array that's fast to traverse
|
170
|
+
// when posting output.
|
171
|
+
|
172
|
+
var i = 0;
|
173
|
+
while (true) {
|
174
|
+
if (!items[i]) {
|
175
|
+
items[i] = item;
|
176
|
+
return i;
|
177
|
+
}
|
178
|
+
i++;
|
179
|
+
}
|
180
|
+
};
|
181
|
+
this.remove = function (id) {
|
182
|
+
delete items[id];
|
183
|
+
};
|
184
|
+
}
|
185
|
+
})();
|
@@ -0,0 +1,174 @@
|
|
1
|
+
/**
|
2
|
+
* Container of frustum culling systems
|
3
|
+
*/
|
4
|
+
define([
|
5
|
+
// Prefix routes to plugin support libs
|
6
|
+
"scenejsPluginDeps/frustum/frustumCullSystem"
|
7
|
+
],
|
8
|
+
function (System) {
|
9
|
+
|
10
|
+
// Systems
|
11
|
+
var items = {};
|
12
|
+
|
13
|
+
// Each scene/lookat/camera combination will have its own culling system
|
14
|
+
// Each system will actually be distributed across multiple systems
|
15
|
+
// This is the number of client scene nodes that will be served by each of those
|
16
|
+
// TODO: tune this
|
17
|
+
var BODIES_PER_SYSTEM = 100;
|
18
|
+
|
19
|
+
return {
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Acquire a frustum culling system for a SceneJS node
|
23
|
+
*
|
24
|
+
* @param {SceneJS.Node} node
|
25
|
+
* @return {System} The system
|
26
|
+
*/
|
27
|
+
getSystem:function (node) {
|
28
|
+
|
29
|
+
// Get parent lookat and camera nodes,
|
30
|
+
// along with the scene root
|
31
|
+
|
32
|
+
var lookat = node.getParentOfType("lookAt");
|
33
|
+
var camera = node.getParentOfType("camera");
|
34
|
+
var scene = node.getScene();
|
35
|
+
|
36
|
+
// Generate a system ID unique to the
|
37
|
+
// scene and whatever view and projection
|
38
|
+
// coordinate system we are within
|
39
|
+
|
40
|
+
var systemBaseId =
|
41
|
+
scene.getId()
|
42
|
+
+ (lookat ? ("." + lookat.getId()) : ".default")
|
43
|
+
+ (camera ? ("." + camera.getId()) : ".default")
|
44
|
+
+ ".";
|
45
|
+
|
46
|
+
var systemId;
|
47
|
+
var item;
|
48
|
+
|
49
|
+
// Try to acquire an existing system
|
50
|
+
// using the system ID
|
51
|
+
|
52
|
+
for (var i = 0, done = false; !done; i++) {
|
53
|
+
systemId = systemBaseId + i;
|
54
|
+
item = items[systemId];
|
55
|
+
if (item) {
|
56
|
+
if (item.useCount < BODIES_PER_SYSTEM) {
|
57
|
+
item.useCount++;
|
58
|
+
return item.system;
|
59
|
+
}
|
60
|
+
} else {
|
61
|
+
done = true;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
// Did not acquire a system - create a new system
|
66
|
+
|
67
|
+
var system = new System(systemId);
|
68
|
+
|
69
|
+
item = {
|
70
|
+
useCount:1,
|
71
|
+
system:system,
|
72
|
+
scene:scene
|
73
|
+
};
|
74
|
+
|
75
|
+
var systemConfigs = {};
|
76
|
+
|
77
|
+
// Updates to a parent 'lookat' node
|
78
|
+
// will update the system's frustum
|
79
|
+
|
80
|
+
if (lookat) {
|
81
|
+
item.lookat = lookat;
|
82
|
+
item.viewMatSub = lookat.on("matrix",
|
83
|
+
function (matrix) {
|
84
|
+
system.setConfigs({
|
85
|
+
viewMat:matrix
|
86
|
+
});
|
87
|
+
});
|
88
|
+
} else {
|
89
|
+
systemConfigs.viewMat = SceneJS.Lookat.getDefaultMatrix();
|
90
|
+
}
|
91
|
+
|
92
|
+
// Updates to a parent 'camera' node
|
93
|
+
// will update the system's frustum
|
94
|
+
|
95
|
+
if (camera) {
|
96
|
+
item.camera = camera;
|
97
|
+
item.projMatSub = camera.on("matrix",
|
98
|
+
function (matrix) {
|
99
|
+
system.setConfigs({
|
100
|
+
projMat:matrix
|
101
|
+
});
|
102
|
+
});
|
103
|
+
} else {
|
104
|
+
systemConfigs.projMat = SceneJS.Camera.getDefaultMatrix();
|
105
|
+
}
|
106
|
+
|
107
|
+
// Updates to a parent 'enable' node will
|
108
|
+
// enable or disable this culling system
|
109
|
+
|
110
|
+
// var enabled = true;
|
111
|
+
// var enable = node.getParentOfType("enable");
|
112
|
+
// if (enable) {
|
113
|
+
// item.enable = enable;
|
114
|
+
// item.enableSub = enable.on("enabled",
|
115
|
+
// function (_enabled) {
|
116
|
+
// enabled = _enabled;
|
117
|
+
// });
|
118
|
+
// }
|
119
|
+
|
120
|
+
// Integrate the system on each scene tick,
|
121
|
+
// unless disabled by parent 'enable' node
|
122
|
+
|
123
|
+
item.tickSub = scene.on("tick", // Start integrating the system on scene tick
|
124
|
+
function () {
|
125
|
+
// if (enabled) {
|
126
|
+
system.integrate();
|
127
|
+
// }
|
128
|
+
});
|
129
|
+
|
130
|
+
//
|
131
|
+
|
132
|
+
var canvas = scene.getCanvas();
|
133
|
+
systemConfigs.viewport = [0, 0, canvas.width, canvas.height];
|
134
|
+
|
135
|
+
system.setConfigs(systemConfigs);
|
136
|
+
|
137
|
+
items[systemId] = item;
|
138
|
+
|
139
|
+
return system;
|
140
|
+
},
|
141
|
+
|
142
|
+
|
143
|
+
/**
|
144
|
+
* Release a frustum culling system, destroying it if no more users.
|
145
|
+
* @param {System} system
|
146
|
+
*/
|
147
|
+
putSystem:function (system) {
|
148
|
+
var item = items[system.systemId];
|
149
|
+
if (item) {
|
150
|
+
if (item.useCount-- <= 0) {
|
151
|
+
item.system.destroy();
|
152
|
+
|
153
|
+
// Unsubscribe from any parent nodes
|
154
|
+
// we were updating the system off
|
155
|
+
|
156
|
+
if (item.lookat) {
|
157
|
+
item.lookat.off(item.viewMatSub);
|
158
|
+
}
|
159
|
+
if (item.camera) {
|
160
|
+
item.camera.off(item.projMatSub);
|
161
|
+
}
|
162
|
+
if (item.enable) {
|
163
|
+
item.enable.off(item.enableSub);
|
164
|
+
}
|
165
|
+
|
166
|
+
// Stop integrating the system
|
167
|
+
item.scene.off(item.tickSub);
|
168
|
+
|
169
|
+
delete items[system.systemId];
|
170
|
+
}
|
171
|
+
}
|
172
|
+
}
|
173
|
+
};
|
174
|
+
});
|
@@ -0,0 +1,142 @@
|
|
1
|
+
/**
|
2
|
+
* Web worker containing an instance of a frustum culling engine implemented
|
3
|
+
* in frustumCullEngine.js
|
4
|
+
*
|
5
|
+
* This worker accepts various commands to configure the engine, add or remove
|
6
|
+
* bodies, and integrate, which means find and changes in frustum intersection
|
7
|
+
* status and projected canvas size of the bodies.
|
8
|
+
*
|
9
|
+
* On each integration, for each body whose intersection state and/or canvas size
|
10
|
+
* has changed, this worker posts back an Int16Array containing those updates.
|
11
|
+
*
|
12
|
+
* Input Commands
|
13
|
+
* --------------------------------------------------------------------------
|
14
|
+
*
|
15
|
+
* Configure the system
|
16
|
+
* --------------------
|
17
|
+
* {
|
18
|
+
* cmd: "setConfigs",
|
19
|
+
* viewMat: Array(16),
|
20
|
+
* projMat: Array(16),
|
21
|
+
* viewport: Array[4]
|
22
|
+
* }
|
23
|
+
*
|
24
|
+
* Create a body
|
25
|
+
* -------------
|
26
|
+
*
|
27
|
+
* Axis-aligned bounding box:
|
28
|
+
* {
|
29
|
+
* cmd: "createBody",
|
30
|
+
* bodyId: Number,
|
31
|
+
* bodyCfg: {
|
32
|
+
* shape: "box",
|
33
|
+
* min: [Number, Number, Number],
|
34
|
+
* max: [Number, Number, Number],
|
35
|
+
* frustumCull: Boolean, // Perform frustum culling for this body? Default is true.
|
36
|
+
* detailCull: Boolean, // Perform detail culling for this body? Default is true.
|
37
|
+
* }
|
38
|
+
* }
|
39
|
+
*
|
40
|
+
* Remove a body:
|
41
|
+
* {
|
42
|
+
* cmd: "removeBody",
|
43
|
+
* bodyId: Number
|
44
|
+
* }
|
45
|
+
*
|
46
|
+
* Integrate the engine:
|
47
|
+
* {
|
48
|
+
* cmd: "integrate"
|
49
|
+
* }
|
50
|
+
*
|
51
|
+
* For efficiency, the physics system manages bodies in an array. The "bodyId"
|
52
|
+
* parameter on the "createBody" command is the index for that body in the array.
|
53
|
+
*
|
54
|
+
* The "removeBody" command will delete a body from the array, leaving a hole.
|
55
|
+
*
|
56
|
+
* The worker can handle holes in the array OK, but in order to keep the array
|
57
|
+
* from getting too sparse, it's the reponsibility of the worker client to make
|
58
|
+
* its next "createBody" command specify a "bodyId" that indexes that hole, to plug
|
59
|
+
* the gap with the next new body.
|
60
|
+
*
|
61
|
+
* Output Buffer
|
62
|
+
* --------------------------------------------------------------------------
|
63
|
+
*
|
64
|
+
* The output buffer is an Int16Array containing a 3-element portion for each
|
65
|
+
* body, each of which contains the body ID, its frustum intersection status and the
|
66
|
+
* projected size within the viewport:
|
67
|
+
*
|
68
|
+
* [
|
69
|
+
* bodyId, intersect, canvasSize,
|
70
|
+
* bodyId, intersect, canvasSize
|
71
|
+
* ...
|
72
|
+
* ]
|
73
|
+
*
|
74
|
+
* intersect:
|
75
|
+
* 0 == body is completely outside frustum
|
76
|
+
* 1 == body is partially inside frustum
|
77
|
+
* 2 == body is completely inside frustum
|
78
|
+
* Undefined when body frustumCull == false
|
79
|
+
*
|
80
|
+
* canvasSize:
|
81
|
+
* For box, will be the length of diagonal size of projected boundary.
|
82
|
+
* Undefined when body detailCull == false or intersect == 0.
|
83
|
+
*
|
84
|
+
*/
|
85
|
+
importScripts("frustumCullEngine.js");
|
86
|
+
|
87
|
+
// Array in which this worker posts back status for each updated body
|
88
|
+
var output;
|
89
|
+
|
90
|
+
// The engine
|
91
|
+
var engine = new Engine();
|
92
|
+
|
93
|
+
// Handle a command from worker owner
|
94
|
+
addEventListener("message",
|
95
|
+
function (e) {
|
96
|
+
|
97
|
+
var data = e.data;
|
98
|
+
|
99
|
+
switch (data.cmd) {
|
100
|
+
|
101
|
+
// Configure the engine
|
102
|
+
case "setConfigs":
|
103
|
+
engine.setConfigs(data.configs);
|
104
|
+
break;
|
105
|
+
|
106
|
+
// Create a body
|
107
|
+
case "createBody":
|
108
|
+
engine.addBody(data.bodyId, data.bodyCfg);
|
109
|
+
break;
|
110
|
+
|
111
|
+
// Remove a body
|
112
|
+
case "removeBody":
|
113
|
+
engine.removeBody(data.bodyId);
|
114
|
+
break;
|
115
|
+
|
116
|
+
// Integrate the engine and post back the body updates
|
117
|
+
case "integrate":
|
118
|
+
var output = new Int16Array(data.buffer);
|
119
|
+
var body;
|
120
|
+
var ibuf = 0;
|
121
|
+
engine.integrate(
|
122
|
+
function (updatedBodies, numUpdated) {
|
123
|
+
for (var i = 0; i < numUpdated; i++) {
|
124
|
+
body = updatedBodies[i];
|
125
|
+
output[ibuf++] = body.bodyId;
|
126
|
+
output[ibuf++] = body.intersect;
|
127
|
+
output[ibuf++] = body.canvasSize;
|
128
|
+
}
|
129
|
+
// Post the output
|
130
|
+
var response = {
|
131
|
+
buffer:output.buffer,
|
132
|
+
lenOutput:ibuf
|
133
|
+
};
|
134
|
+
self.postMessage(response, [response.buffer]);
|
135
|
+
});
|
136
|
+
break;
|
137
|
+
|
138
|
+
default:
|
139
|
+
break;
|
140
|
+
}
|
141
|
+
}, false);
|
142
|
+
|