added aframe map component

This commit is contained in:
Felix Baumgärtner 2024-01-13 23:31:49 +01:00
parent b8ad31544e
commit 16acf15649

270
src/components/Map.svelte Normal file
View File

@ -0,0 +1,270 @@
<script>
</script>
<svelte:head>
<script>
AFRAME.registerComponent("foo", {
init: function() {
this.canvas = document.querySelector("#cam");
this.ctx = this.canvas.getContext("2d");
this.secondaryCam = document.querySelector("#secondarycam").components.camera.camera;
},
tick: function() {
if (!this.secondaryCam) return;
this.el.renderer.render(this.el.sceneEl.object3D, this.secondaryCam);
this.ctx.drawImage(this.el.renderer.domElement, 0, 0, 480, 270);
}
});
AFRAME.registerComponent('mqtt-control', {
init: function () {
let oldDirection = "";
let currentDirection = "";
let animationFrameId;
const moveContinuously = () => {
const entity = this.el;
const currentPosition = entity.getAttribute('position');
const currentRotation = entity.getAttribute('rotation');
let speedPos = 0.01;
let speedRot = 2;
let deltaMove;
let deltaRotate;
switch (currentDirection) {
case "bwd":
speedPos = speedPos * -1;
// fall through
case "fwd":
deltaMove = new AFRAME.THREE.Vector3(
currentPosition.x + speedPos * Math.sin(currentRotation.y * (Math.PI / 180)),
currentPosition.y,
currentPosition.z + speedPos * Math.cos(currentRotation.y * (Math.PI / 180))
);
entity.setAttribute('position', deltaMove);
break;
case "right":
speedRot = speedRot * -1;
// fall through
case "left":
deltaRotate = new AFRAME.THREE.Vector3(
currentRotation.x,
currentRotation.y + speedRot,
currentRotation.z
);
entity.setAttribute('rotation', deltaRotate);
deltaMove = new AFRAME.THREE.Vector3(
currentPosition.x + speedPos * Math.sin(currentRotation.y * (Math.PI / 180)),
currentPosition.y,
currentPosition.z + speedPos * Math.cos(currentRotation.y * (Math.PI / 180))
);
entity.setAttribute('position', deltaMove);
break;
case "turnRight":
speedRot = speedRot * -1;
// fall through
case "turnLeft":
deltaRotate = new AFRAME.THREE.Vector3(
currentRotation.x,
currentRotation.y + speedRot,
currentRotation.z
);
entity.setAttribute('rotation', deltaRotate);
break;
}
animationFrameId = requestAnimationFrame(moveContinuously);
};
const client = mqtt.connect('mqtt://sxl6.feba.me:9002');
client.on("connect", () => {
client.subscribe('fts/1/send/fwd');
client.subscribe('fts/1/send/bwd');
client.subscribe('fts/1/send/left');
client.subscribe('fts/1/send/right');
client.subscribe('fts/1/send/turnLeft');
client.subscribe('fts/1/send/turnRight');
});
client.on('message', (topic, message) => {
const content = message.toString();
if (topic.startsWith('fts/1/send/')) {
const newDirection = topic.replace('fts/1/send/', '');
if (content == 1) {
if (newDirection !== currentDirection) {
oldDirection = newDirection;
currentDirection = newDirection;
cancelAnimationFrame(animationFrameId);
animationFrameId = requestAnimationFrame(moveContinuously);
}
} else {
cancelAnimationFrame(animationFrameId);
}
}
});
},
});
function animateToDest(dest) {
skipAnimation = false;
if (dest == "cannon") {
destCoords = {x: 5, y: 0.025, z: 1};
skipAnimation = true;
} else if (dest == "station-a") {
destCoords = {x: 3, y: 0.025, z: 2};
} else if (dest == "station-b") {
destCoords = {x: 1, y: 0.025, z: 4};
}
rotation = 0;
function startAnimation1(entity) {
// console.log(entity.getAttribute('rotation').y);
// if (entity.getAttribute('rotation').y == -90) {
// document.getElementById("cam-front-view").setAttribute("visible", false);
// document.getElementById("cam-back-view").setAttribute("visible", true);
// } else {
// document.getElementById("cam-back-view").setAttribute("visible", false);
// document.getElementById("cam-front-view").setAttribute("visible", true);
// }
if (entity.getAttribute('position').z < destCoords.z) {
rotation = -90;
} else if (entity.getAttribute('position').z >= destCoords.z) {
rotation = 90;
}
// check if starting from cannon to skip this step
if (JSON.stringify(entity.getAttribute('position')) != JSON.stringify({x: 5, y: 0.025, z: 1})) {
entity.setAttribute('animation__1', {
'property': 'position',
'to': `5 ${entity.getAttribute('position').y} ${entity.getAttribute('position').z}`,
'startEvents': 'start1',
'dur': 1500
});
entity.emit('start1', null, false);
entity.addEventListener('animationcomplete', onAnimationComplete);
} else {
startAnimation03(entity);
}
}
function startAnimation02(entity) {
entity.setAttribute('animation__2', {
'property': 'rotation',
'to': `${entity.getAttribute('rotation').x} ${entity.getAttribute('rotation').y + rotation} ${entity.getAttribute('rotation').z}`,
'startEvents': 'start2',
'dur': 500
});
entity.emit('start2', null, false);
entity.addEventListener('animationcomplete', onAnimationComplete);
}
function startAnimation03(entity) {
entity.setAttribute('animation__3', {
'property': 'position',
'to': `5 ${entity.getAttribute('position').y} ${destCoords.z}`,
'startEvents': 'start3',
'dur': 1500
});
entity.emit('start3', null, false);
entity.addEventListener('animationcomplete', onAnimationComplete);
}
function startAnimation04(entity) {
entity.setAttribute('animation__4', {
'property': 'rotation',
'to': `${entity.getAttribute('rotation').x} ${entity.getAttribute('rotation').y + rotation} ${entity.getAttribute('rotation').z}`,
'startEvents': 'start4',
'dur': 500
});
entity.emit('start4', null, false);
entity.addEventListener('animationcomplete', onAnimationComplete);
}
function startAnimation05(entity) {
entity.setAttribute('animation__5', {
'property': 'position',
'to': destCoords,
'startEvents': 'start5',
'dur': 1500
});
entity.emit('start5', null, false);
}
// chain animations through animation complete event
function onAnimationComplete(event) {
var eventName = event.detail.name;
var entity = event.target;
switch (eventName) {
case 'animation__1':
startAnimation02(entity);
break;
case 'animation__2':
startAnimation03(entity);
break;
case 'animation__3':
if (skipAnimation !== true) {
startAnimation04(entity);
}
break;
case 'animation__4':
startAnimation05(entity);
break;
default:
// Handle other animation events if needed
break;
}
}
startAnimation1(document.getElementById("fts"));
}
</script>
</svelte:head>
<canvas id="cam" width="480" height="270"></canvas>
<div id="aframe-wrapper">
<a-scene embedded background="color: #FAFAFA" foo>
<a-assets>
<!-- <a-asset-item id="fts-case" src="/aframe/fts-case.glb"></a-asset-item> -->
<a-asset-item id="warehouse" src="/aframe/Factory_Warehouse.glb"></a-asset-item>
</a-assets>
<!-- <a-entity gltf-model="#warehouse" position="3 0 2.5" scale="0.1 0.1 0.1"></a-entity> -->
<!-- description -->
<a-text value="Cannon" position="5 0.5 1" rotation="-90 0 0" align="center" opacity="0.5"></a-text>
<a-text value="Station A" position="3 0.5 2" rotation="-90 0 0" align="center" opacity="0.5"></a-text>
<a-text value="Station B" position="1 0.5 4" rotation="-90 0 0" align="center" opacity="0.5"></a-text>
<!-- lines -->
<a-box color="tomato" position="5 0 2.5" depth="3" height="0.001" width="0.01"></a-box>
<a-box color="tomato" position="4 0 2" depth="0.01" height="0.001" width="2"></a-box>
<a-box color="tomato" position="3 0 4" depth="0.01" height="0.001" width="4"></a-box>
<a-entity id="aerial-cam" position="3 4 4.1" rotation="-90 0 0">
<a-camera id="cam1" camera wasd-controls-enabled="false" look-controls-enabled="false" fov="60"></a-camera>
</a-entity>
<!-- dynamic cam fts -->
<a-entity id="fts" position="5 0.025 1" rotation="0 0 0" mqtt-control>
<a-entity id="secondarycam" camera="active: false" camrender="cid: cam-front" position="0 0.005 0.06" rotation="10 180 0" material="opacity: 0" canvas-updater></a-entity>
<a-entity gltf-model="/aframe/fts-case-decimated-export.glb" position="0 -0.02 0" scale="0.1 0.1 0.1"></a-entity>
</a-entity>
</a-scene>
</div>
<button onclick="animateToDest('cannon')">Cannon</button>
<button onclick="animateToDest('station-a')">Station A</button>
<button onclick="animateToDest('station-b')">Station B</button>
<p>Toggle camera view: Follow, Manual, Zoom?</p>
<style>
#aframe-wrapper {
aspect-ratio: 2/1.4;
}
</style>