UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

154 lines (113 loc) 4.16 kB
import { EngineHarness } from "../../EngineHarness.js"; import { ShadedGeometrySystem } from "../../graphics/ecs/mesh-v2/ShadedGeometrySystem.js"; import { Transform } from "../transform/Transform.js"; import { ShadedGeometry } from "../../graphics/ecs/mesh-v2/ShadedGeometry.js"; import { BoxBufferGeometry, MeshLambertMaterial } from "three"; import { EngineConfiguration } from "../../EngineConfiguration.js"; import { EntityNode } from "./EntityNode.js"; import { AttachmentSystem } from "../attachment/AttachmentSystem.js"; import { SurfacePoint3 } from "../../../core/geom/3d/SurfacePoint3.js"; import Vector3 from "../../../core/geom/Vector3.js"; import Vector2 from "../../../core/geom/Vector2.js"; import { FaceEditor, STATE_EDIT, STATE_HOVER } from "./FaceEditor.js"; const eh = new EngineHarness(); function makeConfig(engine) { const r = new EngineConfiguration(); r.addSystem(new ShadedGeometrySystem(engine)); r.addSystem(new AttachmentSystem()) return r; } /** * * @param {Engine} engine */ async function main(engine) { EngineHarness.buildBasics({ engine, enableWater: false }) const ecd = engine.entityManager.dataset; const block_a = EntityNode.fromComponents( ShadedGeometry.from(new BoxBufferGeometry(), new MeshLambertMaterial({ color: 0xFFFFAA })), new Transform() ); block_a.transform.position.set(5, 0.5, 5); const block_b = EntityNode.fromComponents( ShadedGeometry.from(new BoxBufferGeometry(), new MeshLambertMaterial({ color: 0xAAFFFF })), new Transform() ); block_b.transform.position.set(1, 1, 1); block_a.addChild(block_b); block_a.build(ecd); function pick(x, y) { /** * * @type {ShadedGeometrySystem|null} */ const system = engine.entityManager.getSystem(ShadedGeometrySystem); const contact = new SurfacePoint3(); const origin = new Vector3(); const direction = new Vector3(); const p = new Vector2(x, y); const point_2 = p.clone(); engine.graphics.normalizeViewportPoint(p, point_2); engine.graphics.viewportProjectionRay(point_2.x, point_2.y, origin, direction); const hit = system.raycastNearest(contact, origin.x, origin.y, origin.z, direction.x, direction.y, direction.z); if (hit === undefined) { return; } return Object.assign({ contact }, hit); } const editor = new FaceEditor(); function update_hover_state(x, y) { const hit = pick(x, y); if (hit === undefined) { editor.detach(); } else { if (editor.mesh !== hit.mesh) { editor.detach(); editor.contact = hit.contact; editor.mesh = hit.mesh; editor.entity = hit.entity; editor.ecd = ecd; editor.attach(); editor.state = STATE_HOVER; } else { // update contact only editor.contact = hit.contact; } } } engine.devices.pointer.position.onChanged.add((x, y) => { if (editor.state !== STATE_EDIT) { update_hover_state(x, y); } else { } }); engine.devices.pointer.on.dragStart.add((p) => { if (editor.state === STATE_HOVER) { editor.edit_anchor_point = editor.contact.position; editor.state = STATE_EDIT; } }); engine.devices.pointer.on.drag.add(p => { editor.edit_target_point = p; }); engine.devices.pointer.on.dragEnd.add(p => { if (editor.state === STATE_EDIT) { update_hover_state(p.x, p.y); } }); } /** * * @param {EngineHarness} harness */ async function init(harness) { const engine = eh.engine; await makeConfig(engine).apply(engine); await eh.initialize(); main(engine); } init(eh);