import * as THREE from 'three'
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry';
import * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils'
const defaultRadialSegments = 12;
const defaultCapSubdivisions = 2;
const defaultWidthSegments = 12;
const defaultHeightSegments = 6;
const defaultTubularSegments = 12;
const defaultCircularSegments = 32;
const defaultCurveSegments = 12;
const defaultBevelSegments = 8;
var currentFont, currentFontSize, currentFontDepth, currentBevelEnabled, currentBevelThickness, currentBevelSize;
var currentRadialSegments = defaultRadialSegments;
var currentCapSubdivisions = defaultCapSubdivisions;
var currentWidthSegments = defaultWidthSegments;
var currentHeightSegments = defaultHeightSegments
var currentTubularSegments = defaultTubularSegments;
var currentCircularSegments = defaultCircularSegments;
var currentCurveSegments = defaultCurveSegments;
var currentBevelSegments = defaultBevelSegments;
export function setQuality(radialSegments = 1.0, capSubdivisions = 1.0, widthSegments = 1.0, heightSegments = 1.0, tubularSegments = 1.0, circularSegments = 1.0, curveSegments = 1.0, bevelSegments = 1.0) {
currentRadialSegments = radialSegments * defaultRadialSegments;
currentCapSubdivisions = capSubdivisions * defaultCapSubdivisions;
currentWidthSegments = widthSegments * defaultWidthSegments;
currentHeightSegments = heightSegments * defaultHeightSegments;
currentTubularSegments = tubularSegments * defaultTubularSegments;
currentCircularSegments = circularSegments * defaultCircularSegments;
currentCurveSegments = curveSegments * defaultCurveSegments;
currentBevelSegments = bevelSegments * defaultBevelSegments;
}
export function getGeometry(params = {}) {
var geometry;
var type = params.type ? params.type : 'box';
if (type === 'capsule') {
var radius = params.radius ? params.radius : 0.5;
var length = params.length ? params.length : 1;
var radialSegments = params.radialSegments ? params.radialSegments : currentRadialSegments;
var capSubdivisions = params.capSubdivisions ? params.capSubdivisions : currentCapSubdivisions;
var openEnded = params.openEnded ? params.openEnded : false;
//CapsuleGeometry(radius : Float, length : Float, capSubdivisions : Integer, radialSegments : Integer)
geometry = new THREE.CapsuleGeometry(radius, length, capSubdivisions, radialSegments);
} else if (type === 'ellipsoid') {
var width = params.width ? params.width : 1;
var height = params.height ? params.height : 1;
var depth = params.depth ? params.depth : 1;
var widthSegments = params.widthSegments ? params.widthSegments : currentWidthSegments;
var heightSegments = params.heightSegments ? params.heightSegments : currentHeightSegments;
var phiStart = params.phiStart ? params.phiStart : 0;
var phiLength = params.phiLength ? params.phiLength : Math.PI * 2;
var thetaStart = params.thetaStart ? params.thetaStart : 0;
var thetaLength = params.thetaLength ? params.thetaLength : Math.PI;
// SphereGeometry(radius : Float, widthSegments : Integer, heightSegments : Integer, phiStart : Float, phiLength : Float, thetaStart : Float, thetaLength : Float)
geometry = new THREE.SphereGeometry(0.5, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength);
geometry.applyMatrix4(new THREE.Matrix4().makeScale(width, height, depth));
} else if (type === 'plane') {
var width = params.width ? params.width : 1;
var height = params.height ? params.height : 1;
var widthSegments = params.widthSegments ? params.widthSegments : 1;
var heightSegments = params.heightSegments ? params.heightSegments : 1;
//PlaneGeometry(width : Float, height : Float, widthSegments : Integer, heightSegments : Integer)
geometry = new THREE.PlaneGeometry(width, height, widthSegments, heightSegments);
} else if (type === 'circle') {
var radius = params.radius ? params.radius : 0.5;
var segments = params.segments ? params.segments : currentCircularSegments;
var thetaStart = params.thetaStart ? params.thetaStart : 0;
var thetaLength = params.thetaLength ? params.thetaLength : Math.PI * 2;
//CircleGeometry(radius : Float, segments : Integer, thetaStart : Float, thetaLength : Float)
geometry = new THREE.CircleGeometry(radius, segments, thetaStart, thetaLength);
} else if (type === 'box') {
var width = params.width ? params.width : 1;
var height = params.height ? params.height : 1;
var depth = params.depth ? params.depth : 1;
var widthSegments = params.widthSegments ? params.widthSegments : 1;
var heightSegments = params.heightSegments ? params.heightSegments : 1;
var depthSegments = params.depthSegments ? params.depthSegments : 1;
//BoxGeometry(width : Float, height : Float, depth : Float, widthSegments : Integer, heightSegments : Integer, depthSegments : Integer)
geometry = new THREE.BoxGeometry(width, height, depth, widthSegments, heightSegments, depthSegments);
} else if (type === 'cylinder') {
var radiusTop = params.radiusTop ? params.radiusTop : 0.5;
var radiusBottom = params.radiusBottom ? params.radiusBottom : 0.5;
var height = params.height ? params.height : 1;
var radialSegments = params.radialSegments ? params.radialSegments : currentRadialSegments;
var heightSegments = params.heightSegments ? params.heightSegments : currentHeightSegments;
var openEnded = params.openEnded ? params.openEnded : false;
var thetaStart = params.thetaStart ? params.thetaStart : 0;
var thetaLength = params.thetaLength ? params.thetaLength : Math.PI * 2;
// CylinderGeometry(radiusTop : Float, radiusBottom : Float, height : Float, radialSegments : Integer, heightSegments : Integer, openEnded : Boolean, thetaStart : Float, thetaLength : Float)
geometry = new THREE.CylinderGeometry(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength);
} else if (type === 'sphere') {
var radius = params.radius ? params.radius : 0.5;
var widthSegments = params.widthSegments ? params.widthSegments : currentWidthSegments;
var heightSegments = params.heightSegments ? params.heightSegments : currentHeightSegments;
var phiStart = params.phiStart ? params.phiStart : 0;
var phiLength = params.phiLength ? params.phiLength : Math.PI * 2;
var thetaStart = params.thetaStart ? params.thetaStart : 0;
var thetaLength = params.thetaLength ? params.thetaLength : Math.PI;
// SphereGeometry(radius : Float, widthSegments : Integer, heightSegments : Integer, phiStart : Float, phiLength : Float, thetaStart : Float, thetaLength : Float)
geometry = new THREE.SphereGeometry(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength);
} else if (type === 'ring') {
var innerRadius = params.innerRadius ? params.innerRadius : 0.2;
var outerRadius = params.outerRadius ? params.outerRadius : 0.5;
var thetaSegments = params.thetaSegments ? params.thetaSegments : 32;
var phiSegments = params.phiSegments ? params.phiSegments : 12;
var thetaStart = params.thetaStart ? params.thetaStart : 0;
var thetaLength = params.thetaLength ? params.thetaLength : Math.PI * 2;
// RingGeometry(innerRadius : Float, outerRadius : Float, thetaSegments : Integer, phiSegments : Integer, thetaStart : Float, thetaLength : Float)
geometry = new THREE.RingGeometry(innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength);
} else if (type === 'icosahedron') {
var radius = params.radius ? params.radius : 0.5;
var detail = params.detail ? params.detail : 0;
// IcosahedronGeometry(radius : Float, detail : Integer)
const originalGeometry = new THREE.IcosahedronGeometry(radius, detail);
geometry = BufferGeometryUtils.mergeVertices(originalGeometry);
//geometry = new THREE.IcosahedronGeometry(radius, detail);
} else if (type === 'octahedron') {
var radius = params.radius ? params.radius : 0.5;
var detail = params.detail ? params.detail : 0;
// OctahedronGeometry(radius : Float, detail : Integer)
geometry = BufferGeometryUtils.mergeVertices(new THREE.OctahedronGeometry(radius, detail));
} else if (type === 'tetrahedron') {
var radius = params.radius ? params.radius : 0.5;
var detail = params.detail ? params.detail : 0;
// TetrahedronGeometry(radius : Float, detail : Integer)
geometry = BufferGeometryUtils.mergeVertices(new THREE.TetrahedronGeometry(radius, detail));
} else if (type === 'cone') {
var radius = params.radius ? params.radius : 0.5;
var height = params.height ? params.height : 1;
var radialSegments = params.radialSegments ? params.radialSegments : currentRadialSegments;
var heightSegments = params.heightSegments ? params.heightSegments : currentHeightSegments;
var openEnded = params.openEnded ? params.openEnded : false;
var thetaStart = params.thetaStart ? params.thetaStart : 0;
var thetaLength = params.thetaLength ? params.thetaLength : Math.PI * 2;
// ConeGeometry(radius : Float, height : Float, radialSegments : Integer, heightSegments : Integer, openEnded : Boolean, thetaStart : Float, thetaLength : Float)
geometry = new THREE.ConeGeometry(radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength);
} else if (type === 'torus') {
var radius = params.radius ? params.radius : 0.5;
var tube = params.tube ? params.tube : 0.2;
var radialSegments = params.radialSegments ? params.radialSegments : currentRadialSegments;
var tubularSegments = params.tubularSegments ? params.tubularSegments : currentTubularSegments;
var arc = params.arc ? params.arc : Math.PI * 2;
// TorusGeometry(radius : Float, tube : Float, radialSegments : Integer, tubularSegments : Integer, arc : Float)
geometry = new THREE.TorusGeometry(radius, tube, radialSegments, tubularSegments, arc);
} else if (type === 'pyramid') {
var width = params.width ? params.width : 1;
var height = params.height ? params.height : 1;
var depth = params.depth ? params.depth : 1;
const points = [
new THREE.Vector3(0, height, 0),
new THREE.Vector3(-width * .5, 0, -depth * .5),
new THREE.Vector3(-width * .5, 0, depth * .5),
new THREE.Vector3(width * .5, 0, depth * .5),
new THREE.Vector3(width * .5, 0, -depth * .5)
];
const vertices = new Float32Array([
points[0].x, points[0].y, points[0].z,
points[1].x, points[1].y, points[1].z,
points[2].x, points[2].y, points[2].z,
points[0].x, points[0].y, points[0].z,
points[2].x, points[2].y, points[2].z,
points[3].x, points[3].y, points[3].z,
points[0].x, points[0].y, points[0].z,
points[3].x, points[3].y, points[3].z,
points[4].x, points[4].y, points[4].z,
points[0].x, points[0].y, points[0].z,
points[4].x, points[4].y, points[4].z,
points[1].x, points[1].y, points[1].z,
points[1].x, points[1].y, points[1].z,
points[3].x, points[3].y, points[3].z,
points[2].x, points[2].y, points[2].z,
points[1].x, points[1].y, points[1].z,
points[4].x, points[4].y, points[4].z,
points[3].x, points[3].y, points[3].z,
]);
geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
geometry.computeVertexNormals();
} else if (type == 'text') {
if (!currentFont) {
console.warn("You must use loadFont3D(fontJsonURL) and setFont3D(font) before using text3D()")
return;
}
const text = params.text ? params.text : "?!";
geometry = new TextGeometry(text, {
font: currentFont,
size: currentFontSize,
height: currentFontDepth,
bevelEnabled: currentBevelEnabled,
bevelSize: currentBevelSize,
bevelThickness: currentBevelThickness,
curveSegments: currentCurveSegments,
bevelSegments: currentBevelSegments
});
geometry.computeBoundingBox();
const xMid = - 0.5 * (geometry.boundingBox.max.x - geometry.boundingBox.min.x);
const yMid = - 0.5 * (geometry.boundingBox.max.y - geometry.boundingBox.min.y);
geometry.translate(xMid, yMid, 0);
}
return geometry;
}
/**
*
* @param {*} font
* @param {*} size
* @param {*} depth
* @param {*} bevelEnabled
* @param {*} bevelThickness
* @param {*} bevelSize
*/
export const setFont3D = (font, size = 1, depth = size * 0.5, bevelEnabled = true, bevelThickness = depth * 0.1, bevelSize = bevelThickness) => {
currentFont = font.font;
currentFontSize = size;
currentFontDepth = depth;
currentBevelEnabled = bevelEnabled;
currentBevelThickness = bevelThickness;
currentBevelSize = bevelSize;
}