Objects are Losing/Changing shape when used with Ar.js - javascript

I am just starting with Ar.js. I have a problem where the objects appearing on screen have lost their shapes a bit. First I have this simple A-Frame example which shows a sphere which is perfectly round:
<!DOCTYPE>
<html>
<head>
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
</head>
<body>
<a-scene>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"> </a-sphere>
</a-scene>
</body>
</html>
But when I use this following code of Ar.js, the same sphere looks like a oval now:
<!doctype html>
<html>
<head>
<link rel="canonical" href="https://inspiredlabs.github.io/ar.js/markerless.html" />
<!-- location based aframe v0.9.2 -->
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
<script src="https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar-nft.js"></script><!-- debug -->
<script>
const log = console.log;
window.onload = () => {
let scene = document.querySelector('a-scene'); /* Apply to whole scene */
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
let gps = document.createAttribute('gps-entity-place'),
arjs = document.createAttribute('arjs'),
arjs.value = 'sourceType: webcam; sourceWidth: 640; sourceHeight: 480; trackingMethod: best; debugUIEnabled: false;';
gps.value = `latitude: ${position.coords.latitude}; longitude: ${position.coords.longitude}`;
log(gps.value);
scene.setAttributeNode(gps); /* Apply to whole scene */
scene.setAttributeNode(arjs);
});
}
};
</script>
</head>
<a-scene device-orientation-permission-ui="enabled: true" vr-mode-ui="enabled: false">
<a-entity id="wrapper" position="0 -4 -5 " look-at="[camera]">
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E" shadow></a-sphere>
</a-entity><!-- /wrapper -->
<a-camera camera="fov: 60;" gps-camera rotation-reader></a-camera>
</a-scene>
</body>
</html>
I am having trouble figuring it out. Can anyone help me out here please?

Your sphere is perfectly fine. Shapes get distorted when they're close to the screen edges due to the perspective of the camera but that's absolutely normal. If you retry your first example, get further from the sphere and move it somewhere in a corner you'll see the same distortion you see in the second example. It will seem more natural with a background sky cause the whole view will get distorted in the corners. Nothing to worry about anyway!

Related

A-frame set websubsurface source to a variable

I am using the websurface A-frame component () and I'm wondering how I can make it so when a button is clicked, the url of the websurface will change to the value of a variable I've defined called source. What should happen is for example, if the variable source is set to "https://google.ca" and you click the button, the websurface url will change to https://google.ca. Current code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Example 1</title>
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-websurfaces#1.4.0/dist/aframe-websurfaces.umd.js"></script>
<script>
function updateSource() {
let source = "https://google.ca";
}
</script>
</head>
<body>
<button style="position: fixed; z-index: 100000;" onclick="updateSource()">
update src
</button>
<a-scene>
<!--Camera-->
<a-entity
wasd-controls="acceleration: 20;"
camera="active: true"
look-controls="pointerLockEnabled: false"
position="0 1.6 0"
>
<a-cursor position="0 0 -.05" scale=".04 .04 1"></a-cursor>
</a-entity>
<!--Environment-->
<a-sky color="#aff"></a-sky>
<a-plane
rotation="-90 0 0"
width="20"
height="20"
color="#3fa841"
></a-plane>
<!--Websurface-->
<a-entity
websurface="url:https://aframe.io/; width:4; height:2;"
position="2.25 1.5 -4"
></a-entity>
</a-scene>
</body>
</html>
Fiddle with code: https://jsfiddle.net/AidanYoung/7vye3osa/2/
The component is using an i-frame accessible with the reference:
element.websurface_iframe
You can use it like any other i-frame - like changing the src property:
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-websurfaces#1.4.0/dist/aframe-websurfaces.umd.js"></script>
<script>
function updateSource() {
let source = "https://threejs.org";
const websurfaceEl = document.querySelector("[websurface]")
websurfaceEl.websurface_iframe.src = source
}
</script>
<button style="position: fixed; z-index: 100000;" onclick="updateSource()">
update src
</button>
<a-scene>
<a-entity websurface="url:https://aframe.io/; width:4; height:2;"
position="0 1.6 -2"></a-entity>
</a-scene>
Keep in mind - the originating server may not welcome requests from other origins - like https://google.ca which explicitly tells you, that only websites from the same origin may display it in a frame (check the logs in the snippet below):
X-Frame-Options' to 'sameorigin'
<div>
<iframe src="https://google.ca" width="500" height="250">
</div>

A-frame add enable/disable component on function

I have created a scene using A-frame (https://aframe.io) and I currently have some rain in my scene and a button. What I would like to do is when the button is clicked, a function occurs, I'm wondering how I can make this function remove the rain component from the scene. Code:
<head>
<script src="https://cdn.rawgit.com/aframevr/aframe/v0.4.0/dist/aframe-master.min.js"></script>
<script src="https://rawgit.com/takahirox/aframe-rain/master/build/aframe-rain.min.js"></script>
</head>
<body>
<button onclick="toggleRain()">
Toggle rain
</button>
<a-scene rain>
<a-entity position="0 0 10">
<a-camera></a-camera>
</a-entity>
<a-entity geometry="primitive:sphere"></a-entity>
<a-sky color="#222"></a-sky>
<a-entity light="type:directional;color:#666" position="-10 -10 -10"></a-entity>
</a-scene>
</body>
What I would like to happen is when the toggleRain() function is triggered, the
<a-scene rain> part of the code will change and remove the rain part so there is just
<a-scene>
This should stop the rain from falling when the button is clicked. Just to clarify, when the function is triggered, it should rain property from the <a-scene rain> leaving just
<a-scene>
How can this be done? Link to fiddle containing code: https://jsfiddle.net/AidanYoung/z7qstgua/2/
You could just use removeAttribute() to remove the rain
function toggleRain() {
let a = document.getElementById('a');
if (a.hasAttribute('rain')) {
a.removeAttribute('rain');
} else {
a.setAttribute('rain', '1');
}
console.log ("ok");
}
<head>
<script src="https://cdn.rawgit.com/aframevr/aframe/v0.4.0/dist/aframe-master.min.js"></script>
<script src="https://rawgit.com/takahirox/aframe-rain/master/build/aframe-rain.min.js"></script>
</head>
<body>
<button onclick="toggleRain()">
Toggle rain
</button>
<a-scene id="a" rain>
<a-entity position="0 0 10">
<a-camera></a-camera>
</a-entity>
<a-entity geometry="primitive:sphere"></a-entity>
<a-sky color="#222"></a-sky>
<a-entity light="type:directional;color:#666" position="-10 -10 -10"></a-entity>
</a-scene>
</body>

In Aframe AR.js Show A Preloading Screen Till All The Assets Loads And Renders

I Want To Show A Preloading Screen Till All Assets Loads And Renders.
I Tried Using Assets Event loaded but its not working . When We Augment 3d Model , Image and video , So These Assets Are Almost 50-60mb . So it takes time to load the assets and augment . The video when we augment for 4-8 seconds the black screen comes and plays,if the network is slow (In inspect Network Tab Select 3G Slow We Test).
Please Edit My Code in Glitch
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello!</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script type="text/javascript" src="https://aframe.io/releases/0.8.2/aframe.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/jeromeetienne/AR.js/1.7.2/aframe/build/aframe-ar.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/donmccurdy/aframe-extras/v6.0.0/dist/aframe-extras.min.js"></script>
<script src="https://unpkg.com/aframe-animation-component#5.1.2/dist/aframe-animation-component.min.js"></script>
<script>
AFRAME.registerComponent("vidhandler", {
init: function () {
// Set up initial state and variables.
this.toggle = false;
this.vid = document.querySelector("#vid");
this.vid.pause();
console.log('************* Vid Paused');
},
tick: function () {
if (this.el.object3D.visible == true) {
if (!this.toggle) {
this.toggle = true;
this.vid.play();
console.log('************* Vid Play');
}
} else {
this.toggle = false;
this.vid.pause();
//console.log('************* Vid Paused');
}
}
});
</script>
</head>
<body>
<a-scene vr-mode-ui="enabled: false" artoolkit='sourceType: webcam; detectionMode: mono; maxDetectionRate: 90;' arjs='debugUIEnabled: false;detectionMode: mono_and_matrix; matrixCodeType: 3x3;'>
<!-- ALL ASSETS -->
<a-assets>
<!-- 3D MODEL -->
<a-entity id="model" src="https://cdn.glitch.com/c3106e6c-98cb-40e4-b0c1-85257680d25a%2Fygark.glb?v=1564472468760" crossorigin="anonymous" rotation="-90 0 -90">
</a-entity>
<!-- VIDEO -->
<video preload="auto" id="vid" response-type="arraybuffer" loop="false" crossorigin webkit-playsinline playsinline controls>
<source src="https://cdn.glitch.com/c3106e6c-98cb-40e4-b0c1-85257680d25a%2Fvid.mp4?v=1564472320471" type="video/mp4">
</video>
<!-- IMAGE -->
<img id="img" src="https://cdn.glitch.com/c3106e6c-98cb-40e4-b0c1-85257680d25a%2Fsun.png?v=1564472507237">
</a-assets>
<!-- ALL ASSETS -->
<a-marker type="pattern" preset="hiro" vidhandler>
<a-entity position="0 0 0">
<a-video width="2" height="2" rotation="-90 0 0" material='transparent:true;shader:flat;side:double;src:#vid'></a-video>
</a-entity>
<a-image width="2" height="2" material='transparent:true;shader:flat;side:double;src:#img' position="2 0 0" rotation="-90 0 0"></a-image>
<a-entity position="-1.5 0 0" gltf-model="#model" material='transparent:true;shader:flat;side:double;metelness:2' rotation="0 0 0" scale="0.5 0.5 0.5" shadow="receive: false" >
</a-entity>
</a-marker>
<a-entity camera>
<a-entity cursor="rayOrigin: mouse;fuse: false;"></a-entity>
</a-entity>
</a-scene>
</body>
</html>
Asset loaded event is not working . Please Edit My Code in Glitch
Thanks In Advance
There are a couple different options.
Aframe has a built in loading screen that is enabled within the <a-scene> declaration
<a-scene loading-screen="dotsColor: red; backgroundColor: black"></a-scene>
Another option is to follow the steps in the response from Noam Almosnino
Use a component like, Aframe Preloader
Note: I am not associated with this component and have not tested it. Please see the demo page for some examples
Update
Based on your comment (below) I would recommend #2 (above)
create a listener for the scene's loaded event
document.addEventListener('DOMContentLoaded', function() {
var scene = document.querySelector('a-scene');
scene.addEventListener('loaded', function (e) {
// hide splash screen
});
});

In AR.js When Load Model ,Show A Loading Screen

When We Load A Big 3D Model Or Big A Video, It Takes Time To Load The Assets(Resources) And Render The Resources,So I Want To Show A Loading Screen Or Loading Gif File or a Loading A-Box - Till The Whole Assets Loading And Rendering Is Done,On The Screen Or On The Pattern.Please Go Through My GLITCH , Its Working But It Will Take 10-15 Sec to load and render.
I tried To Add Asset Loading Manager But It didn't Worked . I Tried All The Ways But It Didn't Worked
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello!</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script type="text/javascript" src="https://aframe.io/releases/0.8.2/aframe.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/jeromeetienne/AR.js/1.7.2/aframe/build/aframe-ar.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/donmccurdy/aframe-extras/v6.0.0/dist/aframe-extras.min.js"></script>
<script src="https://unpkg.com/aframe-animation-component#5.1.2/dist/aframe-animation-component.min.js"></script>
</head>
<body>
<a-scene vr-mode-ui="enabled: false" artoolkit='sourceType: webcam; detectionMode: mono; maxDetectionRate: 90;' arjs='debugUIEnabled: false;detectionMode: mono_and_matrix; matrixCodeType: 3x3;'>
<a-assets>
<a-entity src="https://cdn.glitch.com/a5ca03d3-3024-44dc-9256-0b75c4247613%2Fscene.gltf?v=1563255364433" id="model"></a-entity>
</a-assets>
<a-marker preset="hiro">
<a-entity gltf-model="#model" material='transparent:true;shader:flat;side:double;metelness:2' scale="0.04 0.04 0.04" ></a-entity>
</a-marker>
<a-entity camera></a-entity>
<a-entity shadow="cast: true"></a-entity>
</a-scene>
<script>
// Workaround for an AR.js bug (https://github.com/jeromeetienne/AR.js/issues/410)
const sceneEl = document.querySelector('a-scene');
sceneEl.addEventListener('loaded', () => {
sceneEl.camera = new THREE.PerspectiveCamera();
scene.add( camera );
});
</script>
</body>
</html>
After Showing The HIRO Pattern Its Takes 10-15 Seconds (Depending Upon The Internet Speed) To Load And Render . I Want To Show Some Preloader Or Loading Screen Or Some Gif Loading Image To Display Till The Object (Assets) Loads Completely And Render And Disappear Once The Rendering And Loading Is Done......
Thanks In Advance
For models, you can use the model-loaded event:
<a-marker preset="hiro">
<a-entity id='loadingEl'></a-entity>
<a-entity gltf-model="#model"></a-entity>
</a-marker>
The #loadingEl could have a primitive box with a "loading" image, and when the model is loaded, you remove (the entity or its visibility):
AFRAME.registerComponent('foo', {
init: function() {
this.el.addEventListener('model-loaded', e => {
document.querySelector("#loadingEl").remove()
})
}
})
Glitch here.
The <a-assets> system have a loaded event emitted, you could use it for videos as well.
This is a fix for Aryan's glitch, use the Hiro marker and your 3d model - Glitch
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello!</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script type="text/javascript" src="https://aframe.io/releases/0.8.2/aframe.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/jeromeetienne/AR.js/1.7.2/aframe/build/aframe-ar.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/donmccurdy/aframe-extras/v6.0.0/dist/aframe-extras.min.js"></script>
<script src="https://unpkg.com/aframe-animation-component#5.1.2/dist/aframe-animation-component.min.js"></script>
<script>
AFRAME.registerComponent('loader', {
init: function() {
let loader = document.querySelector("#loadingEl")
this.el.addEventListener('model-loaded', e => {
console.log('loaded')
loader.setAttribute("visible", "false")
})
}
})
</script>
</head>
<body>
<a-scene vr-mode-ui="enabled: false" artoolkit='sourceType: webcam; detectionMode: mono; maxDetectionRate: 90;' arjs='debugUIEnabled: false;detectionMode: mono_and_matrix; matrixCodeType: 3x3;'>
<a-assets>
<a-entity src="https://cdn.glitch.com/a5ca03d3-3024-44dc-9256-0b75c4247613%2Fscene.gltf" id="model"></a-entity>
</a-assets>
<a-marker preset="hiro">
<a-box id="loadingEl"></a-box>
<a-entity gltf-model="#model" material='transparent:true;shader:flat;side:double;metelness:2' scale="0.04 0.04 0.04" loader></a-entity>
</a-marker>
<a-entity camera></a-entity>
<a-entity shadow="cast: true"></a-entity>
</a-scene>
<script>
// Workaround for an AR.js bug (https://github.com/jeromeetienne/AR.js/issues/410)
const sceneEl = document.querySelector('a-scene');
sceneEl.addEventListener('loaded', () => {
sceneEl.camera = new THREE.PerspectiveCamera();
scene.add( camera );
});
</script>
</body>
</html>

aframe camera not moving in vr mode

I want in an aframe game continuous moving to the viewport of the camera. I used the code from here:
In my desktop browser (not vr mode) it works pretty well, but when I am switching to the vr-mode the moving doesn't work...
Here is an exampe of what i have:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>360° Image Browser</title>
<script src="https://aframe.io/releases/0.7.1/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-extras.ocean#3.13.1/dist/aframe-extras.ocean.min.js"></script>
</head>
<body>
<a-scene>
<!-- sky + ocean -->
<a-sky radius="100" src="http://2.bp.blogspot.com/-ELqPrSgPbGU/Vcnw54n7Q1I/AAAAAAAAGdk/rcfkvjlMNqI/s1600/PANO_360Test09.jpg"
position="0 -6 0 "></a-sky>
<a-ocean width="200" depth="200" density="200" position="0 0 0"></a-ocean>
<!-- camera + cursor. -->
<a-camera id="camera" position="0 20 80" fly wasd-controls-enabled="false" look>
<a-cursor id="cursor" color="black"></a-cursor>
</a-camera>
</a-scene>
<script>
// document.querySelector("a-scene").enterVR();
AFRAME.registerComponent("fly", {
schema: {
stepFactor: { type: "number", default: 0.1 },
isFlying: { type: "boolean", default: true }
},
tick: function () {
if (this.data.isFlying) {
this.el.components.camera.camera.parent.position.add(
this.el.components.camera.camera
.getWorldDirection()
.multiplyScalar(this.data.stepFactor)
);
}
}
});
</script>
</body>
</html>
you can turn on the vr mode in the script by removing the commit
Anyone an idea?
I'm not entirely sure what happens when you switch to VR mode (in regards to the camera element), but trying setAttribute seems to make it work:
https://glitch.com/edit/#!/a-frame-move-camera
tick: function () {
if (this.data.isFlying) {
let newP = this.el.components.camera.camera.parent.position.add(this.el.components.camera.camera.getWorldDirection().multiplyScalar(this.data.stepFactor));
this.el.setAttribute('position', newP)
}
}

Categories