three.js fog on chrome mobile not working - google-chrome

Well I have a scene and I add some fog to it and the result is the fog is filling my entire screen with that color, like having a plain black background.
Chrome version: 39.0.2171.93
Mobile device: nexus 5
Android: lolipop
Here is my code:
Demo.prototype.initializeScene = function( settings ) {
var defaults = {
fogColor: 0x000000,
fogIntensity: 0.0005,
near:50000,
far:120000
};
this.options.scene = $.extend(true, defaults, settings);
this.scene = new THREE.Scene();
this.scene.fog = new THREE.FogExp2( this.options.scene.fogColor, this.options.scene.fogIntensity );
}
The code works fine on desktop and other mobile devices.
If I remove the fog everything seems to work great.
Furthermore everything takes place inside a dome (json) mesh created with blender and then loaded, here is the code in case it's a material issue.
Demo.prototype.initializeEnvironment = function() {
var that = this;
loadMesh("geometry/dome.json", function(geometry, materials) {
var materials = [
new THREE.MeshLambertMaterial({ color: 0x3333ff, shading: THREE.FlatShading, overdraw: false}),
new THREE.MeshLambertMaterial({ color: 0x2e2eff, wireframe: true})
];
that.dome = new THREE.SceneUtils.createMultiMaterialObject(geometry, materials);
that.dome.position.set(0,0,0);
that.dome.scale.set(500,500,500);
that.scene.add(that.dome);
});
}
Finally the renderer code:
Demo.prototype.initializeRenderer = function( settings ) {
var defaults = {
init :{
antialias: true,
alpha: true,
autoClear: false
},
clearColor: 0x000000,
clearColorIntensity: 1
};
this.options.renderer = $.extend(true, defaults, settings);
this.renderer = new THREE.WebGLRenderer( this.options.renderer.init );
this.renderer.setClearColor( this.options.renderer.clearColor, this.options.renderer.clearColorIntensity );
this.renderer.setSize( this.options.generic.container.clientWidth, this.options.generic.container.clientHeight );
this.options.generic.container.appendChild( this.renderer.domElement );
}

I am using Three.js r73 and hit the same issue on my Nexus 4 with Android 5. Fog seems to work again after disabling antialiasing.
You can achieve the same anti-aliasing effect by setting the renderer's pixelRatio. Here's what I do:
renderer.setPixelRatio((window.devicePixelRatio || 1) * 2);

Related

i have a geojson layer button and when i click i have to zoom to the particular layer

this is my layer and i have assigned it to a button, but the zoom is not working when I click the layer button. i tried adding the zoom inside the layer but its not working.
rainfall1 = new ol.layer.Vector({
//title: 'CA_DEVELOPMENT_PLAN',
// extent: [-180, -90, -180, 90],
visible:false,
source: new ol.source.Vector({
url:"./data/village.geojson",
zoom: 12,
format: new ol.format.GeoJSON()
}),
style:function(feature) {
labelStyle.getText().setText(feature.getProperties().CA_NAME);
return style1;
},
declutter: true,
});
document.getElementById("lyr").onclick = function() {
layer1.setVisible(!rainfall1.getVisible());
};
var bindLayerButtonToggle = function (lyr, layer) {
document.getElementById(lyr).onclick = function() {
layer.setVisible(!layer.getVisible());
};
}
bindLayerButtonToggle("lyr", rainfall1);
setVisible will not zoom to a layer, it just turns it on or off.
Instead, you would have to update the view extent, and match it with the layer extent
map.getView().fit(rainfall1.getSource().getExtent());
#JGH's answer might work in some cases but if this is the first time the layer is made visible the source will not be loaded, so if there are no features you will need to wait for it to load before zooming.
if (rainfall1.getSource().getFeatures().length > 0) {
map.getView().fit(rainfall1.getSource().getExtent());
} else {
rainfall1.getSource().once('featuresloadend', function() [
map.getView().fit(rainfall1.getSource().getExtent());
});
}

Implementing Three.js SSAOPass in AFrame

I was able to successfully integrate Threejs Effect composer in aframe as a component by exporting everything as THREE.Effectcomposer, THREE.SSAOPass etc. and adding the effect inside a aframe component and i tweaked the AFrame renderer to update the effects in the scene. OutlinePass from threejs worked fine in this code but SSAO is not working and i don't get any errors. Please someone help me figure out the problem. the code for SSAOPass looks like this
AFRAME.registerComponent('ssao', {
init: function () {
this.el.addEventListener('that', evt => this.onEnter());
this.el.addEventListener('mouseleave', evt => this.onLeave());
setTimeout(() => this.el.emit("that"), 2000);
},
onEnter: function () {
const scene = this.el.sceneEl.object3D;
const camera = this.el.sceneEl.camera;
const renderer = this.el.sceneEl.renderer;
const render = renderer.render;
const composer = new THREE.EffectComposer(renderer);
//let renderPass = new THREE.RenderPass(scene, camera);
//let outlinePass = new THREE.OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera);
const ssaoPass = new THREE.SSAOPass( scene, camera, window.innerWidth, window.innerHeight );
//composer.addPass(renderPass);
//composer.addPass(outlinePass);
ssaoPass.kernelRadius = 16;
composer.addPass( ssaoPass );
// let objects = [];
// this.el.object3D.traverse(node => {
// if (!node.isMesh) return;
// objects.push(node);
// });
// outlinePass.selectedObjects = objects;
// outlinePass.renderToScreen = true;
// outlinePass.edgeStrength = this.data.strength;
// outlinePass.edgeGlow = this.data.glow;
// outlinePass.visibleEdgeColor.set(this.data.color);
// HACK the AFRAME render method (a bit ugly)
const clock = new THREE.Clock();
this.originalRenderMethod = render;
let calledByComposer = false;
renderer.render = function () {
if (calledByComposer) {
render.apply(renderer, arguments);
} else {
calledByComposer = true;
composer.render(clock.getDelta());
calledByComposer = false;
}
};
},
onLeave: function () {
this.el.sceneEl.renderer.render = this.originalRenderMethod;
},
remove: function () {
this.onLeave();
}
});
I have also created a glitch project which i am sharing here. Please feel free to join and collaborate in my project
Edit link: https://glitch.com/edit/#!/accessible-torpid-partridge
Site link:https://accessible-torpid-partridge.glitch.me
Thanks in advance
The code is correct, all you need is to tweak the exposed SSAOShader uniforms: SSAOPass.kernelRadius, SSAOPass.minDistance, SSAOPass.maxDistance - like in the Three.js example.
Keep in mind - the scale in the example is huge, so the values will need to be different in a default aframe scene.
It's a good idea to be able to dynamically update a component (via setAttribute() if you properly handle updates), so you can see what's going on in realtime. Something like I did here - SSAO in a-frame (also based on Don McCurdys gist.
I've used some basic HTML elements, most threejs examples use dat.GUI - it is made for demo / debug tweaks.

iOS select image from camera roll Cordova

I have a jqm+phonegap application running on cordova 2.9.0 for ios platform.
On android, the following code worked, but isn't working on iOS...
JS:
function getImage() {
navigator.camera.getPicture(uploadPhoto, function(message) {
alert('Get Picture Failed. Please Try Again.');
},{
quality: 50,
destinationType: navigator.camera.DestinationType.FILE_URI,
sourceType: navigator.camera.PictureSourceType.PHOTOLIBRARY
}
);
}
function uploadPhoto(imageURI) {
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=curClub+imageURI.substr(imageURI.lastIndexOf('/')+1);
options.mimeType="image/jpeg";
var params = new Object();
params.value1 = "test";
params.value2 = "param";
params.clubID = curClub ;
options.params = params;
options.chunkedMode = false;
var ft = new FileTransfer();
ft.upload(imageURI, "url", win, fail, options);
}
HTML:
<div data-role = "button" onClick = "getImage();" >Upload Logo</div>
If i test the getImage() function by adding an alert inside, it works, so i know that it is going there. What else am I doing wrong?
Do I need to add any permissions in config.xml?
Or what different code is required to make it work on ios?

How can watch my position when I close my App with Phonegap and jquerymobile

I am using phonegap, jquerymobile the googlemap API to get my current position and to watch my position.
For this, when I lunch my map page, my position is shown with a marker and the marker move when I move.
Even if it works excpeted when I close my App (onPause).
Here is my code (you can tell me how I can perfect it :o) )
$('#home').live("pagebeforeshow", function() {
if($('#googleAPI').length != 0){
navigator.geolocation.getCurrentPosition(function(position){
//showMap('mapHome',position.coords.latitude, position.coords.longitude);// Canvas, lat, long
var latLng = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
// Google Map options
var myOptions = {
zoom: 17,
//zoomControl : 1,
center: latLng,
mapTypeId: google.maps.MapTypeId.ROADMAP////ROADMAP, SATELLITE, HYBRID and TERRAIN
};
// Create the Google Map, set options
Tracking.mapy = new google.maps.Map(document.getElementById('mapHome'), myOptions);
//addMarker(position.coords.latitude,position.coords.longitude);
},
showError,
{
enableHighAccuracy : true,
maximumAge : 2000
//maximumAge:Infinity
});
}
})
$('#home').live("pageshow", function() {
// Place and move the marker regarding to my position and deplacement
if($('#googleAPI').length != 0){
//var track_id = "me";
Tracking.watch_id = navigator.geolocation.watchPosition(
// Success
function(position){
var lat = position.coords.latitude;
var long = position.coords.longitude;
var latLng = new Array();
latLng[0] = lat;
latLng[1] = long;
//Tracking.myCoordinates.push(lat,long);
Tracking.myCoordinates.push(latLng);
addMarker(lat, long);
},
// Error
showError,
{
frequency: 1000
});
console.log('HW : WatchPosition called. Id:' + Tracking.watch_id);
}else{
Alert.show('The map API has not been loaded. Check for connection and try again. (pagebeforeshow)');
}
})
$('#home').live("pagebeforehide", function() {
if($('#googleAPI').length != 0){
//track_id = "me";
// Stop tracking the user
if (Tracking.watch_id != null) {
navigator.geolocation.clearWatch(Tracking.watch_id);
console.log('HW : WatchPosition cancelled Id:' + Tracking.watch_id);
Tracking.watch_id = null;
}
//navigator.geolocation.clearWatch(Tracking.watch_id);
//Tracking.watch_id = null;
Tracking.myCoordinates = new Array();
}else{
Alert.show('The map API has not been loaded. Check for connection and try again. (pagebeforeshide)');
}
});
The problem is when I close my App, because I still need to be alert when I go outside of my geofence. Then, as lomg as I do not stop to watch my position, I need it to be watching even if I close my position or if I lunch another app.
Then I do not know how to do when I called that Phonegap even:
document.addEventListener('pause', onPause, false);
function onPause(){}
Should I simply relunch my watch code with a different watch_id?
Any suggestion?
Many thank and happy new year
I think what you're trying to get at is running a background process using phonegap. The discussion in this link seems to say that it's only possible if you write a plugin to perform that functionality. PhoneGap doesn't have an API to do it out of the box.
Executing javascript in background using phonegap

Openlayers zoom in on cluster

Is it possible to zoom in on cluster on click? I also don't know how to disable cluster popup. I read this question , but still have no idea how to do it.
Here is the code:
<html>
<script src="../ol/OpenLayers.js"></script>
<script>
var map, select;
var lat = 53.507;
var lon = 28.145;
var zoom = 7;
function init() {
map = new OpenLayers.Map("map",
{ maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
numZoomLevels: 19,
maxResolution: 156543.0399,
units: 'm',
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
controls: [
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.PanZoomBar(),
new OpenLayers.Control.ScaleLine(),
new OpenLayers.Control.Permalink('permalink'),
new OpenLayers.Control.Attribution(),
new OpenLayers.Control.MousePosition()
] });
var osm = new OpenLayers.Layer.OSM("OpenStreetMap");
map.addLayer(osm);
var lonLat = new OpenLayers.LonLat(lon, lat).transform(map.displayProjection, map.projection);
if (!map.getCenter()) map.setCenter (lonLat, zoom);
var MyStyle = new OpenLayers.Style({
// 'cursor' : 'pointer',
fillColor : "#336699",
fillOpacity : 0.9,
fontColor: "#000080",
fontFamily: "sans-serif, Arial",
// fontWeight: "bold",
externalGraphic: "atm.png",
graphicWidth: 32,
graphicHeight: 37,
label: "${count}",
labelAlign: "ct",
fontSize: "15px",
});
var layer = new OpenLayers.Layer.Vector("Atm", {
protocol: new OpenLayers.Protocol.HTTP({
url: "atm.txt",
format: new OpenLayers.Format.Text({extractStyles: true}),
params: {
extractAttributes: false,
}
}),
styleMap: MyStyle, <!-- --------------------- style -->
projection: map.displayProjection,
strategies: [
new OpenLayers.Strategy.BBOX({ratio: 1, resFactor: 1.1}),
new OpenLayers.Strategy.Cluster({distance: 50, threshold: 3})
]
});
map.addLayer(layer);
// Interaction; not needed for initial display.
selectControl = new OpenLayers.Control.SelectFeature(layer);
map.addControl(selectControl);
selectControl.activate();
layer.events.on({
'featureselected': onFeatureSelect,
'featureunselected': onFeatureUnselect
});
}
// Needed only for interaction, not for the display.
function onPopupClose(evt) {
// 'this' is the popup.
var feature = this.feature;
if (feature.layer) { // The feature is not destroyed
selectControl.unselect(feature);
} else { // After "moveend" or "refresh" events on POIs layer all
// features have been destroyed by the Strategy.BBOX
this.destroy();
}
}
function onFeatureSelect(evt) {
feature = evt.feature;
popup = new OpenLayers.Popup.FramedCloud("featurePopup",
feature.geometry.getBounds().getCenterLonLat(),
new OpenLayers.Size(100,100),
"<h2>"+feature.attributes.title + "</h2>" +
feature.attributes.description,
null, true, onPopupClose);
feature.popup = popup;
popup.feature = feature;
map.addPopup(popup, true);
}
function onFeatureUnselect(evt) {
feature = evt.feature;
if (feature.popup) {
popup.feature = null;
map.removePopup(feature.popup);
feature.popup.destroy();
feature.popup = null;
}
}
</script>
</head>
<body onload="init()">
<div id="map"></div>
</body>
</html>
Thanks. Your post does not have much context to explain the code sections; please explain your scenario more clearly.
function onFeatureSelect(event) {
if(!event.feature.cluster) // if not cluster
{
// handle your popup code for the individual feature
}
else
{
// fetch the cluster's latlon and set the map center to it and call zoomin function
// which takes you to a one level zoom in and I hope this solves your purpose :)
map.setCenter(event.feature.geometry.getBounds().getCenterLonLat());
map.zoomIn();
}
}
Using the example code in the linked question I would iterate over all features in the cluster to create a BBX, and then zoom into that extent.
var cluster_bounds=new OpenLayers.Bounds();
event.feature.cluster.forEach(function(feature){
clouster_bounds.extend(feature.geometry);
})
map.zoomToExtent(cluster_bounds)
If you really don't know how to disable the popups then remove these functions:
function onFeatureSelect(evt) {
function onFeatureUnselect(evt) {
And replace it with:
function onFeatureSelect(event) {
var cluster_bounds=new OpenLayers.Bounds();
event.feature.cluster.forEach(function(feature){
cluster_bounds.extend(feature.geometry);
});
map.zoomToExtent(cluster_bounds);
}