mittsu-gltf 0.1.0 → 0.2.0

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: 7357b9b37036619cd1dcac6a0272db90d88f6e0caf567805c4df6f15ada7c272
4
- data.tar.gz: e9ee54d8195e9b1635163fccc9855dc9bd3a3b61333f2c8b61ac620e65899f84
3
+ metadata.gz: 5f23eb33ddc959a9590cd7a980c9c82d5f94a5377d8837c50ffdbe1b71b82088
4
+ data.tar.gz: efd9a91fbb9830b4ca9e40b802de5ba7dd1af7eb6ef15799e624f31187abdec5
5
5
  SHA512:
6
- metadata.gz: 9c66bb2249b83c4b1b7f8291ab8e619851c08dc462eb0310f08ca0198f9c20bd8cd5f9199f82d438d0dc9cc6dedadd7013129a19eec387942318efa8ef55f41b
7
- data.tar.gz: 4dc4dd25b9001add1c635608dcd3d769a5c4c3828f7a915f33e0694b3c91c697af9120b46b293b56cad9a5338096f1dea88031ee38827048077a2d7ccff370fc
6
+ metadata.gz: 8245cd6f0a0ffedc302328322bb24fba2644246f92e238eb83b2245815d8de42ab6aabeccf5d93d75f05348cbe3950996c909b97da6e5f19758807dcba7b01dc
7
+ data.tar.gz: deba7453768e7aaa50af38dcd714be4ce189b708b6a1bcb8141b59047ba74c292d53cd27a4e2b23cc4d6d4f4d3925ec535c37ade0775d3947f1ed20d5d432403
data/README.md CHANGED
@@ -20,6 +20,12 @@ exporter = Mittsu::GLTFExporter.new
20
20
  exporter.export(object, "output.gltf")
21
21
  ```
22
22
 
23
+ You can also write binary files for simple single-mesh models:
24
+
25
+ ```
26
+ exporter.export(object, "output.glb", mode: :binary)
27
+ ```
28
+
23
29
  ## About
24
30
 
25
31
  This code was originally written for [Manyfold](https://manyfold.app), supported by funding from [NLNet](https://nlnet.nl) and [NGI Zero](https://ngi.eu/ngi-projects/ngi-zero/).
@@ -37,30 +37,45 @@ module Mittsu
37
37
  @meshes = []
38
38
  @buffer_views = []
39
39
  @accessors = []
40
+ @binary_buffer = nil
40
41
  end
41
42
 
42
- def export(object, filename)
43
+ def export(object, filename, mode: :ascii)
44
+ initialize
43
45
  object.traverse do |obj|
44
- @node_indexes << add_mesh(obj) if obj.is_a? Mittsu::Mesh
46
+ @node_indexes << add_mesh(obj, mode: mode) if obj.is_a? Mittsu::Mesh
47
+ end
48
+ json = Jbuilder.new do |json|
49
+ json.asset do
50
+ json.generator "Mittsu-GLTF"
51
+ json.version "2.0"
52
+ end
53
+ json.scene 0
54
+ json.scenes [{
55
+ nodes: @node_indexes
56
+ }]
57
+ json.nodes { json.array! @nodes }
58
+ json.meshes { json.array! @meshes }
59
+ json.buffers { json.array! @buffers }
60
+ json.bufferViews { json.array! @buffer_views }
61
+ json.accessors { json.array! @accessors }
62
+ end.target!
63
+ case mode
64
+ when :ascii
65
+ File.write(filename, json)
66
+ when :binary
67
+ File.open(filename, "wb") do |file|
68
+ size = 12 +
69
+ 8 + json.length + padding_required(json, stride: 4) +
70
+ 8 + @binary_buffer.length + padding_required(@binary_buffer, stride: 4)
71
+ file.write("glTF")
72
+ file.write([2, size].pack("L<*"))
73
+ write_chunk(file, :json, json)
74
+ write_chunk(file, :binary, @binary_buffer)
75
+ end
76
+ else
77
+ raise ArgumentError "Invalid output mode #{mode}"
45
78
  end
46
- File.write(
47
- filename,
48
- Jbuilder.new do |json|
49
- json.asset do
50
- json.generator "Mittsu-GLTF"
51
- json.version "2.0"
52
- end
53
- json.scene 0
54
- json.scenes [{
55
- nodes: @node_indexes
56
- }]
57
- json.nodes { json.array! @nodes }
58
- json.meshes { json.array! @meshes }
59
- json.buffers { json.array! @buffers }
60
- json.bufferViews { json.array! @buffer_views }
61
- json.accessors { json.array! @accessors }
62
- end.target!
63
- )
64
79
  end
65
80
 
66
81
  # Parse is here for consistency with THREE.js's weird naming of exporter methods
@@ -68,7 +83,22 @@ module Mittsu
68
83
 
69
84
  private
70
85
 
71
- def add_mesh(mesh)
86
+ def write_chunk(file, type, data)
87
+ pad = padding_required(data, stride: 4)
88
+ file.write([data.length + pad].pack("L<*"))
89
+ case type
90
+ when :json
91
+ file.write("JSON")
92
+ when :binary
93
+ file.write("BIN\0")
94
+ else
95
+ raise ArgumentError.new("Invalid chunk type: #{type}")
96
+ end
97
+ file.write data
98
+ file.write(Array.new(pad, (type == :json) ? 32 : 0).pack("C*")) # Space characters for JSON, null otherwise
99
+ end
100
+
101
+ def add_mesh(mesh, mode:)
72
102
  # Pack faces into an array
73
103
  pack_string = (mesh.geometry.faces.count > (2**16)) ? "L<*" : "S<*"
74
104
  faces = mesh.geometry.faces.map { |x| [x.a, x.b, x.c] }
@@ -88,7 +118,7 @@ module Mittsu
88
118
  max: mesh.geometry.vertices.count - 1
89
119
  )
90
120
  # Add padding to get to integer multiple of float size
91
- padding = 4 - (data.length % 4)
121
+ padding = padding_required(data, stride: 4)
92
122
  data += Array.new(padding, 0).pack("C*")
93
123
  # Pack vertices in as floats
94
124
  offset = data.length
@@ -110,10 +140,13 @@ module Mittsu
110
140
  max: mesh.geometry.bounding_box.max.elements
111
141
  )
112
142
  # Encode and store in buffers
113
- @buffers << {
143
+ @buffers << ((mode == :ascii) ? {
114
144
  uri: "data:application/octet-stream;base64," + Base64.strict_encode64(data),
115
145
  byteLength: data.length
116
- }
146
+ } : {
147
+ byteLength: data.length
148
+ })
149
+ @binary_buffer = data if mode == :binary
117
150
  # Add mesh
118
151
  mesh_index = @meshes.count
119
152
  @meshes << {
@@ -136,7 +169,7 @@ module Mittsu
136
169
 
137
170
  def add_buffer_view(buffer:, offset:, length:, target: nil)
138
171
  # Check args
139
- raise ArgumentError.new("invalid GPU buffer target: #{target}") unless target.nil? || GPU_BUFFER_TYPES.keys.include?(target)
172
+ raise ArgumentError.new("invalid GPU buffer target: #{target}") unless target.nil? || GPU_BUFFER_TYPES.key?(target)
140
173
  index = @buffer_views.count
141
174
  @buffer_views << {
142
175
  buffer: buffer,
@@ -164,5 +197,9 @@ module Mittsu
164
197
  }
165
198
  index
166
199
  end
200
+
201
+ def padding_required(data, stride: 4)
202
+ (stride - (data.length % stride)) % stride
203
+ end
167
204
  end
168
205
  end
@@ -1,5 +1,5 @@
1
1
  module Mittsu
2
2
  module GLTF
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mittsu-gltf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Smith
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2024-12-12 00:00:00.000000000 Z
@@ -127,7 +127,7 @@ metadata:
127
127
  homepage_uri: https://github.com/manyfold3d/mittsu-gltf
128
128
  source_code_uri: https://github.com/manyfold3d/mittsu-gltf
129
129
  changelog_uri: https://github.com/manyfold3d/mittsu-gltf/releases
130
- post_install_message:
130
+ post_install_message:
131
131
  rdoc_options: []
132
132
  require_paths:
133
133
  - lib
@@ -142,8 +142,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
142
  - !ruby/object:Gem::Version
143
143
  version: '0'
144
144
  requirements: []
145
- rubygems_version: 3.5.11
146
- signing_key:
145
+ rubygems_version: 3.5.22
146
+ signing_key:
147
147
  specification_version: 4
148
148
  summary: GLTF file support for Mittsu
149
149
  test_files: []