Module: Rgltf::Builder::Accessors

Included in:
Rgltf::Builder
Defined in:
lib/rgltf/builder/accessors.rb

Instance Method Summary collapse

Instance Method Details

#accessor(type, component_type, packed, min_max: false, target: :array_buffer, **properties) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/rgltf/builder/accessors.rb', line 6

def accessor(type, component_type, packed, min_max: false, target: :array_buffer, **properties)
  type_name = type.to_s.upcase
  info = AccessorReader::COMPONENTS_BY_SYMBOL.fetch(component_type.to_sym)
  component_count = AccessorReader::ELEMENT_COUNTS.fetch(type_name)
  element_size = info[:size] * component_count
  source = packed.b
  unless (source.bytesize % element_size).zero?
    raise ArgumentError,
          'accessor byte length must be divisible by its element size'
  end

  count = source.bytesize / element_size
  stored = add_matrix_padding(source, type_name, info[:size], count)
  view_index = append_buffer_view(stored, target: target && TARGETS.fetch(target.to_sym))
  value = accessor_properties(type, component_type, count:, **properties)
  value['bufferView'] = view_index
  add_min_max(value, source, info, component_count) if min_max
  handle(:accessor, append('accessors', value), buffer_view_index: view_index)
rescue KeyError => e
  raise ArgumentError, "unsupported accessor type: #{e.message}"
end

#accessor_from_view(type, component_type, buffer_view:, count:, byte_offset: 0, normalized: false, min: nil, max: nil, **properties) ⇒ Object



36
37
38
39
40
41
# File 'lib/rgltf/builder/accessors.rb', line 36

def accessor_from_view(type, component_type, buffer_view:, count:, byte_offset: 0,
                       normalized: false, min: nil, max: nil, **properties)
  value = accessor_properties(type, component_type, count:, byte_offset:, normalized:, min:, max:, **properties)
  value['bufferView'] = reference(buffer_view, :buffer_view)
  handle(:accessor, append('accessors', value), buffer_view_index: buffer_view.index)
end

#buffer_view(bytes, byte_stride: nil, target: nil, name: nil, extensions: nil, extras: nil) ⇒ Object



28
29
30
31
32
33
34
# File 'lib/rgltf/builder/accessors.rb', line 28

def buffer_view(bytes, byte_stride: nil, target: nil, name: nil, extensions: nil, extras: nil)
  target_number = target && TARGETS.fetch(target.to_sym)
  index = append_buffer_view(bytes.b, target: target_number, byte_stride:, name:, extensions:, extras:)
  handle(:buffer_view, index)
rescue KeyError
  raise ArgumentError, "unsupported buffer view target #{target.inspect}"
end

#sparse_accessor(type, component_type, count:, indices:, values:, index_component_type: :u16, base: nil, normalized: false, sparse_extensions: nil, sparse_extras: nil, indices_extensions: nil, indices_extras: nil, values_extensions: nil, values_extras: nil, **properties) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/rgltf/builder/accessors.rb', line 43

def sparse_accessor(type, component_type, count:, indices:, values:, index_component_type: :u16,
                    base: nil, normalized: false, sparse_extensions: nil, sparse_extras: nil,
                    indices_extensions: nil, indices_extras: nil,
                    values_extensions: nil, values_extras: nil, **properties)
  index_info = sparse_index_info(index_component_type)
  index_bytes = indices.is_a?(String) ? indices.b : Array(indices).pack("#{index_info.fetch(:pack)}*")
  unless (index_bytes.bytesize % index_info.fetch(:size)).zero?
    raise ArgumentError, 'sparse index byte length must be divisible by its component size'
  end

  sparse_count = index_bytes.bytesize / index_info.fetch(:size)
  value_info = AccessorReader::COMPONENTS_BY_SYMBOL.fetch(component_type.to_sym)
  type_name = type.to_s.upcase
  component_count = AccessorReader::ELEMENT_COUNTS.fetch(type_name)
  expected_size = sparse_count * component_count * value_info.fetch(:size)
  unless values.bytesize == expected_size
    raise ArgumentError,
          'sparse value byte length does not match its indices'
  end

  value_bytes = add_matrix_padding(values.b, type_name, value_info.fetch(:size), sparse_count)
  sparse = sparse_properties(index_bytes, value_bytes, index_info, sparse_count,
                             sparse_extensions:, sparse_extras:, indices_extensions:,
                             indices_extras:, values_extensions:, values_extras:)
  value = accessor_properties(type, component_type, count:, normalized:, **properties)
  view_index = append_sparse_base(value, base, type_name, value_info, count)
  value['sparse'] = sparse
  handle(:accessor, append('accessors', value), buffer_view_index: view_index)
rescue KeyError => e
  raise ArgumentError, "unsupported sparse accessor type: #{e.message}"
end