Phaser 3, Uncaught TypeError: this.cameras.main.setMask is not a function when trying to apply mask to camera - mask

I am trying to apply a 'fog of war' affect to my game and require the use of a mask over my camera. i have researched and followed the tutorial here - Phaser demo sandbox - and after trying to do it myself i resulted in copying it. this still returns the same error and claims it cannot be applied. if i substiute this.cameras.main with player the game works but doesnt give desired outcome.
const maskImage = this.make.image({
x: 400,
y: 300,
key: 'mask',
add: false
});
const mask = maskImage.createBitmapMask();
this.cameras.main.setMask(mask);

Related

Error: Exported bands must have compatible data types; found inconsistent types: Float32 and Byte

I'm new to use Google Earth Engine and trying to export satellite image dataset to my google drive folder. But I'm getting the error below.
Error: Exported bands must have compatible data types; found inconsistent types: Float32 and Byte.
This is my code.
var dataset = ee.ImageCollection('FIRMS')
.filterDate('2021-04-01', '2021-11-10')
.filterBounds(roi)
.sort('CLOUD_COVER')
.first()
var fires = dataset.select('T21');
var firesVis = {
min: 325.0,
max: 400.0
};
Map.addLayer(fires.clip(roi), firesVis, 'California Fires 2021');
Map.centerObject(roi,15);
// Export data to google drive
Export.image.toDrive({
image : fires,
description : 'California_wildfires_2021',
scale : 30,
region : roi,
maxPixels : 1e13
})
Any help is appreciated.
Also please let me know how to convert the tiff files to images(png/jpeg/jpg).
Now, add any shapefile or roi and try it.
In the middle of the code their I had used max(),there you can use mean(), median() and min() etc.,
here is the code:
var dataset = ee.ImageCollection('FIRMS').filter(
ee.Filter.date('2021-04-01', '2021-11-10'));
var fires = dataset.select('T21').max().clip(shp);
var firesVis = {
min: 325.0,
max: 400.0,
palette: ['red', 'orange', 'yellow'],
};
Map.centerObject(shp, 6);
Map.addLayer(fires, firesVis, 'Fires');
// Export data to google drive
Export.image.toDrive({
image : fires,
description : 'California_wildfires_2021',
scale : 1000,
region : shp,
maxPixels : 1e13
});

How can I merge geometries in A-Frame without losing material information?

I have a large set of block objects using a custom geometry, that I am hoping to merge into a smaller number of larger geometries, as I believe this will reduce rendering costs.
I have been following guidance here: https://aframe.io/docs/1.2.0/introduction/best-practices.html#performance which has led me to the geometry-merger component here:
https://github.com/supermedium/superframe/tree/master/components/geometry-merger/
The A-Frame docs say:
"You can use geometry-merger and then make use a three.js material with vertex colors enabled. three.js geometries keep data such as color, uvs per vertex."
The geometry-merger component also says:
"Useful if using vertex or face coloring as individual geometries' colors can still be manipulated individually since this component keeps a faceIndex and vertexIndex."
However I have a couple of problems.
If I set vertexColors on my material (as suggested by the A-Frame docs), then this ruins the appearance of my blocks.
Whether or not I set vertexColors on my material, all material information seems to be lost when the geometries are merged, and everything just ends up white.
See this glitch for a demonstration of both problems.
https://tundra-mercurial-garden.glitch.me/
My suspicion is that the A-Frame geometry-merger component just won't do what I need here, and I need to implement something myself using the underlying three.js functions.
Is that right, or is there a way that I could make this work using geometry-merger?
For the vertexColors to work, you need to have your vertices coloured :)
More specifically - the BufferGeometry expects an array of rgb values for each vertex - which will be used as color for the material.
In this bit of code:
var geometry = new THREE.BoxGeometry();
var mat = new THREE.MeshStandardMaterial({color: 0xffffff, vertexColors: THREE.FaceColors});
var mesh = new THREE.Mesh(geometry, mat);
The mesh will be be black unless the geometry contains information about the vertex colors:
// create a color attribute in the geometry
geometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(vertices_count), 3));
// grab the array
const colors = this.geometry.attributes.color.array;
// fill the array with rgb values
const faceColor = new THREE.Color(color_hex);
for (var i = 0; i < vertices_count / 3; i += 3) {
colors[i + 0] = faceColor.r; // lol +0
colors[i + 1] = faceColor.g;
colors[i + 2] = faceColor.b;
}
// tell the geometry to update the color attribute
geometry.attributes.color.needsUpdate = true;
I can't make the buffer-geometry-merger component work for some reason, but It's core seems to be valid:
AFRAME.registerComponent("merger", {
init: function() {
// replace with an event where all child entities are ready
setTimeout(this.mergeChildren.bind(this), 500);
},
mergeChildren: function() {
const geometries = [];
// traverse the child and store all geometries.
this.el.object3D.traverse(node => {
if (node.type === "Mesh") {
const geometry = node.geometry.clone();
geometry.applyMatrix4(node.parent.matrix);
geometries.push(geometry)
// dispose the merged meshes
node.parent.remove(node);
node.geometry.dispose();
node.material.dispose();
}
});
// create a mesh from the "merged" geometry
const mergedGeo = THREE.BufferGeometryUtils.mergeBufferGeometries(geometries);
const mergedMaterial = new THREE.MeshStandardMaterial({color: 0xffffff, roughness: 0.3, vertexColors: THREE.FaceColors});
const mergedMesh = new THREE.Mesh(mergedGeo, mergedMaterial);
this.el.object3D.add(mergedMesh)
}
})
You can check it out in this glitch. There is also an example on using the vertex colors here (source).
I agree it sounds like you need to consider other solutions. Here are two different instances of instancing with A-Frame:
https://github.com/takahirox/aframe-instancing
https://github.com/EX3D/aframe-InstancedMesh
Neither are perfect or even fully finished, but can hopefully get you started as a guide.
Although my original question was about geometry merging, I now believe that Instanced Meshes were a better solution in this case.
Based on this suggestion I implemented this new A-Frame Component:
https://github.com/diarmidmackenzie/instanced-mesh
This glitch shows the scene from the original glitch being rendered with just 19 calls using this component. That compares pretty well with > 200 calls that would have been required if every object were rendered individually.
https://dull-stump-psychology.glitch.me/
A key limitation is that I was not able to use a single mesh for all the different block colors, but had to use one mesh per color (7 meshes total).
InstancedMesh can support different colored elements, but each element must have a single color, whereas the elements in this scene had 2 colors each (black frame + face color).

Google Earth Engine video export error (a.element.map is not a function)

I'm trying to export a time-lapse here but got a weird error:
Error Creating or Submitting Task
a.element.map is not a function
I want to keep the visParams on my exported video by visualize() which I'm not sure is the right way to do so or not. do you have any suggestions for it?
var l8 = ee.ImageCollection("LANDSAT/LC08/C01/T1_TOA"),
region = ee.Geometry.Polygon(
[[[44.76385083079123, 38.28074335406828],
[44.76385083079123, 37.1334667575582],
[46.08221020579123, 37.1334667575582],
[46.08221020579123, 38.28074335406828]]], null, false),
params = {"opacity":1,"bands":["B4","B3","B2"],"min":0.07630298537191671,"max":0.3954072752450793,"gamma":1.356};
var collection = l8.filterBounds(region)
.filterMetadata('CLOUD_COVER', 'LESS_THAN', 30);
.filterDate('1999-01-01', '2020-01-01');
var l8med = collection.median();
Map.addLayer(collection, params, 'Layer');
print(collection.size());
var newimg = l8med.visualize(params);
Export.video.toDrive({
collection: newimg,
description: 'a1',
dimensions: 720,
framesPerSecond: 12,
folder: "GEE",
maxFrames: 100000,
region: region
});
You made a single image out of the collection using .median() and then tried to export that, so it can't work — there's no time series to make a video out of, after that.
You do need .visualize() but you need to do it for each image:
Export.video.toDrive({
collection: collection.map(function (image) { return image.visualize(params); }),
...

How to increase resolution of exported image in Google Earth Engine?

I have some code to export an LS8 image to Drive using GEE. Somehow, the resolution of the image seems to be lower (larger pixels) than what I am able to see on the browser. How can I increase the resolution? This is the code I´ve been using, with two different options.
I attempted to use .resample() as a solution but it produced a single band image that did not look good.
geometry2 = /* color: #57d64b */ee.Geometry.Polygon(
[[[-78.2812086867645, 2.3386717366200585],
[-77.56984394067075, 2.3729749945579948],
[-77.72227924340513, 2.776314152654142],
[-78.20842426293638, 2.725560942159387]]]);
function maskL8sr(image)
{
// Bits 3 and 5 are cloud shadow and cloud, respectively.
var cloudShadowBitMask = ee.Number(2).pow(3).int();
var cloudsBitMask = ee.Number(2).pow(5).int();
// Get the pixel QA band.
var qa = image.select('pixel_qa');
// Both flags should be set to zero, indicating clear conditions.
var mask = qa.bitwiseAnd(cloudShadowBitMask).eq(0)
.and(qa.bitwiseAnd(cloudsBitMask).eq(0));
// Return the masked image, scaled to TOA reflectance, without the QA bands.
return image.updateMask(mask).divide(10000)
.select("B[0-9]*")
.copyProperties(image, ["system:time_start"]);
}
// Map the function over one year of data.
var collection = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
.filterDate('2016-04-01', '2018-7-31')
.map(maskL8sr)
var composite = collection.median();
var VIS = {bands: ['B5', 'B6', 'B4'], min: 0, max: 0.47};
// Display the results.
Map.addLayer(composite,VIS ,"compt2");
var params ={
crs: 'EPSG:4326',
maxPixels: 1e12,
region:geometry2
}
Export.image(composite,'Guapi',params);
Export.image.toDrive({
image: composite,
description: 'Guapi',
scale: 30,
region: geometry2,
maxPixels: 1000000000
});

Matter.js Gravity Point

Is it possible to create a single gravity / force point in matter.js that is at the center of x/y coordinates?
I have managed to do it with d3.js but wanted to enquire about matter.js as it has the ability to use multiple polyshapes.
http://bl.ocks.org/mbostock/1021841
The illustrious answer has arisen:
not sure if there is any interest in this. I'm a fan of what you have created. In my latest project, I used matter-js but I needed elements to gravitate to a specific point, rather than into a general direction. That was very easily accomplished. I was wondering if you are interested in that feature as well, it would not break anything.
All one has to do is setting engine.world.gravity.isPoint = true and then the gravity vector is used as point, rather than a direction. One might set:
engine.world.gravity.x = 355;
engine.world.gravity.y = 125;
engine.world.gravity.isPoint = true;
and all objects will gravitate to that point.
If this is not within the scope of this engine, I understand. Either way, thanks for the great work.
You can do this with the matter-attractors plugin. Here's their basic example:
Matter.use(
'matter-attractors' // PLUGIN_NAME
);
var Engine = Matter.Engine,
Events = Matter.Events,
Runner = Matter.Runner,
Render = Matter.Render,
World = Matter.World,
Body = Matter.Body,
Mouse = Matter.Mouse,
Common = Matter.Common,
Bodies = Matter.Bodies;
// create engine
var engine = Engine.create();
// create renderer
var render = Render.create({
element: document.body,
engine: engine,
options: {
width: Math.min(document.documentElement.clientWidth, 1024),
height: Math.min(document.documentElement.clientHeight, 1024),
wireframes: false
}
});
// create runner
var runner = Runner.create();
Runner.run(runner, engine);
Render.run(render);
// create demo scene
var world = engine.world;
world.gravity.scale = 0;
// create a body with an attractor
var attractiveBody = Bodies.circle(
render.options.width / 2,
render.options.height / 2,
50,
{
isStatic: true,
// example of an attractor function that
// returns a force vector that applies to bodyB
plugin: {
attractors: [
function(bodyA, bodyB) {
return {
x: (bodyA.position.x - bodyB.position.x) * 1e-6,
y: (bodyA.position.y - bodyB.position.y) * 1e-6,
};
}
]
}
});
World.add(world, attractiveBody);
// add some bodies that to be attracted
for (var i = 0; i < 150; i += 1) {
var body = Bodies.polygon(
Common.random(0, render.options.width),
Common.random(0, render.options.height),
Common.random(1, 5),
Common.random() > 0.9 ? Common.random(15, 25) : Common.random(5, 10)
);
World.add(world, body);
}
// add mouse control
var mouse = Mouse.create(render.canvas);
Events.on(engine, 'afterUpdate', function() {
if (!mouse.position.x) {
return;
}
// smoothly move the attractor body towards the mouse
Body.translate(attractiveBody, {
x: (mouse.position.x - attractiveBody.position.x) * 0.25,
y: (mouse.position.y - attractiveBody.position.y) * 0.25
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.12.0/matter.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/matter-attractors#0.1.6/build/matter-attractors.min.js"></script>
Historical note: the "gravity point" functionality was proposed as a feature in MJS as PR #132 but it was closed, with the author of MJS (liabru) offering the matter-attractors plugin as an alternate. At the time of writing, this answer misleadingly seems to indicate that functionality from the PR was in fact merged.
Unfortunately, the attractors library is 6 years outdated at the time of writing and raises a warning when using a newer version of MJS than 0.12.0. From discussion in issue #11, it sounds like it's OK to ignore the warning and use this plugin with, for example, 0.18.0. Here's the warning:
matter-js: Plugin.use: matter-attractors#0.1.4 is for matter-js#^0.12.0 but installed on matter-js#0.18.0.
Behavior seemed fine on cursory glance, but I'll keep 0.12.0 in the above example to silence it anyway. If you do update to a recent version, note that Matter.World is deprecated and should be replaced with Matter.Composite and engine.gravity.

Resources