mittsu-gltf 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +6 -0
- data/lib/mittsu/gltf/exporter.rb +62 -25
- data/lib/mittsu/gltf/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f23eb33ddc959a9590cd7a980c9c82d5f94a5377d8837c50ffdbe1b71b82088
|
4
|
+
data.tar.gz: efd9a91fbb9830b4ca9e40b802de5ba7dd1af7eb6ef15799e624f31187abdec5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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/).
|
data/lib/mittsu/gltf/exporter.rb
CHANGED
@@ -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
|
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 =
|
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.
|
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
|
data/lib/mittsu/gltf/version.rb
CHANGED
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.
|
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.
|
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: []
|