polygonjs-engine
Version:
node-based webgl 3D engine https://polygonjs.com
104 lines (96 loc) • 3.23 kB
text/typescript
import {BaseSopOperation} from './_Base';
import {DefaultOperationParams} from '../_Base';
import {CoreGroup} from '../../geometry/Group';
import {SphereBufferGeometry} from 'three/src/geometries/SphereBufferGeometry';
import {IcosahedronBufferGeometry} from 'three/src/geometries/IcosahedronBufferGeometry';
import {Vector2} from 'three/src/math/Vector2';
import {Vector3} from 'three/src/math/Vector3';
import {InputCloneMode} from '../../../engine/poly/InputCloneMode';
interface SphereSopParams extends DefaultOperationParams {
type: number;
radius: number;
resolution: Vector2;
open: boolean;
phiStart: number;
phiLength: number;
thetaStart: number;
thetaLength: number;
detail: number;
center: Vector3;
}
enum SphereType {
DEFAULT = 'default',
ISOCAHEDRON = 'isocahedron',
}
type SphereTypes = {[key in SphereType]: number};
export const SPHERE_TYPE: SphereTypes = {
default: 0,
isocahedron: 1,
};
export const SPHERE_TYPES: Array<SphereType> = [SphereType.DEFAULT, SphereType.ISOCAHEDRON];
export class SphereSopOperation extends BaseSopOperation {
static readonly DEFAULT_PARAMS: SphereSopParams = {
type: SPHERE_TYPE.default,
radius: 1,
resolution: new Vector2(30, 30),
open: false,
phiStart: 0,
phiLength: Math.PI * 2,
thetaStart: 0,
thetaLength: Math.PI,
detail: 1,
center: new Vector3(0, 0, 0),
};
static readonly INPUT_CLONED_STATE = InputCloneMode.FROM_NODE;
static type(): Readonly<'sphere'> {
return 'sphere';
}
cook(input_contents: CoreGroup[], params: SphereSopParams) {
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: SphereSopParams) {
const geometry = this._create_required_geometry(params);
geometry.translate(params.center.x, params.center.y, params.center.z);
return this.create_core_group_from_geometry(geometry);
}
private _cook_with_input(core_group: CoreGroup, params: SphereSopParams) {
const bbox = core_group.boundingBox();
const size = bbox.max.clone().sub(bbox.min);
const center = bbox.max.clone().add(bbox.min).multiplyScalar(0.5);
const geometry = this._create_required_geometry(params);
geometry.translate(params.center.x, params.center.y, params.center.z);
geometry.translate(center.x, center.y, center.z);
geometry.scale(size.x, size.y, size.z);
return this.create_core_group_from_geometry(geometry);
}
private _create_required_geometry(params: SphereSopParams) {
if (params.type == SPHERE_TYPE.default) {
return this._create_default_sphere(params);
} else {
return this._create_default_isocahedron(params);
}
}
private _create_default_sphere(params: SphereSopParams) {
if (params.open) {
return new SphereBufferGeometry(
params.radius,
params.resolution.x,
params.resolution.y,
params.phiStart,
params.phiLength,
params.thetaStart,
params.thetaLength
);
} else {
return new SphereBufferGeometry(params.radius, params.resolution.x, params.resolution.y);
}
}
_create_default_isocahedron(params: SphereSopParams) {
return new IcosahedronBufferGeometry(params.radius, params.detail);
}
}