cione-comp-lib
Version:
`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`
124 lines (123 loc) • 4.47 kB
JavaScript
import { Vector2, Mesh, BufferGeometry, Float32BufferAttribute, DoubleSide, PlaneGeometry } from "../../../../_three@0.150.1@three/build/three.module.mjs";
import { Damper } from "./Damper.mjs";
/* @license
* Copyright 2020 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const RADIUS = 0.2;
const LINE_WIDTH = 0.03;
const MAX_OPACITY = 0.75;
const SEGMENTS = 12;
const DELTA_PHI = Math.PI / (2 * SEGMENTS);
const vector2 = new Vector2();
const addCorner = (vertices, cornerX, cornerY) => {
let phi = cornerX > 0 ? cornerY > 0 ? 0 : -Math.PI / 2 : cornerY > 0 ? Math.PI / 2 : Math.PI;
for (let i = 0; i <= SEGMENTS; ++i) {
vertices.push(cornerX + (RADIUS - LINE_WIDTH) * Math.cos(phi), cornerY + (RADIUS - LINE_WIDTH) * Math.sin(phi), 0, cornerX + RADIUS * Math.cos(phi), cornerY + RADIUS * Math.sin(phi), 0);
phi += DELTA_PHI;
}
};
class PlacementBox extends Mesh {
constructor(scene, side) {
const geometry = new BufferGeometry();
const triangles = [];
const vertices = [];
const { size, boundingBox } = scene;
const x = size.x / 2;
const y = (side === "back" ? size.y : size.z) / 2;
addCorner(vertices, x, y);
addCorner(vertices, -x, y);
addCorner(vertices, -x, -y);
addCorner(vertices, x, -y);
const numVertices = vertices.length / 3;
for (let i2 = 0; i2 < numVertices - 2; i2 += 2) {
triangles.push(i2, i2 + 1, i2 + 3, i2, i2 + 3, i2 + 2);
}
const i = numVertices - 2;
triangles.push(i, i + 1, 1, i, 1, 0);
geometry.setAttribute("position", new Float32BufferAttribute(vertices, 3));
geometry.setIndex(triangles);
super(geometry);
this.side = side;
const material = this.material;
material.side = DoubleSide;
material.transparent = true;
material.opacity = 0;
this.goalOpacity = 0;
this.opacityDamper = new Damper();
this.hitPlane = new Mesh(new PlaneGeometry(2 * (x + RADIUS), 2 * (y + RADIUS)));
this.hitPlane.visible = false;
this.hitPlane.material.side = DoubleSide;
this.add(this.hitPlane);
boundingBox.getCenter(this.position);
switch (side) {
case "bottom":
this.rotateX(-Math.PI / 2);
this.shadowHeight = boundingBox.min.y;
this.position.y = this.shadowHeight;
break;
case "back":
this.shadowHeight = boundingBox.min.z;
this.position.z = this.shadowHeight;
}
scene.target.add(this);
this.offsetHeight = 0;
}
getHit(scene, screenX, screenY) {
vector2.set(screenX, -screenY);
this.hitPlane.visible = true;
const hitResult = scene.positionAndNormalFromPoint(vector2, this.hitPlane);
this.hitPlane.visible = false;
return hitResult == null ? null : hitResult.position;
}
getExpandedHit(scene, screenX, screenY) {
this.hitPlane.scale.set(1e3, 1e3, 1e3);
this.hitPlane.updateMatrixWorld();
const hitResult = this.getHit(scene, screenX, screenY);
this.hitPlane.scale.set(1, 1, 1);
return hitResult;
}
set offsetHeight(offset) {
offset -= 1e-3;
if (this.side === "back") {
this.position.z = this.shadowHeight + offset;
} else {
this.position.y = this.shadowHeight + offset;
}
}
get offsetHeight() {
if (this.side === "back") {
return this.position.z - this.shadowHeight;
} else {
return this.position.y - this.shadowHeight;
}
}
set show(visible) {
this.goalOpacity = visible ? MAX_OPACITY : 0;
}
updateOpacity(delta) {
const material = this.material;
material.opacity = this.opacityDamper.update(material.opacity, this.goalOpacity, delta, 1);
this.visible = material.opacity > 0;
}
dispose() {
var _a;
const { geometry, material } = this.hitPlane;
geometry.dispose();
material.dispose();
this.geometry.dispose();
this.material.dispose();
(_a = this.parent) === null || _a === void 0 ? void 0 : _a.remove(this);
}
}
export { PlacementBox };