@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
63 lines (58 loc) • 2.21 kB
text/typescript
import {BaseSopOperation} from './_Base';
import {CoreGroup} from '../../../core/geometry/Group';
import {CoreGeometryUtilCircle} from '../../../core/geometry/util/Circle';
import {ObjectType} from '../../../core/geometry/Constant';
import {rotateGeometry} from '../../../core/Transform';
import {Vector3, CircleGeometry, BufferGeometry} from 'three';
import {isBooleanTrue} from '../../../core/BooleanValue';
import {DefaultOperationParams} from '../../../core/operations/_Base';
interface CircleSopParams extends DefaultOperationParams {
radius: number;
segments: number;
open: boolean;
arcAngle: number;
direction: Vector3;
center: Vector3;
connectLastPoint: boolean;
}
const DEFAULT_UP = new Vector3(0, 0, 1);
export class CircleSopOperation extends BaseSopOperation {
static override readonly DEFAULT_PARAMS: CircleSopParams = {
radius: 1,
segments: 12,
open: true,
arcAngle: 360,
direction: new Vector3(0, 1, 0),
center: new Vector3(0, 0, 0),
connectLastPoint: true,
};
static override type(): Readonly<'circle'> {
return 'circle';
}
override cook(input_contents: CoreGroup[], params: CircleSopParams) {
if (isBooleanTrue(params.open)) {
return this._createCircle(params);
} else {
return this._createDisk(params);
}
}
private _createCircle(params: CircleSopParams) {
const geometry = CoreGeometryUtilCircle.create(params);
this._setCenterAndDirection(geometry, params);
return this.createCoreGroupFromGeometry(geometry, ObjectType.LINE_SEGMENTS);
}
private _createDisk(params: CircleSopParams) {
const geometry = new CircleGeometry(params.radius, params.segments);
this._setCenterAndDirection(geometry, params);
return this.createCoreGroupFromGeometry(geometry);
}
private _setCenterAndDirection(geometry: BufferGeometry, params: CircleSopParams) {
// rotate 30 deg to:
// - align with the tube
// - so that copying circles on hexagon points gives an hexagon grid immediately
// update: do not rotate, as it creates a poor shape when using 3, 4 or 5 sides
// geometry.rotateZ(degToRad(30));
rotateGeometry(geometry, DEFAULT_UP, params.direction);
geometry.translate(params.center.x, params.center.y, params.center.z);
}
}