How to add markers/hotspots in a-frame panaroma? - aframe

I was trying to find a suitable web framework for VR experience and it should work on PC, and mobiles (i am using ionic). i tried many canvas/webGL based tools, finally stumbled upon aframe. i really like this, but i need help on how to add markers to a panorama image and also is it possible to toggle gyroscope on mobile devices ?

The guide in the docs has an example:
https://aframe.io/docs/0.4.0/guides/building-with-components.html
https://github.com/aframevr/360-image-gallery-boilerplate
In this example, you place planes. You use the cursor component for gaze-based cursor. And do stuff on mouseenter/mouseleave/click. It uses a lot of components, but that's what it looks like:
<a-entity class="link"
geometry="primitive: plane; height: 1; width: 1"
material="shader: flat; src: ${thumb}"
event-set__1="_event: mousedown; scale: 1 1 1"
event-set__2="_event: mouseup; scale: 1.2 1.2 1"
event-set__3="_event: mouseenter; scale: 1.2 1.2 1"
event-set__4="_event: mouseleave; scale: 1 1 1"
set-image="on: click; target: #image-360; src: ${src}"
</script>

Related

aframe viewport changes and positioning of entities

I need some help. For a project on whihc I am working on we use aframe. At this moment there is no need for VR, but we are working on 3d spaces.
I need two ' buttons' on the side of my scene. The user needs to see them the whole time.
Because of that in added the 'buttons as entities as child of the camera. Works like a charm. But when I change the viewport. Smaller screen ,mobile etc. you can't see them anymore the position changes.
Is there anyway to prevent this?
This is the code.
<a-entity camera look-controls>
<a-entity position="3 1 -2" >
<a-entity id="fullScreen" geometry="primitive: circle; radius:
0.1;" position=" 0 0.5 0" material="src:#fullIco; transparent: true; opacity: 0.5; " fullscreen> </a-entity>
<a-entity id="shareScene" geometry="primitive: circle; radius: 0.1;" position=" 0 0.25 0" material="src:#shareIco; transparent: true; opacity: 0.5; "sharescene> </a-entity>
</a-entity>
example
If You're not using VR, how about using normal buttons positioned over the a-frame canvas ?
Create a <div>, or <button> with a fixed position, anywhere you want it to be, and make it execute your code onclick. Like this:
<button onclick="changesphere()">
You can access the a-frame entities with queryselectors, and use them like any other DOM elements.
So just define your function like this:
var changesphere = function() {
if (document.querySelector("a-sphere").getAttribute("color") !== "blue") {
document.querySelector("a-sphere").setAttribute("color", "blue");
} else {
document.querySelector("a-sphere").setAttribute("color", "green");
}
}
Check out my example here.

How do I change an attribute of another object in Aframe?

In Javascript I would do parent.document.sphere1.setAttribute('color','blue');
Is this possible?
Yeah.
`document.querySelector('a-sphere').setAttribute('color', 'blue');
https://aframe.io/docs/0.5.0/guides/using-javascript-and-dom-apis.html
I solved this by using Kevin's Component here (he offered the idea):
[https://github.com/ngokevin/aframe-event-set-component][1]
Then, follow his instructions or add the javascript to the head of your html page and add similar code to this:
<a-image id="map1" src="img/map.png" position="0 14 0" rotation="0 -60 0" height="1" width=".5" scale="6 6 6"
event-set__1="_event: click; _target: #mycamera; position: 0 0 -18;"
event-set__2="_event: click; _target: #secondfloor1; visible: true;"
event-set__3="_event: mouseenter; _target: #archiveTxt; visible: true;"
event-set__4="_event: mouseleave; _target: #archiveTxt; visible: false;">
</a-image>
For moving the camera or teleporting just give your camera the id="myCamera".
Still can't figure out animation with this but it's a great start. event-set numbers must be in order like above.

How to fire A-FRAME collision event when two boxes intersect each other?

I am trying to detect collision of two boxes in A-FRAME v. 0.5.0. I use raycaster example:
https://aframe.io/docs/0.5.0/components/raycaster.html#whitelisting-entities-to-test-for-intersection
but for me it only works with cursor intersecting one of the meshes.
As it is written, raycaster detects when line created from a starting point to a certain direction intersects desired mesh (here marked with a collidable class). It appears that start of this collision-detecting line is somehow set on the camera or on a cursor but not on one of the boxes. How to reassign this starting point?
Before initializing scene I added component:
AFRAME.registerComponent('collider-check', {
dependencies: ['raycaster'],
init: function () {
console.log("we have component");
this.el.addEventListener('raycaster-intersected', function () {
console.log('Player hit something!');
});
},
});
and then A-FRAME entities
<a-entity id="player" collider-check >
<a-entity id="rc"
raycaster="objects: .collidable"
geometry="primitive: box; width: 0.5; height: 4; depth: 0.5"
material="shader: flat; color:gray"
position="0 -0.9 0"
rotation="90 0 0" ></a-entity>
</a-entity>
<a-entity id="inmotion" class="collidable"
geometry="primitive: box; width: 0.5; height: 4; depth: 0.5"
position="1 0 0"
material="shader: flat; color: #00CCDD">
<a-animation id="canim"
attribute="position"
dur="2000"
from ="-2 -1 0"
to="2 0 0.5"
fill="forwards"
direction="alternate"
repeat="indefinite">
</a-animation>
</a-entity>
Here is jsfiddle with the example;
https://jsfiddle.net/Suiseki/9ggs6x4m/2/
Using the raycaster is one way to check for collisions in 3D space, but it's best if one of those shapes is a ray/line. If you have two 3D objects, it's easier to use bounding box or bounding sphere collisions, without a raycaster. Here are example implementations of each:
aabb-collider
sphere-collider
Both will file hit events on the elements when they collide. Example usage, for a slightly different case.

A-frame: How to setup wall colliders

Can anyone tell me how to setup wall colliders? I have setup a room using OBJ files for the walls. Many thanks.
Take a look at the source code for Don McCurdy's "Walls" example:
https://sandbox.donmccurdy.com/vr/walls/
Note the addition of the physics component in the a-scene element. This is what gets the magic going.
You need to include the aframe-extras script along with aframe.
For anyone looking for a good solution nowadays, the best I found so far is to use a nav-mesh
The nav-mesh is a simple 3d object that represents the walkable area in your project.
Here is what you'll need:
To generate the nav-mesh, use the plugin https://github.com/donmccurdy/aframe-inspector-plugin-recast
To move the camera you will not use wasd-controls, but aframe-extras's movement-controls
How to
Once the plugin is added to the page, follow these steps:
I found it was better to generate without the walls, so I hide the walls first, and make sure the floor ends where the walls would be. Also, keep all objects that user should not be able to pass through in their final place.
In the browser, use ctrl + alt + i to open the inspector
In the bottom part of the inspector, you can change cellSize and cellHeight to 0.1
Export and save it
in the HTML add a new asset:
<a-asset-item id="my-nav-mesh" src="assets/navmesh.gltf"></a-asset-item>
Add a new entity that points to the nav mesh:
<a-entity gltf-model="#my-nav-mesh" nav-mesh position="0 -0.1 0" visible="false"></a-entity>
Add the movement-controls to your camera Rig, with the constrainToNavMesh: true;. Here is how mine ended up:
<a-entity id="rig" movement-controls="constrainToNavMesh: true; speed: 0.8;" position="0 0 26">
<a-entity id="camera"
camera position="0 2.6 0"
look-controls="pointerLockEnabled: true">
<a-cursor></a-cursor>
</a-entity>
Expected Result:
So, by adding the nav-mesh and using the movement-controls instead of WASD, for example, you will make your camera moveable only on the created mesh.
You can also make the mesh invisible (adding visible="false to the nav-mesh entity), and toggle its position on Z so it doesnt feel like a higher plane.
Source
I actually got this information structured from this amazing free youtube video, from Danilo Pasquariello.
https://www.youtube.com/watch?v=Y52czIft9OU
How my project is looking after doing the steps above (I just made the mesh visible again for this screenshot
kinematic-body.js is deprecated.
Don McCurdy encourages the use of teleportation
See this post too: Move camera in aframe with physics engine
aframe inspector plugin didn't work on my project.
I did that temporary
<script src="https://aframe.io/releases/0.8.2/aframe.min.js"></script>
<script
src="https://unpkg.com/aframe-aabb-collider-component#^2.2.1/dist/aframe-aabb-collider-component.min.js"></script>
<script src="https://unpkg.com/aframe-event-set-component#3.0.3/dist/aframe-event-set-component.min.js"></script>
<script>
let isStop = false
AFRAME.registerComponent("cam", {
init: function () {
window.addEventListener('keypress', e => {
if (isStop) {
const camera = document.getElementById('camera')
if (e.key === 's' || e.key === 'a' || e.key === 'd') {
camera.setAttribute('wasd-controls-enabled', 'true')
isStop = false
}
}
})
this.el.addEventListener("hitclosest", (e) => {
console.log('ok');
isStop = true
this.el.setAttribute('wasd-controls-enabled', 'false')
})
this.el.addEventListener("hitstart", (e) => {
isStop = true
this.el.setAttribute('wasd-controls-enabled', 'false')
})
}
})
</script>
<a-scene>
<a-entity id="rig" position="0 .5 -1">
<a-camera wasd-controls-enabled="true" cam id="camera" aabb-collider="objects: .collide"
geometry="primitive: box" aabb-collider="objects: a-box">
<a-cursor></a-cursor>
</a-camera>
</a-entity>
<a-box color="blue" class="collide" width='1' height='1' position="0 1.6 -5">
</a-box>
<a-box color="red" class="collide" width='1' height='1' position="2 1.6 -5">
</a-box>
<a-box color="pink" class="collide" width='10' height='1' position="10 1.6 -5">
</a-box>
</a-scene>
Here's ammo, which is a library for aframes.
https://github.com/n5ro/aframe-physics-system/blob/master/AmmoDriver.md#ammo-shape
You could read Collision Filtering for the detailed solution.

A-Frame mouseleave does not change color of cursor

I have an app where the user has to answer a question by clicking the correct area on a collada model - there are 2 options and the user knows that an area is selectable when the cursor turns blue (mouse enters the cylinder, which has visible=false).
The mouse turns blue fine, however where the mouse leaves the cylinder, the cursor color should return to black, but instead it stays blue.
Thanks in advance for your help.
<a-cursor id="myCursor" color="black"></a-cursor>
<a-entity id='questionA' geometry="primitive: cylinder; height: .01; radius: 2.5" material="color:green; opacity: 1" correctAnswer > </a-entity>
var cursorVar = document.getElementById('myCursor');
var questionVar = document.getElementById('questionA');
questionVar.addEventListener('mouseenter', function() {
cursorVar.setAttribute('color', 'blue');
});
questionVar.addEventListener('mouseleave', function() {
cursorVar.setAttribute('color', 'black');
});
The cursor side also emits the event. Try listening to the event from the cursor as a workaround:
cursorEl.addEventListener('mouseleave');
0.3.0 which should be releasing tomorrow or in two days has improvements on the cursor, raycaster, and raycasting against COLLADA models. This includes the ability to limit what the raycaster tests against which would be ideal in the workaround above.
Could be several factors in your bug, I think once 0.3.0 is out, I'd be able to say with more clarity what's happening.
Does this CodePen perform as you expect?
I can't see the problem looking at your code (maybe it's something to do with the cursor primitive). Try replacing the cursor primitive with a manually defined one used in the CodePen link above:
<!-- Camera with gaze cursor -->
<a-entity position="0 1.8 5">
<a-entity camera look-controls wasd-controls>
<a-entity cursor
geometry="primitive: ring; radiusOuter: 0.025;
radiusInner: 0.015; segmentsTheta: 32"
material="color: #283644; shader: flat"
raycaster="far: 30"
position="0 0 -0.75"
id='cursor'>
</a-entity>
</a-entity>
</a-entity>
That said, the raycasting does seem a bit inaccurate (with 0.2.0 at least).

Resources