Class: Rgltf::Builder

Inherits:
Object
  • Object
show all
Includes:
AccessorData, Accessors, DocumentProperties, Materials
Defined in:
lib/rgltf/builder.rb,
lib/rgltf/builder/accessors.rb,
lib/rgltf/builder/materials.rb,
lib/rgltf/builder/accessor_data.rb,
lib/rgltf/builder/component_builders.rb,
lib/rgltf/builder/document_properties.rb

Defined Under Namespace

Modules: AccessorData, Accessors, DocumentProperties, Materials Classes: AnimationBuilder, Handle, MeshBuilder

Constant Summary collapse

TARGETS =
{ array_buffer: 34_962, array: 34_962, element_array: 34_963, element_array_buffer: 34_963 }.freeze

Class Method Summary collapse

Instance Method Summary collapse

Methods included from DocumentProperties

#extension, #extensions_required, #extensions_used, #extras

Methods included from Materials

#image, #material, #normal_texture_info, #occlusion_texture_info, #sampler, #texture, #texture_info

Methods included from Accessors

#accessor, #accessor_from_view, #buffer_view, #sparse_accessor

Constructor Details

#initializeBuilder

Returns a new instance of Builder.



27
28
29
30
31
# File 'lib/rgltf/builder.rb', line 27

def initialize
  @handle_owner = Object.new.freeze
  @json = { 'asset' => { 'version' => '2.0' } }
  @binary = String.new(encoding: Encoding::BINARY)
end

Class Method Details

.build(&block) ⇒ Object



20
21
22
23
24
# File 'lib/rgltf/builder.rb', line 20

def build(&block)
  builder = new
  block.call(builder)
  builder.document
end

Instance Method Details

#animation(name: nil, extensions: nil, extras: nil) {|animation_builder| ... } ⇒ Object

Yields:

  • (animation_builder)


96
97
98
99
100
101
102
# File 'lib/rgltf/builder.rb', line 96

def animation(name: nil, extensions: nil, extras: nil)
  animation_builder = AnimationBuilder.new(self)
  yield animation_builder
  value = { 'samplers' => animation_builder.samplers, 'channels' => animation_builder.channels }
  add_common_properties(value, name:, extensions:, extras:)
  handle(:animation, append('animations', value))
end

#asset(generator: nil, copyright: nil, **properties) ⇒ Object



33
34
35
36
37
38
39
40
# File 'lib/rgltf/builder.rb', line 33

def asset(generator: nil, copyright: nil, **properties)
  values = { 'version' => '2.0' }
  values['generator'] = generator if generator
  values['copyright'] = copyright if copyright
  properties.each { |key, value| values[camelize(key)] = value }
  @json['asset'] = values
  self
end

#attach_skin(node, skin) ⇒ Object



90
91
92
93
94
# File 'lib/rgltf/builder.rb', line 90

def attach_skin(node, skin)
  node_handle = verify_handle(node, :node)
  @json.fetch('nodes').fetch(node_handle.index)['skin'] = reference(skin, :skin)
  node
end

#camera(type:, name: nil, extensions: nil, extras: nil, projection_extensions: nil, projection_extras: nil, **projection) ⇒ Object

Raises:

  • (ArgumentError)


68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/rgltf/builder.rb', line 68

def camera(type:, name: nil, extensions: nil, extras: nil,
           projection_extensions: nil, projection_extras: nil, **projection)
  camera_type = type.to_sym
  raise ArgumentError, 'camera type must be perspective or orthographic' unless %i[perspective
                                                                                   orthographic].include?(camera_type)

  projection_value = stringify_properties(projection)
  projection_value['extensions'] = projection_extensions if projection_extensions
  projection_value['extras'] = projection_extras unless projection_extras.nil?
  value = { 'type' => camera_type.to_s, camera_type.to_s => projection_value }
  add_common_properties(value, name:, extensions:, extras:)
  handle(:camera, append('cameras', value))
end

#documentObject



113
114
115
116
# File 'lib/rgltf/builder.rb', line 113

def document
  @json['buffers'] = [{ 'byteLength' => @binary.bytesize }] unless @binary.empty?
  Rgltf.load_json(@json, buffers: @binary.empty? ? nil : [@binary], strict_extensions: false)
end

#mark_accessor_target(handle, target) ⇒ Object



118
119
120
121
122
123
124
# File 'lib/rgltf/builder.rb', line 118

def mark_accessor_target(handle, target)
  verify_handle(handle, :accessor)
  return handle unless handle.buffer_view_index

  @json.fetch('bufferViews').fetch(handle.buffer_view_index)['target'] = TARGETS.fetch(target)
  handle
end

#mesh(name: nil, weights: nil, extensions: nil, extras: nil) {|mesh_builder| ... } ⇒ Object

Yields:

  • (mesh_builder)


42
43
44
45
46
47
48
49
# File 'lib/rgltf/builder.rb', line 42

def mesh(name: nil, weights: nil, extensions: nil, extras: nil)
  mesh_builder = MeshBuilder.new(self)
  yield mesh_builder
  value = { 'primitives' => mesh_builder.primitives }
  add_common_properties(value, name:, extensions:, extras:)
  value['weights'] = weights if weights
  handle(:mesh, append('meshes', value))
end

#node(name: nil, mesh: nil, skin: nil, camera: nil, children: nil, translation: nil, rotation: nil, scale: nil, matrix: nil, weights: nil, **properties) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/rgltf/builder.rb', line 51

def node(name: nil, mesh: nil, skin: nil, camera: nil, children: nil,
         translation: nil, rotation: nil, scale: nil, matrix: nil, weights: nil, **properties)
  value = {}
  value['name'] = name if name
  value['mesh'] = reference(mesh, :mesh) if mesh
  value['skin'] = reference(skin, :skin) if skin
  value['camera'] = reference(camera, :camera) if camera
  value['children'] = children.map { |child| reference(child, :node) } if children
  value['translation'] = translation if translation
  value['rotation'] = rotation if rotation
  value['scale'] = scale if scale
  value['matrix'] = matrix if matrix
  value['weights'] = weights if weights
  value.merge!(stringify_properties(properties))
  handle(:node, append('nodes', value))
end

#reference(handle, kind) ⇒ Object



126
127
128
# File 'lib/rgltf/builder.rb', line 126

def reference(handle, kind)
  verify_handle(handle, kind).index
end

#scene(nodes:, name: nil, default: false, **properties) ⇒ Object



104
105
106
107
108
109
110
111
# File 'lib/rgltf/builder.rb', line 104

def scene(nodes:, name: nil, default: false, **properties)
  value = { 'nodes' => nodes.map { |node| reference(node, :node) } }
  value['name'] = name if name
  value.merge!(stringify_properties(properties))
  scene_handle = handle(:scene, append('scenes', value))
  @json['scene'] = scene_handle.index if default
  scene_handle
end

#skin(joints:, inverse_bind_matrices: nil, skeleton: nil, name: nil, extensions: nil, extras: nil) ⇒ Object



82
83
84
85
86
87
88
# File 'lib/rgltf/builder.rb', line 82

def skin(joints:, inverse_bind_matrices: nil, skeleton: nil, name: nil, extensions: nil, extras: nil)
  value = { 'joints' => joints.map { |joint| reference(joint, :node) } }
  value['inverseBindMatrices'] = reference(inverse_bind_matrices, :accessor) if inverse_bind_matrices
  value['skeleton'] = reference(skeleton, :node) if skeleton
  add_common_properties(value, name:, extensions:, extras:)
  handle(:skin, append('skins', value))
end