UNPKG

polygonjs-engine

Version:

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

95 lines (82 loc) 3.25 kB
import {BaseSopOperation} from './_Base'; import {DefaultOperationParams} from '../_Base'; import {Vector2} from 'three/src/math/Vector2'; import {Vector3} from 'three/src/math/Vector3'; import {PlaneBufferGeometry} from 'three/src/geometries/PlaneBufferGeometry'; import {CoreTransform} from '../../../core/Transform'; import {CoreGroup} from '../../../core/geometry/Group'; import {InputCloneMode} from '../../../engine/poly/InputCloneMode'; interface PlaneSopParams extends DefaultOperationParams { size: Vector2; useSegmentsCount: boolean; stepSize: number; segments: Vector2; direction: Vector3; center: Vector3; } const DEFAULT_UP = new Vector3(0, 0, 1); const ROTATE_START = new Vector3(0, 0, 1); const ROTATE_END = new Vector3(0, 1, 0); export class PlaneSopOperation extends BaseSopOperation { static readonly DEFAULT_PARAMS: PlaneSopParams = { size: new Vector2(1, 1), useSegmentsCount: false, stepSize: 1, segments: new Vector2(1, 1), direction: new Vector3(0, 1, 0), center: new Vector3(0, 0, 0), }; static readonly INPUT_CLONED_STATE = InputCloneMode.NEVER; static type(): Readonly<'plane'> { return 'plane'; } private _core_transform = new CoreTransform(); cook(input_contents: CoreGroup[], params: PlaneSopParams) { const core_group = input_contents[0]; if (core_group) { return this._cook_with_input(core_group, params); } else { return this._cook_without_input(params); } } private _cook_without_input(params: PlaneSopParams) { const geometry = this._create_plane(params.size, params); // convert to buffer geo, as some render problems can occur otherwise // geometry = BufferGeometryUtils.mergeBufferGeometries([geometry]) // console.log(geometry, geometry.isBufferGeometry) this._core_transform.rotate_geometry(geometry, DEFAULT_UP, params.direction); const matrix = this._core_transform.translation_matrix(params.center); geometry.applyMatrix4(matrix); return this.create_core_group_from_geometry(geometry); } private _cook_with_input(core_group: CoreGroup, params: PlaneSopParams) { const bbox = core_group.boundingBox(); const size = new Vector3(); bbox.getSize(size); const center = new Vector3(); bbox.getCenter(center); // TODO: rotate the input geo to get the accurate bbox const size2d = new Vector2(size.x, size.z); const geometry = this._create_plane(size2d, params); this._core_transform.rotate_geometry(geometry, ROTATE_START, ROTATE_END); const matrix = this._core_transform.translation_matrix(center); geometry.applyMatrix4(matrix); return this.create_core_group_from_geometry(geometry); } private _create_plane(size: Vector2, params: PlaneSopParams) { let segments_count = new Vector2(1, 1); size = size.clone(); if (params.useSegmentsCount) { segments_count.x = Math.floor(params.segments.x); segments_count.y = Math.floor(params.segments.y); } else { if (params.stepSize > 0) { segments_count.x = Math.floor(size.x / params.stepSize); segments_count.y = Math.floor(size.y / params.stepSize); size.x = segments_count.x * params.stepSize; size.y = segments_count.y * params.stepSize; } } return new PlaneBufferGeometry(size.x, size.y, segments_count.x, segments_count.y); } }