123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- import * as THREE from '../threejs/build/three.module.js';
- import { KeyCode } from './KeyCode.js';
- import { Bee } from './Bee.js';
- import { Hive } from './Hive.js';
- import { Flower } from './Flower.js';
- import { Waypoint } from './Waypoint.js';
- // scene size
- var WIDTH = window.innerWidth;
- var HEIGHT = window.innerHeight;
- // camera
- var VIEW_ANGLE = 45;
- var ASPECT = WIDTH / HEIGHT;
- var NEAR = 1;
- var FAR = 10000;
- var camera, scene, renderer, raycaster;
- var clock = new THREE.Clock();
- var intersects;
- export var keys = [];
- var mouse, dragStart, dragOffset;
- var selected;
- var ground;
- var draggingOnGround;
- function init() {
- for (let i = 0; i < 256; i++) {
- keys[i] = false;
- }
- raycaster = new THREE.Raycaster();
- mouse = new THREE.Vector2(-1, -1);
- dragStart = new THREE.Vector3(0, 0, 0);
- dragOffset = new THREE.Vector3(0, 0, 0);
- intersects = [];
- // renderer
- renderer = new THREE.WebGLRenderer();
- renderer.setPixelRatio(window.devicePixelRatio);
- renderer.setSize(WIDTH, HEIGHT);
- renderer.shadowMap.enabled = true;
- renderer.shadowMap.type = THREE.PCFSoftShadowMap;
- renderer.outputEncoding = THREE.sRGBEncoding;
- // scene
- scene = new THREE.Scene();
- // camera
- camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
- camera.focus = new THREE.Vector3(0, 0, 0);
- camera.focusTarget = new THREE.Vector3(0, 0, 0);
- camera.offset = new THREE.Vector3(160, 220, 160);
- camera.position.set(camera.focus.x + camera.offset.x, camera.focus.y + camera.offset.y, camera.focus.z + camera.offset.z);
- camera.follow = false;
- camera.lookAt(camera.focus);
- draggingOnGround = false;
- var container = document.getElementById('container');
- container.appendChild(renderer.domElement);
- }
- function fillScene() {
- //sky
- let cubeloader = new THREE.CubeTextureLoader();
- let texture = cubeloader.load([
- './cubemapsimple/posx.png',
- './cubemapsimple/negx.png',
- './cubemapsimple/posy.png',
- './cubemapsimple/negy.png',
- './cubemapsimple/posz.png',
- './cubemapsimple/negz.png',
- ]);
- scene.background = texture;
- //ground
- let textureLoader = new THREE.TextureLoader();
- let lawnTex = textureLoader.load("textures/lawn.jpg");
- var planeGeo = new THREE.PlaneBufferGeometry(1000, 1000, 32, 32);
- let floorMat = new THREE.MeshPhongMaterial({ map: lawnTex });
- floorMat.flatShading = true;
- floorMat.shininess = 0;
- lawnTex.wrapS = lawnTex.wrapT = THREE.RepeatWrapping;
- lawnTex.repeat.set(5, 5);
- ground = new THREE.Mesh(planeGeo, floorMat);
- ground.rotateX(- Math.PI / 2);
- ground.receiveShadow = true;
- scene.add(ground);
- // lights
- var sunlight = new THREE.PointLight(0xffffff, 0.8, 0, 2);
- sunlight.position.x = 400;
- sunlight.position.y = 400;
- sunlight.position.z = 100;
- sunlight.castShadow = true;
- sunlight.shadow.camera.far = 1600;
- scene.add(sunlight);
- var mainLight = new THREE.HemisphereLight(0xB1E1FF, 0xB97A20, 0.6);
- mainLight.position.x = 1;
- mainLight.position.y = 1;
- mainLight.position.z = 1;
- // mainLight.castShadow = true;
- mainLight.lookAt(0, 0, 0);
- scene.add(mainLight);
- // var light = new THREE.AmbientLight(0xcccccc, 1);
- // scene.add(light);
- //set pieces
- Hive.collection = [];
- Flower.collection = [];
- Bee.collection = [];
- Promise.all([Hive.loadModel(), Flower.loadModel(), Bee.loadModel()]).then(async result => {
- for (let i = 0; i < 3; i++) {
- let hive = new Hive(scene);
- await hive.load(result[0]);
- hive.init(i);
- Hive.collection.push(hive);
- }
- Hive.collection.forEach(hive => hive.addToScene(scene));
- for (let i = 0; i < 24; i++) {
- let flower = new Flower();
- await flower.load(result[1]);
- flower.position.x = ((i % 6) / 6 * 400) - 200;
- flower.position.z = (Math.floor(i / 6) / 6 * 300) + 150;
- flower.rotation.y = (2 * Math.PI) * Math.random();
- Flower.collection.push(flower);
- }
- Flower.collection.forEach(flower => flower.addToScene(scene));
- Bee.baseModel = result[2];
- Hive.collection[0].setSwarm(1);
- Hive.collection[0].honeyReserve = 20;
- Hive.collection[0].toggleFlower(Flower.collection[0]);
- Hive.collection[0].spawnBee();
- Hive.collection[2].setSwarm(2);
- Hive.collection[2].honeyReserve = 20;
- Hive.collection[2].toggleFlower(Flower.collection[5]);
- Hive.collection[2].spawnBee();
- for (let i = 0; i < Waypoint.collection.length; i++) {
- let waypoint = Waypoint.collection[i];
- waypoint.rebuildLines();
- }
- update();
- });
- }
- function setFocus(focus) {
- selected = focus;
- camera.focusTarget.set(selected.position.x, selected.position.y, selected.position.z);
- camera.follow = true;
- }
- function render() {
- renderer.render(scene, camera);
- }
- function update() {
- requestAnimationFrame(update);
- var delta = clock.getDelta();
- var timer = Date.now();
- let origin = new THREE.Vector3(0, camera.offset.y, 0);
- let distance = camera.offset.distanceTo(origin);
- var delta = camera.offset.clone().sub(origin);
- var theta = Math.atan2(delta.z, delta.x);
- let cameraSpeed = 3;
- if (keys[KeyCode.Left] || keys[KeyCode.A]) { //left
- let vector = new THREE.Vector3();
- camera.getWorldDirection(vector);
- vector.multiply(new THREE.Vector3(cameraSpeed, 0, -cameraSpeed));
- camera.focusTarget.add(vector);
- }
- if (keys[KeyCode.Right] || keys[KeyCode.D]) { //right
- let vector = new THREE.Vector3();
- camera.getWorldDirection(vector);
- vector.multiply(new THREE.Vector3(-cameraSpeed, 0, cameraSpeed));
- camera.focusTarget.add(vector);
- }
- if (keys[KeyCode.Up] || keys[KeyCode.W]) { //up
- let vector = new THREE.Vector3();
- camera.getWorldDirection(vector);
- vector.multiply(new THREE.Vector3(cameraSpeed, 0, cameraSpeed));
- camera.focusTarget.add(vector);
- }
- if (keys[KeyCode.Down] || keys[KeyCode.S]) { //down
- let vector = new THREE.Vector3();
- camera.getWorldDirection(vector);
- vector.multiply(new THREE.Vector3(-cameraSpeed, 0, -cameraSpeed));
- camera.focusTarget.add(vector);
- }
- var rotation = THREE.Math.degToRad(6);
- let cameraOffset = new THREE.Vector3(camera.offset.x, camera.offset.y, camera.offset.z);
- if (keys[KeyCode.Q]) {
- cameraOffset.x = distance * Math.cos(theta + rotation);
- cameraOffset.z = distance * Math.sin(theta + rotation);
- }
- if (keys[KeyCode.E]) {
- cameraOffset.x = distance * Math.cos(theta - rotation);
- cameraOffset.z = distance * Math.sin(theta - rotation);
- }
- if (camera.follow) {
- camera.focusTarget = selected.position.clone();
- }
- camera.offset.lerp(cameraOffset, 0.1);
- camera.focus.lerp(camera.focusTarget, 0.1);
- camera.position.set(camera.focus.x + camera.offset.x, camera.focus.y + camera.offset.y, camera.focus.z + camera.offset.z);
- camera.lookAt(camera.focus);
- raycaster.setFromCamera(mouse, camera);
- intersects = raycaster.intersectObjects(scene.children, true);
- Bee.collection.forEach(bee => bee.update(delta, timer));
- Hive.collection.forEach(hive => hive.update(delta, timer));
- Flower.collection.forEach(flower => flower.update(delta, timer));
- render();
- }
- document.addEventListener("DOMContentLoaded", () => {
- init();
- fillScene();
- });
- window.addEventListener("keydown", e => keys[e.keyCode] = true);
- window.addEventListener("keyup", e => keys[e.keyCode] = false);
- window.addEventListener("mousemove", event => {
- mouse.x = normalize(event.clientX / window.innerWidth);
- mouse.y = -normalize(event.clientY / window.innerHeight);
- event.target.style.cursor = "default";
- let hiveIntersects = getIntersectFromCollection(Hive.collection, intersects);
- if (hiveIntersects.length > 0) {
- event.target.style.cursor = "pointer";
- }
- let flowerIntersects = getIntersectFromCollection(Flower.collection, intersects);
- if (flowerIntersects.length > 0) {
- event.target.style.cursor = "pointer";
- }
- let beeIntersects = getIntersectFromCollection(Bee.collection, intersects);
- if (beeIntersects.length > 0) {
- event.target.style.cursor = "pointer";
- }
- let groundIntersect = intersects.filter(i => i.object == ground);
- if (groundIntersect.length > 0) {
- if (draggingOnGround) {
- event.target.style.cursor = "move";
- dragOffset = camera.focus.clone().sub(groundIntersect[0].point);
- camera.focusTarget = dragStart.clone().add(dragOffset);
- }
- }
- });
- window.addEventListener("mousedown", event => {
- camera.follow = false;
- mouse.x = normalize(event.clientX / window.innerWidth);
- mouse.y = -normalize(event.clientY / window.innerHeight);
- let hiveIntersects = getIntersectFromCollection(Hive.collection, intersects);
- if (hiveIntersects.length > 0) {
- return;
- }
- let flowerIntersects = getIntersectFromCollection(Flower.collection, intersects);
- if (flowerIntersects.length > 0) {
- return;
- }
- let beeIntersects = getIntersectFromCollection(Bee.collection, intersects);
- if (beeIntersects.length > 0) {
- setFocus(beeIntersects[0]);
- return;
- }
- let groundIntersect = intersects.filter(i => i.object == ground);
- if (groundIntersect.length > 0) {
- draggingOnGround = true;
- dragStart = groundIntersect[0].point.clone();
- dragOffset = camera.focus.clone().sub(groundIntersect[0].point);
- camera.focusTarget = dragStart.clone().add(dragOffset);
- }
- });
- window.addEventListener("contextmenu", event => {
- event.preventDefault();
- });
- window.addEventListener("mouseup", event => {
- if (draggingOnGround) {
- draggingOnGround = false;
- return;
- }
- draggingOnGround = false;
- if (event.button == 2) {
- if (selected instanceof Hive) {
- let flowerIntersects = getIntersectFromCollection(Flower.collection, intersects);
- if (flowerIntersects.length > 0) {
- selected.toggleFlower(flowerIntersects[0]);
- addLines(selected);
- return;
- }
- return;
- }
- }
- let hiveIntersects = getIntersectFromCollection(Hive.collection, intersects);
- if (hiveIntersects.length > 0) {
- if (selected == hiveIntersects[0]) {
- setFocus(hiveIntersects[0]);
- }
- selected = hiveIntersects[0];
- addLines(selected);
- return;
- }
- let flowerIntersects = getIntersectFromCollection(Flower.collection, intersects);
- if (flowerIntersects.length > 0) {
- if (selected == flowerIntersects[0]) {
- setFocus(flowerIntersects[0]);
- }
- selected = flowerIntersects[0];
- addLines(selected);
- return;
- }
- let beeIntersects = getIntersectFromCollection(Bee.collection, intersects);
- if (beeIntersects.length > 0) {
- setFocus(beeIntersects[0]);
- addLines(selected);
- return;
- }
- });
- window.addEventListener("wheel", event => {
- let vector = new THREE.Vector3();
- camera.getWorldDirection(vector);
- vector.multiplyScalar(-event.deltaY / 4);
- camera.offset.add(vector);
- });
- let addLines = (focus) => {
- for (let i = 0; i < Waypoint.collection.length; i++) {
- let waypoint = Waypoint.collection[i];
- for (let j = 0; j < waypoint.lines.length; j++) {
- let line = waypoint.lines[j];
- scene.remove(line);
- }
- }
- if (focus.hasOwnProperty("entranceWaypoint")) {
- for (let i = 0; i < focus.entranceWaypoint.lines.length; i++) {
- scene.add(focus.entranceWaypoint.lines[i]);
- }
- }
- for (let i = 0; i < Hive.collection.length; i++) {
- let hive = Hive.collection[i];
- scene.remove(hive.billboard);
- if (hive == focus) {
- scene.add(hive.billboard);
- }
- }
- }
- let getIntersectFromCollection = (collection, intersectCollection) => {
- return collection.filter(target => intersectCollection.filter(i => crawlParent(target.model, i.object)).length > 0);
- }
- let crawlParent = (lookingFor, questionObj) => {
- if (questionObj == lookingFor) {
- return true;
- }
- if (questionObj.parent == null) {
- return false;
- }
- if (questionObj.parent == lookingFor) {
- return true;
- }
- return crawlParent(lookingFor, questionObj.parent);
- }
- window.addEventListener("touchmove", event => {
- mouse.x = normalize(event.touches[0].clientX / window.innerWidth);
- mouse.y = -normalize(event.touches[0].clientY / window.innerHeight);
- });
- function normalize(value) {
- return (2 * value) - 1;
- }
|