opal-js_wrap-three 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9cae62516fa7b9a2f924dc94dfa5aa0207b92ced58133989b924da38ecb1a67d
4
- data.tar.gz: 84c1d6bb5d517626befc59cc6bee512697ff1c3d688f59e07947b0ad3d444b6f
3
+ metadata.gz: e37d84ff43dd3664eeef3a40d737af19103b58151c43019579854e963fc2ae2c
4
+ data.tar.gz: 72bd5396cb7796a5ae5715d94bdc5cc15356c521e61416b452b9e1a5877076a5
5
5
  SHA512:
6
- metadata.gz: 2a8d9c1652a52eac070c9343d108eeae2f539b8757687a3607da597eb519c7fef81caff6dfa4bb160835165621e8770a470d7d2259c720867355b05ccc2ee680
7
- data.tar.gz: 7c533af27929c76db80cba39b29d434edc9bf0f84cc6e5847045c33ce439d481ed0b88f2a96ed7329dea2496bbd101823486269b5a785463c7e7f90895733a17
6
+ metadata.gz: c41520ca4af956a414e52501ff5309c0f39e61e8bc4dee9c70095f94e9fc2493ca911dc22cbd0eb564c98105a0555bc462b678415371d2b0d0e8ce1e7fa6e009
7
+ data.tar.gz: 53c23f536184da394793707a58992553e868bf68f6f53dd82a3f43d4e7f6977c5433da833dd3f1bb9b337405ccc089a1a30cd997d0fedb69ff8c2f71efbe3a31
data/.gitignore CHANGED
@@ -8,7 +8,7 @@
8
8
  /tmp/
9
9
 
10
10
  /node_modules/
11
- /lib-opal/js_wrap/three/three.js
11
+ /lib-opal/js_wrap/three/
12
12
 
13
13
  Gemfile.lock
14
14
 
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## [Unreleased]
2
2
 
3
+ - Not specified here improvements to JSWrap
4
+ - 3DObject#<< as an alias to #add
5
+ - Full support for examples (ie. loaders)
6
+ - New examples: clipping_intersection, gltf_loader
7
+
3
8
  ## [0.1.0] - 2021-12-14
4
9
 
5
10
  - Initial release
data/Rakefile CHANGED
@@ -15,4 +15,10 @@ end
15
15
 
16
16
  task build_js: 'lib-opal/js_wrap/three/three.js'
17
17
 
18
- task default: %i[build_js]
18
+ task :build_js_examples do
19
+ Dir["node_modules/three/examples/jsm/**/*.js"].each do |js|
20
+ sh "npx babel #{js} -o lib-opal/js_wrap/three/#{js.split("/jsm/").last}"
21
+ end
22
+ end
23
+
24
+ task default: %i[build_js build_js_examples]
data/babel.config.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "presets": [["@babel/preset-env", {
3
+ "modules": "umd",
4
+ }]],
5
+ "compact" : false,
6
+ "targets": { "chrome": 38 },
7
+ //"plugins": [
8
+ // "@babel/plugin-transform-runtime"
9
+ //]
10
+ }
@@ -0,0 +1,9 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "opal-js_wrap-three", path: "../.."
4
+ # This gem should work with any recent version of Opal (no guarantees),
5
+ # but it's strongly recommended to use Opal v1.4 for improved error
6
+ # reporting.
7
+ gem "opal", github: "opal/opal", ref: "hmdne/ruby31"
8
+ gem "rack"
9
+ gem "webrick"
@@ -0,0 +1,68 @@
1
+ # This example is adapted from https://threejs.org/examples/#webgl_clipping_intersection
2
+
3
+ require 'pp'
4
+ require 'js_wrap/three'
5
+
6
+ clip_planes = [
7
+ Three::Plane.new(Three::Vector3.new(1, 0, 0), 0),
8
+ Three::Plane.new(Three::Vector3.new(0, -1, 0), 0),
9
+ Three::Plane.new(Three::Vector3.new(0, 0, -1), 0),
10
+ ]
11
+
12
+ renderer, scene, camera = nil
13
+
14
+ init = proc do
15
+ renderer = Three::WebGLRenderer.new(antialias: true)
16
+ renderer.set_pixel_ratio(JSGlobal.device_pixel_ratio)
17
+ renderer.set_size(JSGlobal.inner_width, JSGlobal.inner_height)
18
+ renderer.local_clipping_enabled = true
19
+ JSGlobal.document.body.append_child(renderer.dom_element)
20
+
21
+ scene = Three::Scene.new
22
+
23
+ wdh = JSGlobal.inner_width / JSGlobal.inner_height
24
+ $camera = camera = Three::PerspectiveCamera.new(40, wdh, 1, 200)
25
+ camera.position.set(-1.5, 2.5, 3.0)
26
+ camera.quaternion.set(0.122, -0.355, -0.905, 0.202)
27
+
28
+ light = Three::HemisphereLight.new(0xffffff, 0x080808, 1.5)
29
+ light.position.set(-1.25, 1, 1.25)
30
+ scene << light
31
+
32
+ # helper = Three::CameraHelper.new(light.shadow.camera)
33
+ # scene << helper
34
+
35
+ group = Three::Group.new
36
+ (1..30).step(2).each do |i|
37
+ geometry = Three::SphereGeometry.new(i/30, 48, 24)
38
+ material = Three::MeshLambertMaterial.new(
39
+ color: Three::Color.new.setHSL(rand, 0.5, 0.5),
40
+ side: Three::DoubleSide,
41
+ clipping_planes: clip_planes,
42
+ clip_intersection: true
43
+ )
44
+ # line_material = Three::LineBasicMaterial.new(
45
+ # color: 0xffffff,
46
+ # transparent: true,
47
+ # opacity: 0.5
48
+ # )
49
+ # group.add Three::LineSegments.new(geometry, line_material)
50
+ group << Three::Mesh.new(geometry, material)
51
+ end
52
+ scene << group
53
+
54
+ # helpers = Three::Group.new
55
+ # helpers << Three::PlaneHelper.new( clip_planes[0], 2, 0xff0000 )
56
+ # helpers << Three::PlaneHelper.new( clip_planes[1], 2, 0x00ff00 )
57
+ # helpers << Three::PlaneHelper.new( clip_planes[2], 2, 0x0000ff )
58
+ # scene << helpers
59
+ end
60
+
61
+ render = proc do
62
+ renderer.render(scene, camera)
63
+ end
64
+
65
+ JSGlobal.add_event_listener("DOMContentLoaded") do
66
+ init.call
67
+ render.call
68
+ end
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ bundle exec opal -qopal/js_wrap/three -Rserver example.rb
@@ -0,0 +1,9 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "opal-js_wrap-three", path: "../.."
4
+ # This gem should work with any recent version of Opal (no guarantees),
5
+ # but it's strongly recommended to use Opal v1.4 for improved error
6
+ # reporting.
7
+ gem "opal", github: "opal/opal", ref: "hmdne/ruby31"
8
+ gem "rack"
9
+ gem "webrick"
@@ -0,0 +1,78 @@
1
+ # This example is adapted from https://threejs.org/examples/#webgl_loader_gltf
2
+ require 'js_wrap/three'
3
+ require 'js_wrap/three/controls/OrbitControls'
4
+ require 'js_wrap/three/loaders/GLTFLoader'
5
+ require 'js_wrap/three/loaders/RGBELoader'
6
+ require 'js_wrap/three/utils/RoughnessMipmapper'
7
+
8
+ renderer, scene, camera = nil
9
+
10
+ PATH = "https://raw.githubusercontent.com/mrdoob/three.js/master/examples/"
11
+
12
+ render = proc do
13
+ renderer.render(scene, camera)
14
+ end
15
+
16
+ init = proc do
17
+ camera = Three::PerspectiveCamera.new(45, JSGlobal.inner_width / JSGlobal.inner_height, 0.25, 20)
18
+ camera.position.set(-1.8, 0.6, 2.7)
19
+
20
+ scene = Three::Scene.new
21
+
22
+ Three::RGBELoader.new.set_path(PATH + 'textures/equirectangular/')
23
+ .load('royal_esplanade_1k.hdr') do |texture|
24
+ texture.mapping = Three::EquirectangularReflectionMapping
25
+
26
+ scene.background = texture
27
+ scene.environment = texture
28
+
29
+ render.call
30
+
31
+ roughness_mipmapper = Three::RoughnessMipmapper.new(renderer)
32
+
33
+ Three::GLTFLoader.new.set_path(PATH + 'models/gltf/DamagedHelmet/glTF/')
34
+ .load('DamagedHelmet.gltf') do |gltf|
35
+ gltf.scene.traverse do |child|
36
+ if child[:is_mesh]
37
+ roughness_mipmapper.generate_mipmaps(child.material)
38
+ end
39
+ end
40
+
41
+ scene << gltf.scene
42
+
43
+ roughness_mipmapper.dispose
44
+
45
+ render.call
46
+ end
47
+ end
48
+
49
+ renderer = Three::WebGLRenderer.new(antialias: true)
50
+ renderer.set_pixel_ratio(JSGlobal.device_pixel_ratio)
51
+ renderer.set_size(JSGlobal.inner_width, JSGlobal.inner_height)
52
+ renderer.tone_mapping = Three::ACESFilmicToneMapping
53
+ renderer.tone_mapping_exposure = 1
54
+ renderer.outputEncoding = Three.sRGBEncoding
55
+
56
+ JSGlobal.document.body.append_child(renderer.dom_element)
57
+
58
+ controls = Three::OrbitControls.new(camera, renderer.dom_element)
59
+ controls.add_event_listener('change', &render)
60
+ controls.min_distance = 2
61
+ controls.max_distance = 10
62
+ controls.target.set(0, 0, 0.2)
63
+ controls.update
64
+
65
+ JSGlobal.add_event_listener('resize') do
66
+ camera.aspect = JSGlobal.inner_width / JSGlobal.inner_height
67
+ camera.update_projection_matrix
68
+
69
+ renderer.set_size(JSGlobal.inner_width, JSGlobal.inner_height)
70
+
71
+ render.call
72
+ end
73
+ end
74
+
75
+ JSGlobal.add_event_listener("DOMContentLoaded") do
76
+ init.call
77
+ render.call
78
+ end
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ bundle exec opal -qopal/js_wrap/three -Rserver example.rb
@@ -16,7 +16,7 @@ geometry = Three::BoxGeometry.new(0.2, 0.2, 0.2)
16
16
  material = Three::MeshNormalMaterial.new
17
17
 
18
18
  mesh = Three::Mesh.new(geometry, material)
19
- scene.add(mesh)
19
+ scene << mesh
20
20
 
21
21
  renderer = Three::WebGLRenderer.new(antialias: true)
22
22
  renderer.set_size(JSGlobal.inner_width, JSGlobal.inner_height)
@@ -3,7 +3,7 @@
3
3
  module Opal
4
4
  module JSWrap
5
5
  module Three
6
- VERSION = "0.1.0"
6
+ VERSION = "0.1.1"
7
7
  end
8
8
  end
9
9
  end
@@ -231,6 +231,13 @@
231
231
 
232
232
  var runtime = {exports: {}};
233
233
 
234
+ /**
235
+ * Copyright (c) 2014-present, Facebook, Inc.
236
+ *
237
+ * This source code is licensed under the MIT license found in the
238
+ * LICENSE file in the root directory of this source tree.
239
+ */
240
+
234
241
  (function (module) {
235
242
  var runtime = function (exports) {
236
243
 
@@ -384,7 +391,7 @@
384
391
  var result = record.arg;
385
392
  var value = result.value;
386
393
 
387
- if (value && _typeof(value) === "object" && hasOwn.call(value, "__await")) {
394
+ if (value && typeof value === "object" && hasOwn.call(value, "__await")) {
388
395
  return PromiseImpl.resolve(value.__await).then(function (value) {
389
396
  invoke("next", value, resolve, reject);
390
397
  }, function (err) {
@@ -942,7 +949,7 @@
942
949
  // you've misconfigured your bundler to force strict mode and applied a
943
950
  // CSP to forbid Function, and you're not willing to fix either of those
944
951
  // problems, please detail your unique predicament in a GitHub issue.
945
- if ((typeof globalThis === "undefined" ? "undefined" : _typeof(globalThis)) === "object") {
952
+ if (typeof globalThis === "object") {
946
953
  globalThis.regeneratorRuntime = runtime;
947
954
  } else {
948
955
  Function("r", "regeneratorRuntime = r")(runtime);
@@ -954,7 +961,7 @@
954
961
 
955
962
  var _ENCODINGS;
956
963
 
957
- function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
964
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
958
965
 
959
966
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
960
967
 
@@ -11699,7 +11706,7 @@
11699
11706
 
11700
11707
  if (data) {
11701
11708
  gl.deleteBuffer(data.buffer);
11702
- buffers["delete"](attribute);
11709
+ buffers.delete(attribute);
11703
11710
  }
11704
11711
  }
11705
11712
 
@@ -13442,7 +13449,7 @@
13442
13449
  var cubemap = cubemaps.get(texture);
13443
13450
 
13444
13451
  if (cubemap !== undefined) {
13445
- cubemaps["delete"](texture);
13452
+ cubemaps.delete(texture);
13446
13453
  cubemap.dispose();
13447
13454
  }
13448
13455
  }
@@ -14282,7 +14289,7 @@
14282
14289
  var cubemapUV = cubeUVmaps.get(texture);
14283
14290
 
14284
14291
  if (cubemapUV !== undefined) {
14285
- cubeUVmaps["delete"](texture);
14292
+ cubeUVmaps.delete(texture);
14286
14293
  cubemapUV.dispose();
14287
14294
  }
14288
14295
  }
@@ -14392,7 +14399,7 @@
14392
14399
 
14393
14400
  if (attribute) {
14394
14401
  attributes.remove(attribute);
14395
- wireframeAttributes["delete"](geometry);
14402
+ wireframeAttributes.delete(geometry);
14396
14403
  }
14397
14404
 
14398
14405
  bindingStates.releaseStatesOfGeometry(geometry);
@@ -16469,7 +16476,7 @@
16469
16476
  }
16470
16477
 
16471
16478
  function remove(object) {
16472
- properties["delete"](object);
16479
+ properties.delete(object);
16473
16480
  }
16474
16481
 
16475
16482
  function update(object, key, value) {
@@ -18436,7 +18443,7 @@
18436
18443
  deallocateTexture(texture);
18437
18444
 
18438
18445
  if (texture.isVideoTexture) {
18439
- _videoTextures["delete"](texture);
18446
+ _videoTextures.delete(texture);
18440
18447
  }
18441
18448
 
18442
18449
  info.memory.textures--;
@@ -20042,7 +20049,7 @@
20042
20049
  type: 'disconnected',
20043
20050
  data: inputSource
20044
20051
  });
20045
- inputSourcesMap["delete"](inputSource);
20052
+ inputSourcesMap.delete(inputSource);
20046
20053
  }
20047
20054
  } // Notify connected
20048
20055
 
@@ -21132,8 +21139,8 @@
21132
21139
  return _scissorTest;
21133
21140
  };
21134
21141
 
21135
- this.setScissorTest = function (_boolean) {
21136
- state.setScissorTest(_scissorTest = _boolean);
21142
+ this.setScissorTest = function (boolean) {
21143
+ state.setScissorTest(_scissorTest = boolean);
21137
21144
  };
21138
21145
 
21139
21146
  this.setOpaqueSort = function (method) {
@@ -31772,7 +31779,7 @@
31772
31779
  }
31773
31780
 
31774
31781
  _this88.manager.itemEnd(url);
31775
- })["catch"](function (err) {
31782
+ }).catch(function (err) {
31776
31783
  // Abort errors and other errors are handled the same
31777
31784
  var callbacks = loading[url];
31778
31785
  delete loading[url];
@@ -34464,7 +34471,7 @@
34464
34471
  Cache.add(url, imageBitmap);
34465
34472
  if (onLoad) onLoad(imageBitmap);
34466
34473
  scope.manager.itemEnd(url);
34467
- })["catch"](function (e) {
34474
+ }).catch(function (e) {
34468
34475
  if (onError) onError(e);
34469
34476
  scope.manager.itemError(url);
34470
34477
  scope.manager.itemEnd(url);
@@ -40415,9 +40422,9 @@
40415
40422
  return this.extensions.get('ANGLE_instanced_arrays');
40416
40423
  };
40417
40424
 
40418
- WebGLRenderer.prototype.enableScissorTest = function (_boolean2) {
40425
+ WebGLRenderer.prototype.enableScissorTest = function (boolean) {
40419
40426
  console.warn('THREE.WebGLRenderer: .enableScissorTest() is now .setScissorTest().');
40420
- this.setScissorTest(_boolean2);
40427
+ this.setScissorTest(boolean);
40421
40428
  };
40422
40429
 
40423
40430
  WebGLRenderer.prototype.initMaterial = function () {
@@ -40802,7 +40809,7 @@
40802
40809
  }
40803
40810
  }
40804
40811
 
40805
- var Three = /*#__PURE__*/Object.freeze({
40812
+ var THREE = /*#__PURE__*/Object.freeze({
40806
40813
  __proto__: null,
40807
40814
  ACESFilmicToneMapping: ACESFilmicToneMapping,
40808
40815
  AddEquation: AddEquation,
@@ -41263,6 +41270,6 @@
41263
41270
  sRGBEncoding: sRGBEncoding
41264
41271
  });
41265
41272
 
41266
- globalThis.Three = Three;
41273
+ globalThis.THREE = globalThis.three = THREE;
41267
41274
 
41268
41275
  })();
@@ -1,4 +1,31 @@
1
1
  require "js_wrap"
2
2
  require "js_wrap/three/three" # JavaScript
3
3
 
4
- Three = JSWrap::ClassView.wrap(`Three`)
4
+ ThreeMod = JSWrap::ClassView.wrap(`THREE`)
5
+
6
+ module Three
7
+ class Three::Object3D < JSWrap::ObjectView
8
+ js_class `THREE.Object3D`
9
+
10
+ def <<(other)
11
+ add(other)
12
+ self
13
+ end
14
+ end
15
+
16
+ # A hack for UMD exporting things in globalThis
17
+ def self.const_missing(name)
18
+ if ThreeMod.js_property?(name)
19
+ ThreeMod.js_property(name)
20
+ elsif JSGlobal.js_property?(name)
21
+ JSGlobal.js_property(name).js_property(name)
22
+ else
23
+ super
24
+ end
25
+ end
26
+
27
+ def self.method_missing(*args, &block)
28
+ ThreeMod.send(*args, &block)
29
+ end
30
+ end
31
+
data/lib-opal/js_wrap.rb CHANGED
@@ -142,7 +142,7 @@ module JSWrap
142
142
  # @private
143
143
  def js_property_name_rb2js(name, raw: nil)
144
144
  raw = self.js_function_wrap if raw.nil?
145
- if raw || name.start_with?(/[A-Z]/)
145
+ if raw || name.start_with?(/[_A-Z]/)
146
146
  name
147
147
  else
148
148
  name.gsub(/_(.?)/) { Regexp.last_match(1).upcase }
@@ -152,7 +152,7 @@ module JSWrap
152
152
  # @private
153
153
  def js_property_name_js2rb(name, raw: nil)
154
154
  raw = self.js_function_wrap if raw.nil?
155
- if raw || name.start_with?(/[A-Z]/)
155
+ if raw || name.start_with?(/[_A-Z]/)
156
156
  name
157
157
  else
158
158
  name.gsub(/([A-Z])/) { '_' + Regexp.last_match(1).downcase }
@@ -521,7 +521,7 @@ module JSWrap
521
521
  extend WrapperClassMethods
522
522
  include ObjectWrapper
523
523
  self.js_array_wrap = true
524
- undef Array, String
524
+ undef Array, String, load
525
525
  end
526
526
  class ArrayView
527
527
  extend WrapperClassMethods
@@ -672,7 +672,7 @@ JSWrap.register_wrapping(priority: 10) do |item, parent, args|
672
672
  end
673
673
 
674
674
  class Hash
675
- # @return a JavaScript object with the same keys but calling #to_n on
675
+ # @return a JavaScript object with the same keys but calling #to_js on
676
676
  # all values.
677
677
  def to_js(parent=nil)
678
678
  %x{
@@ -696,6 +696,20 @@ class Hash
696
696
  end
697
697
  end
698
698
 
699
+ class Array
700
+ # Retuns a copy of itself trying to call #to_js on each member.
701
+ def to_js(parent=nil)
702
+ %x{
703
+ var result = [];
704
+ for (var i = 0, length = self.length; i < length; i++) {
705
+ var obj = self[i];
706
+ result.push(#{JSWrap.unwrap(`obj`, parent)});
707
+ }
708
+ return result;
709
+ }
710
+ end
711
+ end
712
+
699
713
  class Method
700
714
  def to_js(parent=nil)
701
715
  JSWrap.unwrap_proc(to_proc, parent)
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
  spec.description = "(Mostly) raw wrapper for the Three.js library for Opal"
13
13
  spec.homepage = "https://github.com/hmdne/opal-jswrap-three"
14
14
  spec.license = "MIT"
15
- spec.required_ruby_version = ">= 2.4.0"
15
+ spec.required_ruby_version = ">= 2.6.0"
16
16
 
17
17
  # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
18
18