jax 2.0.6 → 2.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|