import TrsMatrix from "./TrsMatrix"; import BasicColor from "./BasicColor"; import TransformableGeometry from "./TransformableGeometry"; import {triNormal} from "./utils"; import Point3D from "./Point3D"; import {Color, Colored, GeometryParams, Transformable} from "./types"; import {Updatable} from "./App"; class Cone extends TransformableGeometry implements Transformable, Colored, Updatable { private color: Color; private height?: number; private basePoints?: number; private static DEFAULT_BASE_POINTS: number = 10; private static DEFAULT_HEIGHT: number = 1; constructor(geometry: GeometryParams, trsMatrix?: TrsMatrix, color?: Color); constructor(height?: number, basePoints?: number, trsMatrix?: TrsMatrix, color?: Color | ArrayLike); constructor(...args: any[]) { let color; if (typeof args[0] !== "number") { super(args[0], args[1]); color = args[2]; } else { super(Cone.generateGeometry(args[0], args[1]), args[2]); this.height = args[0] ?? Cone.DEFAULT_HEIGHT; this.basePoints = args[1] ?? Cone.DEFAULT_BASE_POINTS; color = args[4] ?? new BasicColor(); } if (color.hasOwnProperty("length")) { this.color = BasicColor.fromVec(color as ArrayLike); } else { this.color = color as Color; } } private static generateGeometry(height: number, basePoints: number): GeometryParams { basePoints = Math.abs(Math.ceil(basePoints)); const basePointsAngle = 2 * Math.PI / basePoints; const pointBuffer = [ 0.0, 0.0, 0.0, 0.0, 0.0, height, 0.0, 1.0, 0.0 ]; const normalBuffer = []; const elementBuffer = []; for (let i = 1; i < basePoints; i++) { pointBuffer.push( Math.sin(basePointsAngle * i), Math.cos(basePointsAngle * i), 0.0 ); elementBuffer.push(0, 2 + i, 1 + i); normalBuffer.push( 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, ); elementBuffer.push(1, 1 + i, 2 + i); normalBuffer.push( ...triNormal( new Point3D(pointBuffer.slice(1, 4)), new Point3D(pointBuffer.slice(1 + i, 4 + i)), new Point3D(pointBuffer.slice(2 + i, 5 + i)), ).vec() ); } elementBuffer.push(0, 2, 1 + basePoints); elementBuffer.push(1, 1 + basePoints, 2); return { pointBuffer: new Float32Array(pointBuffer), normalBuffer: new Float32Array(normalBuffer), elementBuffer: new Uint16Array(elementBuffer) }; } update(delta: number): void { const secs = delta / 1000.0; this.rotateBy(0, 0.05 * secs, 0); } setHeight(height: number) { this.changeHeight(height - (this.height ?? 0)); } changeHeight(deltaHeight: number) { this.height = this.height ?? Cone.DEFAULT_HEIGHT + deltaHeight; this.geometry = Cone.generateGeometry(this.height, this.basePoints ?? Cone.DEFAULT_BASE_POINTS); } setBasePoints(basePoints: number) { this.height = basePoints; this.geometry = Cone.generateGeometry(this.height, this.basePoints ?? Cone.DEFAULT_BASE_POINTS); } setColor(color: Color) { this.color = color; } getColor(): Color { return this.color; } } export default Cone;