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 +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: []
|