Code viewer for World: Lego (clone by Vaidas Buzas)

// Cloned by Vaidas Buzas on 2 Dec 2022 from World "Lego" by Michael Walsh 
// Please leave this clone trail here.
 
AB.loadCSS("/uploads/threeport/main.css");import*as THREE from"/api/threemodule/libs/three.module.js";let camera,scene,renderer,controls,plane,pointer,raycaster,rollOverMesh,rollOverMaterial,cubeGeo,isShiftDown=!1;const realColors=["#f0f8ff","#00ffff","#7fffd4","#f0ffff","#f5f5dc","#ffe4c4","#ffebcd","#0000ff","#8a2be2","#a52a2a","#deb887","#5f9ea0","#7fff00","#d2691e","#ff7f50","#6495ed","#fff8dc","#dc143c","#00ffff","#00008b","#008b8b","#b8860b","#006400","#bdb76b","#8b008b","#556b2f","#ff8c00","#9932cc","#8b0000","#e9967a","#8fbc8f","#483d8b","#00ced1","#9400d3","#ff1493","#00bfff","#1e90ff","#b22222","#228b22","#ff00ff","#dcdcdc","#ffd700","#daa520","#008000","#adff2f","#f0fff0","#ff69b4","#cd5c5c","#4b0082","#fffff0","#f0e68c","#e6e6fa","#fff0f5","#7cfc00","#fffacd","#add8e6","#f08080","#e0ffff","#fafad2","#90ee90","#ffb6c1","#ffa07a","#20b2aa","#87cefa","#b0c4de","#ffffe0","#00ff00","#32cd32","#faf0e6","#ff00ff","#800000","#66cdaa","#0000cd","#ba55d3","#9370db","#3cb371","#7b68ee","#00fa9a","#48d1cc","#c71585","#191970","#f5fffa","#ffe4e1","#ffe4b5","#000080","#fdf5e6","#808000","#6b8e23","#ffa500","#ff4500","#da70d6","#eee8aa","#98fb98","#afeeee","#db7093","#ffefd5","#ffdab9","#cd853f","#ffc0cb","#dda0dd","#b0e0e6","#800080","#663399","#ff0000","#bc8f8f","#4169e1","#8b4513","#fa8072","#f4a460","#2e8b57","#fff5ee","#a0522d","#c0c0c0","#87ceeb","#6a5acd","#fffafa","#00ff7f","#4682b4","#d2b48c","#008080","#d8bfd8","#ff6347","#40e0d0","#ee82ee","#f5deb3","#ffff00","#9acd32"],objects={};let worldId,theta,iota,worldHasStarted=!1;AB.socketStart(),init(),render();let horizontal_dist=1392;function yaw(e){theta+=e;let o=horizontal_dist*Math.sin(theta),t=horizontal_dist*Math.cos(theta),n=camera.position.y;camera.position.set(o,n,t),camera.lookAt(0,0,0),render()}function roll(e){Math.abs(iota+e)>1||(console.log(iota+e),iota+=e,horizontal_dist=1526*Math.cos(iota),camera.position.y=1526*Math.sin(iota),yaw(0))}function init(){AB.runReady=!1,AB.msg('Choose building colour: <input id="user_colour" type="color" value="'+AB.randomElementOfArray(realColors)+'" class=ab-largenormbutton><br>Rotate view using arrow keys'),(camera=new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,1,1e4)).position.set(500,800,1300),camera.lookAt(0,0,0),theta=Math.atan(camera.position.x/camera.position.z),iota=Math.atan(camera.position.y/camera.position.z),console.log("start",iota),(scene=new THREE.Scene).background=new THREE.Color(15790320);const e=new THREE.BoxGeometry(50,50,50);rollOverMaterial=new THREE.MeshBasicMaterial({color:16711680,opacity:.5,transparent:!0}),(rollOverMesh=new THREE.Mesh(e,rollOverMaterial)).visible=!1,scene.add(rollOverMesh),cubeGeo=new THREE.BoxGeometry(50,50,50);const o=new THREE.GridHelper(1e3,20);scene.add(o),raycaster=new THREE.Raycaster,pointer=new THREE.Vector2;const t=new THREE.PlaneGeometry(1e3,1e3);t.rotateX(-Math.PI/2),plane=new THREE.Mesh(t,new THREE.MeshBasicMaterial({visible:!1})),scene.add(plane),objects[0]=plane;const n=new THREE.AmbientLight(6316128);scene.add(n);const a=new THREE.DirectionalLight(16777215);a.position.set(1,.75,.5).normalize(),scene.add(a),(renderer=new THREE.WebGLRenderer({antialias:!0})).setPixelRatio(window.devicePixelRatio),renderer.setSize(window.innerWidth,window.innerHeight),document.body.appendChild(renderer.domElement),document.addEventListener("pointermove",onPointerMove),document.addEventListener("pointerdown",onPointerDown),document.addEventListener("keydown",onDocumentKeyDown),document.addEventListener("keyup",onDocumentKeyUp),window.addEventListener("resize",onWindowResize),AB.runReady=!0,Object.defineProperty(AB,"socket",{configurable:!0,set(e){Object.defineProperty(AB,"socket",{value:e}),AB.socketOut({action:"send_world"})}})}function onWindowResize(){camera.aspect=window.innerWidth/window.innerHeight,camera.updateProjectionMatrix(),renderer.setSize(window.innerWidth,window.innerHeight)}function getFirstIntersectedObject(){let e=raycaster.intersectObjects(Object.values(objects),!1);return e.length>0?e[0]:null}function onPointerMove(e){pointer.set(e.clientX/window.innerWidth*2-1,-e.clientY/window.innerHeight*2+1),raycaster.setFromCamera(pointer,camera);const o=getFirstIntersectedObject();o?(rollOverMesh.visible=!0,rollOverMesh.position.copy(o.point).add(o.face.normal),rollOverMesh.position.divideScalar(50).floor().multiplyScalar(50).addScalar(25)):rollOverMesh.visible=!1,render()}function onPointerDown(e){pointer.set(e.clientX/window.innerWidth*2-1,-e.clientY/window.innerHeight*2+1),raycaster.setFromCamera(pointer,camera);const o=getFirstIntersectedObject();if(o){if(isShiftDown)o.object!==plane&&(scene.remove(o.object),delete objects[o.object.position.toArray().join("-")],AB.socketOut({action:"remove",worldId:worldId,position:o.object.position}));else{let e=document.getElementById("user_colour").value,t=new THREE.Vector3;t.copy(o.point).add(o.face.normal),t.divideScalar(50).floor().multiplyScalar(50).addScalar(25),worldHasStarted||(worldId=Math.floor(1e16*Math.random()),worldHasStarted=!0),addBox(t,e),AB.socketOut({action:"add",worldId:worldId,position:t,color:e})}render()}}function onDocumentKeyDown(e){switch(e.keyCode){case 16:isShiftDown=!0;break;case 37:yaw(.1);break;case 39:yaw(-.1);break;case 38:roll(.1);break;case 40:roll(-.1)}}function onDocumentKeyUp(e){switch(e.keyCode){case 16:isShiftDown=!1}}function render(){renderer.render(scene,camera)}function addBox(e,o){if(e.y<0)return;let t=new THREE.MeshLambertMaterial({color:o,opacity:0,transparent:!1});const n=new THREE.Mesh(cubeGeo,t);n.position.copy(e),scene.add(n),objects[n.position.toArray().join("-")]=n}function removeBox(e){let o=e.toArray().join("-"),t=objects[o];t?(scene.remove(t),delete objects[o]):console.log("Can't remove box")}AB.socketIn=function(e){if(AB.runReady)switch(e.action){case"add":worldId==e.worldId&&(addBox(e.position,e.color),render());break;case"remove":worldId==e.worldId&&(removeBox(e.position),render());break;case"send_world":console.log("Received send world");{let e=Object.values(objects),o=[];for(let t=0;t<e.length;t++)e[t]!==plane&&o.push([e[t].position,e[t].material.color]);AB.socketOut({action:"rec_world",id:worldId,boxes:o})}break;case"rec_world":if(console.log("Received get world"),!worldHasStarted){worldId=e.id,worldHasStarted=!0;for(let o=0;o<e.boxes.length;o++)addBox(e.boxes[o][0],e.boxes[o][1])}render()}};