import * as THREE from '/app/thirdparty/Three/three.module.js' import { OrbitControls } from '/app/thirdparty/Three/OrbitControls.module.js' import * as TWEEN from '/app/thirdparty/Three/tween.module.js' export class kfArena{ constructor(canvasEl, agentSprites){ Object.assign(this, app.helpers.helpers3D) this.agentSprites = app.Assets.Store.json.agentSprites this.canvasEl = canvasEl this.agentSprites = agentSprites this.renderer = null this.mode='3D' this.sceneSize = app.Assets.Store.json.arenaConfig.arenaSize this.initScene() } initScene(){ // Scene this.scene = new THREE.Scene() // Camera this.camera = new THREE.PerspectiveCamera(75, this.canvasEl.clientWidth / this.canvasEl.clientHeight, 0.1, 1000) this.camera.position.set(3, 3, 5) this.camera.lookAt(0, 0, 0) this.camera.layers.enable(1) this.camera.layers.enable(2) // Lights const light = new THREE.DirectionalLight(0xffffff, 1) light.position.set(5, 5, 5) light.intensity = 2 this.scene.add(light) this.scene.add(new THREE.AmbientLight(0xffffff, 0.4)) this.grid = new THREE.GridHelper(this.sceneSize.x, this.sceneSize.x, 0x8888AA, 0x8888AA) this.grid.layers.set(1) this.scene.add(this.grid) // Base plane const planeGeo = new THREE.PlaneGeometry(100, 100) const planeMat = new THREE.MeshBasicMaterial({ color: 0xaaaacc, opacity: 0.3, transparent: true, // needed for opacity < 1 to take effect side: THREE.DoubleSide }) this.basePlane = new THREE.Mesh(planeGeo, planeMat) this.basePlane.rotation.x = -Math.PI / 2 // lay it flat (like the grid) this.basePlane.position.y=-0.01 // to avoid artefacts on objets bases this.scene.add(this.basePlane) this.axes = new THREE.AxesHelper(this.sceneSize.x/2, this.sceneSize.y/2) this.axes.layers.set(2) this.scene.add(this.axes) this.renderer = new THREE.WebGLRenderer({ antialias: true, canvas: this.canvasEl }) } startRendering(){ this.addControls() this.render() } render() { TWEEN.update() if(this.resizeRendererToDisplaySize()) { this.camera.aspect = this.renderer.domElement.clientWidth / this.canvasEl.clientHeight this.camera.updateProjectionMatrix() } this.renderer.render(this.scene, this.camera) requestAnimationFrame(this.render.bind(this)) } resizeRendererToDisplaySize() { const width = this.canvasEl.clientWidth const height = this.canvasEl.clientHeight if (this.canvasEl.width !== width || this.canvasEl.height !== height) { this.renderer.setSize(width, height, false) return true } return false } addControls(){ this.controls = new OrbitControls(this.camera, this.canvasEl) if(this.mode=='2D'){ this.controls.maxPolarAngle = 0 // Math.PI / 2 this.controls.minPolarAngle = 0 // Math.PI / 2 } else if(this.mode=='3D'){ } this.controls.mouseButtons = { LEFT: THREE.MOUSE.ROTATE, // keep orbit on left MIDDLE: THREE.MOUSE.PAN, // pan with middle-click RIGHT: THREE.MOUSE.DOLLY // zoom with right-click } } addAgent(typeId, aid, position){ const agentSprite = this.agentSprites.find(item => item.atp_id==typeId) if(!agentSprite) return const agentObj = this.agentFromJSON(aid, agentSprite.asp_3d) agentObj.position.set(position.x, position.z, position.y ) this.scene.add(agentObj) } removeAgent(id){ //find obj by id //this.scene.remove(this.currentAgentObj) } } // Make this module available to common JS if(!app.LoadedModules) app.LoadedModules = {} app.LoadedModules.kfArena = kfArena