UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

179 lines (148 loc) 5.32 kB
import { BoxBufferGeometry, LineBasicMaterial, MeshBasicMaterial, OctahedronBufferGeometry } from "three"; import { makeHelperBoxGeometry } from "../../../../../editor/process/symbolic/makeHelperBoxGeometry.js"; import { makeHelperSphereGeometry } from "../../../../../editor/process/symbolic/makeHelperSphereGeometry.js"; import { assert } from "../../../../core/assert.js"; import { array_copy } from "../../../../core/collection/array/array_copy.js"; import { compose_matrix4_array } from "../../../../core/geom/3d/mat4/compose_matrix4_array.js"; import Quaternion from "../../../../core/geom/Quaternion.js"; import Vector3 from "../../../../core/geom/Vector3.js"; import { DrawMode } from "../../ecs/mesh-v2/DrawMode.js"; import { InstancedMeshGroup } from "../../geometry/instancing/InstancedMeshGroup.js"; import { Lines } from "../Lines.js"; /** * * @type {number[]} */ const scratch_m4 = []; /** * * @param {InstancedMeshGroup} group * @param {number[]} matrix * @param {number[]} color */ function add_instance(group, matrix, color) { const i = group.count; group.setCount(i + 1); group.setTransformAt(i, matrix); group.setColorByComponentAt( i, Math.round(color[0] * 255), Math.round(color[1] * 255), Math.round(color[2] * 255), Math.round(color[3] * 255) ); group.requestAttributeUpdate(); } /** * Inspired by IMGUI and Unity's debug renderer */ export class GizmoShapeRenderingInterface { constructor() { /** * * @type {number[]|Float32Array} * @private */ this.__color = new Float32Array([1, 1, 1, 1]); this.__boxes_solid = InstancedMeshGroup.from(new BoxBufferGeometry(), new MeshBasicMaterial()); this.__boxes_wire = InstancedMeshGroup.from(makeHelperBoxGeometry(), new LineBasicMaterial()); this.__boxes_wire.draw_mode = DrawMode.LineSegments; this.__sphere_solid = InstancedMeshGroup.from(new OctahedronBufferGeometry(1, 10), new MeshBasicMaterial()); this.__sphere_wire = InstancedMeshGroup.from(makeHelperSphereGeometry(), new LineBasicMaterial()); this.__sphere_wire.draw_mode = DrawMode.Lines; // lines are handles different because they are relatively simple and require 2 archor points this.__lines = new Lines(); } __get_groups() { return [ this.__boxes_wire, this.__boxes_solid, this.__sphere_wire, this.__sphere_solid, this.__lines ]; } /** * * @param {THREE.Object3D[]} destination * @param {number} destination_offset * @param {number[]} frustum */ collect(destination, destination_offset, frustum) { let i = destination_offset; const groups = this.__get_groups(); for (let j = 0; j < groups.length; j++) { destination[i++] = groups[j].mesh; } return i - destination_offset; } clear() { const groups = this.__get_groups(); for (let j = 0; j < groups.length; j++) { groups[j].setCount(0); } } /** * Color used for drawing shapes, draw_x will take on the currently set color when called * RGBA * @param {number[]} color */ set color(color) { assert.defined(color, 'color'); assert.isArray(color, 'color'); assert.greaterThanOrEqual(color.length, 4); array_copy(color, 0, this.__color, 0, 4); } /** * RGBA * @return {number[]} */ get color() { return this.__color; } /** * * @param {number[]} center * @param {number[]} size */ draw_solid_cube(center, size) { compose_matrix4_array(scratch_m4, Vector3.fromArray(center), Quaternion.identity, Vector3.fromArray(size)); add_instance(this.__boxes_solid, scratch_m4, this.__color); } /** * * @param {number[]} center * @param {number[]} size */ draw_wire_cube(center, size) { compose_matrix4_array(scratch_m4, Vector3.fromArray(center), Quaternion.identity, Vector3.fromArray(size)); add_instance(this.__boxes_wire, scratch_m4, this.__color); } /** * * @param {number[]} from * @param {number[]} to */ draw_line(from, to) { this.__lines.add_line(from, to, this.__color); } /** * * @param {number[]} center * @param {number} radius */ draw_solid_sphere(center, radius) { compose_matrix4_array(scratch_m4, Vector3.fromArray(center), Quaternion.identity, Vector3.fromScalar(radius)); add_instance(this.__sphere_solid, scratch_m4, this.__color); } /** * * @param {number[]} center * @param {number} radius */ draw_wire_sphere(center, radius) { compose_matrix4_array(scratch_m4, Vector3.fromArray(center), Quaternion.identity, Vector3.fromScalar(radius)); add_instance(this.__sphere_wire, scratch_m4, this.__color); } } GizmoShapeRenderingInterface.INSTANCE = new GizmoShapeRenderingInterface();