aframe: error in passing data to template under jade - aframe

I am using jade (pug) to dynamically create the required HTML pages. This includes creating of the aframe tags. When using kframe template components I am getting an error.
a-scene(embedded)
a-assets
script#boxesTemplate(type='text/x-jade-template')
a-box(color="${color1}")
a-entity(template='src: #boxesTemplate;', data-color1="blue", position="1 0 1")
a-entity(template='src: #boxesTemplate;', data-color1="red", position="3 0 2")
The generated HTML tags look OK. However, the javascript console shows:
THREE.Color: Unknown color ${color1}
Any ideas why this occurs?. Thanks.
Raj

It's not exactly what you like, but this 2 examples work for me:
a-assets
script#boxesTemplate1(type="text/x-html-template").
<a-box color="${box}" position="-1 0 -5"></a-box>
script#boxesTemplate2(type="text/x-nunjucks-template").
<a-box color="{{box}}" position="1 0 -5"></a-box>
a-entity(template="src: #boxesTemplate1" data-box="red")
a-entity(template="src: #boxesTemplate2" data-box="blue")
Maybe the type attribute of the template define the syntax of 'vars'. Maybe text/x-jade-template conflicts with the entire file.
Also, in a html file (not jade file) this works:
<a-scene>
<script id="boxesTemplate3" type="text/x-jade-template">
a-box(color="#{box}" position="0 1 -5")
</script>
</a-assets>
<a-entity template="src: #boxesTemplate3" data-box="green"></a-entity>
¡saludos!

Related

Why the ocean program in documentation is not working and showing error?

In Official documentation there's a program in which they mentioned reference of Don McCurdy’s aframe-extras to get for Aframe 1.2.0. But when I am running the program using CDN of production link. It never works. And I receive the following error as well.
My code is :
<!
DOCTYPE html>
<html lang="en">
<head>
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/donmccurdy/aframe-extras#v6.1.1/dist/aframe-extras.min.js"></script>
<title>Proyectos</title>
</head>
<body>
<a-scene physics>
<script>
AFRAME.registerPrimitive('a-ocean', {
// Attaches the `ocean` component by default.
// Defaults the ocean to be parallel to the ground.
defaultComponents: {
ocean: {},
rotation: {x: -90, y: 0, z: 0}
},
// Maps HTML attributes to the `ocean` component's properties.
mappings: {
width: 'ocean.width',
depth: 'ocean.depth',
density: 'ocean.density',
color: 'ocean.color',
opacity: 'ocean.opacity'
}
});
</script>
<a-ocean color="aqua" depth="100" width="100"></a-ocean>
</a-scene>
</body>
</html>
a-ocean is defined in a-frame extras, so there is no need for you to define it again, you should be able to just use it. That explains the first error ("a-ocean is already registered").
Unfortunately is written using the THREE.js Geometry component, which was deprecated in THREE.js r125.
That corresponds to A-Frame 1.2.0.
This explains the second error ("mergeVertices is not a function").
So (until someone updates a-ocean) you have to use A-Frame 1.1.0 or earlier if you want to use a-ocean.
This code will give you a basic ocean
<html lang="en">
<head>
<script src="https://aframe.io/releases/1.1.0/aframe.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/donmccurdy/aframe-extras#v6.1.1/dist/aframe-extras.min.js"></script>
<title>Proyectos</title>
</head>
<body>
<a-scene physics>
<a-ocean color="aqua" depth="100" width="100"></a-ocean>
</a-scene>
</body>
</html>
In terms of getting a-ocean fixed, it looks like there has been some work on this:
https://github.com/n5ro/aframe-extras/issues/362
That issue includes sample code for a fix, but nobody has made it into a PR yet...

aframe glTF cube-env-map

I'm unable to see any reflexion on my gtLF model using "cube-env-map".
I'd like to get something like this :
helmet from threejs.org examples
I don't know if this is because of the .jpg files I use, or html or linked javascript scripts, or... anything else?
Here's my html :
<!DOCTYPE html>
<html>
<head>
<script src="https://aframe.io/releases/0.8.2/aframe.min.js"></script><!-- Master file for aframe (== a-scene) -->
<script src="https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar.js"></script><!-- webcam/mobilecam -->
<script src="https://mkwy.fr/js/play-all-model-animations.js"></script><!-- animation -->
<script src="https://mkwy.fr/js/aframe-orbit-controls.min.js"></script><!-- orbit cam around target -->
<script src="https://mkwy.fr/js/aframe-extras.js"></script><!-- cub-env-map -->
</head>
<body>
<a-scene vr-mode-ui="enabled: false" embedded>
<a-assets>
<a-asset-item id="toy" src="https://mkwy.fr/assets/toyDrummerSolo.glb"></a-asset-item>
</a-assets>
<a-entity
gltf-model="#toy"
cube-env-map="path: https://mkwy.fr/assets/cube-env/; extension: jpg; reflectivity: 0.9;"
play-all-model-animations >
</a-entity>
<a-entity camera look-controls orbit-controls="target: 0 1 0; minDistance: 0.5; maxDistance: 60; initialPosition: 0 5 5"></a-entity>
</a-scene>
</body>
</html>
Many thanks in advance for your help,
(Assuming there are no console errors suggesting incorrect cubemap paths, or wrong extensions)
If your model looks like this:
And you want it to be more like this:
Then the answer lies in two factors - metalness, and roughness.
roughness determines whether the material is like a mirror (0), or completely diffuses the reflection (1).
metalness determines whether the material is metallic (1), or not (0).
You can deal with this in at least two ways:
Modify the materials in a modelling software like blender, or maya.
Modify the properties within an a-frame custom component.
A component would have to wait until the model is loaded, and change all (or some selected) model nodes. Like this:
AFRAME.registerComponent("foo", {
init: function() {
// wait until the model is loaded
this.el.addEventListener("model-loaded", e => {
// grab the mesh
let mesh = this.el.getObject3D("mesh");
mesh.traverse(node => {
// ignore nodes without materials
if (!node.material) return;
// assign the values.
node.material.metalness = 1;
node.material.roughness = 0;
})
})
}
})
You can check it out in this example.
The helmet is working with both jpg and png maps. As for arjs, if your model will be glitchy, and you'll experience z-fighting, just set the logarithmicDepthBuffer in the renderer:
<a-scene renderer="logarithmicDepthBuffer: true" embedded arjs>
Example here
.Seems to be working as expected:
Ok, I changed the settings in Blender, adding metalness, and now it works like a charm. It was confusing because in Blender you don't need to set metalness to get reflection (i.e. : a plastic bottle may have reflections). I have to play with these parameters. Many thanks!

Changing 'src' on A-asset does not update material

I'm using A-frame 0.8.2 and don't get behaviour I expect. When I change the source of my asset, it will not refresh on things that use this source. For example:
<a-scene>
<a-assets>
<img id="myPicture" src="myPicture.jpg">
<a-assets>
<a-sky id="sky" src="#myPicture"></a-sky>
</a-scene>
JS: $("#sky")[0].setAttribute("src", "myPicture2.jpg");
Now, my a-sky still shows "myPicture", even though the inspector shows myPicture2. Any ideas how to work around this? In my application I wish not to change the id of the asset.
I recommend having two different img's and change the src on the entity:
<a-scene>
<a-assets>
<img id="myPicture" src="myPicture.jpg">
<img id="myPicture2" src="myPicture2.jpg">
<a-assets>
<a-sky src="#myPicture"></a-sky>
</a-scene>
JS: $("a-sky")[0].setAttribute("src", "#myPicture2");
What I did was:
Remove the src from Sky
jQuery(scene).find('#' + skyId ).attr('src','');
Update the material
jQuery(scene).find('#' + Img360assetId).attr('src',url);
Setting the id again
jQuery(scene).find('#' skyId).attr('src', '#' + Img360assetId);

How does the asset schema property work with img assets?

I am trying to pass an image as an asset property type to some other component (so that either a #selector or a url(url) can be passed) but it seems to take in the entire html component, instead of just the url.
<!DOCTYPE html>
<html>
<head>
<title>Hello, WebVR! - A-Frame</title>
<meta name='description' content='Hello, WebVR! - A-Frame'>
<script src='../../global/js/aframe-v0.8.0.min.js'></script>
<script>
AFRAME.registerComponent('some-component', {
schema: {
image: {type:'asset', default:''},
model: {type:'asset', default:''}
},
init: function() {
console.log(this.data.image); //prints out <img id="SomeImage" src="../../someDir/someFile.jpg">
console.log(this.data.model); //prints out '../../someDir/someModel.gltf'
}
});
</script>
</head>
<body>
<a-scene >
<a-assets timeout='3000'>
<!-- this works as an asset no problem -->
<a-asset-item id='SomeModel' src='../../global/assets/models/gltf/UserHead/UserHead.gltf'></a-asset-item>
<!-- this does not pass as an asset but rather an html element -->
<img id='SomeImage' src='../../global/assets/textures/equirectangular/CloudySky.jpg'>
</a-assets>
<a-entity some-component='image:#SomeImage; model:#SomeModel;'></a-entity>
</a-scene>
</body>
</html>
Thought I might look to see how A-Frame handles this in the material component can't see where does the 'src' property on material come from?
<a-entity id='skyBox'
geometry='primitive:sphere; radius:50; segments-height:6; segments-width:6;'
material='shader:flat; src:#skyMap; side:back; height:2048; width:2048'>
</a-entity>
Material component (can't see src): https://github.com/aframevr/aframe/blob/master/src/components/material.js
Thanks!
EDIT:
As per Piotr's discoveries below it looks like images are handed as a special case, as can be in the src code here with frame 0.8.0 where an image source is handed like this:
hash: function (data) {
if (data.src.tagName) {
// Since `data.src` can be an element, parse out the string if necessary for the hash.
data = utils.extendDeep({}, data);
data.src = data.src.src;
}
return JSON.stringify(data);
},
So basically if an image we the asset property will not handle image's properly and an additional step of grabbing the url from it via
data.src.src
OR
data.src.getAttribute('src');
Please correct me if i'm wrong, but i think it's not in the material schema.
I think the devil's in the component.js, which not only seems to allow you to assign a value to any given property, but also has the constructor for any component, and parses the schema.
That being said, the material does not need a src in the schema, as it seems to be a part of every component. Furthermore there are multiple parsers like the assetParse, or src-loader, checking whether an attribute is a html element, or even a video / image asset.
As for the material part, check out the dist source code, where
I think what you're looking for is:
module.exports.updateMapMaterialFromData
where you can see a-frame team uses the data.src for the material, and updates the texture with it. Just give it a ctrl+F (only 3 hits).
So when
module.exports.updateMapMaterialFromData('map', 'src', shader, data);
is called, with the given definition:
module.exports.updateMapMaterialFromData = function (materialName, dataName, shader, data) {
var el = shader.el;
var material = shader.material;
var src = data[dataName];
.......
makes src = data[src] => they make updates using a local variable src.
Also you can see the src-loader in action where the material system is registered, and when a src attribute is found out, the validateSrc function fires one of the two callbacks:
utils.srcLoader.validateSrc(src, loadImageCb, loadVideoCb);

Videos in aframe on samsung internet

I know I should have limited expectations towards gearVr, as documented here, but i need to make a site specifically for it.
Although primitives textured with images work like a charm, when i add a plane with a video texture, the lighting goes off on one eye, moreover playing the video on fusing is not working whatsoever. Here's the most simplified version of my code:
<!DOCTYPE html>
<html>
<head>
<script src="https://rawgit.com/aframevr/aframe/d47ce98/dist/aframe-master.min.js"></script>
<script>
AFRAME.registerComponent('vidtest', {
init: function() {
this.el.addEventListener('click',function(){
document.querySelector('#vid').load();
document.querySelector('#vid').play();
});
}
});
</script>
</head>
<body>
<a-scene>
<a-assets>
<video id="vid" src="tlo1.mp4" autoplay="false" crossorigin playsinline webkit-playsinline>
</a-assets>
<a-plane vidtest position="0 1 -2" material="src:#vid"></a-plane>
<a-camera>
<a-entity cursor="fuse: true; fuseTimeout: 500"
position="0 0 -1"
geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03"
material="color: black; shader: flat">
</a-entity>
</a-camera>
</a-scene>
</body>
</html>
Its live here.
I think it's ok, given the fact it works on android firefox, and on desktop chrome/firefox. Though it seems to have issues on android-chrome.
Btw I can make my site work on gear ONLY on the master build, earlier builds won't even let me enter vr-mode.
Anyone had these issues ? I tried adding gear controls there, internet://webvr-enable seem to do nothing. Can i open chrome or firefox on the gearVr ?

Resources