jax 0.0.0.5 → 0.0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/CHANGELOG +26 -1
  2. data/Rakefile +3 -1
  3. data/builtin/shaders/picking/common.ejs +2 -0
  4. data/builtin/shaders/picking/fragment.ejs +4 -0
  5. data/builtin/shaders/picking/material.js +14 -0
  6. data/builtin/shaders/picking/vertex.ejs +24 -0
  7. data/lib/jax/generators/app/templates/public/javascripts/jax.js +289 -681
  8. data/lib/jax/generators/app/templates/spec/javascripts/support/spec_layout.html.erb +55 -2
  9. data/lib/jax/generators/shader/templates/common.ejs.tt +2 -2
  10. data/lib/jax/packager/sprockets_template.rb +1 -4
  11. data/lib/jax/routes.rb +3 -0
  12. data/lib/jax/version.rb +1 -1
  13. data/spec/example_app/app/controllers/noise_controller.js +37 -5
  14. data/spec/example_app/app/controllers/picking_controller.js +32 -0
  15. data/spec/example_app/app/helpers/picking_helper.js +3 -0
  16. data/spec/example_app/app/models/blob.js +38 -0
  17. data/spec/example_app/app/resources/blobs/default.yml +2 -0
  18. data/spec/example_app/app/resources/materials/blob.yml +2 -2
  19. data/spec/example_app/app/shaders/blob/common.ejs +8 -13
  20. data/spec/example_app/app/shaders/blob/fragment.ejs +1 -1
  21. data/spec/example_app/app/shaders/blob/material.js +15 -12
  22. data/spec/example_app/app/shaders/blob/vertex.ejs +33 -8
  23. data/spec/example_app/app/views/picking/index.js +4 -0
  24. data/spec/example_app/config/routes.rb +1 -0
  25. data/spec/example_app/spec/javascripts/controllers/picking_controller_spec.js +11 -0
  26. data/spec/example_app/spec/javascripts/helpers/picking_helper_spec.js +12 -0
  27. data/spec/example_app/spec/javascripts/models/blob_spec.js +11 -0
  28. data/spec/example_app/spec/javascripts/support/spec_layout.html.erb +40 -2
  29. data/spec/javascripts/jax/model_spec.js +10 -0
  30. data/spec/javascripts/jax/world_spec.js +74 -1
  31. data/spec/javascripts/shaders/preprocessor_spec.js +35 -0
  32. data/src/constants.yml +1 -1
  33. data/src/jax.js +30 -8
  34. data/src/jax/anim_frame.js +6 -2
  35. data/src/jax/builtin/meshes/cube.js +22 -1
  36. data/src/jax/builtin/meshes/plane.js +27 -0
  37. data/src/jax/builtin/meshes/quad.js +7 -1
  38. data/src/jax/builtin/meshes/sphere.js +20 -1
  39. data/src/jax/builtin/meshes/teapot.js +10 -0
  40. data/src/jax/builtin/meshes/torus.js +18 -0
  41. data/src/jax/compatibility.js +165 -2
  42. data/src/jax/context.js +176 -9
  43. data/src/jax/core.js +6 -3
  44. data/src/jax/core/math.js +18 -3
  45. data/src/jax/core/matrix_stack.js +4 -3
  46. data/src/jax/core/util.js +15 -0
  47. data/src/jax/events.js +67 -12
  48. data/src/jax/geometry.js +5 -1
  49. data/src/jax/geometry/plane.js +59 -5
  50. data/src/jax/{controller.js → mvc/controller.js} +38 -0
  51. data/src/jax/mvc/helper.js +35 -0
  52. data/src/jax/mvc/model.js +301 -0
  53. data/src/jax/{route_set.js → mvc/route_set.js} +0 -0
  54. data/src/jax/{view.js → mvc/view.js} +6 -0
  55. data/src/jax/{view_manager.js → mvc/view_manager.js} +1 -0
  56. data/src/jax/noise.js +13 -0
  57. data/src/jax/prototype/class.js +3 -0
  58. data/src/jax/prototype/extensions.js +26 -8
  59. data/src/jax/webgl/camera.js +6 -6
  60. data/src/jax/webgl/core/framebuffer.js +4 -4
  61. data/src/jax/webgl/material.js +16 -0
  62. data/src/jax/webgl/mesh.js +19 -4
  63. data/src/jax/webgl/scene/light_manager.js +8 -0
  64. data/src/jax/webgl/scene/light_source.js +3 -3
  65. data/src/jax/webgl/shader.js +4 -2
  66. data/src/jax/webgl/shader_chain.js +1 -0
  67. data/src/jax/webgl/world.js +157 -6
  68. data/vendor/glmatrix/glMatrix.js +365 -408
  69. metadata +32 -10
  70. data/src/jax/helper.js +0 -8
  71. data/src/jax/model.js +0 -163
@@ -28,15 +28,56 @@
28
28
 
29
29
  window.onload = function() {
30
30
  jasmineEnv.execute();
31
+
32
+ /*
33
+ Create a canvas element and add it to the document.
34
+ There's nothing special about this element.
35
+ */
31
36
  var canvas = document.createElement("canvas");
32
37
  canvas.setAttribute("id", "webgl-canvas");
33
38
  canvas.setAttribute("width", "600");
34
39
  canvas.setAttribute("height", "400");
35
40
  document.body.appendChild(canvas);
36
41
 
37
- window.JAX_CONTEXT = new Jax.Context(canvas);
42
+ /*
43
+ Instantiate a Jax context.
44
+ Note that you can have more than one, though you usually won't need to do so.
45
+ Each context should be initialized with its own canvas element.
46
+ */
47
+ window.context = new Jax.Context(canvas);
48
+
49
+ /*
50
+ That's all there is to initializing a Jax context, if you have a root route.
51
+ If not, you'll need to point it at a Jax controller manually:
52
+ */
53
+ // context.redirect_to("controller_name/action_name");
54
+
55
+ /* Set up framerate monitoring */
56
+ function updateFramerateMessage() {
57
+ document.getElementById('jax_fps').innerHTML = parseInt(context.getFramesPerSecond());
58
+ document.getElementById('jax_ups').innerHTML = parseInt(context.getUpdatesPerSecond());
59
+ }
60
+ window.context.afterUpdate(function() { if (document.show_framerate) updateFramerateMessage(); });
38
61
  };
39
62
  })();
63
+
64
+ /*
65
+ helpers for the framerate links. Updating the DIV with framerates incurs a performance
66
+ hit, so it's disabled by default; enable it when you need it, leave it when you don't.
67
+ */
68
+ function showFramerate() {
69
+ document.show_framerate = true;
70
+ document.getElementById('jax_fpsups').style.display = 'inline';
71
+ document.getElementById('jax_showfps').style.display = "none";
72
+ }
73
+
74
+ function hideFramerate() {
75
+ document.show_Framerate = false;
76
+ context.disableFrameSpeedCalculations();
77
+ context.disableUpdateSpeedCalculations();
78
+ document.getElementById('jax_fpsups').style.display = "none";
79
+ document.getElementById('jax_showfps').style.display = "inline";
80
+ }
40
81
  </script>
41
82
 
42
83
  <% js_files.each do |js_file| %>
@@ -52,11 +93,23 @@
52
93
  background-color: #fff0f0;
53
94
  font-size:14pt;
54
95
  }
96
+
97
+ #jax_fpsups { display:none; }
98
+ #jax_fps { display:inline; }
99
+ #jax_ups { display:inline; }
55
100
  </style>
56
101
  </head>
57
102
  <body>
58
103
  <div id="jax_banner">
59
- Jax
104
+ <!-- or we could use <%%=Jax::Version::STRING%> for the Rubygem version -->
105
+ Jax v<script type="text/javascript">document.write(Jax.VERSION);</script>
106
+ &rarr;
107
+ <a href="#" id="jax_showfps" onclick="showFramerate();return false;">Show Framerate</a>
108
+ <div id="jax_fpsups">
109
+ Frames per second: <div id="jax_fps">(calculating...)</div>
110
+ Updates per second: <div id="jax_ups">(calculating...)</div>
111
+ <a href="#" onclick="hideFramerate();return false;">Hide Framerate</a>
112
+ </div>
60
113
  </div>
61
114
  <div id="jasmine_content"></div>
62
115
  </body>
@@ -5,8 +5,8 @@ shared uniform mat3 nMatrix;
5
5
  shared uniform mat4 mvMatrix, pMatrix;
6
6
 
7
7
  shared varying vec2 vTexCoords;
8
- shared varying vec3 vNormals;
9
- shared varying vec4 vColor;
8
+ shared varying vec3 vNormal;
9
+ shared varying vec4 vBaseColor;
10
10
 
11
11
  // If a variable isn't shared, it will be defined specifically for this shader.
12
12
  // If this shader is used twice in one materials, unshared variables will be
@@ -18,10 +18,7 @@ class Jax::Packager::SprocketsTemplate < Sprockets::SourceFile
18
18
  template << "//= require \"#{relative_path}\""
19
19
  end
20
20
  end
21
- template.concat [
22
- "if (Jax.doVersionCheck) Jax.doVersionCheck('#{Jax::Version::STRING}');",
23
- "else alert('Your Jax gem version is newer than your Jax JavaScript library!\n\nRun `rake jax:update` to fix this.');"
24
- ]
21
+
25
22
  template
26
23
  end
27
24
  end
data/lib/jax/routes.rb CHANGED
@@ -30,6 +30,9 @@ module Jax
30
30
 
31
31
  outfile.puts "Jax.routes.map(#{path.inspect}, #{controller_name_for(set[1])}, #{args});"
32
32
  end
33
+
34
+ outfile.puts "if (Jax.doVersionCheck) Jax.doVersionCheck('#{Jax::Version::STRING}');"
35
+ outfile.puts "else alert('Your Jax gem version is newer than your Jax JavaScript library!\\n\\nRun `rake jax:update` to fix this.');"
33
36
  end
34
37
 
35
38
  def root(controller = nil, action = 'index')
data/lib/jax/version.rb CHANGED
@@ -3,7 +3,7 @@ module Jax
3
3
  MAJOR = 0
4
4
  MINOR = 0
5
5
  TINY = 0
6
- PATCH = 5
6
+ PATCH = 6
7
7
 
8
8
  STRING = PATCH == 0 ? "#{MAJOR}.#{MINOR}.#{TINY}" : "#{MAJOR}.#{MINOR}.#{TINY}.#{PATCH}"
9
9
  end
@@ -1,18 +1,50 @@
1
1
  //= require "application_controller"
2
2
 
3
3
  var NoiseController = (function() {
4
+ var red, green, blue;
5
+
4
6
  return Jax.Controller.create("noise", ApplicationController, {
5
7
  index: function() {
6
- var model = new Jax.Model({mesh:new Jax.Mesh.Sphere({material:Material.find("blob")})});
8
+ var model = new Blob();
7
9
  this.world.addObject(model);
8
10
  this.player.camera.move(-5);
9
- },
11
+
12
+ var light_options = {
13
+ type: Jax.POINT_LIGHT,
14
+ attenuation: {
15
+ constant: 0,
16
+ linear: 0,
17
+ quadratic: 0.002
18
+ }
19
+ };
20
+
21
+ red = new LightSource(Jax.Util.normalizeOptions({
22
+ position: [-20, 0, 20], color: { ambient: [0.2, 0, 0, 1], diffuse: [0.8, 0, 0, 1], specular:[1.0, 0, 0, 1] }
23
+ }, light_options));
24
+ this.world.addLightSource(red);
10
25
 
26
+ green = new LightSource(Jax.Util.normalizeOptions({
27
+ position: [ 20, 20, 20], color: { ambient: [0, 0.2, 0, 1], diffuse: [0, 0.8, 0, 1], specular:[0, 1.0, 0, 1] }
28
+ }, light_options));
29
+ this.world.addLightSource(green);
30
+
31
+ blue = new LightSource(Jax.Util.normalizeOptions({
32
+ position: [ 20, -20, 20], color: { ambient: [0, 0, 0.2, 1], diffuse: [0, 0, 0.8, 1], specular:[0, 0, 1.0, 1] }
33
+ }, light_options));
34
+ this.world.addLightSource(blue);
35
+ },
11
36
 
12
- // Some special actions are fired whenever the corresponding input is
13
- // received from the user.
14
- mouse_clicked: function(event) {
37
+ update: function(tc) {
38
+ this.rot = (this.rot || 0) + tc * 3.0;
15
39
 
40
+ function set(light, angle) {
41
+ var s = Math.sin(angle), c = Math.cos(angle);
42
+ light.camera.setPosition(s*20, c*20, 20);
43
+ }
44
+ var dif = Math.deg2rad(120);
45
+ set(red, this.rot + dif);
46
+ set(blue, this.rot + dif*2);
47
+ set(green, this.rot + dif*3);
16
48
  }
17
49
  });
18
50
  })();
@@ -0,0 +1,32 @@
1
+ //= require "application_controller"
2
+
3
+ var PickingController = (function() {
4
+ return Jax.Controller.create("picking", ApplicationController, {
5
+ index: function() {
6
+ function mesh() { return new Jax.Mesh.Sphere({size: 1.0}); };
7
+
8
+ ofront = this.world.addObject(new Jax.Model({position:[ 0.0, 0.0,-5],mesh:mesh()}));
9
+ otopleft = this.world.addObject(new Jax.Model({position:[-2.5, 2.5,-5],mesh:mesh()}));
10
+ otopright = this.world.addObject(new Jax.Model({position:[ 2.5, 2.5,-5],mesh:mesh()}));
11
+ obottomleft = this.world.addObject(new Jax.Model({position:[-2.5,-2.5,-5],mesh:mesh()}));
12
+ obottomright = this.world.addObject(new Jax.Model({position:[ 2.5,-2.5,-5],mesh:mesh()}));
13
+ },
14
+
15
+ mouse_pressed: function(e) { alert(e.x+" "+e.y); },
16
+
17
+ mouse_moved: function(evt) {
18
+ var obj = this.world.pick(evt.x, evt.y);
19
+ if (obj) {
20
+ if (this.current_obj && obj != this.current_obj) {
21
+ this.current_obj.mesh.setColor(1,1,1,1);
22
+ }
23
+ obj.mesh.setColor(1,0,0,1);
24
+ } else {
25
+ if (this.current_obj) {
26
+ this.current_obj.mesh.setColor(1,1,1,1);
27
+ }
28
+ }
29
+ this.current_obj = obj;
30
+ }
31
+ });
32
+ })();
@@ -0,0 +1,3 @@
1
+ var PickingHelper = Jax.Helper.create({
2
+
3
+ });
@@ -0,0 +1,38 @@
1
+ /**
2
+ * class Blob < Jax.Model
3
+ *
4
+ **/
5
+ var Blob = (function() {
6
+ return Jax.Model.create({
7
+ update: function(tc) {
8
+ this.camera.rotate(tc, [1,0,0]);
9
+ },
10
+
11
+ after_initialize: function() {
12
+ var u = (2*Math.PI)/16, v = (Math.PI/16);
13
+
14
+ this.mesh = new Jax.Mesh({
15
+ material: Material.find("blob"),
16
+
17
+ init: function(vertices, colors, textureCoords, normals, indices) {
18
+ for (var x = 0; x < 64; x++) {
19
+ for (var y = 0; y < 64; y++) {
20
+ var u = x, v = y;
21
+
22
+ vertices.push(u, v, 0);
23
+ vertices.push(u+1, v, 0);
24
+ vertices.push(u, v+1, 0);
25
+
26
+ vertices.push(u, v+1, 0);
27
+ vertices.push(u+1, v, 0);
28
+ vertices.push(u+1, v+1, 0);
29
+ }
30
+ }
31
+ }
32
+ });
33
+
34
+ this.mesh.material.u = u;
35
+ this.mesh.material.v = v;
36
+ }
37
+ });
38
+ })();
@@ -0,0 +1,2 @@
1
+ # default attribute values
2
+ # (these will apply to all blobs)
@@ -21,8 +21,8 @@ specular:
21
21
 
22
22
  shininess: 30
23
23
 
24
+ type: Blob
25
+
24
26
  layers:
25
27
  # remove Lighting to conserve video memory if you don't need/want support for light sources
26
28
  - type: Lighting
27
-
28
- - type: Blob
@@ -1,18 +1,13 @@
1
1
  //= require "functions/noise"
2
2
 
3
- // Shared variables save on graphics memory and allow you to "piggy-back" off of
4
- // variables defined in other shaders:
3
+ shared uniform mat4 ivMatrix, mvMatrix, pMatrix, vMatrix;
4
+ shared uniform mat3 vnMatrix, nMatrix;
5
5
 
6
- shared uniform mat3 nMatrix;
7
- shared uniform mat4 mvMatrix, pMatrix;
6
+ shared uniform vec4 materialDiffuse, materialAmbient, materialSpecular;
7
+ shared uniform float materialShininess;
8
8
 
9
- shared varying vec2 vTexCoords;
10
- shared varying vec3 vNormals;
11
- shared varying vec4 vColor;
12
-
13
- // If a variable isn't shared, it will be defined specifically for this shader.
14
- // If this shader is used twice in one materials, unshared variables will be
15
- // defined twice -- once for each use of the shader.
9
+ shared uniform int PASS_TYPE;
16
10
 
17
- // uniform sampler2D Texture;
18
- // uniform float TextureScaleX, TextureScaleY;
11
+ shared varying vec2 vTexCoords;
12
+ shared varying vec3 vNormal, vSurfacePos;
13
+ shared varying vec4 vBaseColor;
@@ -4,5 +4,5 @@
4
4
  to make your shader more efficient.
5
5
  */
6
6
  void main(inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) {
7
- diffuse = vColor;
7
+ // diffuse = vBaseColor;
8
8
  }
@@ -7,9 +7,11 @@ Jax.Material.Blob = (function() {
7
7
 
8
8
  return Jax.Class.create(Jax.Material, {
9
9
  initialize: function($super, options) {
10
+ this.u = this.v = 0.0;
11
+
10
12
  options = Jax.Util.normalizeOptions(options, {
11
- shader: "blob",
12
-
13
+ shader: "blob"
14
+
13
15
  // You can specify default options (see +manifest.yml+) here.
14
16
  });
15
17
 
@@ -21,28 +23,29 @@ Jax.Material.Blob = (function() {
21
23
  $super(context, mesh, options, uniforms);
22
24
 
23
25
  uniforms.set('mvMatrix', context.getModelViewMatrix());
24
- uniforms.set('nMatrix', context.getNormalMatrix());
25
- uniforms.set('pMatrix', context.getProjectionMatrix());
26
+ uniforms.set('nMatrix', context.getNormalMatrix());
27
+ uniforms.set('pMatrix', context.getProjectionMatrix());
26
28
 
27
29
  // uniforms.texture('Texture', this.texture, context);
28
30
 
29
- this.l = this.l || new Date().getTime();
30
- var tc = (new Date().getTime() - this.l) / 1000;
31
+ // this.l = this.l || new Date().getTime();
32
+ // var tc = (new Date().getTime() - this.l) / 1000;
31
33
 
32
34
  var noise = getNoise(this, context);
33
35
 
34
- uniforms.texture('permTexture', noise.perm, context);
36
+ uniforms.texture('permTexture', noise.perm, context);
35
37
  uniforms.texture('simplexTexture', noise.simplex, context);
36
- uniforms.texture('gradTexture', noise.grad, context);
38
+ uniforms.texture('gradTexture', noise.grad, context);
37
39
 
38
- uniforms.set('time', tc);
40
+ uniforms.set('time', Jax.uptime);
39
41
  },
40
42
 
41
43
  setAttributes: function($super, context, mesh, options, attributes) {
42
44
  attributes.set('VERTEX_POSITION', mesh.getVertexBuffer());
43
- attributes.set('VERTEX_COLOR', mesh.getColorBuffer());
44
- attributes.set('VERTEX_NORMAL', mesh.getNormalBuffer());
45
- attributes.set('VERTEX_TEXCOORDS', mesh.getTextureCoordsBuffer());
45
+ attributes.set('VERTEX_TANGENT', mesh.getTangentBuffer());
46
+ // attributes.set('VERTEX_COLOR', mesh.getColorBuffer());
47
+ // attributes.set('VERTEX_NORMAL', mesh.getNormalBuffer());
48
+ // attributes.set('VERTEX_TEXCOORDS', mesh.getTextureCoordsBuffer());
46
49
  }
47
50
  });
48
51
  })();
@@ -1,13 +1,38 @@
1
- shared attribute vec4 VERTEX_POSITION, VERTEX_COLOR;
1
+ shared attribute vec4 VERTEX_POSITION, VERTEX_TANGENT;
2
2
  shared attribute vec3 VERTEX_NORMAL;
3
- shared attribute vec2 VERTEX_TEXCOORDS;
4
3
 
5
- void main(void) {
6
- vec4 pos = VERTEX_POSITION;
7
- float n = snoise(vec4(pos.xyz, time));
8
- pos.xyz += normalize(pos.xyz)*n;
4
+ #define PI 3.141592653589793
5
+
6
+ vec3 sphere(in float slice, in float stack) {
7
+ vec3 res;
8
+
9
+ float theta = (slice / 64.0) * PI,
10
+ phi = (stack / 64.0) * 2.0 * PI;
11
+ float sinth = sin(theta), costh = cos(theta),
12
+ sinph = sin(phi), cosph = cos(phi);
13
+
14
+ res.x = cosph * sinth;
15
+ res.y = costh;
16
+ res.z = sinph * sinth;
17
+
18
+ float n = snoise(vec4(res, time*0.5)) * 0.5;
19
+ res += normalize(res)*n;
9
20
 
10
- gl_Position = pMatrix * mvMatrix * pos;
21
+ return res;
22
+ }
23
+
24
+ void main(void) {
25
+ vec3 pos = sphere(VERTEX_POSITION.x, VERTEX_POSITION.y);
26
+ vec3 a = sphere(VERTEX_POSITION.x+1.0, VERTEX_POSITION.y);
27
+ vec3 b = sphere(VERTEX_POSITION.x, VERTEX_POSITION.y+1.0);
28
+
29
+ a = (a - pos);
30
+ b = (b - pos);
31
+
32
+ vNormal = nMatrix * cross(b, a);
33
+
34
+ vSurfacePos = (mvMatrix * vec4(pos, 1.0)).xyz;
35
+ gl_Position = pMatrix * mvMatrix * vec4(pos, 1.0);
11
36
 
12
- vColor = vec4(n);
37
+ vBaseColor = vec4(1,1,1,1);
13
38
  }
@@ -0,0 +1,4 @@
1
+ Jax.views.push('picking/index', function() {
2
+ this.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3
+ this.world.render();
4
+ });
@@ -1,4 +1,5 @@
1
1
  ExampleApp.routes.map do
2
+ map 'picking/index'
2
3
  map 'noise/index'
3
4
  map 'textures/index'
4
5
  root 'lighting'
@@ -0,0 +1,11 @@
1
+ describe("PickingController", function() {
2
+ var controller;
3
+
4
+ beforeEach(function() {
5
+ controller = new PickingController();
6
+ });
7
+
8
+ it("does something", function() {
9
+ expect(1).toEqual(1);
10
+ });
11
+ });
@@ -0,0 +1,12 @@
1
+ describe("PickingHelper", function() {
2
+ var helper;
3
+
4
+ beforeEach(function() {
5
+ var klass = Jax.Class.create({helpers: function() { return [PickingHelper]; } });
6
+ helper = new klass();
7
+ });
8
+
9
+ it("does something", function() {
10
+ expect(1).toEqual(1);
11
+ });
12
+ });