diff options
Diffstat (limited to 'src/models')
| -rw-r--r-- | src/models/Colour.ts | 16 | ||||
| -rw-r--r-- | src/models/FrameChunk.ts | 10 | ||||
| -rw-r--r-- | src/models/Geometry.ts | 49 | ||||
| -rw-r--r-- | src/models/Light.ts | 10 | ||||
| -rw-r--r-- | src/models/Material.ts | 27 | ||||
| -rw-r--r-- | src/models/RaytraceContext.ts | 43 | ||||
| -rw-r--r-- | src/models/Vector.ts | 40 |
7 files changed, 195 insertions, 0 deletions
diff --git a/src/models/Colour.ts b/src/models/Colour.ts new file mode 100644 index 0000000..3c9d8da --- /dev/null +++ b/src/models/Colour.ts @@ -0,0 +1,16 @@ +import {Vector} from './Vector'; +import 'reflect-metadata'; + +export class Colour extends Vector { + constructor(readonly r: number, readonly g: number, readonly b: number) { + super(r, g, b); + } + + static fromVector(vector: Vector): Colour { + return new Colour(vector.x, vector.y, vector.z); + } + + toVector(): Vector { + return new Vector(this.r, this.g, this.b); + } +} diff --git a/src/models/FrameChunk.ts b/src/models/FrameChunk.ts new file mode 100644 index 0000000..f05fd88 --- /dev/null +++ b/src/models/FrameChunk.ts @@ -0,0 +1,10 @@ +export class FrameChunk { + constructor( + readonly xStart: number, + readonly yStart: number, + readonly width: number, + readonly height: number + ) { + + } +}
\ No newline at end of file diff --git a/src/models/Geometry.ts b/src/models/Geometry.ts new file mode 100644 index 0000000..556c7ea --- /dev/null +++ b/src/models/Geometry.ts @@ -0,0 +1,49 @@ +import {Type} from 'class-transformer'; +import {Colour} from './Colour'; +import {Albedo, Material} from './Material'; +import {Vector} from './Vector'; + +export class Sphere { + @Type(() => Vector) + readonly centerPoint: Vector; + @Type(() => Material) + readonly material: Material; + constructor( + readonly radius: number, + centerPoint: Vector, + material: Material + ) { + this.centerPoint = centerPoint; + this.material = material; + } +} + +export class Plane { + @Type(() => Colour) + readonly checkerboardColour1: Colour; + @Type(() => Colour) + readonly checkerboardColour2: Colour; + constructor( + readonly yPos: number, + readonly width: number, // How far the plane extends into x/-x from 0 + readonly zStartPos: number, + readonly zEndPos: number, + readonly checkerboardScale: number, + checkerboardColour1: Colour, + checkerboardColour2: Colour + ) { + this.checkerboardColour1 = checkerboardColour1; + this.checkerboardColour2 = checkerboardColour2; + } + + getMaterialAtPoint(x: number, z: number): Material { + let colour: Colour; + // prettier-ignore + if ((Math.round(this.checkerboardScale * x) + Math.round(this.checkerboardScale * z)) & 1) { + colour = this.checkerboardColour1; + } else { + colour = this.checkerboardColour2; + } + return new Material(colour, new Albedo(1, 0, 0, 0), 0, 1); + } +} diff --git a/src/models/Light.ts b/src/models/Light.ts new file mode 100644 index 0000000..58e4185 --- /dev/null +++ b/src/models/Light.ts @@ -0,0 +1,10 @@ +import {Type} from 'class-transformer'; +import {Vector} from './Vector'; + +export class Light { + @Type(() => Vector) + readonly position: Vector; + constructor(position: Vector, readonly intensity: number) { + this.position = position; + } +} diff --git a/src/models/Material.ts b/src/models/Material.ts new file mode 100644 index 0000000..f0af5e2 --- /dev/null +++ b/src/models/Material.ts @@ -0,0 +1,27 @@ +import {Type} from 'class-transformer'; +import {Colour} from './Colour'; + +export class Material { + @Type(() => Colour) + readonly diffuseColour: Colour; + @Type(() => Albedo) + readonly albedo: Albedo; + constructor( + diffuseColour: Colour, + albedo: Albedo, + readonly specularExponent: number, + readonly refractiveIndex: number + ) { + this.diffuseColour = diffuseColour; + this.albedo = albedo; + } +} + +export class Albedo { + constructor( + readonly diffuseAlbedo: number, + readonly specularAlbedo: number, + readonly reflectionAlbedo: number, + readonly refractionAlbedo: number + ) {} +} diff --git a/src/models/RaytraceContext.ts b/src/models/RaytraceContext.ts new file mode 100644 index 0000000..acd4336 --- /dev/null +++ b/src/models/RaytraceContext.ts @@ -0,0 +1,43 @@ +import {Type} from 'class-transformer'; +import {Colour} from './Colour'; +import {Plane, Sphere} from './Geometry'; +import {Light} from './Light'; + +export class RaytraceContext { + @Type(() => Sphere) + readonly spheres: Sphere[]; + @Type(() => Plane) + readonly planes: Plane[]; + @Type(() => Light) + readonly lights: Light[]; + @Type(() => Colour) + readonly backgroundColour: Colour; + constructor( + readonly height: number, + readonly width: number, + readonly fov: number, + spheres: Sphere[], + planes: Plane[], + lights: Light[], + backgroundColour: Colour, + readonly options: RaytracerOptions + ) { + this.spheres = spheres; + this.planes = planes; + this.lights = lights; + this.backgroundColour = backgroundColour; + } +} + +export interface RaytracerOptions { + numThreads: number; + shadows: boolean; + diffuseLighting: boolean; + specularLighting: boolean; + reflections: boolean; + refractions: boolean; + maxRecurseDepth: number; + maxDrawDistance: number; + bufferDrawCalls: boolean; + directMemoryTransfer: boolean; +} diff --git a/src/models/Vector.ts b/src/models/Vector.ts new file mode 100644 index 0000000..2be8e57 --- /dev/null +++ b/src/models/Vector.ts @@ -0,0 +1,40 @@ +export class Vector { + constructor(readonly x: number, readonly y: number, readonly z: number) {} + + add(v: Vector): Vector { + return new Vector(this.x + v.x, this.y + v.y, this.z + v.z); + } + + addScalar(n: number): Vector { + return new Vector(this.x + n, this.y + n, this.z + n); + } + + subtract(v: Vector): Vector { + return new Vector(this.x - v.x, this.y - v.y, this.z - v.z); + } + + multiply(n: number): Vector { + return new Vector(this.x * n, this.y * n, this.z * n); + } + + dotProduct(v: Vector): number { + return this.x * v.x + this.y * v.y + this.z * v.z; + } + + normalise(): Vector { + const vecLength = this.norm(); + return new Vector( + this.x / vecLength, + this.y / vecLength, + this.z / vecLength + ); + } + + norm(): number { + return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + } + + negative(): Vector { + return new Vector(-this.x, -this.y, -this.z); + } +} |