2019-05-29 00:40:29 +08:00
|
|
|
import { Object3D } from 'three';
|
|
|
|
import { Section } from '../../domain';
|
2019-05-29 07:37:00 +08:00
|
|
|
import { getAreaRenderData, getAreaCollisionData } from './assets';
|
|
|
|
import { parseCRel, parseNRel } from '../parsing/geometry';
|
2019-05-29 00:40:29 +08:00
|
|
|
|
|
|
|
//
|
|
|
|
// Caches
|
|
|
|
//
|
2019-05-29 07:37:00 +08:00
|
|
|
const sectionsCache: Map<string, Promise<Section[]>> = new Map();
|
|
|
|
const renderGeometryCache: Map<string, Promise<Object3D>> = new Map();
|
|
|
|
const collisionGeometryCache: Map<string, Promise<Object3D>> = new Map();
|
2019-05-29 00:40:29 +08:00
|
|
|
|
2019-05-29 07:37:00 +08:00
|
|
|
export function getAreaSections(
|
2019-05-29 00:40:29 +08:00
|
|
|
episode: number,
|
2019-05-29 07:37:00 +08:00
|
|
|
areaId: number,
|
|
|
|
areaVariant: number
|
2019-05-29 00:40:29 +08:00
|
|
|
): Promise<Section[]> {
|
2019-05-29 07:37:00 +08:00
|
|
|
const sections = sectionsCache.get(`${episode}-${areaId}-${areaVariant}`);
|
2019-05-29 00:40:29 +08:00
|
|
|
|
|
|
|
if (sections) {
|
|
|
|
return sections;
|
|
|
|
} else {
|
2019-05-29 07:37:00 +08:00
|
|
|
return getAreaSectionsAndRenderGeometry(
|
|
|
|
episode, areaId, areaVariant).then(({sections}) => sections);
|
2019-05-29 00:40:29 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-29 07:37:00 +08:00
|
|
|
export function getAreaRenderGeometry(
|
2019-05-29 00:40:29 +08:00
|
|
|
episode: number,
|
2019-05-29 07:37:00 +08:00
|
|
|
areaId: number,
|
|
|
|
areaVariant: number
|
2019-05-29 00:40:29 +08:00
|
|
|
): Promise<Object3D> {
|
2019-05-29 07:37:00 +08:00
|
|
|
const object3d = renderGeometryCache.get(`${episode}-${areaId}-${areaVariant}`);
|
2019-05-29 00:40:29 +08:00
|
|
|
|
2019-05-29 07:37:00 +08:00
|
|
|
if (object3d) {
|
|
|
|
return object3d;
|
2019-05-29 00:40:29 +08:00
|
|
|
} else {
|
2019-05-29 07:37:00 +08:00
|
|
|
return getAreaSectionsAndRenderGeometry(
|
|
|
|
episode, areaId, areaVariant).then(({object3d}) => object3d);
|
2019-05-29 00:40:29 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-29 07:37:00 +08:00
|
|
|
export function getAreaCollisionGeometry(
|
2019-05-29 00:40:29 +08:00
|
|
|
episode: number,
|
2019-05-29 07:37:00 +08:00
|
|
|
areaId: number,
|
|
|
|
areaVariant: number
|
2019-05-29 00:40:29 +08:00
|
|
|
): Promise<Object3D> {
|
2019-05-29 07:37:00 +08:00
|
|
|
const object3d = collisionGeometryCache.get(`${episode}-${areaId}-${areaVariant}`);
|
2019-05-29 00:40:29 +08:00
|
|
|
|
2019-05-29 07:37:00 +08:00
|
|
|
if (object3d) {
|
|
|
|
return object3d;
|
2019-05-29 00:40:29 +08:00
|
|
|
} else {
|
2019-05-29 07:37:00 +08:00
|
|
|
const object3d = getAreaCollisionData(
|
|
|
|
episode, areaId, areaVariant).then(parseCRel);
|
|
|
|
collisionGeometryCache.set(`${areaId}-${areaVariant}`, object3d);
|
|
|
|
return object3d;
|
2019-05-29 00:40:29 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-29 07:37:00 +08:00
|
|
|
function getAreaSectionsAndRenderGeometry(
|
2019-05-29 00:40:29 +08:00
|
|
|
episode: number,
|
2019-05-29 07:37:00 +08:00
|
|
|
areaId: number,
|
|
|
|
areaVariant: number
|
|
|
|
): Promise<{ sections: Section[], object3d: Object3D }> {
|
|
|
|
const promise = getAreaRenderData(
|
|
|
|
episode, areaId, areaVariant).then(parseNRel);
|
2019-05-29 00:40:29 +08:00
|
|
|
|
|
|
|
const sections = new Promise<Section[]>((resolve, reject) => {
|
|
|
|
promise.then(({sections}) => resolve(sections)).catch(reject);
|
|
|
|
});
|
2019-05-29 07:37:00 +08:00
|
|
|
const object3d = new Promise<Object3D>((resolve, reject) => {
|
|
|
|
promise.then(({object3d}) => resolve(object3d)).catch(reject);
|
2019-05-29 00:40:29 +08:00
|
|
|
});
|
|
|
|
|
2019-05-29 07:37:00 +08:00
|
|
|
sectionsCache.set(`${episode}-${areaId}-${areaVariant}`, sections);
|
|
|
|
renderGeometryCache.set(`${episode}-${areaId}-${areaVariant}`, object3d);
|
2019-05-29 00:40:29 +08:00
|
|
|
|
|
|
|
return promise;
|
|
|
|
}
|