Files
webgl_play/src/Cone.ts
Daniel Ledda 32a62f6d98 Big update
2020-08-06 16:55:53 +02:00

106 lines
3.6 KiB
TypeScript

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<number>);
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<number>);
}
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;