UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

107 lines (84 loc) 3.55 kB
import { vec3 } from "gl-matrix"; import { Box3, MeshStandardMaterial, PlaneBufferGeometry, Sphere } from "three"; import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js"; import { Color } from "../../../../core/color/Color.js"; import { kelvin_to_rgb } from "../../../../core/color/kelvin/kelvin_to_rgb.js"; import { noop } from "../../../../core/function/noop.js"; import Quaternion from "../../../../core/geom/Quaternion.js"; import Vector3 from "../../../../core/geom/Vector3.js"; import { Transform } from "../../../ecs/transform/Transform.js"; import { DirectionalLight } from "../../render/forward_plus/model/DirectionalLight.js"; import { three_object_replace_materials } from "../../three/three_object_replace_materials.js"; import { three_object_to_path_traced_scene } from "./three_object_to_path_traced_scene.js"; export function make_sun({ temperature = 5000, // around clear-sky day color = '#FFFFFF', intensity = 1, direction = new Vector3(-0.5, -1, -0.05) } = {}) { const temp_c = new Color(); kelvin_to_rgb(temp_c, 0, temperature); const light = new DirectionalLight(); light.color.parse(color); vec3.multiply(light.color, light.color, temp_c); const n = vec3.length(light.color); vec3.scale(light.color, light.color, 1 / n); // normalize color vector light.intensity.set(intensity * n); light.direction.copy(direction); light.direction.normalize(); return light; } /** * * @param {string} url * @return {Promise<GLTF>} */ function promise_gltf(url) { return new Promise((resolve, reject) => { new GLTFLoader().load(url, resolve, noop, reject); }); } /** * * @param {PathTracedScene} scene * @param {THREE.Camera} camera * @param {string} url * @param {number} [zoom] * @param {number} [floor_level] * @param {Object} [sun] * @param {boolean} [no_materials] * @return {Promise<void>} */ export async function prepare_scene_gltf({ scene, camera, url, zoom = 1, floor_level = 0, sun, no_materials = false }) { const gltf = await promise_gltf(url); const ground_material = new MeshStandardMaterial({ color: '#ffceae' }); scene.createMesh(new PlaneBufferGeometry(), ground_material, Transform.fromJSON({ position: new Vector3(0, floor_level, 0), scale: 5000, rotation: Quaternion.fromEulerAngles(-Math.PI / 2, 0, 0) }).matrix); const gltf_scene = gltf.scene; if (no_materials) { three_object_replace_materials(gltf_scene, new MeshStandardMaterial({ color: 'white' })); } three_object_to_path_traced_scene(gltf_scene, scene); const box3 = new Box3(); box3.setFromObject(gltf_scene); const sphere = new Sphere(); box3.getBoundingSphere(sphere); scene.addLight(make_sun(sun)); camera.position.set(1, 1.3, 1) .normalize() .multiplyScalar(sphere.radius * 2.6 * (1 / zoom)); camera.lookAt(sphere.center); }