-
Notifications
You must be signed in to change notification settings - Fork 0
/
loaders.js
176 lines (156 loc) · 5.32 KB
/
loaders.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/*jshint esversion: 11 */
// @ts-check
/**
* Access to THREE's loaders within the CS559 framework
*
* @module loaders
*/
import * as T from "../CS559-Three/build/three.module.js";
import { GrObject } from "./GrObject.js";
import { FBXLoader } from "../CS559-Three/examples/jsm/loaders/FBXLoader.js";
import { MTLLoader } from "../CS559-Three/examples/jsm/loaders/MTLLoader.js";
import { OBJLoader } from "../CS559-Three/examples/jsm/loaders/OBJLoader.js";
import { GrCube} from "./SimpleObjects.js";
/**
* Rescale an object - assumes that the object is a group with 1 mesh in it
*
* @param {THREE.Object3D} obj
*/
function normObject(obj, scale = 1.0, center = true, ground = true) {
// since other bounding box things aren't reliable
const box = new T.Box3();
box.setFromObject(obj);
// easier than vector subtract
const dx = box.max.x - box.min.x;
const dy = box.max.y - box.min.y;
const dz = box.max.z - box.min.z;
const size = Math.max(dx, dy, dz);
const s = scale / size;
obj.scale.set(s, s, s);
if (center) {
obj.translateX((-s * (box.max.x + box.min.x)) / 2);
obj.translateZ((-s * (box.max.z + box.min.z)) / 2);
if (!ground) {
// only center Y if not grounding
obj.translateY((-s * (box.max.y + box.min.y)) / 2);
}
}
if (ground) {
obj.translateY(-box.min.y * s);
}
}
/**
* The loaders have optional callbacks that take a GrObject (not an Object3D!)
*
* @callback LoaderCallback
* @param {GrObject} object
*/
/**
* A base class of GrObjects loaded from an OBJ file
* note: this has to deal with the deferred loading
*
* Warning: While ObjLoader2 might be better, ObjLoader is simpler
*/
export class ObjGrObject extends GrObject {
/**
*
* @param {Object} params
* @property {string} params.obj
* @property {string} [params.mtl]
* @property {string} [params.name]
* @property {Object} [params.mtloptions]
* @property {Number} [params.norm] - normalize the object (make the largest dimension this value)
* @property {Number} [params.x] - initial translate for the group
* @property {Number} [params.y]
* @property {Number} [params.z]
* @property {LoaderCallback} [params.callback]
*/
constructor(params = {}) {
if (!params.obj) {
alert("Bad OBJ object - no obj file given!");
throw "No OBJ given!";
}
const name = params.name || `Objfile(${params.obj})`;
const objholder = new T.Group();
super(name, objholder);
const self = this;
// if there is a material, load it first, and then have that load the OBJ file
if (params.mtl) {
const mtloader = new MTLLoader();
if (params.mtloptions) {
mtloader.setMaterialOptions(params.mtloptions);
}
// note that the callback then calls the Obj Loader
mtloader.load(params.mtl, function(myMaterialCreator) {
myMaterialCreator.preload();
const objLoader = new OBJLoader();
objLoader.setMaterials(myMaterialCreator);
objLoader.load(params.obj, function(obj) {
if (params.norm) normObject(obj, params.norm);
objholder.add(obj);
if (params.callback) params.callback(self);
});
});
} else {
// no material file, just an obj
const objLoader = new OBJLoader();
objLoader.load(params.obj, function(obj) {
if (params.norm) normObject(obj, params.norm);
objholder.add(obj);
if (params.callback) params.callback(self);
});
}
objholder.translateX(Number(params.x) || 0);
objholder.translateY(Number(params.y) || 0);
objholder.translateZ(Number(params.z) || 0);
}
}
/**
* load from an FBX file - this is quite simple
* it makes a group so it can stick the FBX object in once
* it is loaded.
*
* Note: if the loading fails, an error is printed in the console
* and a red cube is made instead of the loaded object.
* (added May 2022)
* */
export class FbxGrObject extends GrObject {
/**
*
* @param {Object} [params]
* @property {string} params.fbx
* @property {Number} [params.norm] - normalize the object (make the largest dimension this value)
* @property {Number} [params.x] - initial translate for the group
* @property {Number} [params.y]
* @property {Number} [params.z]
* @property {String} [params.name]
* @property {LoaderCallback} [params.callback]
*/
constructor(params = {}) {
const name = params.name || `FBXfile(${params.fbx})`;
const objholder = new T.Group();
super(name, objholder);
const self = this;
const fbx = new FBXLoader();
fbx.load(params.fbx,
function(obj) { /* loaded callback */
if (params.norm) normObject(obj, params.norm);
objholder.add(obj);
if (params.callback) params.callback(self);
},
undefined, /* progress callback */
function(error) { /* error callback */
console.log(error);
// put a dummy object in as an error warning
let tempGr = new GrCube({color:"red"});
let obj = tempGr.objects[0];
if (params.norm) normObject(obj, params.norm);
objholder.add(obj);
if (params.callback) params.callback(self);
}
);
objholder.translateX(Number(params.x) || 0);
objholder.translateY(Number(params.y) || 0);
objholder.translateZ(Number(params.z) || 0);
}
}