vanta-engine 1.0.1 → 1.0.3
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/dist/chunk-AAWFTQHP.js +35 -0
- package/dist/chunk-AAWFTQHP.js.map +1 -0
- package/dist/index.cjs +8407 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +755 -0
- package/dist/index.d.ts +755 -27
- package/dist/index.js +8368 -26
- package/dist/index.js.map +1 -1
- package/dist/module-A2C3IOOM.js +11 -0
- package/dist/module-A2C3IOOM.js.map +1 -0
- package/package.json +14 -7
- package/dist/engine.d.ts +0 -18
- package/dist/engine.d.ts.map +0 -1
- package/dist/engine.js +0 -23
- package/dist/engine.js.map +0 -1
- package/dist/graphics/assets/asset_format/format.d.ts +0 -115
- package/dist/graphics/assets/asset_format/format.d.ts.map +0 -1
- package/dist/graphics/assets/asset_format/format.js +0 -29
- package/dist/graphics/assets/asset_format/format.js.map +0 -1
- package/dist/graphics/assets/asset_loaders/obj.d.ts +0 -127
- package/dist/graphics/assets/asset_loaders/obj.d.ts.map +0 -1
- package/dist/graphics/assets/asset_loaders/obj.js +0 -762
- package/dist/graphics/assets/asset_loaders/obj.js.map +0 -1
- package/dist/graphics/assets/material.d.ts +0 -33
- package/dist/graphics/assets/material.d.ts.map +0 -1
- package/dist/graphics/assets/material.js +0 -104
- package/dist/graphics/assets/material.js.map +0 -1
- package/dist/graphics/assets/mesh.d.ts +0 -17
- package/dist/graphics/assets/mesh.d.ts.map +0 -1
- package/dist/graphics/assets/mesh.js +0 -47
- package/dist/graphics/assets/mesh.js.map +0 -1
- package/dist/graphics/assets/model.d.ts +0 -13
- package/dist/graphics/assets/model.d.ts.map +0 -1
- package/dist/graphics/assets/model.js +0 -18
- package/dist/graphics/assets/model.js.map +0 -1
- package/dist/graphics/assets/texture.d.ts +0 -93
- package/dist/graphics/assets/texture.d.ts.map +0 -1
- package/dist/graphics/assets/texture.js +0 -318
- package/dist/graphics/assets/texture.js.map +0 -1
- package/dist/graphics/assets/uniform_buffer.d.ts +0 -28
- package/dist/graphics/assets/uniform_buffer.d.ts.map +0 -1
- package/dist/graphics/assets/uniform_buffer.js +0 -132
- package/dist/graphics/assets/uniform_buffer.js.map +0 -1
- package/dist/graphics/assets/vaos.d.ts +0 -9
- package/dist/graphics/assets/vaos.d.ts.map +0 -1
- package/dist/graphics/assets/vaos.js +0 -98
- package/dist/graphics/assets/vaos.js.map +0 -1
- package/dist/graphics/framebuffer.d.ts +0 -77
- package/dist/graphics/framebuffer.d.ts.map +0 -1
- package/dist/graphics/framebuffer.js +0 -265
- package/dist/graphics/framebuffer.js.map +0 -1
- package/dist/graphics/graphics_manager.d.ts +0 -70
- package/dist/graphics/graphics_manager.d.ts.map +0 -1
- package/dist/graphics/graphics_manager.js +0 -503
- package/dist/graphics/graphics_manager.js.map +0 -1
- package/dist/graphics/shader_program.d.ts +0 -66
- package/dist/graphics/shader_program.d.ts.map +0 -1
- package/dist/graphics/shader_program.js +0 -92
- package/dist/graphics/shader_program.js.map +0 -1
- package/dist/graphics/utility.d.ts +0 -14
- package/dist/graphics/utility.d.ts.map +0 -1
- package/dist/graphics/utility.js +0 -81
- package/dist/graphics/utility.js.map +0 -1
- package/dist/hook_manager.d.ts +0 -33
- package/dist/hook_manager.d.ts.map +0 -1
- package/dist/hook_manager.js +0 -102
- package/dist/hook_manager.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/input/input_manager.d.ts +0 -41
- package/dist/input/input_manager.d.ts.map +0 -1
- package/dist/input/input_manager.js +0 -121
- package/dist/input/input_manager.js.map +0 -1
- package/dist/node/camera3d.d.ts +0 -10
- package/dist/node/camera3d.d.ts.map +0 -1
- package/dist/node/camera3d.js +0 -25
- package/dist/node/camera3d.js.map +0 -1
- package/dist/node/lights/directional_light.d.ts +0 -20
- package/dist/node/lights/directional_light.d.ts.map +0 -1
- package/dist/node/lights/directional_light.js +0 -111
- package/dist/node/lights/directional_light.js.map +0 -1
- package/dist/node/lights/light.d.ts +0 -15
- package/dist/node/lights/light.d.ts.map +0 -1
- package/dist/node/lights/light.js +0 -24
- package/dist/node/lights/light.js.map +0 -1
- package/dist/node/lights/point_light.d.ts +0 -26
- package/dist/node/lights/point_light.d.ts.map +0 -1
- package/dist/node/lights/point_light.js +0 -109
- package/dist/node/lights/point_light.js.map +0 -1
- package/dist/node/lights/spot_light.d.ts +0 -13
- package/dist/node/lights/spot_light.d.ts.map +0 -1
- package/dist/node/lights/spot_light.js +0 -35
- package/dist/node/lights/spot_light.js.map +0 -1
- package/dist/node/object3d.d.ts +0 -10
- package/dist/node/object3d.d.ts.map +0 -1
- package/dist/node/object3d.js +0 -60
- package/dist/node/object3d.js.map +0 -1
- package/dist/node/skybox.d.ts +0 -15
- package/dist/node/skybox.d.ts.map +0 -1
- package/dist/node/skybox.js +0 -33
- package/dist/node/skybox.js.map +0 -1
- package/dist/node/sprite2d.d.ts +0 -14
- package/dist/node/sprite2d.d.ts.map +0 -1
- package/dist/node/sprite2d.js +0 -33
- package/dist/node/sprite2d.js.map +0 -1
- package/dist/node.d.ts +0 -76
- package/dist/node.d.ts.map +0 -1
- package/dist/node.js +0 -308
- package/dist/node.js.map +0 -1
- package/dist/scene.d.ts +0 -19
- package/dist/scene.d.ts.map +0 -1
- package/dist/scene.js +0 -50
- package/dist/scene.js.map +0 -1
- package/dist/shaders/default_2d.fs.d.ts +0 -3
- package/dist/shaders/default_2d.fs.d.ts.map +0 -1
- package/dist/shaders/default_2d.fs.js +0 -14
- package/dist/shaders/default_2d.fs.js.map +0 -1
- package/dist/shaders/default_2d.vs.d.ts +0 -3
- package/dist/shaders/default_2d.vs.d.ts.map +0 -1
- package/dist/shaders/default_2d.vs.js +0 -16
- package/dist/shaders/default_2d.vs.js.map +0 -1
- package/dist/shaders/default_3d.fs.d.ts +0 -3
- package/dist/shaders/default_3d.fs.d.ts.map +0 -1
- package/dist/shaders/default_3d.fs.js +0 -327
- package/dist/shaders/default_3d.fs.js.map +0 -1
- package/dist/shaders/default_3d.vs.d.ts +0 -3
- package/dist/shaders/default_3d.vs.d.ts.map +0 -1
- package/dist/shaders/default_3d.vs.js +0 -36
- package/dist/shaders/default_3d.vs.js.map +0 -1
- package/dist/shaders/default_directional_shadow.fs.d.ts +0 -3
- package/dist/shaders/default_directional_shadow.fs.d.ts.map +0 -1
- package/dist/shaders/default_directional_shadow.fs.js +0 -6
- package/dist/shaders/default_directional_shadow.fs.js.map +0 -1
- package/dist/shaders/default_directional_shadow.vs.d.ts +0 -3
- package/dist/shaders/default_directional_shadow.vs.d.ts.map +0 -1
- package/dist/shaders/default_directional_shadow.vs.js +0 -11
- package/dist/shaders/default_directional_shadow.vs.js.map +0 -1
- package/dist/shaders/default_point_shadow.fs.d.ts +0 -3
- package/dist/shaders/default_point_shadow.fs.d.ts.map +0 -1
- package/dist/shaders/default_point_shadow.fs.js +0 -18
- package/dist/shaders/default_point_shadow.fs.js.map +0 -1
- package/dist/shaders/default_point_shadow.vs.d.ts +0 -3
- package/dist/shaders/default_point_shadow.vs.d.ts.map +0 -1
- package/dist/shaders/default_point_shadow.vs.js +0 -14
- package/dist/shaders/default_point_shadow.vs.js.map +0 -1
- package/dist/shaders/default_skybox.fs.d.ts +0 -3
- package/dist/shaders/default_skybox.fs.d.ts.map +0 -1
- package/dist/shaders/default_skybox.fs.js +0 -14
- package/dist/shaders/default_skybox.fs.js.map +0 -1
- package/dist/shaders/default_skybox.vs.d.ts +0 -3
- package/dist/shaders/default_skybox.vs.d.ts.map +0 -1
- package/dist/shaders/default_skybox.vs.js +0 -23
- package/dist/shaders/default_skybox.vs.js.map +0 -1
- package/dist/utility.d.ts +0 -5
- package/dist/utility.d.ts.map +0 -1
- package/dist/utility.js +0 -19
- package/dist/utility.js.map +0 -1
|
@@ -1,762 +0,0 @@
|
|
|
1
|
-
import { Vec3 } from "@vicimpa/glm";
|
|
2
|
-
import { Texture, TextureType } from "../texture.js";
|
|
3
|
-
import { Model } from "../model.js";
|
|
4
|
-
import { Material } from "../material.js";
|
|
5
|
-
import { Mesh } from "../mesh.js";
|
|
6
|
-
import { Node3D } from "../../../node.js";
|
|
7
|
-
import { Object3D } from "../../../node/object3d.js";
|
|
8
|
-
import { parse_path, join_path, basename_path, dirname_path } from "../../utility.js";
|
|
9
|
-
export var AssetFile;
|
|
10
|
-
(function (AssetFile) {
|
|
11
|
-
let OBJ;
|
|
12
|
-
(function (OBJ) {
|
|
13
|
-
let BumpChannel;
|
|
14
|
-
(function (BumpChannel) {
|
|
15
|
-
BumpChannel["RED"] = "r";
|
|
16
|
-
BumpChannel["GREEN"] = "g";
|
|
17
|
-
BumpChannel["BLUE"] = "b";
|
|
18
|
-
BumpChannel["MATTE"] = "m";
|
|
19
|
-
BumpChannel["LUMINANCE"] = "l";
|
|
20
|
-
BumpChannel["Z_DEPTH"] = "z";
|
|
21
|
-
})(BumpChannel = OBJ.BumpChannel || (OBJ.BumpChannel = {}));
|
|
22
|
-
let ReflectionMapType;
|
|
23
|
-
(function (ReflectionMapType) {
|
|
24
|
-
ReflectionMapType["SPHERE"] = "sphere";
|
|
25
|
-
ReflectionMapType["CUBE_TOP"] = "cube_top";
|
|
26
|
-
ReflectionMapType["CUBE_BOTTOM"] = "cube_bottom";
|
|
27
|
-
ReflectionMapType["CUBE_FRONT"] = "cube_front";
|
|
28
|
-
ReflectionMapType["CUBE_BACK"] = "cube_back";
|
|
29
|
-
ReflectionMapType["CUBE_LEFT"] = "cube_left";
|
|
30
|
-
ReflectionMapType["CUBE_RIGHT"] = "cube_right";
|
|
31
|
-
})(ReflectionMapType = OBJ.ReflectionMapType || (OBJ.ReflectionMapType = {}));
|
|
32
|
-
let IlluminationModel;
|
|
33
|
-
(function (IlluminationModel) {
|
|
34
|
-
IlluminationModel[IlluminationModel["COLOR_ON_AMBIENT_OFF"] = 0] = "COLOR_ON_AMBIENT_OFF";
|
|
35
|
-
IlluminationModel[IlluminationModel["COLOR_ON_AMBIENT_ON"] = 1] = "COLOR_ON_AMBIENT_ON";
|
|
36
|
-
IlluminationModel[IlluminationModel["HIGHLIGHT_ON"] = 2] = "HIGHLIGHT_ON";
|
|
37
|
-
IlluminationModel[IlluminationModel["REFLECTION_ON_RAY_TRACE_ON"] = 3] = "REFLECTION_ON_RAY_TRACE_ON";
|
|
38
|
-
IlluminationModel[IlluminationModel["TRANSPARENCY_GLASS_ON__REFLECTION_RAY_TRACE_ON"] = 4] = "TRANSPARENCY_GLASS_ON__REFLECTION_RAY_TRACE_ON";
|
|
39
|
-
IlluminationModel[IlluminationModel["REFLECTION_FRESNEL_ON_RAY_TRACE_ON"] = 5] = "REFLECTION_FRESNEL_ON_RAY_TRACE_ON";
|
|
40
|
-
IlluminationModel[IlluminationModel["TRANSPARENCY_REFRACTION_ON__REFLECTION_FRESNEL_OFF_RAY_TRACE_ON"] = 6] = "TRANSPARENCY_REFRACTION_ON__REFLECTION_FRESNEL_OFF_RAY_TRACE_ON";
|
|
41
|
-
IlluminationModel[IlluminationModel["TRANSPARENCY_REFRACTION_ON__REFLECTION_FRESNEL_ON_RAY_TRACE_ON"] = 7] = "TRANSPARENCY_REFRACTION_ON__REFLECTION_FRESNEL_ON_RAY_TRACE_ON";
|
|
42
|
-
IlluminationModel[IlluminationModel["REFLECTION_ON_RAY_TRACE_OFF"] = 8] = "REFLECTION_ON_RAY_TRACE_OFF";
|
|
43
|
-
IlluminationModel[IlluminationModel["TRANSPARENCY_GLASS_ON__REFLECTION_RAY_TRACE_OFF"] = 9] = "TRANSPARENCY_GLASS_ON__REFLECTION_RAY_TRACE_OFF";
|
|
44
|
-
IlluminationModel[IlluminationModel["CAST_SHADOWS_ON_INVISIBLE_SURFACES"] = 10] = "CAST_SHADOWS_ON_INVISIBLE_SURFACES";
|
|
45
|
-
})(IlluminationModel = OBJ.IlluminationModel || (OBJ.IlluminationModel = {}));
|
|
46
|
-
let CollectionType;
|
|
47
|
-
(function (CollectionType) {
|
|
48
|
-
CollectionType[CollectionType["OBJECT"] = 0] = "OBJECT";
|
|
49
|
-
CollectionType[CollectionType["GROUP"] = 1] = "GROUP";
|
|
50
|
-
})(CollectionType || (CollectionType = {}));
|
|
51
|
-
function create_material(engine, material_data, image_assets_path, image_assets) {
|
|
52
|
-
const get_fallback = (...fallbacks) => {
|
|
53
|
-
for (const fallback of fallbacks) {
|
|
54
|
-
if (fallback !== undefined)
|
|
55
|
-
return fallback;
|
|
56
|
-
}
|
|
57
|
-
throw new Error("A valid defined fallback was not supplied.");
|
|
58
|
-
};
|
|
59
|
-
return new Material(engine.graphics_manager, material_data.name, get_fallback(material_data.diffuse_texture?.name ?
|
|
60
|
-
image_assets.get(material_data.diffuse_texture?.name)
|
|
61
|
-
: undefined, material_data.diffuse_color, new Vec3(1.0)), get_fallback(material_data.metalic_texture?.name ?
|
|
62
|
-
image_assets.get(material_data.metalic_texture?.name)
|
|
63
|
-
: undefined, material_data.metalic, 0.0), get_fallback(material_data.roughness_texture?.name ?
|
|
64
|
-
image_assets.get(material_data.roughness_texture?.name)
|
|
65
|
-
: undefined, material_data.roughness, 0.0), get_fallback(material_data.ambient_texture?.name ?
|
|
66
|
-
image_assets.get(material_data.ambient_texture?.name)
|
|
67
|
-
: undefined, 0.0), get_fallback(material_data.normal_texture?.name ?
|
|
68
|
-
image_assets.get(material_data.normal_texture?.name)
|
|
69
|
-
: undefined, null), engine.graphics_manager.default_3d_shader_program);
|
|
70
|
-
}
|
|
71
|
-
async function load_obj(engine, obj_path, image_assets_path) {
|
|
72
|
-
const obj_name = parse_path(obj_path).name;
|
|
73
|
-
var image_assets = new Map();
|
|
74
|
-
var material_assets = new Map();
|
|
75
|
-
var obj_root_node = new Node3D(engine, obj_name + "_root");
|
|
76
|
-
// Load File
|
|
77
|
-
const res = await fetch(obj_path);
|
|
78
|
-
if (res.ok) {
|
|
79
|
-
const raw_text = await res.text();
|
|
80
|
-
const [objects, materials] = await Parser.parse_obj(engine, obj_path, raw_text, image_assets_path, image_assets);
|
|
81
|
-
// parse materials
|
|
82
|
-
for (const material_data of materials) {
|
|
83
|
-
const material = create_material(engine, material_data, image_assets_path, image_assets);
|
|
84
|
-
material_assets.set(material.name, material);
|
|
85
|
-
}
|
|
86
|
-
for (const object_data of objects) {
|
|
87
|
-
var object;
|
|
88
|
-
if (object_data.data) {
|
|
89
|
-
const data = object_data.data;
|
|
90
|
-
const mesh = new Mesh(engine.graphics_manager, data.vertices, data.normals, data.uvs, data.indices, data.dimensions, data.center);
|
|
91
|
-
var material;
|
|
92
|
-
if (object_data.material) {
|
|
93
|
-
material = material_assets.get(object_data.material);
|
|
94
|
-
if (material === undefined) {
|
|
95
|
-
throw new Error(`Failed to find the material named "${object_data.material}" associated with the object named "${object_data.name}" in the .obj file at "${obj_path}" when attempting to load the obj model.`);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
material = new Material(engine.graphics_manager, "default", new Vec3(0.0), 0.0, 0.0, 0.0, null, engine.graphics_manager.default_3d_shader_program);
|
|
100
|
-
}
|
|
101
|
-
var model = new Model(engine.graphics_manager, "default", mesh, material);
|
|
102
|
-
object = new Object3D(engine, object_data.name, model);
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
object = new Node3D(engine, object_data.name);
|
|
106
|
-
}
|
|
107
|
-
// add groups as children of object
|
|
108
|
-
for (const group_data of object_data.groups) {
|
|
109
|
-
const data = group_data.data;
|
|
110
|
-
const mesh = new Mesh(engine.graphics_manager, data.vertices, data.normals, data.uvs, data.indices, data.dimensions, data.center);
|
|
111
|
-
var material;
|
|
112
|
-
if (group_data.material) {
|
|
113
|
-
material = material_assets.get(group_data.material);
|
|
114
|
-
if (material === undefined) {
|
|
115
|
-
throw new Error(`Failed to find the material named "${group_data.material}" associated with the group named "${group_data.name}" object named "${object_data.name}" in the .obj file at "${obj_path}" when attempting to load the obj model.`);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
else {
|
|
119
|
-
material = new Material(engine.graphics_manager, "default", new Vec3(0.0), 0.0, 0.0, 0.0, null, engine.graphics_manager.default_3d_shader_program);
|
|
120
|
-
}
|
|
121
|
-
var model = new Model(engine.graphics_manager, "default", mesh, material);
|
|
122
|
-
object.push_child(new Object3D(engine, group_data.name, model));
|
|
123
|
-
}
|
|
124
|
-
// add object to root
|
|
125
|
-
obj_root_node.push_child(object);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
throw new Error(`The .obj file at "${obj_path}" does not exist.`);
|
|
130
|
-
}
|
|
131
|
-
return obj_root_node;
|
|
132
|
-
}
|
|
133
|
-
OBJ.load_obj = load_obj;
|
|
134
|
-
class Parser {
|
|
135
|
-
static create_group(name) {
|
|
136
|
-
return {
|
|
137
|
-
name,
|
|
138
|
-
data: Parser.create_data()
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
static create_object(name) {
|
|
142
|
-
return {
|
|
143
|
-
name,
|
|
144
|
-
groups: []
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
static create_data() {
|
|
148
|
-
return {
|
|
149
|
-
temp: {
|
|
150
|
-
min_x: Number.MAX_VALUE,
|
|
151
|
-
min_y: Number.MAX_VALUE,
|
|
152
|
-
min_z: Number.MAX_VALUE,
|
|
153
|
-
max_x: Number.MIN_VALUE,
|
|
154
|
-
max_y: Number.MIN_VALUE,
|
|
155
|
-
max_z: Number.MIN_VALUE,
|
|
156
|
-
vertices: [],
|
|
157
|
-
normals: [],
|
|
158
|
-
uvs: [],
|
|
159
|
-
vertex_map: new Map(),
|
|
160
|
-
vertices_final: [],
|
|
161
|
-
normals_final: [],
|
|
162
|
-
uvs_final: [],
|
|
163
|
-
indices_final: []
|
|
164
|
-
},
|
|
165
|
-
vertices: new Float32Array([]),
|
|
166
|
-
normals: new Float32Array([]),
|
|
167
|
-
uvs: new Float32Array([]),
|
|
168
|
-
indices: new Uint16Array([]),
|
|
169
|
-
dimensions: new Vec3(0.0),
|
|
170
|
-
center: new Vec3(0.0)
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
static create_material(name) {
|
|
174
|
-
return { name };
|
|
175
|
-
}
|
|
176
|
-
static async load_mtl(engine, file_url, image_assets_path, image_assets) {
|
|
177
|
-
const res = await fetch(file_url);
|
|
178
|
-
if (res.ok) {
|
|
179
|
-
const raw_text = await res.text();
|
|
180
|
-
const mtls = await Parser.parse_mtl(engine, file_url, raw_text, image_assets_path, image_assets);
|
|
181
|
-
return mtls;
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
throw new Error(`The .mtl file at "${file_url}" does not exist.`);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
static async parse_mtl(engine, file_url, text, image_assets_path, image_assets) {
|
|
188
|
-
var material_list = [];
|
|
189
|
-
var current_material = null;
|
|
190
|
-
const lines = text.split("\n");
|
|
191
|
-
for (const line of lines) {
|
|
192
|
-
const parts = line.trim().split(/\s+/);
|
|
193
|
-
switch (parts[0].toLowerCase()) {
|
|
194
|
-
case "newmtl":
|
|
195
|
-
current_material = Parser.create_material(parts[1]);
|
|
196
|
-
material_list.push(current_material);
|
|
197
|
-
break;
|
|
198
|
-
case "illum":
|
|
199
|
-
if (current_material) {
|
|
200
|
-
current_material.illumination_model = Number(parts[1]);
|
|
201
|
-
}
|
|
202
|
-
break;
|
|
203
|
-
case "kd":
|
|
204
|
-
if (current_material) {
|
|
205
|
-
const [r, g, b] = parts.slice(1).map(Number);
|
|
206
|
-
current_material.diffuse_color = new Vec3(r, g, b);
|
|
207
|
-
}
|
|
208
|
-
break;
|
|
209
|
-
case "ka":
|
|
210
|
-
if (current_material) {
|
|
211
|
-
const [r, g, b] = parts.slice(1).map(Number);
|
|
212
|
-
current_material.ambient_color = new Vec3(r, g, b);
|
|
213
|
-
}
|
|
214
|
-
break;
|
|
215
|
-
case "ks":
|
|
216
|
-
if (current_material) {
|
|
217
|
-
const [r, g, b] = parts.slice(1).map(Number);
|
|
218
|
-
current_material.specular_color = new Vec3(r, g, b);
|
|
219
|
-
}
|
|
220
|
-
break;
|
|
221
|
-
case "ns":
|
|
222
|
-
if (current_material) {
|
|
223
|
-
current_material.specular_exponent = Number(parts[1]);
|
|
224
|
-
}
|
|
225
|
-
break;
|
|
226
|
-
case "d":
|
|
227
|
-
if (current_material) {
|
|
228
|
-
current_material.transparency = Number(parts[1]);
|
|
229
|
-
}
|
|
230
|
-
break;
|
|
231
|
-
case "tr":
|
|
232
|
-
if (current_material) {
|
|
233
|
-
current_material.transparency = 1.0 - Number(parts[1]);
|
|
234
|
-
}
|
|
235
|
-
break;
|
|
236
|
-
case "ni":
|
|
237
|
-
if (current_material) {
|
|
238
|
-
current_material.optical_density = Number(parts[1]);
|
|
239
|
-
}
|
|
240
|
-
break;
|
|
241
|
-
case "pr":
|
|
242
|
-
if (current_material) {
|
|
243
|
-
current_material.roughness = Number(parts[1]);
|
|
244
|
-
}
|
|
245
|
-
break;
|
|
246
|
-
case "pm":
|
|
247
|
-
if (current_material) {
|
|
248
|
-
current_material.metalic = Number(parts[1]);
|
|
249
|
-
}
|
|
250
|
-
break;
|
|
251
|
-
case "ps":
|
|
252
|
-
if (current_material) {
|
|
253
|
-
current_material.sheen = Number(parts[1]);
|
|
254
|
-
}
|
|
255
|
-
break;
|
|
256
|
-
case "pc":
|
|
257
|
-
if (current_material) {
|
|
258
|
-
current_material.clearcoat_thickness = Number(parts[1]);
|
|
259
|
-
}
|
|
260
|
-
break;
|
|
261
|
-
case "pcr":
|
|
262
|
-
if (current_material) {
|
|
263
|
-
current_material.clearcoat_roughness = Number(parts[1]);
|
|
264
|
-
}
|
|
265
|
-
break;
|
|
266
|
-
case "ke":
|
|
267
|
-
if (current_material) {
|
|
268
|
-
current_material.emissive = Number(parts[1]);
|
|
269
|
-
}
|
|
270
|
-
break;
|
|
271
|
-
case "aniso":
|
|
272
|
-
if (current_material) {
|
|
273
|
-
current_material.anisotropy = Number(parts[1]);
|
|
274
|
-
}
|
|
275
|
-
break;
|
|
276
|
-
case "anisor":
|
|
277
|
-
if (current_material) {
|
|
278
|
-
current_material.anisotropy_rotation = Number(parts[1]);
|
|
279
|
-
}
|
|
280
|
-
break;
|
|
281
|
-
case "tf":
|
|
282
|
-
if (current_material) {
|
|
283
|
-
if (parts[1].includes("x", 0)) {
|
|
284
|
-
const x = Number(parts[2]);
|
|
285
|
-
var y = null;
|
|
286
|
-
var z = null;
|
|
287
|
-
if (parts.length >= 4)
|
|
288
|
-
y = Number(parts[3]);
|
|
289
|
-
if (parts.length >= 5)
|
|
290
|
-
z = Number(parts[4]);
|
|
291
|
-
current_material.transmission_filter_color = new Vec3(x, y !== null ? y : x, z !== null ? z : x);
|
|
292
|
-
current_material.transmission_filter_xyz;
|
|
293
|
-
}
|
|
294
|
-
else {
|
|
295
|
-
const [r, g, b] = parts.slice(1).map(Number);
|
|
296
|
-
current_material.transmission_filter_color = new Vec3(r, g, b);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
break;
|
|
300
|
-
// TEXTURE MAPS
|
|
301
|
-
case "map_ka":
|
|
302
|
-
if (current_material)
|
|
303
|
-
current_material.ambient_texture = await Parser.parse_mtl_map(engine, current_material, [...parts], image_assets_path, image_assets);
|
|
304
|
-
break;
|
|
305
|
-
case "map_kd":
|
|
306
|
-
if (current_material)
|
|
307
|
-
current_material.diffuse_texture = await Parser.parse_mtl_map(engine, current_material, [...parts], image_assets_path, image_assets);
|
|
308
|
-
break;
|
|
309
|
-
case "map_ks":
|
|
310
|
-
if (current_material)
|
|
311
|
-
current_material.specular_color_texture = await Parser.parse_mtl_map(engine, current_material, [...parts], image_assets_path, image_assets);
|
|
312
|
-
break;
|
|
313
|
-
case "map_ns":
|
|
314
|
-
if (current_material)
|
|
315
|
-
current_material.specular_highlight_texture = await Parser.parse_mtl_map(engine, current_material, [...parts], image_assets_path, image_assets);
|
|
316
|
-
break;
|
|
317
|
-
case "map_d":
|
|
318
|
-
if (current_material)
|
|
319
|
-
current_material.alpha_texture = await Parser.parse_mtl_map(engine, current_material, [...parts], image_assets_path, image_assets);
|
|
320
|
-
break;
|
|
321
|
-
case "refl":
|
|
322
|
-
if (current_material)
|
|
323
|
-
if (current_material.reflection_textures === undefined)
|
|
324
|
-
current_material.reflection_textures = [await Parser.parse_mtl_map(engine, current_material, [...parts], image_assets_path, image_assets)];
|
|
325
|
-
else
|
|
326
|
-
current_material.reflection_textures.push(await Parser.parse_mtl_map(engine, current_material, [...parts], image_assets_path, image_assets));
|
|
327
|
-
break;
|
|
328
|
-
case "map_bump":
|
|
329
|
-
if (current_material)
|
|
330
|
-
current_material.bump_texture = await Parser.parse_mtl_map(engine, current_material, [...parts], image_assets_path, image_assets);
|
|
331
|
-
break;
|
|
332
|
-
case "bump":
|
|
333
|
-
if (current_material)
|
|
334
|
-
current_material.bump_texture = await Parser.parse_mtl_map(engine, current_material, [...parts], image_assets_path, image_assets);
|
|
335
|
-
break;
|
|
336
|
-
case "disp":
|
|
337
|
-
if (current_material)
|
|
338
|
-
current_material.displacement_texture = await Parser.parse_mtl_map(engine, current_material, [...parts], image_assets_path, image_assets);
|
|
339
|
-
break;
|
|
340
|
-
case "decal":
|
|
341
|
-
if (current_material)
|
|
342
|
-
current_material.decal_texture = await Parser.parse_mtl_map(engine, current_material, [...parts], image_assets_path, image_assets);
|
|
343
|
-
break;
|
|
344
|
-
case "map_pr":
|
|
345
|
-
if (current_material)
|
|
346
|
-
current_material.roughness_texture = await Parser.parse_mtl_map(engine, current_material, [...parts], image_assets_path, image_assets);
|
|
347
|
-
break;
|
|
348
|
-
case "map_pm":
|
|
349
|
-
if (current_material)
|
|
350
|
-
current_material.metalic_texture = await Parser.parse_mtl_map(engine, current_material, [...parts], image_assets_path, image_assets);
|
|
351
|
-
break;
|
|
352
|
-
case "map_ps":
|
|
353
|
-
if (current_material)
|
|
354
|
-
current_material.sheen_texture = await Parser.parse_mtl_map(engine, current_material, [...parts], image_assets_path, image_assets);
|
|
355
|
-
break;
|
|
356
|
-
case "map_ke":
|
|
357
|
-
if (current_material)
|
|
358
|
-
current_material.emissive_texture = await Parser.parse_mtl_map(engine, current_material, [...parts], image_assets_path, image_assets);
|
|
359
|
-
break;
|
|
360
|
-
case "norm":
|
|
361
|
-
if (current_material)
|
|
362
|
-
current_material.normal_texture = await Parser.parse_mtl_map(engine, current_material, [...parts], image_assets_path, image_assets);
|
|
363
|
-
break;
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
return material_list;
|
|
367
|
-
}
|
|
368
|
-
static async parse_mtl_map(engine, current_material, parts, image_assets_path, image_assets) {
|
|
369
|
-
var texture_name;
|
|
370
|
-
var current_flag = null;
|
|
371
|
-
const texture_file = parts.pop();
|
|
372
|
-
const map_type_string = parts.shift();
|
|
373
|
-
var current_flag_arguments = [];
|
|
374
|
-
if (texture_file) {
|
|
375
|
-
const texture_file_url = join_path(image_assets_path, texture_file);
|
|
376
|
-
const res = await fetch(texture_file_url.trim());
|
|
377
|
-
if (res.ok) {
|
|
378
|
-
const blob = await res.blob();
|
|
379
|
-
if (map_type_string) {
|
|
380
|
-
texture_name = current_material.name + "_" + map_type_string;
|
|
381
|
-
image_assets.set(texture_name, new Texture(engine.graphics_manager, texture_name, await createImageBitmap(blob, { imageOrientation: 'flipY' }), TextureType.COLOR, {}));
|
|
382
|
-
}
|
|
383
|
-
else {
|
|
384
|
-
throw Error(`A parsing error has occured that should not be possible while parsing a .mtl file map.`);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
else {
|
|
388
|
-
throw new Error(`The .obj image asset file at "${texture_file_url}" does not exist.`);
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
else {
|
|
392
|
-
throw new Error(`Failed to get get texture map file name for material named "${current_material.name}" when parsign .mtl file associated with .obj file.`);
|
|
393
|
-
}
|
|
394
|
-
const texture_data = { name: texture_name };
|
|
395
|
-
const set_flag = () => {
|
|
396
|
-
switch (current_flag) {
|
|
397
|
-
case "-blendu":
|
|
398
|
-
texture_data.horizontal_blend =
|
|
399
|
-
current_flag_arguments[0] === "off" ?
|
|
400
|
-
false : true;
|
|
401
|
-
break;
|
|
402
|
-
case "-blendv":
|
|
403
|
-
texture_data.vertical_blend =
|
|
404
|
-
current_flag_arguments[0] === "off" ?
|
|
405
|
-
false : true;
|
|
406
|
-
break;
|
|
407
|
-
case "-boost":
|
|
408
|
-
texture_data.mip_map_sharpness_boost = Number(current_flag_arguments[0]);
|
|
409
|
-
break;
|
|
410
|
-
case "-mm":
|
|
411
|
-
texture_data.additive_color_offset = Number(current_flag_arguments[0]);
|
|
412
|
-
texture_data.contrast_multiplier = Number(current_flag_arguments[1]);
|
|
413
|
-
break;
|
|
414
|
-
case "-o":
|
|
415
|
-
var u = Number(current_flag_arguments[0]);
|
|
416
|
-
var v = 0;
|
|
417
|
-
var w = 0;
|
|
418
|
-
if (current_flag_arguments.length >= 2)
|
|
419
|
-
v = Number(current_flag_arguments[1]);
|
|
420
|
-
if (current_flag_arguments.length >= 3)
|
|
421
|
-
w = Number(current_flag_arguments[2]);
|
|
422
|
-
texture_data.offset = new Vec3(u, v, w);
|
|
423
|
-
break;
|
|
424
|
-
case "-s":
|
|
425
|
-
var u = Number(current_flag_arguments[0]);
|
|
426
|
-
var v = 1;
|
|
427
|
-
var w = 1;
|
|
428
|
-
if (current_flag_arguments.length >= 2)
|
|
429
|
-
v = Number(current_flag_arguments[1]);
|
|
430
|
-
if (current_flag_arguments.length >= 3)
|
|
431
|
-
w = Number(current_flag_arguments[2]);
|
|
432
|
-
texture_data.scale = new Vec3(u, v, w);
|
|
433
|
-
break;
|
|
434
|
-
case "-t":
|
|
435
|
-
var u = Number(current_flag_arguments[0]);
|
|
436
|
-
var v = 0;
|
|
437
|
-
var w = 0;
|
|
438
|
-
if (current_flag_arguments.length >= 2)
|
|
439
|
-
v = Number(current_flag_arguments[1]);
|
|
440
|
-
if (current_flag_arguments.length >= 3)
|
|
441
|
-
w = Number(current_flag_arguments[2]);
|
|
442
|
-
texture_data.turbulence = new Vec3(u, v, w);
|
|
443
|
-
break;
|
|
444
|
-
case "-texres":
|
|
445
|
-
texture_data.generated_texture_resolution = Number(current_flag_arguments[0]);
|
|
446
|
-
break;
|
|
447
|
-
case "-clamp":
|
|
448
|
-
texture_data.clamp =
|
|
449
|
-
current_flag_arguments[0] === "on" ?
|
|
450
|
-
true : false;
|
|
451
|
-
break;
|
|
452
|
-
case "-bm":
|
|
453
|
-
texture_data.bump_multiplier = Number(current_flag_arguments[0]);
|
|
454
|
-
break;
|
|
455
|
-
case "-imfchan":
|
|
456
|
-
texture_data.bump_channel = current_flag_arguments[0];
|
|
457
|
-
break;
|
|
458
|
-
case "-type":
|
|
459
|
-
texture_data.reflection_map_type = current_flag_arguments[0];
|
|
460
|
-
break;
|
|
461
|
-
}
|
|
462
|
-
current_flag_arguments = [];
|
|
463
|
-
};
|
|
464
|
-
for (const part of parts) {
|
|
465
|
-
switch (part) {
|
|
466
|
-
case "-blendu":
|
|
467
|
-
case "-blendv":
|
|
468
|
-
case "-boost":
|
|
469
|
-
case "-mm":
|
|
470
|
-
case "-o":
|
|
471
|
-
case "-s":
|
|
472
|
-
case "-t":
|
|
473
|
-
case "-texres":
|
|
474
|
-
case "-clamp":
|
|
475
|
-
case "-bm":
|
|
476
|
-
case "-imfchan":
|
|
477
|
-
case "-type":
|
|
478
|
-
set_flag();
|
|
479
|
-
current_flag = part;
|
|
480
|
-
break;
|
|
481
|
-
default:
|
|
482
|
-
current_flag_arguments.push(part);
|
|
483
|
-
break;
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
set_flag();
|
|
487
|
-
return texture_data;
|
|
488
|
-
}
|
|
489
|
-
static async parse_obj(engine, file_url, text, image_assets_path, image_assets) {
|
|
490
|
-
const file_name = basename_path(file_url);
|
|
491
|
-
const file_directory = dirname_path(file_url);
|
|
492
|
-
const obj_name = file_name.split(".")[0];
|
|
493
|
-
var object_list = [];
|
|
494
|
-
var material_list = [];
|
|
495
|
-
var current_group = null;
|
|
496
|
-
var current_object = Parser.create_object(obj_name);
|
|
497
|
-
var current_data = Parser.create_data();
|
|
498
|
-
const temp_vertices = [];
|
|
499
|
-
const temp_normals = [];
|
|
500
|
-
const temp_uvs = [];
|
|
501
|
-
object_list.push(current_object);
|
|
502
|
-
var collection_type = CollectionType.OBJECT;
|
|
503
|
-
const insert_data = () => {
|
|
504
|
-
// Bake the data lists into arrays and delete temp
|
|
505
|
-
current_data.indices = new Uint16Array(current_data.temp.indices_final);
|
|
506
|
-
current_data.vertices = new Float32Array(current_data.temp.vertices_final);
|
|
507
|
-
current_data.uvs = new Float32Array(current_data.temp.uvs_final);
|
|
508
|
-
current_data.normals = new Float32Array(current_data.temp.normals_final);
|
|
509
|
-
current_data.dimensions = new Vec3(current_data.temp.max_x - current_data.temp.min_x, current_data.temp.max_y - current_data.temp.min_y, current_data.temp.max_z - current_data.temp.min_z);
|
|
510
|
-
current_data.center = new Vec3((current_data.temp.max_x + current_data.temp.min_x) / 2.0, (current_data.temp.max_y + current_data.temp.min_y) / 2.0, (current_data.temp.max_z + current_data.temp.min_z) / 2.0);
|
|
511
|
-
// set the data for the object
|
|
512
|
-
if (collection_type === CollectionType.OBJECT) {
|
|
513
|
-
current_object.data = current_data;
|
|
514
|
-
}
|
|
515
|
-
else if (current_group) {
|
|
516
|
-
current_group.data = current_data;
|
|
517
|
-
}
|
|
518
|
-
current_data = Parser.create_data();
|
|
519
|
-
};
|
|
520
|
-
const get_object = (name) => {
|
|
521
|
-
for (const object of object_list)
|
|
522
|
-
if (object.name === name)
|
|
523
|
-
return object;
|
|
524
|
-
return null;
|
|
525
|
-
};
|
|
526
|
-
const get_group = (name) => {
|
|
527
|
-
for (const group of current_object.groups)
|
|
528
|
-
if (group.name === name)
|
|
529
|
-
return group;
|
|
530
|
-
return null;
|
|
531
|
-
};
|
|
532
|
-
const lines = text.split("\n");
|
|
533
|
-
for (const line of lines) {
|
|
534
|
-
const parts = line.trim().split(/\s+/);
|
|
535
|
-
switch (parts[0].toLowerCase()) {
|
|
536
|
-
case "mtllib":
|
|
537
|
-
material_list = material_list.concat(await Parser.load_mtl(engine, join_path(file_directory, parts[1]), image_assets_path, image_assets));
|
|
538
|
-
break;
|
|
539
|
-
case "usemtl":
|
|
540
|
-
if (collection_type === CollectionType.OBJECT) {
|
|
541
|
-
if (current_object.material !== undefined && current_object.material !== parts[1]) {
|
|
542
|
-
insert_data();
|
|
543
|
-
// Creates an adjacent subobject with the name objectName_materialName
|
|
544
|
-
current_object = Parser.create_object(current_object.name.replace("_" + current_object.material, "") + "_" + parts[1]);
|
|
545
|
-
current_object.material = parts[1];
|
|
546
|
-
object_list.push(current_object);
|
|
547
|
-
collection_type = CollectionType.OBJECT;
|
|
548
|
-
}
|
|
549
|
-
else {
|
|
550
|
-
current_object.material = parts[1];
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
else if (current_group) {
|
|
554
|
-
if (current_group.material !== undefined && current_group.material !== parts[1]) {
|
|
555
|
-
insert_data();
|
|
556
|
-
// Creates an adjacent subobject with the name objectName_materialName
|
|
557
|
-
current_group = Parser.create_group(current_group.name.replace("_" + current_group.material, "") + "_" + parts[1]);
|
|
558
|
-
current_group.material = parts[1];
|
|
559
|
-
current_object.groups.push(current_group);
|
|
560
|
-
collection_type = CollectionType.GROUP;
|
|
561
|
-
}
|
|
562
|
-
else {
|
|
563
|
-
current_group.material = parts[1];
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
break;
|
|
567
|
-
case "o":
|
|
568
|
-
// Object
|
|
569
|
-
insert_data();
|
|
570
|
-
const existing_object = get_object(parts[1]);
|
|
571
|
-
if (existing_object) {
|
|
572
|
-
current_object = existing_object;
|
|
573
|
-
}
|
|
574
|
-
else {
|
|
575
|
-
// add current_object to groups and create a new object
|
|
576
|
-
current_object = Parser.create_object(parts[1]);
|
|
577
|
-
object_list.push(current_object);
|
|
578
|
-
collection_type = CollectionType.OBJECT;
|
|
579
|
-
}
|
|
580
|
-
break;
|
|
581
|
-
case "g":
|
|
582
|
-
insert_data();
|
|
583
|
-
const existing_group = get_group(parts[1]);
|
|
584
|
-
if (existing_group) {
|
|
585
|
-
current_group = existing_group;
|
|
586
|
-
}
|
|
587
|
-
else {
|
|
588
|
-
// add current_object to groups and create a new object
|
|
589
|
-
current_group = Parser.create_group(parts[1]);
|
|
590
|
-
current_object.groups.push(current_group);
|
|
591
|
-
collection_type = CollectionType.GROUP;
|
|
592
|
-
}
|
|
593
|
-
break;
|
|
594
|
-
case "v":
|
|
595
|
-
var [x, y, z] = parts.slice(1).map(Number);
|
|
596
|
-
temp_vertices.push([x, y, z]);
|
|
597
|
-
break;
|
|
598
|
-
case "vn":
|
|
599
|
-
var [x, y, z] = parts.slice(1).map(Number);
|
|
600
|
-
temp_normals.push([x, y, z]);
|
|
601
|
-
break;
|
|
602
|
-
case "vt":
|
|
603
|
-
var [u, v] = parts.slice(1).map(Number);
|
|
604
|
-
temp_uvs.push([u, v]);
|
|
605
|
-
break;
|
|
606
|
-
case "f":
|
|
607
|
-
// Each face can be triangles or quads
|
|
608
|
-
const face_verts = parts.slice(1);
|
|
609
|
-
const face_indices = [];
|
|
610
|
-
for (const fv of face_verts) {
|
|
611
|
-
if (!current_data.temp.vertex_map.has(fv)) {
|
|
612
|
-
const [vIdx, vtIdx, vnIdx] = fv.split("/").map(s => parseInt(s));
|
|
613
|
-
const [x, y, z] = temp_vertices[vIdx - 1];
|
|
614
|
-
// FIND MINS AND MAXES
|
|
615
|
-
current_data.temp.min_x = x < current_data.temp.min_x ? x : current_data.temp.min_x;
|
|
616
|
-
current_data.temp.min_y = y < current_data.temp.min_y ? y : current_data.temp.min_y;
|
|
617
|
-
current_data.temp.min_z = z < current_data.temp.min_z ? z : current_data.temp.min_z;
|
|
618
|
-
current_data.temp.max_x = x > current_data.temp.max_x ? x : current_data.temp.max_x;
|
|
619
|
-
current_data.temp.max_y = y > current_data.temp.max_y ? y : current_data.temp.max_y;
|
|
620
|
-
current_data.temp.max_z = z > current_data.temp.max_z ? z : current_data.temp.max_z;
|
|
621
|
-
// FIND VERTEX
|
|
622
|
-
current_data.temp.vertices_final.push(x, y, z);
|
|
623
|
-
if (vtIdx && temp_uvs[vtIdx - 1])
|
|
624
|
-
current_data.temp.uvs_final.push(...temp_uvs[vtIdx - 1]);
|
|
625
|
-
else
|
|
626
|
-
current_data.temp.uvs_final.push(0, 0);
|
|
627
|
-
if (vnIdx && temp_normals[vnIdx - 1])
|
|
628
|
-
current_data.temp.normals_final.push(...temp_normals[vnIdx - 1]);
|
|
629
|
-
else
|
|
630
|
-
current_data.temp.normals_final.push(0, 0, 0);
|
|
631
|
-
const index = (current_data.temp.vertices_final.length / 3) - 1;
|
|
632
|
-
current_data.temp.vertex_map.set(fv, index);
|
|
633
|
-
face_indices.push(index);
|
|
634
|
-
}
|
|
635
|
-
else {
|
|
636
|
-
face_indices.push(current_data.temp.vertex_map.get(fv));
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
// Triangulate quads if necessary
|
|
640
|
-
if (face_indices.length === 3) {
|
|
641
|
-
current_data.temp.indices_final.push(...face_indices);
|
|
642
|
-
}
|
|
643
|
-
else if (face_indices.length === 4) {
|
|
644
|
-
current_data.temp.indices_final.push(face_indices[0], face_indices[1], face_indices[2]);
|
|
645
|
-
current_data.temp.indices_final.push(face_indices[0], face_indices[2], face_indices[3]);
|
|
646
|
-
}
|
|
647
|
-
break;
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
insert_data();
|
|
651
|
-
return [object_list, material_list];
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
})(OBJ = AssetFile.OBJ || (AssetFile.OBJ = {}));
|
|
655
|
-
})(AssetFile || (AssetFile = {}));
|
|
656
|
-
async function parse_obj(text) {
|
|
657
|
-
const positions = [];
|
|
658
|
-
const normals = [];
|
|
659
|
-
const uvs = [];
|
|
660
|
-
const indices = [];
|
|
661
|
-
const temp_vertices = [];
|
|
662
|
-
const temp_normals = [];
|
|
663
|
-
const temp_uvs = [];
|
|
664
|
-
const vertex_map = new Map(); // maps "v/vt/vn" to index
|
|
665
|
-
var [min_x, min_y, min_z] = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE];
|
|
666
|
-
var [max_x, max_y, max_z] = [Number.MIN_VALUE, Number.MIN_VALUE, Number.MIN_VALUE];
|
|
667
|
-
const lines = text.split("\n");
|
|
668
|
-
for (const line of lines) {
|
|
669
|
-
const parts = line.trim().split(/\s+/);
|
|
670
|
-
if (parts.length === 0)
|
|
671
|
-
continue;
|
|
672
|
-
switch (parts[0]) {
|
|
673
|
-
case "v":
|
|
674
|
-
const [x, y, z] = parts.slice(1).map(Number);
|
|
675
|
-
min_x = x < min_x ? x : min_x;
|
|
676
|
-
min_y = y < min_y ? y : min_y;
|
|
677
|
-
min_z = z < min_z ? z : min_z;
|
|
678
|
-
max_x = x > max_x ? x : max_x;
|
|
679
|
-
max_y = y > max_y ? y : max_y;
|
|
680
|
-
max_z = z > max_z ? z : max_z;
|
|
681
|
-
temp_vertices.push([x, y, z]);
|
|
682
|
-
break;
|
|
683
|
-
case "vn":
|
|
684
|
-
temp_normals.push(parts.slice(1).map(Number));
|
|
685
|
-
break;
|
|
686
|
-
case "vt":
|
|
687
|
-
temp_uvs.push(parts.slice(1).map(Number));
|
|
688
|
-
break;
|
|
689
|
-
case "f":
|
|
690
|
-
// Each face can be triangles or quads
|
|
691
|
-
const face_verts = parts.slice(1);
|
|
692
|
-
const face_indices = [];
|
|
693
|
-
for (const fv of face_verts) {
|
|
694
|
-
if (!vertex_map.has(fv)) {
|
|
695
|
-
const [vIdx, vtIdx, vnIdx] = fv.split("/").map(s => parseInt(s));
|
|
696
|
-
const pos = temp_vertices[vIdx - 1];
|
|
697
|
-
positions.push(...pos);
|
|
698
|
-
if (vtIdx && temp_uvs[vtIdx - 1])
|
|
699
|
-
uvs.push(...temp_uvs[vtIdx - 1]);
|
|
700
|
-
else
|
|
701
|
-
uvs.push(0, 0);
|
|
702
|
-
if (vnIdx && temp_normals[vnIdx - 1])
|
|
703
|
-
normals.push(...temp_normals[vnIdx - 1]);
|
|
704
|
-
else
|
|
705
|
-
normals.push(0, 0, 0);
|
|
706
|
-
const index = (positions.length / 3) - 1;
|
|
707
|
-
vertex_map.set(fv, index);
|
|
708
|
-
face_indices.push(index);
|
|
709
|
-
}
|
|
710
|
-
else {
|
|
711
|
-
face_indices.push(vertex_map.get(fv));
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
// Triangulate quads if necessary
|
|
715
|
-
if (face_indices.length === 3) {
|
|
716
|
-
indices.push(...face_indices);
|
|
717
|
-
}
|
|
718
|
-
else if (face_indices.length === 4) {
|
|
719
|
-
indices.push(face_indices[0], face_indices[1], face_indices[2]);
|
|
720
|
-
indices.push(face_indices[0], face_indices[2], face_indices[3]);
|
|
721
|
-
}
|
|
722
|
-
break;
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
return {
|
|
726
|
-
vertices: new Float32Array(positions),
|
|
727
|
-
normals: new Float32Array(normals),
|
|
728
|
-
uvs: new Float32Array(uvs),
|
|
729
|
-
indices: new Uint16Array(indices),
|
|
730
|
-
dimensions: new Vec3(max_x - min_x, max_y - min_y, max_z - min_z),
|
|
731
|
-
center: new Vec3((max_x + min_x) / 2.0, (max_y + min_y) / 2.0, (max_z + min_z) / 2.0),
|
|
732
|
-
};
|
|
733
|
-
}
|
|
734
|
-
export async function load_obj(gm, model_path, image_asset_paths) {
|
|
735
|
-
var image_assets = [];
|
|
736
|
-
const vertexMap = new Map();
|
|
737
|
-
for (const image_asset_path of image_asset_paths) {
|
|
738
|
-
const res = await fetch(image_asset_path);
|
|
739
|
-
if (res.ok) {
|
|
740
|
-
const blob = await res.blob();
|
|
741
|
-
image_assets.push(new Texture(gm, image_asset_path, await createImageBitmap(blob, { imageOrientation: 'flipY' }), TextureType.COLOR, {}));
|
|
742
|
-
}
|
|
743
|
-
else {
|
|
744
|
-
throw new Error(`The .obj image asset file at "${image_asset_path}" does not exist.`);
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
// Parse the mesh file
|
|
748
|
-
const res = await fetch(model_path);
|
|
749
|
-
if (res.ok) {
|
|
750
|
-
const raw_text = await res.text();
|
|
751
|
-
var obj = await parse_obj(raw_text);
|
|
752
|
-
}
|
|
753
|
-
else {
|
|
754
|
-
throw new Error(`The .obj file at "${model_path}" does not exist.`);
|
|
755
|
-
}
|
|
756
|
-
// Build the model
|
|
757
|
-
var mesh = new Mesh(gm, obj.vertices, obj.normals, obj.uvs, obj.indices, obj.dimensions, obj.center);
|
|
758
|
-
var material = new Material(gm, "default", image_assets[0], 0.0, 0.0, 0.0, null, gm.default_3d_shader_program);
|
|
759
|
-
var model = new Model(gm, "default", mesh, material);
|
|
760
|
-
return model;
|
|
761
|
-
}
|
|
762
|
-
//# sourceMappingURL=obj.js.map
|