@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
147 lines (139 loc) • 5.26 kB
text/typescript
import {ColorRepresentation, PerspectiveCamera, RectAreaLight, SpotLight} from 'three';
import {ObjectType, registerObjectType} from './geometry/Constant';
import {monkeyPatchSpotLight} from './monkeyPatch/SpotLight';
export interface PerspectiveCameraOptions {
fov: number;
aspect: number;
near: number;
far: number;
}
type PerspectiveCameraConstructor = (options: PerspectiveCameraOptions) => PerspectiveCamera;
export interface PerspectiveCameraUpdateOptions<C extends PerspectiveCamera> {
camera: C;
params: {
apertureBlades: number;
fStop: number;
focusDistance: number;
apertureRotation: number;
anamorphicRatio: number;
};
}
export type PerspectiveCameraUpdate<C extends PerspectiveCamera> = (options: PerspectiveCameraUpdateOptions<C>) => void;
export interface AreaLightOptions {
color: ColorRepresentation;
intensity: number;
width: number;
height: number;
}
type AreaLightConstructor = (options: AreaLightOptions) => RectAreaLight;
type SpotLightConstructor = () => SpotLight;
export interface SpotLightUpdateOptions<L extends SpotLight> {
spotLight: L;
textureName: string;
}
export type SpotLightUpdate<L extends SpotLight> = (options: SpotLightUpdateOptions<L>) => void;
export enum GeneratorName {
PERSPECTIVE_CAMERA = 'perspectiveCamera',
PERSPECTIVE_CAMERA_UPDATE = 'perspectiveCameraUpdate',
AREA_LIGHT = 'areaLight',
SPOT_LIGHT = 'spotLight',
SPOT_LIGHT_UPDATE = 'spotLightUpdate',
}
type GeneratorMap = {
[GeneratorName.PERSPECTIVE_CAMERA]: PerspectiveCameraConstructor;
[GeneratorName.PERSPECTIVE_CAMERA_UPDATE]: PerspectiveCameraUpdate<PerspectiveCamera>;
[GeneratorName.AREA_LIGHT]: AreaLightConstructor;
[GeneratorName.SPOT_LIGHT]: SpotLightConstructor;
[GeneratorName.SPOT_LIGHT_UPDATE]: SpotLightUpdate<SpotLight>;
};
const DEFAULT_PERSPECTIVE_CAMERA_CONSTRUCTOR: PerspectiveCameraConstructor = (options: PerspectiveCameraOptions) => {
registerObjectType({
type: ObjectType.PERSPECTIVE_CAMERA,
checkFunc: (obj) => {
if ((obj as PerspectiveCamera).isPerspectiveCamera) {
return ObjectType.PERSPECTIVE_CAMERA;
}
},
ctor: PerspectiveCamera,
humanName: 'PerspectiveCamera',
});
const {fov, aspect, near, far} = options;
return new PerspectiveCamera(fov, aspect, near, far);
};
const DEFAULT_PERSPECTIVE_CAMERA_UPDATE: PerspectiveCameraUpdate<PerspectiveCamera> = <C extends PerspectiveCamera>(
options: PerspectiveCameraUpdateOptions<C>
) => {};
const DEFAULT_AREA_LIGHT_CONSTRUCTOR: AreaLightConstructor = (options: AreaLightOptions) => {
registerObjectType({
type: ObjectType.AREA_LIGHT,
checkFunc: (obj) => {
if ((obj as RectAreaLight).isRectAreaLight) {
return ObjectType.AREA_LIGHT;
}
},
ctor: RectAreaLight,
humanName: 'AreaLight',
});
const {color, intensity, width, height} = options;
return new RectAreaLight(color, intensity, width, height);
};
const DEFAULT_SPOT_LIGHT_CONSTRUCTOR: SpotLightConstructor = () => {
registerObjectType({
type: ObjectType.SPOT_LIGHT,
checkFunc: (obj) => {
if ((obj as SpotLight).isSpotLight) {
return ObjectType.SPOT_LIGHT;
}
},
ctor: SpotLight,
humanName: ObjectType.SPOT_LIGHT,
});
const spotLight = new SpotLight();
monkeyPatchSpotLight(spotLight);
return spotLight;
};
const DEFAULT_SPOT_LIGHT_UPDATE: SpotLightUpdate<SpotLight> = <L extends SpotLight>(
options: SpotLightUpdateOptions<L>
) => {};
class CoreSceneObjectsFactoryClass {
private constructor() {}
private static _instance: CoreSceneObjectsFactoryClass | undefined;
static instance() {
return (this._instance = this._instance || new CoreSceneObjectsFactoryClass());
}
private _generators: GeneratorMap = {
[GeneratorName.PERSPECTIVE_CAMERA]: DEFAULT_PERSPECTIVE_CAMERA_CONSTRUCTOR,
[GeneratorName.PERSPECTIVE_CAMERA_UPDATE]: DEFAULT_PERSPECTIVE_CAMERA_UPDATE,
[GeneratorName.AREA_LIGHT]: DEFAULT_AREA_LIGHT_CONSTRUCTOR,
[GeneratorName.SPOT_LIGHT]: DEFAULT_SPOT_LIGHT_CONSTRUCTOR,
[GeneratorName.SPOT_LIGHT_UPDATE]: DEFAULT_SPOT_LIGHT_UPDATE,
};
generator<G extends GeneratorName>(generatorName: G): GeneratorMap[G] {
return this._generators[generatorName];
}
registerGenerator<G extends GeneratorName>(generatorName: G, generator: GeneratorMap[G]) {
this._generators[generatorName] = generator;
}
// static generators: Generators = {
// perspectiveCamera: (options:PerspectiveCameraOptions) => {
// registerObjectType({
// type: ObjectType.PERSPECTIVE_CAMERA,
// ctor: PerspectiveCamera,
// humanName: 'PerspectiveCamera',
// });
// const {fov, aspect, near, far}= options
// return new PerspectiveCamera(fov, aspect, near, far);
// },
// areaLight: (options:AreaLightOptions) => {
// registerObjectType({type: ObjectType.AREA_LIGHT, ctor: RectAreaLight, humanName: 'AreaLight'});
// const {color, intensity, width, height}=options
// return new RectAreaLight(color, intensity, width, height);
// },
// spotLight: () => {
// registerObjectType({type: ObjectType.SPOT_LIGHT, ctor: SpotLight, humanName: ObjectType.SPOT_LIGHT});
// return new SpotLight();
// },
// spotLightUpdate: <L extends SpotLight>(options:SpotLightUpdateOptions<L>) => {},
// };
}
export const CoreSceneObjectsFactory = CoreSceneObjectsFactoryClass.instance();