Light classes, gathering materials
This commit is contained in:
@@ -6,9 +6,9 @@
|
||||
|
||||
import { Node } from ".";
|
||||
|
||||
export type Camera = CameraOrthographic | CameraPerspective;
|
||||
export type Camera = OrthographicCamera | PerspectiveCamera;
|
||||
|
||||
export interface CameraOrthographicProps {
|
||||
export interface OrthographicCameraProps {
|
||||
readonly name?: string;
|
||||
|
||||
readonly verticalSize: number;
|
||||
@@ -16,7 +16,7 @@ export interface CameraOrthographicProps {
|
||||
readonly farPlane: number;
|
||||
}
|
||||
|
||||
export interface CameraPerspectiveProps {
|
||||
export interface PerspectiveCameraProps {
|
||||
readonly name?: string;
|
||||
|
||||
readonly verticalFovRad: number;
|
||||
@@ -24,9 +24,9 @@ export interface CameraPerspectiveProps {
|
||||
readonly farPlane: number;
|
||||
}
|
||||
|
||||
export class CameraOrthographic {
|
||||
export class OrthographicCamera {
|
||||
|
||||
readonly type!: "CameraOrthographic";
|
||||
readonly type!: "OrthographicCamera";
|
||||
|
||||
_name: string;
|
||||
|
||||
@@ -42,7 +42,7 @@ export class CameraOrthographic {
|
||||
verticalSize,
|
||||
nearPlane,
|
||||
farPlane,
|
||||
}: CameraOrthographicProps) {
|
||||
}: OrthographicCameraProps) {
|
||||
this._name = name;
|
||||
|
||||
this._verticalSize = verticalSize;
|
||||
@@ -64,7 +64,7 @@ export class CameraOrthographic {
|
||||
set farPlane(value: number) { this._farPlane = value; }
|
||||
get farPlane(): number { return this._farPlane; }
|
||||
|
||||
attach(node: Node): CameraOrthographic {
|
||||
attach(node: Node): OrthographicCamera {
|
||||
if (this._node !== null) {
|
||||
this._node._camera = null;
|
||||
}
|
||||
@@ -78,7 +78,7 @@ export class CameraOrthographic {
|
||||
return this;
|
||||
}
|
||||
|
||||
detach(): CameraOrthographic {
|
||||
detach(): OrthographicCamera {
|
||||
if (this._node === null) {
|
||||
return this;
|
||||
}
|
||||
@@ -89,11 +89,9 @@ export class CameraOrthographic {
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(CameraOrthographic.prototype, "type", { value: "CameraOrthographic" });
|
||||
export class PerspectiveCamera {
|
||||
|
||||
export class CameraPerspective {
|
||||
|
||||
readonly type!: "CameraPerspective";
|
||||
readonly type!: "PerspectiveCamera";
|
||||
|
||||
_name: string;
|
||||
|
||||
@@ -109,7 +107,7 @@ export class CameraPerspective {
|
||||
verticalFovRad,
|
||||
nearPlane,
|
||||
farPlane,
|
||||
}: CameraPerspectiveProps) {
|
||||
}: PerspectiveCameraProps) {
|
||||
this._name = name;
|
||||
|
||||
this._verticalFovRad = verticalFovRad;
|
||||
@@ -128,7 +126,7 @@ export class CameraPerspective {
|
||||
set farPlane(value: number) { this._farPlane = value; }
|
||||
get farPlane(): number { return this._farPlane; }
|
||||
|
||||
attach(node: Node): CameraPerspective {
|
||||
attach(node: Node): PerspectiveCamera {
|
||||
if (this._node !== null) {
|
||||
this._node._camera = null;
|
||||
}
|
||||
@@ -142,7 +140,7 @@ export class CameraPerspective {
|
||||
return this;
|
||||
}
|
||||
|
||||
detach(): CameraPerspective {
|
||||
detach(): PerspectiveCamera {
|
||||
if (this._node === null) {
|
||||
return this;
|
||||
}
|
||||
@@ -153,12 +151,14 @@ export class CameraPerspective {
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(CameraPerspective.prototype, "type", { value: "CameraPerspective" });
|
||||
Object.defineProperty(OrthographicCamera.prototype, "type", { value: "OrthographicCamera" });
|
||||
|
||||
export function isCameraOrthographic(value: unknown): value is CameraOrthographic {
|
||||
return Boolean(value) && (value as CameraOrthographic).type === "CameraOrthographic";
|
||||
Object.defineProperty(PerspectiveCamera.prototype, "type", { value: "PerspectiveCamera" });
|
||||
|
||||
export function isOrthographicCamera(value: unknown): value is OrthographicCamera {
|
||||
return Boolean(value) && (value as OrthographicCamera).type === "OrthographicCamera";
|
||||
}
|
||||
|
||||
export function isCameraPerspective(value: unknown): value is CameraPerspective {
|
||||
return Boolean(value) && (value as CameraPerspective).type === "CameraPerspective";
|
||||
export function isPerspectiveCamera(value: unknown): value is PerspectiveCamera {
|
||||
return Boolean(value) && (value as PerspectiveCamera).type === "PerspectiveCamera";
|
||||
}
|
||||
|
151
src/data/Light.ts
Normal file
151
src/data/Light.ts
Normal file
@@ -0,0 +1,151 @@
|
||||
/*!
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public License,
|
||||
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
* obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { Color, ColorObject, Node } from ".";
|
||||
|
||||
export type Light = DirectionalLight | PointLight;
|
||||
|
||||
export interface DirectionalLightProps {
|
||||
readonly name?: string;
|
||||
|
||||
readonly color: ColorObject;
|
||||
}
|
||||
|
||||
export interface PointLightProps {
|
||||
readonly name?: string;
|
||||
|
||||
readonly color: ColorObject;
|
||||
}
|
||||
|
||||
export class DirectionalLight {
|
||||
|
||||
readonly type!: "DirectionalLight";
|
||||
|
||||
_name: string;
|
||||
|
||||
_color: Color;
|
||||
|
||||
/** backreference */
|
||||
_node: Node | null;
|
||||
|
||||
constructor({
|
||||
name = "",
|
||||
color,
|
||||
}: DirectionalLightProps) {
|
||||
this._name = name;
|
||||
|
||||
this._color = Color.fromObject(color);
|
||||
|
||||
this._node = null;
|
||||
}
|
||||
|
||||
set name(value: string) { this._name = value; }
|
||||
get name(): string { return this._name; }
|
||||
|
||||
setColor(value: ColorObject): DirectionalLight {
|
||||
this._color.setObject(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
getColor(res: Color): Color {
|
||||
return res.setObject(this._color);
|
||||
}
|
||||
|
||||
attach(node: Node): DirectionalLight {
|
||||
if (this._node !== null) {
|
||||
this._node._light = null;
|
||||
}
|
||||
|
||||
if (node._light !== null) {
|
||||
node._light._node = null;
|
||||
}
|
||||
|
||||
node._light = this;
|
||||
this._node = node;
|
||||
return this;
|
||||
}
|
||||
|
||||
detach(): DirectionalLight {
|
||||
if (this._node === null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this._node._light = null;
|
||||
this._node = null;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export class PointLight {
|
||||
|
||||
readonly type!: "PointLight";
|
||||
|
||||
_name: string;
|
||||
|
||||
_color: Color;
|
||||
|
||||
/** backreference */
|
||||
_node: Node | null;
|
||||
|
||||
constructor({
|
||||
name = "",
|
||||
color,
|
||||
}: PointLightProps) {
|
||||
this._name = name;
|
||||
|
||||
this._color = Color.fromObject(color);
|
||||
|
||||
this._node = null;
|
||||
}
|
||||
|
||||
set name(value: string) { this._name = value; }
|
||||
get name(): string { return this._name; }
|
||||
|
||||
setColor(value: ColorObject): PointLight {
|
||||
this._color.setObject(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
getColor(res: Color): Color {
|
||||
return res.setObject(this._color);
|
||||
}
|
||||
|
||||
attach(node: Node): PointLight {
|
||||
if (this._node !== null) {
|
||||
this._node._light = null;
|
||||
}
|
||||
|
||||
if (node._light !== null) {
|
||||
node._light._node = null;
|
||||
}
|
||||
|
||||
node._light = this;
|
||||
this._node = node;
|
||||
return this;
|
||||
}
|
||||
|
||||
detach(): PointLight {
|
||||
if (this._node === null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this._node._light = null;
|
||||
this._node = null;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(DirectionalLight.prototype, "type", { value: "DirectionalLight" });
|
||||
|
||||
Object.defineProperty(PointLight.prototype, "type", { value: "PointLight" });
|
||||
|
||||
export function isDirectionalLight(value: unknown): value is DirectionalLight {
|
||||
return Boolean(value) && (value as DirectionalLight).type === "DirectionalLight";
|
||||
}
|
||||
|
||||
export function isPointLight(value: unknown): value is PointLight {
|
||||
return Boolean(value) && (value as PointLight).type === "PointLight";
|
||||
}
|
114
src/data/Material.ts
Normal file
114
src/data/Material.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
/*!
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public License,
|
||||
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
||||
* obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { Color, ColorObject } from ".";
|
||||
import { Texture2D } from "../resources";
|
||||
|
||||
export const UNIFORM_BUFFER_SIZE = 64;
|
||||
|
||||
export interface MaterialProps {
|
||||
name?: string;
|
||||
|
||||
baseColor?: ColorObject;
|
||||
partialCoverage?: number;
|
||||
transmission?: ColorObject;
|
||||
collimation?: number;
|
||||
occlusionTextureStrength?: number;
|
||||
roughness?: number;
|
||||
metallic?: number;
|
||||
normalScale?: number;
|
||||
emissive?: ColorObject;
|
||||
ior?: number;
|
||||
|
||||
baseColorPartialCoverageTexture?: Texture2D | null;
|
||||
occlusionTexture?: Texture2D | null;
|
||||
roughnessMetallicTexture?: Texture2D | null;
|
||||
normalTexture?: Texture2D | null;
|
||||
emissiveTexture?: Texture2D | null;
|
||||
transmissionCollimationTexture?: Texture2D | null;
|
||||
|
||||
transparent?: boolean;
|
||||
doubleSided?: boolean;
|
||||
}
|
||||
|
||||
export class Material {
|
||||
|
||||
readonly type!: "Material";
|
||||
|
||||
_name: string;
|
||||
|
||||
_baseColor: Color;
|
||||
_partialCoverage: number;
|
||||
_occlusionTextureStrength: number;
|
||||
_metallic: number;
|
||||
_roughness: number;
|
||||
_normalScale: number;
|
||||
_emissive: Color;
|
||||
_transmission: Color;
|
||||
_collimation: number;
|
||||
_ior: number;
|
||||
|
||||
_baseColorPartialCoverageTexture: Texture2D | null;
|
||||
_occlusionTexture: Texture2D | null;
|
||||
_roughnessMetallicTexture: Texture2D | null;
|
||||
_normalTexture: Texture2D | null;
|
||||
_emissiveTexture: Texture2D | null;
|
||||
_transmissionCollimationTexture: Texture2D | null;
|
||||
|
||||
_transparent: boolean;
|
||||
_doubleSided: boolean;
|
||||
|
||||
constructor({
|
||||
name = "",
|
||||
baseColor,
|
||||
partialCoverage = 1,
|
||||
occlusionTextureStrength = 1,
|
||||
metallic = 1,
|
||||
roughness = 1,
|
||||
normalScale = 1,
|
||||
emissive,
|
||||
transmission,
|
||||
collimation = 1,
|
||||
ior = 1.45,
|
||||
baseColorPartialCoverageTexture = null,
|
||||
occlusionTexture = null,
|
||||
roughnessMetallicTexture = null,
|
||||
normalTexture = null,
|
||||
emissiveTexture = null,
|
||||
transmissionCollimationTexture = null,
|
||||
transparent = false,
|
||||
doubleSided = false,
|
||||
}: MaterialProps) {
|
||||
this._name = name;
|
||||
|
||||
this._baseColor = baseColor !== undefined ? Color.fromObject(baseColor) : Color.white();
|
||||
this._partialCoverage = partialCoverage;
|
||||
this._occlusionTextureStrength = occlusionTextureStrength;
|
||||
this._metallic = metallic;
|
||||
this._roughness = roughness;
|
||||
this._normalScale = normalScale;
|
||||
this._emissive = emissive !== undefined ? Color.fromObject(emissive) : Color.black();
|
||||
this._transmission = transmission !== undefined ? Color.fromObject(transmission) : Color.black();
|
||||
this._collimation = collimation;
|
||||
this._ior = ior;
|
||||
|
||||
this._baseColorPartialCoverageTexture = baseColorPartialCoverageTexture;
|
||||
this._occlusionTexture = occlusionTexture;
|
||||
this._roughnessMetallicTexture = roughnessMetallicTexture;
|
||||
this._normalTexture = normalTexture;
|
||||
this._emissiveTexture = emissiveTexture;
|
||||
this._transmissionCollimationTexture = transmissionCollimationTexture;
|
||||
|
||||
this._transparent = transparent;
|
||||
this._doubleSided = doubleSided;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(Material.prototype, "type", { value: "Material" });
|
||||
|
||||
export function isMaterial(value: unknown): value is Material {
|
||||
return Boolean(value) && (value as Material).type === "Material";
|
||||
}
|
@@ -4,8 +4,7 @@
|
||||
* obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { Camera, Matrix4x4, Mesh, Quaternion, QuaternionObject, Vector3, Vector3Object } from ".";
|
||||
import { Material } from "../resources";
|
||||
import { Camera, Light, Material, Matrix4x4, Mesh, Quaternion, QuaternionObject, Vector3, Vector3Object } from ".";
|
||||
|
||||
export interface NodeProps {
|
||||
readonly name?: string;
|
||||
@@ -15,6 +14,7 @@ export interface NodeProps {
|
||||
readonly scale?: Vector3Object;
|
||||
|
||||
readonly camera?: Camera | null;
|
||||
readonly light?: Light | null;
|
||||
readonly mesh?: Mesh | null;
|
||||
readonly materials?: Material[];
|
||||
|
||||
@@ -33,6 +33,8 @@ export class Node {
|
||||
|
||||
/** unique */
|
||||
_camera: Camera | null;
|
||||
/** unique */
|
||||
_light: Light | null;
|
||||
/** shared */
|
||||
_mesh: Mesh | null;
|
||||
/** shared */
|
||||
@@ -56,6 +58,7 @@ export class Node {
|
||||
rotation,
|
||||
scale,
|
||||
camera = null,
|
||||
light = null,
|
||||
mesh = null,
|
||||
materials = [],
|
||||
children = [],
|
||||
@@ -67,6 +70,7 @@ export class Node {
|
||||
this._scale = scale !== undefined ? Vector3.fromObject(scale) : Vector3.one();
|
||||
|
||||
this._camera = camera;
|
||||
this._light = light;
|
||||
this._mesh = mesh;
|
||||
this._materials = materials;
|
||||
|
||||
@@ -94,6 +98,10 @@ export class Node {
|
||||
this._camera._node = this;
|
||||
}
|
||||
|
||||
if (this._light !== null) {
|
||||
this._light._node = this;
|
||||
}
|
||||
|
||||
if (this._children !== null) {
|
||||
for (const child of this._children) {
|
||||
child._parent = this;
|
||||
@@ -101,6 +109,9 @@ export class Node {
|
||||
}
|
||||
}
|
||||
|
||||
set name(value: string) { this._name = value; }
|
||||
get name(): string { return this._name; }
|
||||
|
||||
setTranslation(value: Vector3Object): Node {
|
||||
this._translation.setObject(value);
|
||||
this._localMatrixNeedsUpdate = true;
|
||||
@@ -109,8 +120,7 @@ export class Node {
|
||||
}
|
||||
|
||||
getTranslation(res: Vector3): Vector3 {
|
||||
res.setObject(this._translation);
|
||||
return res;
|
||||
return res.setObject(this._translation);
|
||||
}
|
||||
|
||||
setRotation(value: QuaternionObject): Node {
|
||||
@@ -121,8 +131,7 @@ export class Node {
|
||||
}
|
||||
|
||||
getRotation(res: Quaternion): Quaternion {
|
||||
res.setObject(this._rotation);
|
||||
return res;
|
||||
return res.setObject(this._rotation);
|
||||
}
|
||||
|
||||
setScale(value: Vector3Object): Node {
|
||||
@@ -133,8 +142,7 @@ export class Node {
|
||||
}
|
||||
|
||||
getScale(res: Vector3): Vector3 {
|
||||
res.setObject(this._scale);
|
||||
return res;
|
||||
return res.setObject(this._scale);
|
||||
}
|
||||
|
||||
set camera(value: Camera | null) {
|
||||
@@ -172,6 +180,41 @@ export class Node {
|
||||
return this;
|
||||
}
|
||||
|
||||
set light(value: Light | null) {
|
||||
if (value !== null) {
|
||||
this.attachLight(value);
|
||||
} else {
|
||||
this.detachLight();
|
||||
}
|
||||
}
|
||||
get light(): Light | null { return this._light; }
|
||||
|
||||
attachLight(light: Light): Node {
|
||||
if (this._light !== null) {
|
||||
this._light._node = null;
|
||||
}
|
||||
|
||||
this._light = light;
|
||||
|
||||
if (light._node !== null) {
|
||||
light._node._light = null;
|
||||
}
|
||||
|
||||
light._node = this;
|
||||
this._light = light;
|
||||
return this;
|
||||
}
|
||||
|
||||
detachLight(): Node {
|
||||
if (this._light === null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this._light._node = null;
|
||||
this._light = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
set mesh(value: Mesh | null) { this._mesh = value; }
|
||||
get mesh(): Mesh | null { return this._mesh; }
|
||||
|
||||
@@ -269,3 +312,10 @@ Object.defineProperty(Node.prototype, "type", { value: "Node" });
|
||||
export function isNode(value: unknown): value is Node {
|
||||
return Boolean(value) && (value as Node).type === "Node";
|
||||
}
|
||||
|
||||
export function* preOrder(nodes: Iterable<Node>): Generator<Node, void, undefined> {
|
||||
for (const node of nodes) {
|
||||
yield node;
|
||||
yield* node._children;
|
||||
}
|
||||
}
|
||||
|
@@ -6,6 +6,8 @@
|
||||
|
||||
export * from "./Camera";
|
||||
export * from "./Color";
|
||||
export * from "./Light";
|
||||
export * from "./Material";
|
||||
export * from "./Matrix4x4";
|
||||
export * from "./Mesh";
|
||||
export * from "./Node";
|
||||
|
Reference in New Issue
Block a user