@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
154 lines (113 loc) • 4.16 kB
JavaScript
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);