@that-sky-project/that-sky-level 1.0.0 → 1.0.2
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.
- package/LICENSE +636 -479
- package/package.json +24 -3
- package/docs/img/blender_edit_obj_model.png +0 -0
- package/docs/materials.md +0 -37
- package/level_example/HTNH_Test/HTNH_Test.Objects.level.json +0 -258
- package/level_example/HTNH_Test/HTNH_Test.obj +0 -46
- package/level_example/HTNH_Test/Makefile +0 -11
- package/src/formats/triangleMesh.js +0 -82
- package/src/formats/wavefront.js +0 -148
- package/src/level/adjacency.js +0 -466
- package/src/level/enums/kFieldType.js +0 -8
- package/src/level/enums/kMaterial.js +0 -39
- package/src/level/meshes/levelGeo.js +0 -283
- package/src/level/meshes/levelLod.js +0 -15
- package/src/level/meshes/levelMeshes.js +0 -141
- package/src/level/meshes/levelToc.js +0 -69
- package/src/level/objects/levelObjects.js +0 -683
- package/src/level/objects/levelObjectsJson.js +0 -256
- package/src/meshopt/LICENSE +0 -21
- package/src/meshopt/meshopt_decoder.js +0 -199
- package/src/meshopt/meshopt_encoder.js +0 -221
- package/src/utils/binaryStream.js +0 -806
- package/src/utils/helperClasses.js +0 -110
- package/src/utils/logger.js +0 -14
- package/src/utils/normVec.js +0 -67
- package/src/utils/vector.js +0 -232
- package/webpack.config.js +0 -31
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@that-sky-project/that-sky-level",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"@htmonkeyg/tformat": "^1.0.1",
|
|
6
6
|
"arg": "^5.0.2",
|
|
@@ -9,15 +9,36 @@
|
|
|
9
9
|
"lz4": "^0.6.5",
|
|
10
10
|
"parsenbt-js": "^3.1.3"
|
|
11
11
|
},
|
|
12
|
+
"files": [
|
|
13
|
+
"./dist",
|
|
14
|
+
"./package.json",
|
|
15
|
+
"./README.md",
|
|
16
|
+
"./LICENSE"
|
|
17
|
+
],
|
|
12
18
|
"scripts": {
|
|
13
19
|
"build": "npx webpack"
|
|
14
20
|
},
|
|
15
21
|
"bin": {
|
|
16
|
-
"tslevel": "
|
|
22
|
+
"tslevel": "dist/cli.js"
|
|
17
23
|
},
|
|
18
24
|
"devDependencies": {
|
|
19
25
|
"terser-webpack-plugin": "^5.6.1",
|
|
20
26
|
"webpack": "^5.108.3",
|
|
21
27
|
"webpack-cli": "^7.1.0"
|
|
22
|
-
}
|
|
28
|
+
},
|
|
29
|
+
"description": "A simple level converter for Sky:CotL level binaries.",
|
|
30
|
+
"main": "main.js",
|
|
31
|
+
"directories": {
|
|
32
|
+
"doc": "docs"
|
|
33
|
+
},
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/that-sky-project/that-sky-level.git"
|
|
37
|
+
},
|
|
38
|
+
"author": "That Sky Project",
|
|
39
|
+
"license": "AGPL-3.0-or-later",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/that-sky-project/that-sky-level/issues"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/that-sky-project/that-sky-level#readme"
|
|
23
44
|
}
|
|
Binary file
|
package/docs/materials.md
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
```
|
|
2
|
-
kMaterial_None: 0,
|
|
3
|
-
kMaterial_Transparent: 2,
|
|
4
|
-
kMaterial_Void: 3,
|
|
5
|
-
kMaterial_Particle: 4,
|
|
6
|
-
kMaterial_WoodSlippery: 5,
|
|
7
|
-
kMaterial_VoidMinor: 6,
|
|
8
|
-
kMaterial_WoodPlank: 7,
|
|
9
|
-
kMaterial_Cliff: 16,
|
|
10
|
-
kMaterial_Soil: 17,
|
|
11
|
-
kMaterial_CliffLight: 18,
|
|
12
|
-
kMaterial_WallDamaged: 19,
|
|
13
|
-
kMaterial_Wall: 20,
|
|
14
|
-
kMaterial_Gold: 21,
|
|
15
|
-
kMaterial_Glacier: 22,
|
|
16
|
-
kMaterial_TileCeiling: 23,
|
|
17
|
-
kMaterial_TileFloor: 24,
|
|
18
|
-
kMaterial_TileWall: 25,
|
|
19
|
-
kMaterial_WallBrick: 26,
|
|
20
|
-
kMaterial_SoilWet: 27,
|
|
21
|
-
kMaterial_CliffWet: 28,
|
|
22
|
-
kMaterial_Bone: 29,
|
|
23
|
-
kMaterial_Wood: 30,
|
|
24
|
-
kMaterial_Ceramics: 31,
|
|
25
|
-
kMaterial_Sand: 32,
|
|
26
|
-
kMaterial_SandWet: 33,
|
|
27
|
-
kMaterial_SandLight: 34,
|
|
28
|
-
kMaterial_Snow: 35,
|
|
29
|
-
kMaterial_SandDeep: 36,
|
|
30
|
-
kMaterial_Mud: 37,
|
|
31
|
-
kMaterial_Grass: 48,
|
|
32
|
-
kMaterial_GrassWet: 49,
|
|
33
|
-
kMaterial_GrassLight: 50,
|
|
34
|
-
kMaterial_GrassMoss: 51,
|
|
35
|
-
kMaterial_Cloth: 52,
|
|
36
|
-
kMaterial_Cloud: 80,
|
|
37
|
-
```
|
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"classes": {
|
|
3
|
-
"Clump": {
|
|
4
|
-
"data": "arr>ref"
|
|
5
|
-
},
|
|
6
|
-
"Marker": {
|
|
7
|
-
"enabled": "raw>b01",
|
|
8
|
-
"scale": "raw>b16",
|
|
9
|
-
"quat": "raw>b16",
|
|
10
|
-
"pos": "raw>b16"
|
|
11
|
-
},
|
|
12
|
-
"AvatarSetPos": {
|
|
13
|
-
"autoStart": "raw>b01",
|
|
14
|
-
"randomGroundInMarker": "raw>b01",
|
|
15
|
-
"setLevelStartPosition": "raw>b01",
|
|
16
|
-
"onGround": "raw>b01",
|
|
17
|
-
"relMarker": "raw>ref",
|
|
18
|
-
"marker": "raw>ref",
|
|
19
|
-
"breakHandHold": "raw>b01",
|
|
20
|
-
"bstGuid": "raw>b04",
|
|
21
|
-
"killMomentum": "raw>b01"
|
|
22
|
-
},
|
|
23
|
-
"OnLevelStart": {
|
|
24
|
-
"autoStart": "raw>b01",
|
|
25
|
-
"onlyOnWorldLoad": "raw>b01",
|
|
26
|
-
"events": "raw>ref",
|
|
27
|
-
"skipOnWorldLoad": "raw>b01"
|
|
28
|
-
},
|
|
29
|
-
"MeditationArea": {
|
|
30
|
-
"transform": "raw>b64",
|
|
31
|
-
"spawnSeatDelay": "raw>b04",
|
|
32
|
-
"camCustomFadeIn": "raw>b04",
|
|
33
|
-
"enabled": "raw>b01",
|
|
34
|
-
"confirmHintText": "raw>str",
|
|
35
|
-
"dialogType": "raw>b01",
|
|
36
|
-
"spawnSeatTail": "raw>b01",
|
|
37
|
-
"needSit": "raw>b01",
|
|
38
|
-
"spawnSeatCameraDist": "raw>b04",
|
|
39
|
-
"goals": "raw>ref",
|
|
40
|
-
"meditationSound": "raw>str",
|
|
41
|
-
"holyAreas": "raw>ref",
|
|
42
|
-
"disableMergeWithAnyProgress": "raw>b01",
|
|
43
|
-
"onlyFireWhenLocalPresent": "raw>b01",
|
|
44
|
-
"fullBonus": "raw>b04",
|
|
45
|
-
"camCustomFadeOut": "raw>b04",
|
|
46
|
-
"localOnly": "raw>b01",
|
|
47
|
-
"confirmHintIcon": "raw>str",
|
|
48
|
-
"minimumLocalPresentTime": "raw>b04",
|
|
49
|
-
"altar": "raw>ref",
|
|
50
|
-
"minRequired": "raw>b04",
|
|
51
|
-
"type": "raw>b01",
|
|
52
|
-
"onSitPressed": "raw>ref",
|
|
53
|
-
"time": "raw>b04",
|
|
54
|
-
"spawnSeatFX": "raw>b01",
|
|
55
|
-
"progressObjs": "raw>ref",
|
|
56
|
-
"spawnSeatFXBrightnessMult": "raw>b04",
|
|
57
|
-
"sitIconOverride": "raw>str",
|
|
58
|
-
"keyFrame": "raw>ref",
|
|
59
|
-
"spawnSeatSFX": "raw>b01",
|
|
60
|
-
"onMenuConfirm": "raw>ref",
|
|
61
|
-
"onMenuCancel": "raw>ref",
|
|
62
|
-
"onComplete": "raw>ref",
|
|
63
|
-
"progressOut": "raw>ref"
|
|
64
|
-
},
|
|
65
|
-
"OnBubbleButton": {
|
|
66
|
-
"autoStart": "raw>b01",
|
|
67
|
-
"activeDistance": "raw>b04",
|
|
68
|
-
"buttonTarget": "raw>ref",
|
|
69
|
-
"useAvatar": "raw>b01",
|
|
70
|
-
"showInSharedSpaceEditMode": "raw>b01",
|
|
71
|
-
"fireOnce": "raw>b01",
|
|
72
|
-
"ignoreAllowUI": "raw>b01",
|
|
73
|
-
"displayDuration": "raw>b04",
|
|
74
|
-
"networkedOnHandhold": "raw>b01",
|
|
75
|
-
"iconName": "raw>str",
|
|
76
|
-
"priority": "raw>b04",
|
|
77
|
-
"events": "raw>ref",
|
|
78
|
-
"cooldownAfterPressed": "raw>b04"
|
|
79
|
-
},
|
|
80
|
-
"Enable": {
|
|
81
|
-
"autoStart": "raw>b01",
|
|
82
|
-
"objects": "raw>ref",
|
|
83
|
-
"killEvents": "raw>b01",
|
|
84
|
-
"enable": "raw>b01",
|
|
85
|
-
"bstGuid": "raw>b04",
|
|
86
|
-
"selectObjectRandomly": "raw>b01"
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
"objects": {
|
|
90
|
-
"OnLevelStart>OnLevelStart_Trigger": {
|
|
91
|
-
"autoStart": true,
|
|
92
|
-
"onlyOnWorldLoad": 0,
|
|
93
|
-
"events": "Clump>OnLevelStart_Listeners",
|
|
94
|
-
"skipOnWorldLoad": 0
|
|
95
|
-
},
|
|
96
|
-
"AvatarSetPos>EntryPoint": {
|
|
97
|
-
"autoStart": false,
|
|
98
|
-
"randomGroundInMarker": 0,
|
|
99
|
-
"setLevelStartPosition": 1,
|
|
100
|
-
"onGround": 1,
|
|
101
|
-
"relMarker": null,
|
|
102
|
-
"marker": "Marker>BstNode_3",
|
|
103
|
-
"breakHandHold": 0,
|
|
104
|
-
"bstGuid": 1,
|
|
105
|
-
"killMomentum": 0
|
|
106
|
-
},
|
|
107
|
-
"Marker>BstNode_3": {
|
|
108
|
-
"enabled": true,
|
|
109
|
-
"scale": {
|
|
110
|
-
"x": 1,
|
|
111
|
-
"y": 1,
|
|
112
|
-
"z": 1,
|
|
113
|
-
"w": 0
|
|
114
|
-
},
|
|
115
|
-
"quat": {
|
|
116
|
-
"x": 0,
|
|
117
|
-
"y": 0,
|
|
118
|
-
"z": 0,
|
|
119
|
-
"w": 1
|
|
120
|
-
},
|
|
121
|
-
"pos": {
|
|
122
|
-
"x": 0,
|
|
123
|
-
"y": 0.5,
|
|
124
|
-
"z": 0,
|
|
125
|
-
"w": 0
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
|
-
"Marker>Marker_2": {
|
|
129
|
-
"enabled": true,
|
|
130
|
-
"scale": {
|
|
131
|
-
"x": 1,
|
|
132
|
-
"y": 1,
|
|
133
|
-
"z": 1,
|
|
134
|
-
"w": 0
|
|
135
|
-
},
|
|
136
|
-
"quat": {
|
|
137
|
-
"x": 0,
|
|
138
|
-
"y": 0,
|
|
139
|
-
"z": 0,
|
|
140
|
-
"w": 1
|
|
141
|
-
},
|
|
142
|
-
"pos": {
|
|
143
|
-
"x": 0,
|
|
144
|
-
"y": 0.5,
|
|
145
|
-
"z": 0,
|
|
146
|
-
"w": 0
|
|
147
|
-
}
|
|
148
|
-
},
|
|
149
|
-
"Clump>OnLevelStart_Listeners": {
|
|
150
|
-
"data": [
|
|
151
|
-
"AvatarSetPos>EntryPoint"
|
|
152
|
-
]
|
|
153
|
-
},
|
|
154
|
-
"Clump>MeditationEnd_1": {
|
|
155
|
-
"data": [
|
|
156
|
-
"AvatarSetPos>EntryPoint",
|
|
157
|
-
"Enable>EnableMeditation",
|
|
158
|
-
"OnBubbleButton>BstNode_1898217744"
|
|
159
|
-
]
|
|
160
|
-
},
|
|
161
|
-
"Clump>MeditationAreaClump": {
|
|
162
|
-
"data": [
|
|
163
|
-
"MeditationArea>BstNode_100"
|
|
164
|
-
]
|
|
165
|
-
},
|
|
166
|
-
"Enable>EnableMeditation": {
|
|
167
|
-
"autoStart": false,
|
|
168
|
-
"objects": "Clump>MeditationAreaClump",
|
|
169
|
-
"killEvents": 0,
|
|
170
|
-
"enable": 1,
|
|
171
|
-
"bstGuid": 1232312,
|
|
172
|
-
"selectObjectRandomly": 0
|
|
173
|
-
},
|
|
174
|
-
"MeditationArea>BstNode_100": {
|
|
175
|
-
"transform": {
|
|
176
|
-
"matrix": [
|
|
177
|
-
[
|
|
178
|
-
1,
|
|
179
|
-
0,
|
|
180
|
-
0,
|
|
181
|
-
0
|
|
182
|
-
],
|
|
183
|
-
[
|
|
184
|
-
0,
|
|
185
|
-
1,
|
|
186
|
-
0,
|
|
187
|
-
0
|
|
188
|
-
],
|
|
189
|
-
[
|
|
190
|
-
0,
|
|
191
|
-
0,
|
|
192
|
-
1,
|
|
193
|
-
0
|
|
194
|
-
],
|
|
195
|
-
[
|
|
196
|
-
2,
|
|
197
|
-
0.05,
|
|
198
|
-
2,
|
|
199
|
-
1
|
|
200
|
-
]
|
|
201
|
-
],
|
|
202
|
-
"pos": {
|
|
203
|
-
"x": 2,
|
|
204
|
-
"y": 0.05,
|
|
205
|
-
"z": 2
|
|
206
|
-
}
|
|
207
|
-
},
|
|
208
|
-
"spawnSeatDelay": 0,
|
|
209
|
-
"camCustomFadeIn": -1,
|
|
210
|
-
"enabled": true,
|
|
211
|
-
"confirmHintText": "hint.meditation.test.1",
|
|
212
|
-
"dialogType": 0,
|
|
213
|
-
"spawnSeatTail": 1,
|
|
214
|
-
"needSit": 1,
|
|
215
|
-
"spawnSeatCameraDist": 0,
|
|
216
|
-
"goals": null,
|
|
217
|
-
"meditationSound": "Pray_Loop",
|
|
218
|
-
"holyAreas": null,
|
|
219
|
-
"disableMergeWithAnyProgress": 1,
|
|
220
|
-
"onlyFireWhenLocalPresent": 0,
|
|
221
|
-
"fullBonus": 2,
|
|
222
|
-
"camCustomFadeOut": -1,
|
|
223
|
-
"localOnly": 1,
|
|
224
|
-
"confirmHintIcon": "",
|
|
225
|
-
"minimumLocalPresentTime": 0,
|
|
226
|
-
"altar": null,
|
|
227
|
-
"minRequired": 0,
|
|
228
|
-
"type": 0,
|
|
229
|
-
"onSitPressed": null,
|
|
230
|
-
"time": 2,
|
|
231
|
-
"spawnSeatFX": 1,
|
|
232
|
-
"progressObjs": null,
|
|
233
|
-
"spawnSeatFXBrightnessMult": 1,
|
|
234
|
-
"sitIconOverride": "UiMenuPresent",
|
|
235
|
-
"keyFrame": null,
|
|
236
|
-
"spawnSeatSFX": 0,
|
|
237
|
-
"onMenuConfirm": null,
|
|
238
|
-
"onMenuCancel": null,
|
|
239
|
-
"onComplete": "Clump>MeditationEnd_1",
|
|
240
|
-
"progressOut": null
|
|
241
|
-
},
|
|
242
|
-
"OnBubbleButton>BstNode_1898217744": {
|
|
243
|
-
"autoStart": false,
|
|
244
|
-
"activeDistance": 3,
|
|
245
|
-
"buttonTarget": null,
|
|
246
|
-
"useAvatar": 1,
|
|
247
|
-
"showInSharedSpaceEditMode": 0,
|
|
248
|
-
"fireOnce": 0,
|
|
249
|
-
"ignoreAllowUI": 0,
|
|
250
|
-
"displayDuration": 0,
|
|
251
|
-
"networkedOnHandhold": 0,
|
|
252
|
-
"iconName": "UiMiscStarCluster",
|
|
253
|
-
"priority": 1,
|
|
254
|
-
"events": "Clump>OnLevelStart_Listeners",
|
|
255
|
-
"cooldownAfterPressed": 0
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# Blender 4.3.2
|
|
2
|
-
# www.blender.org
|
|
3
|
-
mtllib 测试1.mtl
|
|
4
|
-
o Cube.001
|
|
5
|
-
v 10.000000 -0.000002 -10.000000
|
|
6
|
-
v 10.000000 -1.000002 -10.000000
|
|
7
|
-
v 10.000000 0.000002 10.000000
|
|
8
|
-
v 10.000000 -0.999998 10.000000
|
|
9
|
-
v -10.000000 -0.000002 -10.000000
|
|
10
|
-
v -10.000000 -1.000002 -10.000000
|
|
11
|
-
v -10.000000 0.000002 10.000000
|
|
12
|
-
v -10.000000 -0.999998 10.000000
|
|
13
|
-
vn -0.0000 1.0000 -0.0000
|
|
14
|
-
vn -0.0000 -0.0000 1.0000
|
|
15
|
-
vn -1.0000 -0.0000 -0.0000
|
|
16
|
-
vn -0.0000 -1.0000 -0.0000
|
|
17
|
-
vn 1.0000 -0.0000 -0.0000
|
|
18
|
-
vn -0.0000 -0.0000 -1.0000
|
|
19
|
-
vt 0.875000 0.500000
|
|
20
|
-
vt 0.625000 0.750000
|
|
21
|
-
vt 0.625000 0.500000
|
|
22
|
-
vt 0.375000 1.000000
|
|
23
|
-
vt 0.375000 0.750000
|
|
24
|
-
vt 0.375000 0.000000
|
|
25
|
-
vt 0.625000 0.250000
|
|
26
|
-
vt 0.375000 0.250000
|
|
27
|
-
vt 0.375000 0.500000
|
|
28
|
-
vt 0.125000 0.750000
|
|
29
|
-
vt 0.125000 0.500000
|
|
30
|
-
vt 0.875000 0.750000
|
|
31
|
-
vt 0.625000 1.000000
|
|
32
|
-
vt 0.625000 0.000000
|
|
33
|
-
s 1
|
|
34
|
-
usemtl kMaterial_Grass
|
|
35
|
-
f 5/1/1 3/2/1 1/3/1
|
|
36
|
-
f 3/2/2 8/4/2 4/5/2
|
|
37
|
-
f 8/6/3 5/7/3 6/8/3
|
|
38
|
-
f 2/9/4 8/10/4 6/11/4
|
|
39
|
-
f 1/3/5 4/5/5 2/9/5
|
|
40
|
-
f 5/7/6 2/9/6 6/8/6
|
|
41
|
-
f 5/1/1 7/12/1 3/2/1
|
|
42
|
-
f 3/2/2 7/13/2 8/4/2
|
|
43
|
-
f 8/6/3 7/14/3 5/7/3
|
|
44
|
-
f 2/9/4 4/5/4 8/10/4
|
|
45
|
-
f 1/3/5 3/2/5 4/5/5
|
|
46
|
-
f 5/7/6 1/3/6 2/9/6
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
MAKEFLAGS += -s
|
|
2
|
-
|
|
3
|
-
LEVEL_BULID = node ../../main.js
|
|
4
|
-
|
|
5
|
-
all: HTNH_Test.BstBaked.meshes HTNH_Test.Objects.level.bin
|
|
6
|
-
|
|
7
|
-
HTNH_Test.BstBaked.meshes: HTNH_Test.obj
|
|
8
|
-
$(LEVEL_BULID) --convert -i $< -o $@
|
|
9
|
-
|
|
10
|
-
HTNH_Test.Objects.level.bin: HTNH_Test.Objects.level.json
|
|
11
|
-
$(LEVEL_BULID) --serialize -i $< -o $@
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
const { kMaterial } = require("../level/enums/kMaterial.js");
|
|
2
|
-
const { Vec3 } = require("../utils/vector.js");
|
|
3
|
-
|
|
4
|
-
class TriangleMeshVertex {
|
|
5
|
-
constructor(pos, normal) {
|
|
6
|
-
this.pos = pos || new Vec3();
|
|
7
|
-
this.normal = normal || new Vec3();
|
|
8
|
-
/** A list of vertices considered adjacent to the current vertex. */
|
|
9
|
-
this.nearby = new Set();
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
class TriangleMeshMaterial {
|
|
14
|
-
static Null = new TriangleMeshMaterial();
|
|
15
|
-
static Default = new TriangleMeshMaterial("kMaterial_Cliff");
|
|
16
|
-
|
|
17
|
-
static isNull(mat) {
|
|
18
|
-
return mat == TriangleMeshMaterial.Null;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
constructor(name) {
|
|
22
|
-
this.name = name || "";
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
getId() {
|
|
26
|
-
if (this.name.substring(0, 10) !== "kMaterial_")
|
|
27
|
-
return 0;
|
|
28
|
-
return kMaterial[this.name.substring(10)];
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
class TriangleMeshMaterialBarn {
|
|
33
|
-
constructor() {
|
|
34
|
-
this.materials = new Map();
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
initialize() {
|
|
38
|
-
this.materials.clear();
|
|
39
|
-
this.materials.set("", TriangleMeshMaterial.Null);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
tryAddMaterial(name) {
|
|
43
|
-
if (this.materials.has(name))
|
|
44
|
-
return this.materials.get(name);
|
|
45
|
-
|
|
46
|
-
var result = new TriangleMeshMaterial(name);
|
|
47
|
-
this.materials.set(name, result);
|
|
48
|
-
|
|
49
|
-
return result;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
class TriangleMeshFace {
|
|
54
|
-
constructor() {
|
|
55
|
-
this.materialRef = TriangleMeshMaterial.Null;
|
|
56
|
-
this.indices = [];
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
class TriangleMesh {
|
|
61
|
-
constructor() {
|
|
62
|
-
this.cmdBuffer = [];
|
|
63
|
-
this.vtxBuffer = [];
|
|
64
|
-
this.materials = new TriangleMeshMaterialBarn();
|
|
65
|
-
|
|
66
|
-
this.clear();
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
clear() {
|
|
70
|
-
this.cmdBuffer = [];
|
|
71
|
-
this.vtxBuffer = [];
|
|
72
|
-
this.materials.initialize();
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
module.exports = {
|
|
77
|
-
TriangleMeshVertex,
|
|
78
|
-
TriangleMeshMaterial,
|
|
79
|
-
TriangleMeshMaterialBarn,
|
|
80
|
-
TriangleMeshFace,
|
|
81
|
-
TriangleMesh
|
|
82
|
-
};
|
package/src/formats/wavefront.js
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
const { R8G8B8A8_SNORM } = require("../utils/normVec.js");
|
|
2
|
-
const { Vec3 } = require("../utils/vector");
|
|
3
|
-
const {
|
|
4
|
-
TriangleMesh,
|
|
5
|
-
TriangleMeshVertex,
|
|
6
|
-
TriangleMeshMaterial,
|
|
7
|
-
TriangleMeshMaterialBarn,
|
|
8
|
-
TriangleMeshFace
|
|
9
|
-
} = require("./triangleMesh.js");
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Parse a Wavefront OBJ string into vertices, indices, and per-triangle
|
|
13
|
-
* material names. Only vertex positions and face indices are extracted.
|
|
14
|
-
* Returns an object with vertices (array of [x, y, z]), indices
|
|
15
|
-
* (flattened triangle index list), and materials (material name per
|
|
16
|
-
* triangle). If no usemtl is given, "" is used.
|
|
17
|
-
*
|
|
18
|
-
* @param {string} objStr
|
|
19
|
-
* @param {TriangleMeshMaterialBarn} materialBarn
|
|
20
|
-
*/
|
|
21
|
-
function parseObj(objStr, materialBarn) {
|
|
22
|
-
// Split the file content into lines.
|
|
23
|
-
var lines = objStr.split("\n")
|
|
24
|
-
// Storage for raw vertex positions and normals.
|
|
25
|
-
, positions = []
|
|
26
|
-
, normals = []
|
|
27
|
-
, positionRefs = []
|
|
28
|
-
// Current material name, defaults to "".
|
|
29
|
-
, currentMtl = ""
|
|
30
|
-
// Map from combined position/normal keys to vertex indices.
|
|
31
|
-
, vertexMap = {}
|
|
32
|
-
// Output arrays.
|
|
33
|
-
, vertices = []
|
|
34
|
-
, faces = [];
|
|
35
|
-
|
|
36
|
-
// Process every line.
|
|
37
|
-
for (var i = 0; i < lines.length; i++) {
|
|
38
|
-
var line = lines[i].trim();
|
|
39
|
-
// Skip empty lines and comments.
|
|
40
|
-
if (line === "" || line.charAt(0) === "#")
|
|
41
|
-
continue;
|
|
42
|
-
|
|
43
|
-
var parts = line.split(/\s+/);
|
|
44
|
-
var keyword = parts[0];
|
|
45
|
-
|
|
46
|
-
if (keyword === "v") {
|
|
47
|
-
// Store a vertex position.
|
|
48
|
-
positionRefs[positions.length] = new Set();
|
|
49
|
-
positions.push(new Vec3(
|
|
50
|
-
parseFloat(parts[1]),
|
|
51
|
-
parseFloat(parts[2]),
|
|
52
|
-
parseFloat(parts[3])
|
|
53
|
-
));
|
|
54
|
-
} else if (keyword === "vn") {
|
|
55
|
-
// Store a vertex normal.
|
|
56
|
-
normals.push(new R8G8B8A8_SNORM(
|
|
57
|
-
parseFloat(parts[1]),
|
|
58
|
-
parseFloat(parts[2]),
|
|
59
|
-
parseFloat(parts[3])
|
|
60
|
-
));
|
|
61
|
-
} else if (keyword === "usemtl") {
|
|
62
|
-
// Switch active material.
|
|
63
|
-
currentMtl = parts[1] || "";
|
|
64
|
-
} else if (keyword === "f") {
|
|
65
|
-
// Parse a face definition.
|
|
66
|
-
var faceIndices = [];
|
|
67
|
-
var material = currentMtl;
|
|
68
|
-
|
|
69
|
-
// Loop through each vertex reference in the face.
|
|
70
|
-
for (var j = 1; j < parts.length; j++) {
|
|
71
|
-
var token = parts[j];
|
|
72
|
-
var subParts = token.split("/");
|
|
73
|
-
var posIdx = parseInt(subParts[0], 10);
|
|
74
|
-
var normIdx = null;
|
|
75
|
-
|
|
76
|
-
// Extract normal index when available (third component).
|
|
77
|
-
if (subParts.length >= 3 && subParts[2] !== "")
|
|
78
|
-
normIdx = parseInt(subParts[2], 10);
|
|
79
|
-
|
|
80
|
-
// Resolve negative indices relative to the end of the lists.
|
|
81
|
-
if (posIdx < 0)
|
|
82
|
-
posIdx = positions.length + 1 + posIdx;
|
|
83
|
-
if (normIdx !== null && normIdx < 0)
|
|
84
|
-
normIdx = normals.length + 1 + normIdx;
|
|
85
|
-
|
|
86
|
-
// Build a unique key based on position and normal pair.
|
|
87
|
-
var normKey = normIdx !== null
|
|
88
|
-
? normIdx
|
|
89
|
-
: "none";
|
|
90
|
-
var key = posIdx + "," + normKey;
|
|
91
|
-
|
|
92
|
-
// Add a new vertex if the pair hasn't been seen.
|
|
93
|
-
if (!vertexMap.hasOwnProperty(key)) {
|
|
94
|
-
if (posIdx - 1 > positions.length)
|
|
95
|
-
throw new Error("encountered invalid vertex pos");
|
|
96
|
-
if (normIdx - 1 > normals.length)
|
|
97
|
-
throw new Error("encountered invalid vertex normal");
|
|
98
|
-
|
|
99
|
-
var pos = positions[posIdx - 1]
|
|
100
|
-
, posRef = positionRefs[posIdx - 1]
|
|
101
|
-
, norm = (normIdx !== null && normals[normIdx - 1])
|
|
102
|
-
? normals[normIdx - 1]
|
|
103
|
-
: [0, 1, 0];
|
|
104
|
-
|
|
105
|
-
var vtx = new TriangleMeshVertex(pos, norm);
|
|
106
|
-
vtx.nearby = posRef;
|
|
107
|
-
|
|
108
|
-
vertexMap[key] = vertices.length;
|
|
109
|
-
posRef.add(vtx);
|
|
110
|
-
vertices.push(vtx);
|
|
111
|
-
}
|
|
112
|
-
// Record the index for the face.
|
|
113
|
-
faceIndices.push(vertexMap[key]);
|
|
114
|
-
}
|
|
115
|
-
// Store the face with its material.
|
|
116
|
-
var face = new TriangleMeshFace();
|
|
117
|
-
face.indices = faceIndices;
|
|
118
|
-
face.materialRef = materialBarn.tryAddMaterial(material);
|
|
119
|
-
faces.push(face);
|
|
120
|
-
}
|
|
121
|
-
// Other OBJ keywords (vt, g, o, s, mtllib, etc.) are ignored.
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Return the assembled vertices and indexed faces.
|
|
125
|
-
return { vertices: vertices, faces: faces };
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
class WavefrontObj extends TriangleMesh {
|
|
129
|
-
constructor() {
|
|
130
|
-
super();
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* @param {Buffer} fileBuffer
|
|
135
|
-
*/
|
|
136
|
-
fromFileBuffer(fileBuffer) {
|
|
137
|
-
this.clear();
|
|
138
|
-
|
|
139
|
-
var raw = parseObj(fileBuffer.toString("uit-8"), this.materials);
|
|
140
|
-
|
|
141
|
-
this.vtxBuffer = raw.vertices;
|
|
142
|
-
this.cmdBuffer = raw.faces;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
module.exports = {
|
|
147
|
-
WavefrontObj
|
|
148
|
-
};
|