UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

112 lines (99 loc) 3.84 kB
import {CoreGeometryOperationHexagon} from './../../../core/geometry/operation/Hexagon'; import {BaseSopOperation} from './_Base'; import {BufferGeometry, Vector2, Vector3, Quaternion, BoxGeometry, Box3} from 'three'; import {rotateGeometry} from '../../../core/Transform'; import {CoreGroup} from '../../../core/geometry/Group'; import {InputCloneMode} from '../../poly/InputCloneMode'; import {isBooleanTrue} from '../../../core/BooleanValue'; import {DefaultOperationParams} from '../../../core/operations/_Base'; import {ObjectType} from '../../../core/geometry/Constant'; const tmpBox = new Box3(); const tmpBoxPreRotation = new Box3(); const tmpSize = new Vector3(); const tmpCenter = new Vector3(); interface HexagonsSopParams extends DefaultOperationParams { size: Vector2; hexagonRadius: number; direction: Vector3; pointsOnly: boolean; } const DEFAULT_UP = new Vector3(0, 0, 1); // const ROTATE_END = new Vector3(0, 1, 0); const q = new Quaternion(); // const size = new Vector3(); // const center = new Vector3(); // const inputObjectCenter = new Vector3(); export class HexagonsSopOperation extends BaseSopOperation { static override readonly DEFAULT_PARAMS: HexagonsSopParams = { size: new Vector2(1, 1), hexagonRadius: 0.1, direction: new Vector3(0, 1, 0), pointsOnly: false, }; static override readonly INPUT_CLONED_STATE = InputCloneMode.NEVER; static override type(): Readonly<'hexagons'> { return 'hexagons'; } override cook(inputCoreGroups: CoreGroup[], params: HexagonsSopParams) { const coreGroup = inputCoreGroups[0]; if (coreGroup) { return this._cookWithInput(coreGroup, params); } else { return this._cookWithoutInput(params); } } private _cookWithoutInput(params: HexagonsSopParams) { if (params.hexagonRadius > 0) { const geometry = this._createHexagons(params.size, params); rotateGeometry(geometry, DEFAULT_UP, params.direction); return this.createCoreGroupFromObjects([this._createHexagonsObjects(geometry, params)]); } else { return this.createCoreGroupFromObjects([]); } } private _cookWithInput(coreGroup: CoreGroup, params: HexagonsSopParams) { coreGroup.boundingBox(tmpBoxPreRotation); tmpBoxPreRotation.getCenter(tmpCenter); // create box coreGroup.boundingBox(tmpBox); tmpBox.getSize(tmpSize); tmpBox.getCenter(tmpCenter); const boxGeometry = new BoxGeometry(tmpSize.x, tmpSize.y, tmpSize.z, 1, 1, 1); // rotate box function _applyInputQuaternion(_q: Quaternion) { boxGeometry.applyQuaternion(_q); boxGeometry.computeBoundingBox(); } function _setInputRotation() { q.setFromUnitVectors(DEFAULT_UP, params.direction); _applyInputQuaternion(q); } // function _resetInputRotation() { // q.invert(); // _applyInputQuaternion(q); // } _setInputRotation(); const bboxPostRotation = boxGeometry.boundingBox!; //coreGroup.boundingBox(true); bboxPostRotation.getSize(tmpSize); // bboxPreRotation.getCenter(center); // debug // _resetInputRotation(); const size2d = new Vector2(tmpSize.x, tmpSize.y); const geometry = this._createHexagons(size2d, params); rotateGeometry(geometry, DEFAULT_UP, params.direction); geometry.translate(tmpCenter.x, tmpCenter.y, tmpCenter.z); const object = this._createHexagonsObjects(geometry, params); return this.createCoreGroupFromObjects([object]); } private _createHexagonsObjects(geometry: BufferGeometry, params: HexagonsSopParams) { if (isBooleanTrue(params.pointsOnly)) { return this.createObject(geometry, ObjectType.POINTS); } else { return this.createObject(geometry, ObjectType.MESH); } } private _createHexagons(size: Vector2, params: HexagonsSopParams) { const operation = new CoreGeometryOperationHexagon(size, params.hexagonRadius, params.pointsOnly); const geometry = operation.process(); return geometry; } }