jax 2.0.6 → 2.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +8 -0
- data/Rakefile +3 -2
- data/features/support/env.rb +1 -2
- data/features/support/setup.rb +13 -0
- data/lib/assets/javascripts/jax/mvc/model.js +18 -0
- data/lib/assets/javascripts/jax/mvc/route_set.js +3 -3
- data/lib/assets/javascripts/jax/mvc/view_manager.js +9 -5
- data/lib/assets/javascripts/jax/webgl/world.js +58 -53
- data/lib/jax/version.rb +1 -1
- data/spec/javascripts/jax/mvc/controller_spec.js +22 -0
- data/spec/javascripts/jax/mvc/route_set_spec.js +4 -1
- data/spec/javascripts/jax/world_spec.js +54 -37
- metadata +42 -42
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
* 2.0.7 *
|
2
|
+
|
3
|
+
* Resolved issue #48: Unable to reliably pick any object not explicitly added to World
|
4
|
+
|
5
|
+
* Resolved issue #54: Default views can't be overridden
|
6
|
+
|
7
|
+
|
8
|
+
|
1
9
|
* 2.0.6 *
|
2
10
|
|
3
11
|
* Resolved issue #30: `Jax.Framebuffer#getTexture(context, index)` now returns texture
|
data/Rakefile
CHANGED
@@ -21,7 +21,7 @@ end
|
|
21
21
|
|
22
22
|
require 'cucumber/rake/task'
|
23
23
|
Cucumber::Rake::Task.new(:cucumber) do |t|
|
24
|
-
t.cucumber_opts = ["-f", "pretty", "-f", "rerun", "-o", "features/rerun.txt", "-t", "~@wip"]
|
24
|
+
t.cucumber_opts = ["-f", "pretty", "-f", "rerun", "-r", "features", "-o", "features/rerun.txt", "-t", "~@wip"]
|
25
25
|
unless ENV['FEATURE']
|
26
26
|
if !ENV['ALL'] &&
|
27
27
|
File.file?(rerun = File.expand_path("features/rerun.txt", File.dirname(__FILE__))) &&
|
@@ -177,7 +177,7 @@ namespace :doc do
|
|
177
177
|
"https://github.com/sinisterchipmunk/jax/tree/master/#{obj.file}#L#{obj.line_number}"
|
178
178
|
},
|
179
179
|
:pretty_urls => false,
|
180
|
-
:bust_cache =>
|
180
|
+
:bust_cache => true,
|
181
181
|
:name => 'Jax WebGL Framework',
|
182
182
|
:short_name => 'Jax',
|
183
183
|
:home_url => 'http://jaxgl.com',
|
@@ -339,3 +339,4 @@ task :guides => 'guides:generate'
|
|
339
339
|
|
340
340
|
# disabled node tests for now, since Jax.DataRegion and friends break it. Rake jasmine instead.
|
341
341
|
task :default => ['spec', 'cucumber', 'travis', 'guides']
|
342
|
+
task :release => 'guides:publish'
|
data/features/support/env.rb
CHANGED
@@ -8,8 +8,7 @@ Jax::Rails::Application.config.cache_classes = false
|
|
8
8
|
|
9
9
|
# IMPORTANT: it is necessary to set this _prior_ to app initialization in order to pick up asset dirs
|
10
10
|
::Rails.application.config.root = File.expand_path("../../tmp/rails-cukes", File.dirname(__FILE__))
|
11
|
-
|
12
|
-
Jax::Rails::Application.initialize!
|
11
|
+
::Rails.application.config.reload_plugins = true
|
13
12
|
|
14
13
|
require 'cucumber/rails/action_controller'
|
15
14
|
|
data/features/support/setup.rb
CHANGED
@@ -6,9 +6,22 @@ Before do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
Before("@rails") do
|
9
|
+
FileUtils.rm_rf File.join($cucumber_root, "tmp/rails-cukes").to_s
|
9
10
|
setup_rails_environment
|
10
11
|
create_directory "app/assets/jax/shaders"
|
12
|
+
create_directory "vendor/plugins/mine/app/assets/jax"
|
11
13
|
route "mount Jax::Engine => '/'"
|
14
|
+
|
15
|
+
# boot the app, failing silently if it's already booted
|
16
|
+
# silent failure is necessary because we can't boot for
|
17
|
+
# each feature in isolation
|
18
|
+
begin
|
19
|
+
Jax::Rails::Application.initialize!
|
20
|
+
rescue
|
21
|
+
if $!.message != "Application has been already initialized."
|
22
|
+
raise
|
23
|
+
end
|
24
|
+
end
|
12
25
|
end
|
13
26
|
|
14
27
|
After do
|
@@ -89,6 +89,7 @@
|
|
89
89
|
*
|
90
90
|
**/
|
91
91
|
initialize: function(data) {
|
92
|
+
this.__unique_id = Jax.Model.__unique_id_tracker++;
|
92
93
|
this.camera = new Jax.Camera();
|
93
94
|
|
94
95
|
initProperties(this, Jax.Model.default_properties);
|
@@ -137,6 +138,9 @@
|
|
137
138
|
if (this.mesh)
|
138
139
|
{
|
139
140
|
var self = this;
|
141
|
+
if (!Jax.Model.__instances[this.__unique_id])
|
142
|
+
Jax.Model.__instances[this.__unique_id] = this;
|
143
|
+
options = Jax.Util.normalizeOptions(options, { model_index: this.__unique_id });
|
140
144
|
context.pushMatrix(function() {
|
141
145
|
context.multModelMatrix(self.camera.getTransformationMatrix());
|
142
146
|
self.mesh.render(context, options);
|
@@ -201,6 +205,8 @@
|
|
201
205
|
dispose: function() {
|
202
206
|
if (this.mesh)
|
203
207
|
this.mesh.dispose();
|
208
|
+
if (Jax.Model.__instances[this.__unique_id])
|
209
|
+
delete Jax.Model.__instances[this.__unique_id];
|
204
210
|
},
|
205
211
|
|
206
212
|
/**
|
@@ -330,4 +336,16 @@
|
|
330
336
|
Object.extend(klass, model_class_methods);
|
331
337
|
return klass;
|
332
338
|
};
|
339
|
+
|
340
|
+
/*
|
341
|
+
This is touchy. Jax.World needs to be able to look up models
|
342
|
+
that aren't necessarily in the world (using its unique ID).
|
343
|
+
However, we want to be careful not to leave references to
|
344
|
+
models strewn about; the user may need to garbage-collect
|
345
|
+
them. So, we'll track them using this variable; they only
|
346
|
+
get added to the variable upon render, and the reference
|
347
|
+
gets deleted whenever the model is disposed.
|
348
|
+
*/
|
349
|
+
Jax.Model.__unique_id_tracker = 1;
|
350
|
+
Jax.Model.__instances = {};
|
333
351
|
})();
|
@@ -64,9 +64,9 @@ Jax.RouteSet = (function() {
|
|
64
64
|
map: function(path, controller) {
|
65
65
|
if (!path) throw new Error("path is required");
|
66
66
|
var parts = path.split(/\//);
|
67
|
-
var controller_name = parts[0];
|
67
|
+
var controller_name = Jax.Util.underscore(parts[0]);
|
68
68
|
|
69
|
-
this._map[
|
69
|
+
this._map[controller_name] = controller;
|
70
70
|
|
71
71
|
if (!Jax.views.exists(controller_name+"/index"))
|
72
72
|
Jax.views.push(controller_name+"/index", function() {
|
@@ -104,7 +104,7 @@ Jax.RouteSet = (function() {
|
|
104
104
|
var parts = path.split(/\//);
|
105
105
|
if (parts.length > 2 || parts.length == 0)
|
106
106
|
throw new Error("Invalid path format. String should look like 'controller/action'.");
|
107
|
-
var controller_name = parts[0];
|
107
|
+
var controller_name = Jax.Util.underscore(parts[0]);
|
108
108
|
var action_name = parts[1] || "index";
|
109
109
|
|
110
110
|
var controller_class = this._map[Jax.Util.underscore(controller_name)];
|
@@ -17,7 +17,7 @@ Jax.ViewManager = (function() {
|
|
17
17
|
* If the path is already stored, the current one will be replaced.
|
18
18
|
**/
|
19
19
|
push: function(path, view) {
|
20
|
-
this.views[
|
20
|
+
this.views[Jax.Util.underscore(path)] = view;
|
21
21
|
},
|
22
22
|
|
23
23
|
/**
|
@@ -29,8 +29,8 @@ Jax.ViewManager = (function() {
|
|
29
29
|
* if not handled appropriately.
|
30
30
|
**/
|
31
31
|
get: function(path) {
|
32
|
-
if (this.views[
|
33
|
-
return new Jax.View(this.views[
|
32
|
+
if (this.views[Jax.Util.underscore(path)])
|
33
|
+
return new Jax.View(this.views[Jax.Util.underscore(path)]);
|
34
34
|
else throw new Error("Could not find view at '"+path+"'!");
|
35
35
|
},
|
36
36
|
|
@@ -51,7 +51,11 @@ Jax.ViewManager = (function() {
|
|
51
51
|
* Removes the specified view path and, if it existed to begin with, returns it.
|
52
52
|
* Otherwise undefined is returned.
|
53
53
|
**/
|
54
|
-
remove: function(path) {
|
54
|
+
remove: function(path) {
|
55
|
+
var result = this.views[Jax.Util.underscore(path)];
|
56
|
+
delete this.views[Jax.Util.underscore(path)];
|
57
|
+
return result;
|
58
|
+
},
|
55
59
|
|
56
60
|
/**
|
57
61
|
* Jax.ViewManager#exists(path) -> Boolean
|
@@ -59,7 +63,7 @@ Jax.ViewManager = (function() {
|
|
59
63
|
* Returns true if a view exists for the specified view path, false otherwise.
|
60
64
|
**/
|
61
65
|
exists: function(path) {
|
62
|
-
return !!this.views[path];
|
66
|
+
return !!this.views[Jax.Util.underscore(path)];
|
63
67
|
}
|
64
68
|
});
|
65
69
|
})();
|
@@ -22,7 +22,7 @@ Jax.World = (function() {
|
|
22
22
|
initialize: function(context) {
|
23
23
|
this.context = context;
|
24
24
|
this.lighting = new Jax.Scene.LightManager(context);
|
25
|
-
this.objects
|
25
|
+
this.objects = {};
|
26
26
|
},
|
27
27
|
|
28
28
|
/**
|
@@ -41,42 +41,40 @@ Jax.World = (function() {
|
|
41
41
|
*
|
42
42
|
**/
|
43
43
|
addObject: function(object) {
|
44
|
-
this.objects.
|
44
|
+
this.objects[object.__unique_id] = object;
|
45
|
+
// this.objects.push(object);
|
45
46
|
if (object.isLit() || object.isShadowCaster())
|
46
47
|
this.lighting.addObject(object);
|
47
48
|
return object;
|
48
49
|
},
|
49
50
|
|
50
51
|
/**
|
51
|
-
* Jax.World#getObject(
|
52
|
-
* -
|
52
|
+
* Jax.World#getObject(unique_id) -> Jax.Model
|
53
|
+
* - unique_id (Number): the unique ID associated with this model instance
|
53
54
|
*
|
54
|
-
* Returns the object with the specified
|
55
|
+
* Returns the object with the specified unique ID if it has been
|
56
|
+
* added to this World, or undefined if it has not.
|
55
57
|
**/
|
56
|
-
getObject: function(
|
58
|
+
getObject: function(unique_id) { return this.objects[unique_id]; },
|
57
59
|
|
58
60
|
/**
|
59
|
-
* Jax.World#removeObject(
|
60
|
-
* -
|
61
|
+
* Jax.World#removeObject(object_or_unique_id) -> Jax.Model
|
62
|
+
* - object_or_unique_id (Number|Jax.Model): the model instance to remove,
|
63
|
+
* or its unique ID
|
61
64
|
*
|
62
|
-
* If the model or its
|
63
|
-
* Otherwise, the object is removed from
|
65
|
+
* If the model or its ID has not been added to this World, nothing happens
|
66
|
+
* and the return value is undefined. Otherwise, the object is removed from
|
67
|
+
* this World and then returned.
|
64
68
|
**/
|
65
|
-
removeObject: function(
|
66
|
-
if (
|
67
|
-
var obj = this.objects[
|
68
|
-
this.objects
|
69
|
+
removeObject: function(object_or_id) {
|
70
|
+
if (typeof(object_or_id) == 'number') {
|
71
|
+
var obj = this.objects[object_or_id];
|
72
|
+
delete this.objects[object_or_id];
|
69
73
|
this.lighting.removeObject(obj);
|
70
74
|
return obj;
|
75
|
+
} else {
|
76
|
+
this.removeObject(object_or_id.__unique_id);
|
71
77
|
}
|
72
|
-
else
|
73
|
-
for (var i = 0; i < this.objects.length; i++)
|
74
|
-
if (this.objects[i] == object_or_index)
|
75
|
-
{
|
76
|
-
this.objects.splice(i, 1);
|
77
|
-
this.lighting.removeObject(this.objects[i]);
|
78
|
-
return this.objects[i];
|
79
|
-
}
|
80
78
|
},
|
81
79
|
|
82
80
|
/**
|
@@ -88,13 +86,13 @@ Jax.World = (function() {
|
|
88
86
|
* - ary (Array): an optional array to populate. A new one will be created if this is not specified.
|
89
87
|
* (Note: the array's contents will be cleared.)
|
90
88
|
*
|
91
|
-
* Picks all visible object
|
89
|
+
* Picks all visible object IDs within the specified rectangular regions and returns them as elements in
|
92
90
|
* an array.
|
93
91
|
*
|
94
|
-
* An object's
|
95
|
-
* valid:
|
92
|
+
* An object's ID matches is unique throughout Jax, even across multiple contexts.
|
96
93
|
*
|
97
|
-
*
|
94
|
+
* If you want references to the actual objects, instead of just their unique IDs, consider using
|
95
|
+
* the #pickRegion() method instead.
|
98
96
|
*
|
99
97
|
**/
|
100
98
|
pickRegionalIndices: function(x1, y1, x2, y2, ary) {
|
@@ -103,6 +101,8 @@ Jax.World = (function() {
|
|
103
101
|
else ary = new Array();
|
104
102
|
var world = this, pickBuffer = getPickBuffer(this), context = this.context;
|
105
103
|
var data = new Uint8Array(w*h*4);
|
104
|
+
x1 = Math.min(x1, x2);
|
105
|
+
y1 = Math.min(y1, y2);
|
106
106
|
|
107
107
|
pickBuffer.bind(context, function() {
|
108
108
|
pickBuffer.viewport(context);
|
@@ -122,7 +122,7 @@ Jax.World = (function() {
|
|
122
122
|
for (var i = 2; i < data.length; i += 4) {
|
123
123
|
if (data[i] > 0) { // blue key exists, we've found an object
|
124
124
|
index = Jax.Util.decodePickingColor(data[i-2], data[i-1], data[i], data[i+1]);
|
125
|
-
if (index != undefined) {
|
125
|
+
if (index != undefined && ary.indexOf(index) == -1) {
|
126
126
|
ary.push(index);
|
127
127
|
}
|
128
128
|
}
|
@@ -132,7 +132,7 @@ Jax.World = (function() {
|
|
132
132
|
},
|
133
133
|
|
134
134
|
/**
|
135
|
-
* Jax.World#pickRegion(x1, y1, x2, y2) -> Array
|
135
|
+
* Jax.World#pickRegion(x1, y1, x2, y2[, ary]) -> Array
|
136
136
|
* - x1 (Number): the screen X coordinate of the first corner of the 2D rectangle within which to pick
|
137
137
|
* - y1 (Number): the screen Y coordinate of the first corner of the 2D rectangle within which to pick
|
138
138
|
* - x2 (Number): the screen X coordinate of the second corner of the 2D rectangle within which to pick
|
@@ -144,9 +144,9 @@ Jax.World = (function() {
|
|
144
144
|
* an array.
|
145
145
|
**/
|
146
146
|
pickRegion: function(x1, y1, x2, y2, ary) {
|
147
|
-
var result = this.pickRegionalIndices(x1, y1, x2, y2);
|
147
|
+
var result = this.pickRegionalIndices(x1, y1, x2, y2, ary);
|
148
148
|
for (var i = 0; i < result.length; i++)
|
149
|
-
result[i] =
|
149
|
+
result[i] = Jax.Model.__instances[result[i]];
|
150
150
|
return result;
|
151
151
|
},
|
152
152
|
|
@@ -176,7 +176,7 @@ Jax.World = (function() {
|
|
176
176
|
pick: function(x, y) {
|
177
177
|
var index = this.pickIndex(x, y);
|
178
178
|
if (index != undefined) {
|
179
|
-
return
|
179
|
+
return Jax.Model.__instances[index];
|
180
180
|
}
|
181
181
|
return index;
|
182
182
|
},
|
@@ -186,7 +186,9 @@ Jax.World = (function() {
|
|
186
186
|
* Returns the number of objects currently registered with this World.
|
187
187
|
**/
|
188
188
|
countObjects: function() {
|
189
|
-
|
189
|
+
var count = 0;
|
190
|
+
for (var i in this.objects) count++;
|
191
|
+
return count;
|
190
192
|
},
|
191
193
|
|
192
194
|
/**
|
@@ -216,26 +218,22 @@ Jax.World = (function() {
|
|
216
218
|
/* this.current_pass is used by the material */
|
217
219
|
|
218
220
|
this.context.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
219
|
-
var
|
221
|
+
var _options = Jax.Util.normalizeOptions(options, {unlit:true});
|
220
222
|
|
221
|
-
if (this.lighting.isEnabled() && (!
|
223
|
+
if (this.lighting.isEnabled() && (!_options.material || (_options.material.supportsLighting && _options.material.supportsLighting()))) {
|
222
224
|
/* illumination pass */
|
223
225
|
this.context.current_pass = Jax.Scene.ILLUMINATION_PASS;
|
224
226
|
this.lighting.illuminate(this.context, options);
|
225
227
|
|
226
228
|
/* ambient pass - unlit objects only because lit objects get ambient+diffuse+specular in one pass */
|
227
229
|
this.context.current_pass = Jax.Scene.AMBIENT_PASS;
|
228
|
-
for (i
|
229
|
-
if (!this.objects[i].isLit())
|
230
|
-
|
231
|
-
this.objects[i].render(this.context, unlit);
|
232
|
-
}
|
230
|
+
for (i in this.objects)
|
231
|
+
if (!this.objects[i].isLit())
|
232
|
+
this.objects[i].render(this.context, _options);
|
233
233
|
} else {
|
234
234
|
this.context.current_pass = Jax.Scene.AMBIENT_PASS;
|
235
|
-
for (i
|
236
|
-
|
237
|
-
this.objects[i].render(this.context, unlit);
|
238
|
-
}
|
235
|
+
for (i in this.objects)
|
236
|
+
this.objects[i].render(this.context, _options);
|
239
237
|
}
|
240
238
|
|
241
239
|
return this;
|
@@ -250,27 +248,34 @@ Jax.World = (function() {
|
|
250
248
|
* the objects' respective +update+ functions (if they have one).
|
251
249
|
**/
|
252
250
|
update: function(timechange) {
|
253
|
-
for (var i
|
251
|
+
for (var i in this.objects) {
|
254
252
|
if (this.objects[i].update)
|
255
253
|
this.objects[i].update(timechange);
|
254
|
+
}
|
256
255
|
return this;
|
257
256
|
},
|
258
257
|
|
259
258
|
/**
|
260
|
-
* Jax.World#dispose() -> Jax.World
|
259
|
+
* Jax.World#dispose([include_objects=true]) -> Jax.World
|
261
260
|
*
|
262
261
|
* Disposes of this world by removing all references to its objects and
|
263
|
-
* reinitializing its +Jax.Scene.LightManager+ instance. Note that
|
264
|
-
*
|
265
|
-
*
|
266
|
-
*
|
267
|
-
*
|
262
|
+
* reinitializing its +Jax.Scene.LightManager+ instance. Note that by
|
263
|
+
* default, objects within this world will also be disposed. Pass
|
264
|
+
* `false` as an argument if you do not want the objects to be disposed.
|
265
|
+
*
|
266
|
+
* Note that both models and meshes _can_ be reused after disposal; they'll just
|
267
|
+
* be silently re-initialized. This means it is safe to dispose of models while
|
268
|
+
* they are still being used (although this is slow and not recommended if at all
|
269
|
+
* avoidable).
|
270
|
+
*
|
268
271
|
**/
|
269
|
-
dispose: function() {
|
272
|
+
dispose: function(include_objects) {
|
270
273
|
var i, o;
|
271
274
|
|
272
|
-
for (i
|
273
|
-
|
275
|
+
for (i in this.objects) {
|
276
|
+
if (include_objects !== false)
|
277
|
+
delete this.objects[i];
|
278
|
+
}
|
274
279
|
|
275
280
|
this.lighting = new Jax.Scene.LightManager(this.context);
|
276
281
|
}
|
data/lib/jax/version.rb
CHANGED
@@ -8,6 +8,28 @@ describe("Jax.Controller", function() {
|
|
8
8
|
expect(Jax.views.find("welcome/index")).not.toBeUndefined();
|
9
9
|
});
|
10
10
|
|
11
|
+
describe("with a view defined", function() {
|
12
|
+
var view;
|
13
|
+
beforeEach(function() {
|
14
|
+
view = function() { };
|
15
|
+
Jax.views.push("FooBars/index", view);
|
16
|
+
});
|
17
|
+
|
18
|
+
it("should indicate the view exists", function() {
|
19
|
+
expect(Jax.views.exists("foo_bars/index")).toBeTruthy();
|
20
|
+
});
|
21
|
+
|
22
|
+
it("should indicate CamelCased variants of the view exist", function() {
|
23
|
+
expect(Jax.views.exists("Foo_bars/index")).toBeTruthy();
|
24
|
+
expect(Jax.views.exists("FooBars/index")).toBeTruthy();
|
25
|
+
});
|
26
|
+
|
27
|
+
it("should override the default view", function() {
|
28
|
+
Jax.Controller.create("FooBars", {});
|
29
|
+
expect(Jax.views.find("foo_bars/index").view_func).toBe(view);
|
30
|
+
});
|
31
|
+
});
|
32
|
+
|
11
33
|
describe("with an update method", function() {
|
12
34
|
var context;
|
13
35
|
|
@@ -3,7 +3,10 @@ describe("Jax.RouteSet", function() {
|
|
3
3
|
var controller_class = Jax.Controller.create({index: function() { }});
|
4
4
|
Jax.views.push("generic/index", function() { });
|
5
5
|
|
6
|
-
beforeEach(function() {
|
6
|
+
beforeEach(function() {
|
7
|
+
map = Jax.routes;
|
8
|
+
map.clear();
|
9
|
+
});
|
7
10
|
|
8
11
|
describe("when a CamelCase controller name is given", function() {
|
9
12
|
beforeEach(function() {
|
@@ -44,64 +44,81 @@ describe("Jax.World", function() {
|
|
44
44
|
obottomright = world.addObject(new Jax.Model({position:[ 2.5,-2.5, -5],mesh:mesh}));
|
45
45
|
});
|
46
46
|
|
47
|
-
it("center", function() { expect(world.pick(at.center_x, at.center_y)).
|
48
|
-
it("top left", function() { expect(world.pick(at.left, at.top)).
|
49
|
-
it("top right", function() { expect(world.pick(at.right,at.top)).
|
50
|
-
it("bottom left", function() { expect(world.pick(at.left, at.bottom)).
|
51
|
-
it("bottom right", function() { expect(world.pick(at.right,at.bottom)).
|
52
|
-
|
47
|
+
it("center", function() { expect(world.pick(at.center_x, at.center_y) === ofront).toBeTruthy(); });
|
48
|
+
it("top left", function() { expect(world.pick(at.left, at.top) === otopleft).toBeTruthy(); });
|
49
|
+
it("top right", function() { expect(world.pick(at.right,at.top) === otopright).toBeTruthy(); });
|
50
|
+
it("bottom left", function() { expect(world.pick(at.left, at.bottom) === obottomleft).toBeTruthy(); });
|
51
|
+
it("bottom right", function() { expect(world.pick(at.right,at.bottom) === obottomright).toBeTruthy(); });
|
52
|
+
|
53
53
|
it("region: everything", function() {
|
54
54
|
var objects = world.pickRegion(at.left, at.top, at.right, at.bottom);
|
55
|
-
expect(objects
|
56
|
-
expect(objects
|
57
|
-
expect(objects
|
58
|
-
expect(objects
|
59
|
-
expect(objects
|
55
|
+
expect(objects.indexOf(ofront)).not.toEqual(-1);
|
56
|
+
expect(objects.indexOf(otopleft)).not.toEqual(-1);
|
57
|
+
expect(objects.indexOf(otopright)).not.toEqual(-1);
|
58
|
+
expect(objects.indexOf(obottomleft)).not.toEqual(-1);
|
59
|
+
expect(objects.indexOf(obottomright)).not.toEqual(-1);
|
60
60
|
});
|
61
61
|
|
62
62
|
it("region: top-left quadrant", function() {
|
63
63
|
var objects = world.pickRegion(at.left, at.top, at.center_x, at.center_y);
|
64
|
-
expect(objects
|
65
|
-
expect(objects
|
66
|
-
expect(objects
|
67
|
-
expect(objects
|
68
|
-
expect(objects
|
64
|
+
expect(objects.indexOf(ofront)).not.toEqual(-1);
|
65
|
+
expect(objects.indexOf(otopleft)).not.toEqual(-1);
|
66
|
+
expect(objects.indexOf(otopright)).toEqual(-1);
|
67
|
+
expect(objects.indexOf(obottomleft)).toEqual(-1);
|
68
|
+
expect(objects.indexOf(obottomright)).toEqual(-1);
|
69
69
|
});
|
70
|
-
|
70
|
+
|
71
71
|
it("region: top-right quadrant", function() {
|
72
72
|
var objects = world.pickRegion(at.right, at.top, at.center_x, at.center_y);
|
73
|
-
expect(objects
|
74
|
-
expect(objects
|
75
|
-
expect(objects
|
76
|
-
expect(objects
|
77
|
-
expect(objects
|
73
|
+
expect(objects.indexOf(ofront)).not.toEqual(-1);
|
74
|
+
expect(objects.indexOf(otopleft)).toEqual(-1);
|
75
|
+
expect(objects.indexOf(otopright)).not.toEqual(-1);
|
76
|
+
expect(objects.indexOf(obottomleft)).toEqual(-1);
|
77
|
+
expect(objects.indexOf(obottomright)).toEqual(-1);
|
78
78
|
});
|
79
|
-
|
79
|
+
|
80
80
|
it("region: bottom-left quadrant", function() {
|
81
81
|
var objects = world.pickRegion(at.left, at.bottom, at.center_x, at.center_y);
|
82
|
-
expect(objects
|
83
|
-
expect(objects
|
84
|
-
expect(objects
|
85
|
-
expect(objects
|
86
|
-
expect(objects
|
82
|
+
expect(objects.indexOf(ofront)).not.toEqual(-1);
|
83
|
+
expect(objects.indexOf(otopleft)).toEqual(-1);
|
84
|
+
expect(objects.indexOf(otopright)).toEqual(-1);
|
85
|
+
expect(objects.indexOf(obottomleft)).not.toEqual(-1);
|
86
|
+
expect(objects.indexOf(obottomright)).toEqual(-1);
|
87
87
|
});
|
88
88
|
|
89
89
|
it("region: bottom-right quadrant", function() {
|
90
90
|
var objects = world.pickRegion(at.right, at.bottom, at.center_x, at.center_y);
|
91
|
-
expect(objects
|
92
|
-
expect(objects
|
93
|
-
expect(objects
|
94
|
-
expect(objects
|
95
|
-
expect(objects
|
91
|
+
expect(objects.indexOf(ofront)).not.toEqual(-1);
|
92
|
+
expect(objects.indexOf(otopleft)).toEqual(-1);
|
93
|
+
expect(objects.indexOf(otopright)).toEqual(-1);
|
94
|
+
expect(objects.indexOf(obottomleft)).toEqual(-1);
|
95
|
+
expect(objects.indexOf(obottomright)).not.toEqual(-1);
|
96
|
+
});
|
97
|
+
|
98
|
+
it("should be able to pick objects not explicitly added to the world", function() {
|
99
|
+
var onested = new Jax.Model({position: [0.0, 0.0, -5], mesh: mesh});
|
100
|
+
ofront.render = function(context, options) { onested.render(context, options); };
|
101
|
+
expect(world.pick(at.center_x, at.center_y) === onested).toBeTruthy();
|
102
|
+
});
|
103
|
+
|
104
|
+
it("should be able to regionally pick objects not explicitly added to the world", function() {
|
105
|
+
var onested = new Jax.Model({position: [0.0, 0.0, -5], mesh: mesh});
|
106
|
+
ofront.render = function(context, options) { onested.render(context, options); };
|
107
|
+
expect(world.pickRegion(at.center_x-1, at.center_y-1, at.center_x+1, at.center_y+1)[0] === onested).toBeTruthy();
|
96
108
|
});
|
97
|
-
*/
|
98
109
|
});
|
99
110
|
|
100
111
|
describe("with an object", function() {
|
101
|
-
|
112
|
+
var model;
|
113
|
+
beforeEach(function() { world.addObject(model = new Jax.Model()); });
|
102
114
|
|
103
|
-
it("should remove
|
104
|
-
world.removeObject(
|
115
|
+
it("should remove objects by reference", function() {
|
116
|
+
world.removeObject(model);
|
117
|
+
expect(world.countObjects()).toEqual(0);
|
118
|
+
});
|
119
|
+
|
120
|
+
it("should remove objects by ID", function() {
|
121
|
+
world.removeObject(model.__unique_id);
|
105
122
|
expect(world.countObjects()).toEqual(0);
|
106
123
|
});
|
107
124
|
});
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jax
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-01-08 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
16
|
-
requirement: &
|
16
|
+
requirement: &2153840660 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 3.1.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2153840660
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: jquery-rails
|
27
|
-
requirement: &
|
27
|
+
requirement: &2153840160 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 1.0.13
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2153840160
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: jasmine
|
38
|
-
requirement: &
|
38
|
+
requirement: &2153839600 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 1.0.2.0
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2153839600
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rest-client
|
49
|
-
requirement: &
|
49
|
+
requirement: &2153839120 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 1.6.3
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *2153839120
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rspec
|
60
|
-
requirement: &
|
60
|
+
requirement: &2153838620 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 2.6.0
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *2153838620
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: coffee-rails
|
71
|
-
requirement: &
|
71
|
+
requirement: &2153837980 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: 3.1.0
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *2153837980
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: coderay
|
82
|
-
requirement: &
|
82
|
+
requirement: &2153837480 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ~>
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: 0.9.7
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *2153837480
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: sqlite3
|
93
|
-
requirement: &
|
93
|
+
requirement: &2153837020 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ~>
|
@@ -98,10 +98,10 @@ dependencies:
|
|
98
98
|
version: 1.3.4
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *2153837020
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
103
|
name: sass-rails
|
104
|
-
requirement: &
|
104
|
+
requirement: &2153836420 !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
107
|
- - ~>
|
@@ -109,10 +109,10 @@ dependencies:
|
|
109
109
|
version: 3.1.0
|
110
110
|
type: :development
|
111
111
|
prerelease: false
|
112
|
-
version_requirements: *
|
112
|
+
version_requirements: *2153836420
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: uglifier
|
115
|
-
requirement: &
|
115
|
+
requirement: &2153835940 !ruby/object:Gem::Requirement
|
116
116
|
none: false
|
117
117
|
requirements:
|
118
118
|
- - ~>
|
@@ -120,10 +120,10 @@ dependencies:
|
|
120
120
|
version: 1.0.2
|
121
121
|
type: :development
|
122
122
|
prerelease: false
|
123
|
-
version_requirements: *
|
123
|
+
version_requirements: *2153835940
|
124
124
|
- !ruby/object:Gem::Dependency
|
125
125
|
name: genspec
|
126
|
-
requirement: &
|
126
|
+
requirement: &2153835460 !ruby/object:Gem::Requirement
|
127
127
|
none: false
|
128
128
|
requirements:
|
129
129
|
- - ~>
|
@@ -131,10 +131,10 @@ dependencies:
|
|
131
131
|
version: 0.2.3
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
|
-
version_requirements: *
|
134
|
+
version_requirements: *2153835460
|
135
135
|
- !ruby/object:Gem::Dependency
|
136
136
|
name: selenium-webdriver
|
137
|
-
requirement: &
|
137
|
+
requirement: &2153834860 !ruby/object:Gem::Requirement
|
138
138
|
none: false
|
139
139
|
requirements:
|
140
140
|
- - ~>
|
@@ -142,10 +142,10 @@ dependencies:
|
|
142
142
|
version: 2.9.1
|
143
143
|
type: :development
|
144
144
|
prerelease: false
|
145
|
-
version_requirements: *
|
145
|
+
version_requirements: *2153834860
|
146
146
|
- !ruby/object:Gem::Dependency
|
147
147
|
name: fakeweb
|
148
|
-
requirement: &
|
148
|
+
requirement: &2153834380 !ruby/object:Gem::Requirement
|
149
149
|
none: false
|
150
150
|
requirements:
|
151
151
|
- - ~>
|
@@ -153,10 +153,10 @@ dependencies:
|
|
153
153
|
version: 1.3.0
|
154
154
|
type: :development
|
155
155
|
prerelease: false
|
156
|
-
version_requirements: *
|
156
|
+
version_requirements: *2153834380
|
157
157
|
- !ruby/object:Gem::Dependency
|
158
158
|
name: ansi
|
159
|
-
requirement: &
|
159
|
+
requirement: &2153834000 !ruby/object:Gem::Requirement
|
160
160
|
none: false
|
161
161
|
requirements:
|
162
162
|
- - ! '>='
|
@@ -164,10 +164,10 @@ dependencies:
|
|
164
164
|
version: '0'
|
165
165
|
type: :development
|
166
166
|
prerelease: false
|
167
|
-
version_requirements: *
|
167
|
+
version_requirements: *2153834000
|
168
168
|
- !ruby/object:Gem::Dependency
|
169
169
|
name: cucumber-rails
|
170
|
-
requirement: &
|
170
|
+
requirement: &2153833460 !ruby/object:Gem::Requirement
|
171
171
|
none: false
|
172
172
|
requirements:
|
173
173
|
- - ~>
|
@@ -175,10 +175,10 @@ dependencies:
|
|
175
175
|
version: 1.0.2
|
176
176
|
type: :development
|
177
177
|
prerelease: false
|
178
|
-
version_requirements: *
|
178
|
+
version_requirements: *2153833460
|
179
179
|
- !ruby/object:Gem::Dependency
|
180
180
|
name: RedCloth
|
181
|
-
requirement: &
|
181
|
+
requirement: &2153832860 !ruby/object:Gem::Requirement
|
182
182
|
none: false
|
183
183
|
requirements:
|
184
184
|
- - ~>
|
@@ -186,10 +186,10 @@ dependencies:
|
|
186
186
|
version: '4.2'
|
187
187
|
type: :development
|
188
188
|
prerelease: false
|
189
|
-
version_requirements: *
|
189
|
+
version_requirements: *2153832860
|
190
190
|
- !ruby/object:Gem::Dependency
|
191
191
|
name: w3c_validators
|
192
|
-
requirement: &
|
192
|
+
requirement: &2153832400 !ruby/object:Gem::Requirement
|
193
193
|
none: false
|
194
194
|
requirements:
|
195
195
|
- - ~>
|
@@ -197,10 +197,10 @@ dependencies:
|
|
197
197
|
version: '1.2'
|
198
198
|
type: :development
|
199
199
|
prerelease: false
|
200
|
-
version_requirements: *
|
200
|
+
version_requirements: *2153832400
|
201
201
|
- !ruby/object:Gem::Dependency
|
202
202
|
name: treetop
|
203
|
-
requirement: &
|
203
|
+
requirement: &2153831940 !ruby/object:Gem::Requirement
|
204
204
|
none: false
|
205
205
|
requirements:
|
206
206
|
- - ~>
|
@@ -208,10 +208,10 @@ dependencies:
|
|
208
208
|
version: 1.4.9
|
209
209
|
type: :development
|
210
210
|
prerelease: false
|
211
|
-
version_requirements: *
|
211
|
+
version_requirements: *2153831940
|
212
212
|
- !ruby/object:Gem::Dependency
|
213
213
|
name: bluecloth
|
214
|
-
requirement: &
|
214
|
+
requirement: &2153831320 !ruby/object:Gem::Requirement
|
215
215
|
none: false
|
216
216
|
requirements:
|
217
217
|
- - ~>
|
@@ -219,7 +219,7 @@ dependencies:
|
|
219
219
|
version: 2.0.11
|
220
220
|
type: :development
|
221
221
|
prerelease: false
|
222
|
-
version_requirements: *
|
222
|
+
version_requirements: *2153831320
|
223
223
|
description: ! "\n Framework for creating rich WebGL-enabled applications using
|
224
224
|
JavaScript and Ruby.\n Can be used stand-alone to create static JavaScript documents,
|
225
225
|
or integrated\n seamlessly with Ruby on Rails to build dynamic WebGL applications.\n
|
@@ -648,7 +648,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
648
648
|
version: '0'
|
649
649
|
segments:
|
650
650
|
- 0
|
651
|
-
hash:
|
651
|
+
hash: -1809678549776687615
|
652
652
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
653
653
|
none: false
|
654
654
|
requirements:
|
@@ -657,7 +657,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
657
657
|
version: '0'
|
658
658
|
segments:
|
659
659
|
- 0
|
660
|
-
hash:
|
660
|
+
hash: -1809678549776687615
|
661
661
|
requirements: []
|
662
662
|
rubyforge_project: jax
|
663
663
|
rubygems_version: 1.8.10
|