Class: Three::Backends::ThreeJS

Inherits:
Base
  • Object
show all
Includes:
Materialization, Parameters, ResourceManagement, Synchronization
Defined in:
lib/three/backends/threejs.rb,
lib/three/backends/threejs/parameters.rb,
lib/three/backends/threejs/materialization.rb,
lib/three/backends/threejs/synchronization.rb,
lib/three/backends/threejs/ruby_wasm_adapter.rb,
lib/three/backends/threejs/resource_management.rb

Defined Under Namespace

Modules: Materialization, Parameters, ResourceManagement, Synchronization Classes: RubyWasmAdapter

Constant Summary collapse

MATERIAL_TEXTURE_PARAMETERS =
{
  map: :map,
  alpha_map: :alphaMap,
  ao_map: :aoMap,
  bump_map: :bumpMap,
  displacement_map: :displacementMap,
  emissive_map: :emissiveMap,
  env_map: :envMap,
  gradient_map: :gradientMap,
  light_map: :lightMap,
  matcap: :matcap,
  metalness_map: :metalnessMap,
  normal_map: :normalMap,
  roughness_map: :roughnessMap,
  specular_map: :specularMap,
  anisotropy_map: :anisotropyMap,
  clearcoat_map: :clearcoatMap,
  clearcoat_normal_map: :clearcoatNormalMap,
  clearcoat_roughness_map: :clearcoatRoughnessMap,
  transmission_map: :transmissionMap,
  thickness_map: :thicknessMap,
  iridescence_map: :iridescenceMap,
  iridescence_thickness_map: :iridescenceThicknessMap,
  sheen_color_map: :sheenColorMap,
  sheen_roughness_map: :sheenRoughnessMap,
  specular_color_map: :specularColorMap,
  specular_intensity_map: :specularIntensityMap
}.freeze
MATERIAL_COLOR_PARAMETERS =
%i[color emissive specular attenuationColor sheenColor specularColor].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(adapter: nil) ⇒ ThreeJS

Returns a new instance of ThreeJS.



75
76
77
78
79
80
# File 'lib/three/backends/threejs.rb', line 75

def initialize(adapter: nil)
  @adapter = adapter || RubyWasmAdapter.new
  @handles = {}
  @objects_by_handle_key = {}
  @geometry_attribute_names = {}
end

Instance Attribute Details

#adapterObject (readonly)

Returns the value of attribute adapter.



73
74
75
# File 'lib/three/backends/threejs.rb', line 73

def adapter
  @adapter
end

#handlesObject (readonly)

Returns the value of attribute handles.



73
74
75
# File 'lib/three/backends/threejs.rb', line 73

def handles
  @handles
end

Instance Method Details

#add_effect_composer_pass(composer_handle, pass_handle) ⇒ Object



124
125
126
# File 'lib/three/backends/threejs.rb', line 124

def add_effect_composer_pass(composer_handle, pass_handle)
  @adapter.effect_composer_add_pass(composer_handle, pass_handle)
end

#add_event_listener(object, type, callback) ⇒ Object

Raises:

  • (ArgumentError)


297
298
299
300
301
# File 'lib/three/backends/threejs.rb', line 297

def add_event_listener(object, type, callback)
  raise ArgumentError, "callback is required" unless callback

  @adapter.add_event_listener(materialize(object), type, callback)
end

#animation_mixer_clip_action(mixer_handle, clip_handle, root_handle = nil) ⇒ Object



215
216
217
# File 'lib/three/backends/threejs.rb', line 215

def animation_mixer_clip_action(mixer_handle, clip_handle, root_handle = nil)
  @adapter.animation_mixer_clip_action(mixer_handle, clip_handle, root_handle)
end

#cached?(object) ⇒ Boolean

Returns:

  • (Boolean)


303
304
305
306
# File 'lib/three/backends/threejs.rb', line 303

def cached?(object)
  key = cache_key(object)
  key ? @handles.key?(key) : false
end

#create_animation_mixer(root_handle) ⇒ Object



211
212
213
# File 'lib/three/backends/threejs.rb', line 211

def create_animation_mixer(root_handle)
  @adapter.new_animation_mixer(root_handle)
end

#create_dot_screen_pass(center, angle, scale) ⇒ Object



150
151
152
# File 'lib/three/backends/threejs.rb', line 150

def create_dot_screen_pass(center, angle, scale)
  @adapter.new_dot_screen_pass(center, angle, scale)
end

#create_effect_composer(renderer_handle) ⇒ Object



120
121
122
# File 'lib/three/backends/threejs.rb', line 120

def create_effect_composer(renderer_handle)
  @adapter.new_effect_composer(renderer_handle)
end

#create_orbit_controls(camera, dom_element = nil) ⇒ Object



166
167
168
# File 'lib/three/backends/threejs.rb', line 166

def create_orbit_controls(camera, dom_element = nil)
  @adapter.new_orbit_controls(camera, dom_element)
end

#create_output_passObject



154
155
156
# File 'lib/three/backends/threejs.rb', line 154

def create_output_pass
  @adapter.new_output_pass
end

#create_raycasterObject



196
197
198
# File 'lib/three/backends/threejs.rb', line 196

def create_raycaster
  @adapter.new_raycaster
end

#create_render_pass(scene, camera) ⇒ Object



142
143
144
# File 'lib/three/backends/threejs.rb', line 142

def create_render_pass(scene, camera)
  @adapter.new_render_pass(sync(scene), sync(camera))
end

#create_renderer(canvas: nil, **options) ⇒ Object



82
83
84
# File 'lib/three/backends/threejs.rb', line 82

def create_renderer(canvas: nil, **options)
  @adapter.new_webgl_renderer({ canvas: canvas }.merge(options))
end

#create_unreal_bloom_pass(resolution, strength, radius, threshold) ⇒ Object



146
147
148
# File 'lib/three/backends/threejs.rb', line 146

def create_unreal_bloom_pass(resolution, strength, radius, threshold)
  @adapter.new_unreal_bloom_pass(resolution, strength, radius, threshold)
end

#dispose(object, dispose_textures: false) ⇒ Object



286
287
288
289
290
291
292
293
294
295
# File 'lib/three/backends/threejs.rb', line 286

def dispose(object, dispose_textures: false)
  dispose_material_textures(object) if dispose_textures && object.is_a?(Material)

  key = cache_key(object)
  handle = key ? @handles.delete(key) : nil
  handle_key = @adapter.object_handle_key(handle) if handle
  @objects_by_handle_key.delete(handle_key) if handle_key
  @adapter.dispose(handle) if handle
  handle
end

#dispose_controls(control_handle) ⇒ Object



182
183
184
# File 'lib/three/backends/threejs.rb', line 182

def dispose_controls(control_handle)
  @adapter.dispose_controls(control_handle)
end

#dispose_effect_composer(composer_handle) ⇒ Object



138
139
140
# File 'lib/three/backends/threejs.rb', line 138

def dispose_effect_composer(composer_handle)
  @adapter.dispose_effect_composer(composer_handle)
end

#dispose_subtree(object, remove: true, dispose_geometries: true, dispose_materials: true, dispose_textures: false, dispose_skeletons: true) ⇒ Object



316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
# File 'lib/three/backends/threejs.rb', line 316

def dispose_subtree(
  object,
  remove: true,
  dispose_geometries: true,
  dispose_materials: true,
  dispose_textures: false,
  dispose_skeletons: true
)
  handle = object3d_handle(object)
  @adapter.dispose_object3d_subtree(
    handle,
    remove: remove,
    dispose_geometries: dispose_geometries,
    dispose_materials: dispose_materials,
    dispose_textures: dispose_textures,
    dispose_skeletons: dispose_skeletons
  )
  object.remove_from_parent if remove && object.respond_to?(:remove_from_parent)
  release_cached_subtree_handles(
    object,
    dispose_geometries: dispose_geometries,
    dispose_materials: dispose_materials,
    dispose_textures: dispose_textures
  )
  handle
end

#fade_in_animation_action(action_handle, duration) ⇒ Object



247
248
249
# File 'lib/three/backends/threejs.rb', line 247

def fade_in_animation_action(action_handle, duration)
  @adapter.fade_in_animation_action(action_handle, duration)
end

#fade_out_animation_action(action_handle, duration) ⇒ Object



251
252
253
# File 'lib/three/backends/threejs.rb', line 251

def fade_out_animation_action(action_handle, duration)
  @adapter.fade_out_animation_action(action_handle, duration)
end

#intersect_objects(raycaster_handle, objects, recursive: false) ⇒ Object



204
205
206
207
208
209
# File 'lib/three/backends/threejs.rb', line 204

def intersect_objects(raycaster_handle, objects, recursive: false)
  handles = Array(objects).map { |object| sync(object) }
  @adapter.intersect_objects(raycaster_handle, handles, recursive: recursive).map do |intersection|
    normalize_intersection(intersection)
  end
end

#materialize(object) ⇒ Object



255
256
257
258
259
260
261
262
263
264
265
# File 'lib/three/backends/threejs.rb', line 255

def materialize(object)
  key = cache_key(object)
  return @handles[key] if key && @handles.key?(key)

  handle = build_handle(object)
  sync_geometry_operations(object, handle) if object.is_a?(BufferGeometry)
  @handles[key] = handle if key
  register_object_handle(object, handle)
  mark_clean_after_materialize(object)
  handle
end

#play_animation_action(action_handle) ⇒ Object



235
236
237
# File 'lib/three/backends/threejs.rb', line 235

def play_animation_action(action_handle)
  @adapter.play_animation_action(action_handle)
end

#render(renderer_handle, scene, camera) ⇒ Object



114
115
116
117
118
# File 'lib/three/backends/threejs.rb', line 114

def render(renderer_handle, scene, camera)
  scene_handle = sync(scene)
  camera_handle = sync(camera)
  @adapter.render(renderer_handle, scene_handle, camera_handle)
end

#render_effect_composer(composer_handle, scene = nil, camera = nil) ⇒ Object



132
133
134
135
136
# File 'lib/three/backends/threejs.rb', line 132

def render_effect_composer(composer_handle, scene = nil, camera = nil)
  sync(scene) if scene
  sync(camera) if camera
  @adapter.effect_composer_render(composer_handle)
end

#renderer_dom_element(renderer_handle) ⇒ Object



86
87
88
# File 'lib/three/backends/threejs.rb', line 86

def renderer_dom_element(renderer_handle)
  @adapter.renderer_dom_element(renderer_handle)
end

#reset_animation_action(action_handle) ⇒ Object



243
244
245
# File 'lib/three/backends/threejs.rb', line 243

def reset_animation_action(action_handle)
  @adapter.reset_animation_action(action_handle)
end

#set_animation_action_property(action_handle, name, value) ⇒ Object



231
232
233
# File 'lib/three/backends/threejs.rb', line 231

def set_animation_action_property(action_handle, name, value)
  @adapter.set_animation_action_property(action_handle, name, value)
end

#set_animation_loop(renderer_handle, callback) ⇒ Object



110
111
112
# File 'lib/three/backends/threejs.rb', line 110

def set_animation_loop(renderer_handle, callback)
  @adapter.set_animation_loop(renderer_handle, callback)
end

#set_clear_color(renderer_handle, color, alpha = 1) ⇒ Object



94
95
96
# File 'lib/three/backends/threejs.rb', line 94

def set_clear_color(renderer_handle, color, alpha = 1)
  @adapter.set_clear_color(renderer_handle, color, alpha)
end

#set_control_property(control_handle, name, value) ⇒ Object



170
171
172
# File 'lib/three/backends/threejs.rb', line 170

def set_control_property(control_handle, name, value)
  @adapter.set_control_property(control_handle, name, value)
end

#set_effect_composer_size(composer_handle, width, height) ⇒ Object



128
129
130
# File 'lib/three/backends/threejs.rb', line 128

def set_effect_composer_size(composer_handle, width, height)
  @adapter.effect_composer_set_size(composer_handle, width, height)
end

#set_orbit_controls_target(control_handle, target) ⇒ Object



174
175
176
# File 'lib/three/backends/threejs.rb', line 174

def set_orbit_controls_target(control_handle, target)
  @adapter.set_orbit_controls_target(control_handle, target)
end

#set_postprocessing_pass_property(pass_handle, name, value) ⇒ Object



158
159
160
# File 'lib/three/backends/threejs.rb', line 158

def set_postprocessing_pass_property(pass_handle, name, value)
  @adapter.set_postprocessing_pass_property(pass_handle, name, value)
end

#set_postprocessing_pass_uniform(pass_handle, name, value) ⇒ Object



162
163
164
# File 'lib/three/backends/threejs.rb', line 162

def set_postprocessing_pass_uniform(pass_handle, name, value)
  @adapter.set_postprocessing_pass_uniform(pass_handle, name, value)
end

#set_raycaster_from_camera(raycaster_handle, coords, camera) ⇒ Object



200
201
202
# File 'lib/three/backends/threejs.rb', line 200

def set_raycaster_from_camera(raycaster_handle, coords, camera)
  @adapter.set_raycaster_from_camera(raycaster_handle, coords, sync(camera))
end

#set_renderer_shadow_map(renderer_handle, enabled: nil, type: nil, auto_update: nil) ⇒ Object



106
107
108
# File 'lib/three/backends/threejs.rb', line 106

def set_renderer_shadow_map(renderer_handle, enabled: nil, type: nil, auto_update: nil)
  @adapter.set_renderer_shadow_map(renderer_handle, enabled: enabled, type: type, auto_update: auto_update)
end

#set_renderer_size(renderer_handle, width, height) ⇒ Object



90
91
92
# File 'lib/three/backends/threejs.rb', line 90

def set_renderer_size(renderer_handle, width, height)
  @adapter.set_renderer_size(renderer_handle, width, height)
end

#set_renderer_tone_mapping(renderer_handle, value) ⇒ Object



98
99
100
# File 'lib/three/backends/threejs.rb', line 98

def set_renderer_tone_mapping(renderer_handle, value)
  @adapter.set_renderer_tone_mapping(renderer_handle, value)
end

#set_renderer_tone_mapping_exposure(renderer_handle, value) ⇒ Object



102
103
104
# File 'lib/three/backends/threejs.rb', line 102

def set_renderer_tone_mapping_exposure(renderer_handle, value)
  @adapter.set_renderer_tone_mapping_exposure(renderer_handle, value)
end

#stop_all_animation_actions(mixer_handle) ⇒ Object



223
224
225
# File 'lib/three/backends/threejs.rb', line 223

def stop_all_animation_actions(mixer_handle)
  @adapter.stop_all_animation_actions(mixer_handle)
end

#stop_animation_action(action_handle) ⇒ Object



239
240
241
# File 'lib/three/backends/threejs.rb', line 239

def stop_animation_action(action_handle)
  @adapter.stop_animation_action(action_handle)
end

#sync(object) ⇒ Object



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/three/backends/threejs.rb', line 267

def sync(object)
  handle = materialize(object)

  case object
  when Object3D
    sync_object3d(object, handle)
  when Fog
    sync_fog(object, handle)
  when BufferGeometry
    sync_geometry(object, handle)
  when Texture
    sync_texture(object, handle)
  when Material
    sync_material(object, handle)
  end

  handle
end

#sync_object_transform_from_handle(object) ⇒ Object



186
187
188
189
190
191
192
193
194
# File 'lib/three/backends/threejs.rb', line 186

def sync_object_transform_from_handle(object)
  handle = materialize(object)
  position, quaternion, scale = @adapter.object_transform(handle)
  object.position.set(*position)
  object.quaternion.set(*quaternion)
  object.scale.set(*scale)
  object.mark_clean!(:transform) if object.respond_to?(:mark_clean!)
  object
end

#traverse_handles(object, &block) ⇒ Object



308
309
310
311
312
313
314
# File 'lib/three/backends/threejs.rb', line 308

def traverse_handles(object, &block)
  return enum_for(:traverse_handles, object) unless block

  handle = object3d_handle(object)
  @adapter.traverse_object3d(handle, block)
  handle
end

#uncache_animation_root(mixer_handle, root_handle) ⇒ Object



227
228
229
# File 'lib/three/backends/threejs.rb', line 227

def uncache_animation_root(mixer_handle, root_handle)
  @adapter.uncache_animation_root(mixer_handle, root_handle)
end

#update_animation_mixer(mixer_handle, delta) ⇒ Object



219
220
221
# File 'lib/three/backends/threejs.rb', line 219

def update_animation_mixer(mixer_handle, delta)
  @adapter.update_animation_mixer(mixer_handle, delta)
end

#update_controls(control_handle) ⇒ Object



178
179
180
# File 'lib/three/backends/threejs.rb', line 178

def update_controls(control_handle)
  @adapter.update_controls(control_handle)
end