js/Mobilizing/renderer/3D/three/shape/2D/Arc.js
import * as THREE from 'three';
import Mesh from "../Mesh";
import Vector3 from "../../types/Vector3";
import Vector2 from "../../types/Vector2";
import Transform from "../../scene/Transform";
export default class Arc extends Mesh {
/**
* @param {Object} params Parameters object, given by the constructor.
* @param {Number} [params.radius=1] the arc radius in world unit
* @param {Number} [params.width=0.2] the arc width (or weight, distance between the exterior segments and the center) in world unit
* @param {Number} [params.segments=32] the segments number (detail level)
* @param {Number} [params.startAngle=0] 0 and Math.PI*2 are at 3 o'clock, value is counter clock-wise
* @param {Number} [params.endAngle=Math.PI*2] 0 and Math.PI*2 are at 3 o'clock, value is counter clock-wise
* @param {Number} [params.uvScale]
* @param {Number} [params.center=Vector3.zero]
*/
constructor({
width = 0.2,
radius = 1,
segments = 32,
startAngle = 0,
endAngle = Math.PI * 2,
uvScale = undefined,
center = Vector3.zero,
} = {}) {
super(...arguments);
this.width = width;
this.radius = radius;
this.segments = segments;
this.startAngle = startAngle;
this.endAngle = endAngle;
this.uvScale = uvScale !== undefined ? uvScale : this.radius * (this.endAngle - this.startAngle) * 1;
this.center = center;
//this.geometry = new THREE.BufferGeometry();
const innerpoints = [];
const outerpoints = [];
const interval = (Math.PI * 2) / this.segments;
let a = 0;
for (a = this.startAngle; a <= this.endAngle; a += interval) {
innerpoints.push(new Vector3(Math.cos(a) * (this.radius - this.width / 2), Math.sin(a) * (this.radius - this.width / 2), 0));
outerpoints.push(new Vector3(Math.cos(a) * (this.radius + this.width / 2), Math.sin(a) * (this.radius + this.width / 2), 0));
}
//on termine l'arc si on n'était pas sur un multiple
if (a !== this.endAngle) {
innerpoints.push(new Vector3(Math.cos(this.endAngle) * (this.radius - this.width / 2), Math.sin(this.endAngle) * (this.radius - this.width / 2), 0));
outerpoints.push(new Vector3(Math.cos(this.endAngle) * (this.radius + this.width / 2), Math.sin(this.endAngle) * (this.radius + this.width / 2), 0));
}
for (let k = 0; k < innerpoints.length - 1; ++k) {
const v1 = outerpoints[k];
const v2 = innerpoints[k];
const v3 = innerpoints[(k + 1) % innerpoints.length];
const v4 = outerpoints[(k + 1) % innerpoints.length];
this.pushQuad(v1, v2, v3, v4);
const uv1 = new Vector2(0, (k + 0) * this.uvScale / (innerpoints.length - 1));
const uv2 = new Vector2(1, (k + 0) * this.uvScale / (innerpoints.length - 1));
const uv3 = new Vector2(1, (k + 1) * this.uvScale / (innerpoints.length - 1));
const uv4 = new Vector2(0, (k + 1) * this.uvScale / (innerpoints.length - 1));
this.pushUV(uv1);
this.pushUV(uv2);
this.pushUV(uv3);
this.pushUV(uv4);
}
//generates the geom normals (lazy!)
this.computeNormals();
//manage the material according to the passed params, see the attachMaterial method below
this.attachMaterial(this.material);
this._mesh = new THREE.Mesh(this.geometry, this.material._material);
//console.log(this._mesh);
this.transform = new Transform(this);
this.transform.setLocalPosition(this.center);
}
}