106 lines
3.6 KiB
TypeScript
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; |