wip(type): fix gltf loader

This commit is contained in:
pissang 2022-05-02 15:54:00 +08:00
parent 0b8b348b7d
commit 2e1cc5905b
9 changed files with 72 additions and 24 deletions

View File

@ -597,7 +597,7 @@ class ClayNode extends Notifier {
* @see http://www.opengl.org/sdk/docs/man2/xhtml/gluLookAt.xml
* @function
*/
lookAt(target: Vector3, up: Vector3) {
lookAt(target: Vector3, up?: Vector3) {
tmpMat4.lookAt(this.position, target, up || this.localTransform.y).invert();
this.setLocalTransform(tmpMat4);

View File

@ -54,4 +54,18 @@ export {
StandardMRShader
} from './shader/index';
export { load as loadGLTF } from './loader/GLTF';
export {
load as loadGLTF,
loadAsync as loadGLTFAsync,
parse as parseGLTF,
parseBinary as parseGLB
} from './loader/GLTF';
export { default as ShadowMapPass } from './prePass/ShadowMap';
export { default as EnvironmentMapPass } from './prePass/EnvironmentMap';
export { default as OrbitControl } from './plugin/OrbitControl';
export { default as FreeControl } from './plugin/FreeControl';
export { default as GamepadControl } from './plugin/GamepadControl';
export { default as Skybox } from './plugin/Skybox';

View File

@ -244,6 +244,26 @@ interface GLTFLoadOpts {
onprogress?: (percent: number, loaded: number, total: number) => void;
}
// Load with promise
export function loadAsync(
url: string,
opts?: Omit<GLTFLoadOpts, 'onload' | 'onerror'>
): Promise<GLTFLoadResult> {
return new Promise((resolve, reject) => {
load(
url,
Object.assign({}, opts, {
onload(res: GLTFLoadResult) {
resolve(res);
},
onerror(err: any) {
reject(err);
}
})
);
});
}
export function load(url: string, opts?: GLTFLoadOpts) {
opts = Object.assign(
{
@ -382,7 +402,7 @@ export function parse(json: GLTFFormat, buffers: ArrayBuffer[] | undefined, opts
afterLoadBuffer(true);
} else {
// Load buffers
json.buffers.forEach((bufferInfo: GLTFBuffer, idx: number) => {
(json.buffers || []).forEach((bufferInfo: GLTFBuffer, idx: number) => {
loading++;
const path = bufferInfo.uri;
@ -422,7 +442,7 @@ export function parse(json: GLTFFormat, buffers: ArrayBuffer[] | undefined, opts
return;
}
json.bufferViews.forEach((bufferViewInfo: GLTFBufferView, idx: number) => {
(json.bufferViews || []).forEach((bufferViewInfo: GLTFBufferView, idx: number) => {
// PENDING Performance
lib.bufferViews[idx] = lib.buffers[bufferViewInfo.buffer].slice(
bufferViewInfo.byteOffset || 0,
@ -523,7 +543,7 @@ function loadBuffers(
// https://github.com/KhronosGroup/glTF/issues/193
function parseSkins(json: GLTFFormat, lib: ParsedLib, opts: GLTFLoadOpts) {
// Create skeletons and joints
json.skins.forEach((skinInfo: GLTFSkin, idx: number) => {
(json.skins || []).forEach((skinInfo: GLTFSkin, idx: number) => {
const skeleton = new Skeleton(skinInfo.name);
for (let i = 0; i < skinInfo.joints.length; i++) {
const nodeIdx = skinInfo.joints[i];
@ -561,7 +581,7 @@ function parseSkins(json: GLTFFormat, lib: ParsedLib, opts: GLTFLoadOpts) {
return joint.index;
}
json.nodes.forEach((nodeInfo: GLTFNode, nodeIdx: number) => {
(json.nodes || []).forEach((nodeInfo: GLTFNode, nodeIdx: number) => {
if (nodeInfo.skin != null) {
const skinIdx = nodeInfo.skin;
const skeleton = lib.skeletons[skinIdx];
@ -582,7 +602,7 @@ function parseSkins(json: GLTFFormat, lib: ParsedLib, opts: GLTFLoadOpts) {
}
function parseTextures(json: GLTFFormat, lib: ParsedLib, opts: GLTFLoadOpts) {
json.textures.forEach((textureInfo: GLTFTexture, idx: number) => {
(json.textures || []).forEach((textureInfo: GLTFTexture, idx: number) => {
// samplers is optional
const samplerInfo = (json.samplers && json.samplers[textureInfo.sampler]) || {};
const parameters: Partial<TextureOpts> = {};
@ -945,7 +965,7 @@ function pbrSpecularGlossinessToStandard(
}
function parseMaterials(json: GLTFFormat, lib: ParsedLib, opts: GLTFLoadOpts) {
json.materials.forEach((materialInfo: GLTFMaterial, idx: number) => {
(json.materials || []).forEach((materialInfo: GLTFMaterial, idx: number) => {
/* eslint-disable-next-line */
if (materialInfo.extensions && materialInfo.extensions['KHR_materials_common']) {
lib.materials[idx] = KHRCommonMaterialToStandard(materialInfo, lib, opts);
@ -973,7 +993,7 @@ function parseMaterials(json: GLTFFormat, lib: ParsedLib, opts: GLTFLoadOpts) {
}
function parseMeshes(json: GLTFFormat, lib: ParsedLib, opts: GLTFLoadOpts) {
json.meshes.forEach((meshInfo: GLTFMesh, idx: number) => {
(json.meshes || []).forEach((meshInfo: GLTFMesh, idx: number) => {
lib.meshes[idx] = [];
// Geometry
for (let pp = 0; pp < meshInfo.primitives.length; pp++) {
@ -1154,7 +1174,7 @@ function parseNodes(json: GLTFFormat, lib: ParsedLib, opts: GLTFLoadOpts) {
});
}
json.nodes.forEach((nodeInfo: GLTFNode, idx: number) => {
(json.nodes || []).forEach((nodeInfo: GLTFNode, idx: number) => {
let node: ClayNode;
if (nodeInfo.camera != null && opts.includeCamera) {
node = instanceCamera(json, nodeInfo);
@ -1201,7 +1221,7 @@ function parseNodes(json: GLTFFormat, lib: ParsedLib, opts: GLTFLoadOpts) {
});
// Build hierarchy
json.nodes.forEach((nodeInfo: GLTFNode, idx: number) => {
(json.nodes || []).forEach((nodeInfo: GLTFNode, idx: number) => {
const node = lib.nodes[idx];
if (nodeInfo.children) {
for (let i = 0; i < nodeInfo.children.length; i++) {
@ -1227,7 +1247,7 @@ function parseAnimations(json: GLTFFormat, lib: ParsedLib, opts: GLTFLoadOpts) {
}
const timeAccessorMultiplied: Record<string, boolean> = {};
json.animations.forEach((animationInfo: GLTFAnimation, idx: number) => {
(json.animations || []).forEach((animationInfo: GLTFAnimation, idx: number) => {
const channels = animationInfo.channels.filter(checkChannelPath);
if (!channels.length) {
@ -1289,7 +1309,7 @@ function parseAnimations(json: GLTFFormat, lib: ParsedLib, opts: GLTFLoadOpts) {
const maxLife = lib.animators.reduce(function (maxTime, animator) {
return Math.max(maxTime, animator.getLife());
}, 0);
lib.animators.forEach(function (animator) {
(lib.animators || []).forEach(function (animator) {
animator.setLife(maxLife);
});

View File

@ -70,8 +70,13 @@ class FreeControl extends Notifier {
private _offsetPitch = 0;
private _offsetRoll = 0;
constructor(opts?: Partial<FreeControlOpts>) {
constructor(
opts: Omit<Partial<FreeControlOpts>, 'domElement'> & {
domElement: HTMLElement;
}
) {
super();
Object.assign(
this,
{

View File

@ -37,12 +37,12 @@ interface GamepadControlOpts {
/**
* Function to be called when a standard gamepad is ready to use.
*/
onStandardGamepadReady?: (gamepad) => void;
onStandardGamepadReady?: (gamepad: Gamepad) => void;
/**
* Function to be called when a gamepad is disconnected.
*/
onGamepadDisconnected?: (gamepad) => void;
onGamepadDisconnected?: (gamepad: Gamepad) => void;
}
interface GamepadControl extends GamepadControlOpts {}
@ -75,7 +75,11 @@ class GamepadControl extends Notifier {
private _standardGamepadAvailable = false;
private _gamepadAxisThreshold = 0.3;
constructor(opts?: Partial<GamepadControlOpts>) {
constructor(
opts: Omit<Partial<GamepadControlOpts>, 'domElement'> & {
domElement: HTMLElement;
}
) {
super();
Object.assign(
this,

View File

@ -170,9 +170,15 @@ class OrbitControl extends Notifier {
private _gestureMgr = new GestureMgr();
constructor(opts?: Partial<OrbitControlOpts>) {
constructor(
opts: Omit<Partial<OrbitControlOpts>, 'domElement'> & {
domElement: HTMLElement;
}
) {
super();
this.domElement = opts.domElement;
this.setOption(
Object.assign(
{
@ -200,6 +206,8 @@ class OrbitControl extends Notifier {
opts
)
);
// Set target after option updated.
this._target = opts.target;
// Each OrbitControl has it's own handler
this._mouseDownHandler = this._mouseDownHandler.bind(this);

View File

@ -1,3 +0,0 @@
import Skybox from './Skybox';
export default Skybox;

View File

@ -142,7 +142,7 @@ class ShadowMapPass extends Notifier {
/**
* Render scene to shadow textures
*/
render(renderer: Renderer, scene: Scene, sceneCamera: Camera, notUpdateScene?: boolean) {
render(renderer: Renderer, scene: Scene, sceneCamera?: Camera, notUpdateScene?: boolean) {
if (!sceneCamera) {
sceneCamera = scene.getMainCamera();
}

View File

@ -3,7 +3,7 @@ import Texture2D from '../Texture2D';
import TextureCube from '../TextureCube';
import vendor from '../core/vendor';
import EnvironmentMapPass from '../prePass/EnvironmentMap';
import Skydome from '../plugin/Skydome';
import Skybox from '../plugin/Skybox';
import Scene from '../Scene';
import dds from './dds';
@ -121,7 +121,7 @@ const textureUtil = {
*/
panoramaToCubeMap: function (renderer, panoramaMap, cubeMap, option) {
const environmentMapPass = new EnvironmentMapPass();
const skydome = new Skydome({
const skydome = new Skybox({
scene: new Scene()
});
skydome.setEnvironmentMap(panoramaMap);