I want to divide the Google map display into 200 parts , I have this code
bounds = map.getBounds();
southWest = bounds.getSouthWest();
northEast = bounds.getNorthEast();
tileWidth = (northEast.lng() - southWest.lng()) / 10;
tileHeight = (northEast.lat() - southWest.lat()) / 20;
for (x=0; x < 20 ; x++)
{
for (y=0; y < 10 ; y++)
{
var x1 = southWest.lat()+ (tileHeight * x);
var y1 = southWest.lng()+ (tileWidth * y);
var x2 = x1 + tileHeight;
var y2 = y1 + tileWidth;
var tempCell = new GLatLngBounds(new GLatLng(x1, y1), new GLatLng(x2, y2));
}
}
I just cant figure out what is wrong with it...
Any Idea ??
I tried the code you posted - it seems to work just fine. The problem is probably elsewhere in your code. Can you post more details?
It is worthwhile to note, however, that this code will fail in spectacular fashion if the bounds include the international date line. Let us know if this is the problem.
I can't help but notice you use tempCell to hold the result, but what is done after that? do you ever refer to those bounded regions again?
Related
I'm making a mode 7/perspective projection project in Godot. When I run it, it produces the expected effect, displaying a 2d image as if it were a 3d plane.
Code:
func _ready():
map.load("res://map2.png")
perspective.load("res://map2.png")
for px in 1:
self.texture = display
for y in map.get_height():
_y = (y + py - 1)/z
for x in map.get_width():
_x = (x + px)/z
map.lock()
pix = map.get_pixel(_x, _y)
map.unlock()
perspective.lock()
perspective.set_pixel(x, y, pix)
perspective.unlock()
display.create_from_image(perspective)
z += 1
Image:
However, I have a problem. I have the code in the ready function, in a for loop. I want it to be called every frame, but when I increase the number of repeats from one to two, it turns the entire image red. I don't know what's causing this. one guess was that I wasn't locking and unlocking the images properly, but that is most likely not the case. Another guess was that the x and y variables were not resetting each time, but that was also working fine. I don't think the loop itself is the problem, but I have no idea what's wrong.
I struggled to make your code run. I half way gave up, and implemented the logic from my prior answer using lock bits instead. This is the code:
extends Sprite
export(Transform) var matrix:Transform
var sampler:Image
var buffer:Image
var size:Vector2
var center:Vector2
func _ready():
sampler = texture.get_data()
var err = sampler.decompress()
if err != OK:
push_error("Failed to decompress texture")
return
size = Vector2(texture.get_width(), texture.get_height())
center = size * 0.5
buffer = Image.new()
buffer.create(int(size.x), int(size.y), false, Image.FORMAT_RGBA8)
func _process(_delta):
#matrix = matrix.rotated(Vector3.RIGHT, 0.01)
sampler.lock()
buffer.lock()
for y in size.x:
for x in size.y:
var uv:Vector3 = matrix * Vector3(x - center.x, y - center.y, 1.0)
if uv.z <= 0.0:
buffer.set_pixel(x, y, Color.transparent)
continue
var _x = (uv.x / uv.z) + center.x
var _y = (uv.y / uv.z) + center.y
if _x < 0.0 or _x >= size.x or _y < 0.0 or _y >= size.y:
buffer.set_pixel(x, y, Color.transparent)
continue
#buffer.set_pixel(x, y, Color(_x / size.x, y / size.y, 0.0))
buffer.set_pixel(x, y, sampler.get_pixel(_x, _y))
buffer.unlock()
sampler.unlock()
var display = ImageTexture.new()
display.create_from_image(buffer, 0)
self.texture = display
As you can see, I'm exporting a Transfrom to be available on the editor. That is a proper 3D Transform. There is a commented line on _process that does a rotation, try it out.
The sampler Image is a copy of the Texture of the Sprite (the copy is made on _ready). And the buffer Image is where what is to be displayed is constructed.
The code is creating an ImageTexture from buffer and replacing the current texture with it, each frame (on _process). I'm setting flags to 0, because FLAG_REPEAT plus FLAG_FILTER blurred the border to the opposite side of the Sprite.
The vector Vector2 size holds the size of the texture. And the Vector2 Center is the coordinates of the center.
As I said at the start, this is the logic from my prior answer. This line:
vec3 uv = matrix * vec3(UV - 0.5, 1.0);
Is equivalent to (except I'm not scaling the coordinates to the range from 0 to 1):
var uv:Vector3 = matrix * Vector3(x - center.x, y - center.y, 1.0)
Then I had this line:
if (uv.z < 0.0) discard;
Which turned out like this:
if uv.z <= 0.0:
buffer.set_pixel(x, y, Color.transparent)
continue
I'm setting transparent because I do not recreate the buffer, nor clear it before hand.
Finally this line:
COLOR = texture(TEXTURE, (uv.xy / uv.z) + 0.5);
Turned out like this:
var _x = (uv.x / uv.z) + center.x
var _y = (uv.y / uv.z) + center.y
if _x < 0.0 or _x >= size.x or _y < 0.0 or _y >= size.y:
buffer.set_pixel(x, y, Color.transparent)
continue
buffer.set_pixel(x, y, sampler.get_pixel(_x, _y))
As per the result, here is the Godot Icon "rotating in 3D" (not really, but that is the idea):
Please disregard visual artifact due to GIF encoding.
I'm not sure if you want to stay with the logic of my prior answer. However, I believe this one should not be too hard to modify for your needs.
Addendum
I used a Transform because there is no convenient Matrix type available. However, the Transform uses a Matrix internally. See also Transformation matrix.
The Mode 7 formula according to Wikipedia works with a 2 by 2 Matrix, which is simpler that what I have here. However, you are going to need the product of a Matrix and a Vector anyway. You cannot compute the components independently.
This is the formula according to Wikipedia:
r' = M*(r - r_0) + r_0
That is:
var rp = mult(M, r - r_0) + r_0
Where mult would look like this:
func mult(matrix, vector:Vector2) -> Vector2:
var x = vector.x * matrix.a + vector.y * matrix.b
var y = vector.x * matrix.c + vector.y * matrix.d
return Vector2(x, y)
However, as I said, there is no convenient matrix type. If we export a, b, c, and d, we have:
var rp = mult(a, b, c, d, r - r_0) + r_0
And mult looks like this:
func mult(a:float, b:float, c:float, d:float, vector:Vector2) -> Vector2:
var x = vector.x * a + vector.y * b
var y = vector.x * c + vector.y * d
return Vector2(x, y)
We can easily use modify the code to do that. First export a, b, c and d as I said:
export(float) var a:float
export(float) var b:float
export(float) var c:float
export(float) var d:float
And this is _process modified:
func _process(_delta):
sampler.lock()
buffer.lock()
for y in size.x:
for x in size.y:
var rp = mult(a, b, c, d, Vector2(x, y) - center) + center
if rp.x < 0.0 or rp.x >= size.x or rp.y < 0.0 or rp.y >= size.y:
buffer.set_pixel(x, y, Color.transparent)
continue
buffer.set_pixel(x, y, sampler.get_pixel(rp.x, rp.y))
buffer.unlock()
sampler.unlock()
var display = ImageTexture.new()
display.create_from_image(buffer, 6)
self.texture = display
Of course, mult is the one I showed above. I'm assuming here that r_0 is what I called center.
I'm not sure how to interpret a, b, c and d, so here is a = 1, b = 2, c = 3 and d = 4:
I am attempting to find a simple way in SceneKit to calculate the depth of a pixels in SceneKit and LiDAR data from
sceneView.session.currentFrame?.smoothedSceneDepth?.depthMap
Ideally I don't want to use metal shaders. I would prefer find a points in my currentFrame and their corresponding depth map, to get the depth of a points in SceneKit (ideally in world coordinates, not just local to that frustum at that point in time).
Fast performance isn't necessary as it won't be calculated at capture.
I am aware of the Apple project at link, however this is far too complex for my needs.
As a starting point, my code works like this:
guard let depthData = frame.sceneDepth else { return }
let camera = frame.camera
let depthPixelBuffer = depthData.depthMap
let depthHeight = CVPixelBufferGetHeight(depthPixelBuffer)
let depthWidth = CVPixelBufferGetWidth(depthPixelBuffer)
let resizeScale = CGFloat(depthWidth) / CGFloat(CVPixelBufferGetWidth(frame.capturedImage))
let resizedColorImage = frame.capturedImage.toCGImage(scale: resizeScale);
guard let colorData = resizedColorImage.pixelData() else {
fatalError()
}
var intrinsics = camera.intrinsics;
let referenceDimensions = camera.imageResolution;
let ratio = Float(referenceDimensions.width) / Float(depthWidth)
intrinsics.columns.0[0] /= ratio
intrinsics.columns.1[1] /= ratio
intrinsics.columns.2[0] /= ratio
intrinsics.columns.2[1] /= ratio
var points: [SCNVector3] = []
let depthValues = depthPixelBuffer.depthValues()
for vv in 0..<depthHeight {
for uu in 0..<depthWidth {
let z = -depthValues[uu + vv * depthWidth]
let x = Float32(uu) / Float32(depthWidth) * 2.0 - 1.0;
let y = 1.0 - Float32(vv) / Float32(depthHeight) * 2.0;
points.append(SCNVector3(x, y, z))
}
}
The resulting point cloud looks ok, but is severely bent on the Z-axis. I realize this code is also not adjusting for screen orientation either.
Cupertino kindly got back to me with this response on the forums at developer.apple.com:
The unprojection calculation itself is going to be identical, regardless of whether it is done CPU side or GPU side.
CPU side, the calculation would look something like this:
/// Returns a world space position given a point in the camera image, the eye space depth (sampled/read from the corresponding point in the depth image), the inverse camera intrinsics, and the inverse view matrix.
func worldPoint(cameraPoint: SIMD2<Float>, eyeDepth: Float, cameraIntrinsicsInversed: simd_float3x3, viewMatrixInversed: simd_float4x4) -> SIMD3<Float> {
let localPoint = cameraIntrinsicsInversed * simd_float3(cameraPoint, 1) * -eyeDepth
let worldPoint = viewMatrixInversed * simd_float4(localPoint, 1);
return (worldPoint / worldPoint.w)[SIMD3(0,1,2)];
}
Implemented, this looks like
for vv in 0..<depthHeight {
for uu in 0..<depthWidth {
let z = -depthValues[uu + vv * depthWidth]
let viewMatInverted = (sceneView.session.currentFrame?.camera.viewMatrix(for: UIApplication.shared.statusBarOrientation))!.inverse
let worldPoint = worldPoint(cameraPoint: SIMD2(Float(uu), Float(vv)), eyeDepth: z, cameraIntrinsicsInversed: intrinsics.inverse, viewMatrixInversed: viewMatInverted * rotateToARCamera )
points.append(SCNVector3(worldPoint))
}
}
The point cloud is pretty messy, needs confidence worked out, and there are gaps vertically where Int rounding has occurred, but it's a solid start. Missing functions come from the link to the Apple demo project in the question above.
Recently I purchased gamemaker and followed Shaun Spalding's menu tutorial to get set up, but I've come across something that I want to change with the code. In the tutorial the options from the array are positioned so that they are one above the other, however for my game I want them to be right next to each other so that option 1 can be positioned on the left side of the screen, and option 2 on the right side of the screen on the same 'line' (but still able to switch between selecting either).
This is what it looks like currently.
As you can see, they are above each other, when really I want them side by side.
This is the code I have:
'Create' Event:
instruction[0] = "Back";
instruction[1] = "Start Game";
space = 100;
ipos = 0;
'Step' Event:
var move = 0;
move -= max(keyboard_check_pressed(vk_left),keyboard_check_pressed(ord("A")),0);
move += max(keyboard_check_pressed(vk_right),keyboard_check_pressed(ord("D")),0);
if (move != 0)
{
ipos += move;
if (ipos < 0) ipos = array_length_1d(instruction) - 1;
if (ipos > array_length_1d(instruction) - 1) ipos = 0;
}
var push;
push = max(keyboard_check_released(vk_enter),keyboard_check_released(vk_shift),keyboard_check_released(vk_space),0);
if (push == 1) scr_instructions();
'Draw' Event:
draw_set_halign(fa_left);
draw_set_valign(fa_middle);
draw_set_font(fnt_options);
draw_set_color(c_white);
var m;
for (m = 0; m < array_length_1d(instruction); m += 1)
{
draw_text(x + space, y + (m * space),string(instruction[m]))
}
draw_sprite(sprite_index, -1, x + 16, y + ipos * space - 21);
Anyone know what I need to change to get this to work?
Your draw_text seems to increase the y coordinate for each iteration in the loop.
Try to increase x using m instead.
Example:
draw_text(x + (m * space), y + space,string(instruction[m]))
You will likely have to adapt the spacing to get desired look.
Easiest is probably to hard code the coordinates instead of using a loop.
Do the same with draw_sprite.
draw_sprite(sprite_index, -1, x + 16 + ipos * space, y - 21);
So I have a program. And I am trying to simulate tons of moving particles with intricate moment logic that i would not want to have going on the CGP for many reasons. Of course I am then going to draw this all on the GPU.
Now originally I thought that when simulating TONS of particles that GPU delay would be a problem not the CPU. Unfortunately I am running 500 particles at a whopping 6fps :(.
I have tracked the latency down to how I send the vertices to the particle simulator. And not even the buffer creation, simply how I build the arrays. Basically I have arrays I clear every frame, and then go through for each particle in an array of particles and create arrays for each of them. And this leads to around 17500 append calls (with 500 particles). So I need a different way to do this because without building these arrays it runs at 60fps no cpu latency. Most of these append calls call a member of a struct.
Currently each particle is made based off of a class object. And it has things like position and color that are stored in structs. Would it be wroth my while to switch structs to arrays? Or perhaps I should switch everything to arrays? Obviously doing any of that would make things much harder to program. But would it be worth it?
A big problem is that I need each particle to be drawn as a capsule. Which I would make out of two dots and a thick line. Unfortunately OpenGL es 2.0 doesn't support thick lines so I have to draw it with two dots and two triangles :(. As you can see the function "calculateSquare" makes these two triangles based off to the two points. It is also very laggy, however it isn't the only problem, I will try to find a different way later.
What are your thoughts?
Note: According to xcode ram usage is only at 10 mb. However the cpu frame time is 141 ms.
Here is the code BTW:
func buildParticleArrays()
{
lineStrip = []
lineStripColors = []
lineStripsize = []
s_vertes = []
s_color = []
s_size = []
for cparticle in particles
{
let pp = cparticle.lastPosition
let np = cparticle.position
if (cparticle.frozen == true)
{
addPoint(cparticle.position, color: cparticle.color, size: cparticle.size)
}
else
{
let s = cparticle.size / 2.0
//Add point merely adds the data in array format
addPoint(cparticle.position, color: cparticle.color, size: cparticle.size)
addPoint(cparticle.lastPosition, color: cparticle.color, size: cparticle.size)
lineStrip += calculateSquare(pp, pp2: np, size: s)
for var i = 0; i < 6; i++
{
let rgb = hsvtorgb(cparticle.color)
lineStripColors.append(GLfloat(rgb.r))
lineStripColors.append(GLfloat(rgb.g))
lineStripColors.append(GLfloat(rgb.b))
lineStripColors.append(GLfloat(rgb.a))
lineStripsize.append(GLfloat(cparticle.size))
}
}
}
}
func addPoint(theObject: point, color: colorhsv, size: CGFloat)
{
let rgb = hsvtorgb(color)
s_vertes += [GLfloat(theObject.x), GLfloat(theObject.y), GLfloat(theObject.z)]
s_color += [GLfloat(rgb.r), GLfloat(rgb.g), GLfloat(rgb.b), GLfloat(rgb.a)]
s_size.append(GLfloat(size))
}
func calculateSquare(pp1: point, pp2: point, size: CGFloat) -> [GLfloat]
{
let p1 = pp1
var p2 = pp2
var s1 = point()
var s2 = point()
let center = CGPointMake((p1.x + p2.x) / 2.0, (p1.y + p2.y) / 2.0)
var angle:CGFloat = 0
if ((p1.x == p2.x) && (p1.y == p2.y))
{
//They are ontop of eachother
angle = CGFloat(M_PI) / 2.0
p2.x += 0.0001
p2.y += 0.0001
}
else
{
if(p1.x == p2.x)
{
//UH OH x axis is equal
if (p1.y < p2.y)
{
//RESULT: p1 is lower so should be first
s1 = p1
s2 = p2
}
else
{
//RESULT: p2 is lower and should be first
s1 = p2
s2 = p1
}
}
else
{
//We could be all good
if (p1.y == p2.y)
{
//Uh oh y axis is equal
if (p1.x < p2.x)
{
//RESULT: p1 is left so should be first
s1 = p1
s2 = p2
}
else
{
//RESULT: p2 is to the right so should be first
s1 = p2
s2 = p1
}
}
else
{
//Feuf everything is ok
if ((p1.x < p2.x) && (p1.y < p2.y)) //First point is left and below
{
//P1 should be first
s1 = p1
s2 = p2
}
else //First point is right and top
{
//P2 should be first
s1 = p2
s2 = p1
}
}
}
angle = angle2p(s1, p2: s2)
}
if (angle < 0)
{
angle += CGFloat(M_PI) * 2.0
}
let yh = size / 2.0
let distance = dist(p1, p2: p2)
let xh = distance / 2.0
let tl = rotateVector(CGPointMake(-xh, yh), angle: angle) + center
let tr = rotateVector(CGPointMake(xh, yh), angle: angle) + center
let bl = rotateVector(CGPointMake(-xh, -yh), angle: angle) + center
let br = rotateVector(CGPointMake(xh, -yh), angle: angle) + center
let c1:[GLfloat] = [GLfloat(bl.x), GLfloat(bl.y), 0]
let c2:[GLfloat] = [GLfloat(tl.x), GLfloat(tl.y), 0]
let c3:[GLfloat] = [GLfloat(br.x), GLfloat(br.y), 0]
let c4:[GLfloat] = [GLfloat(tr.x), GLfloat(tr.y), 0]
let part1 = c1 + c2 + c3
let part2 = c2 + c3 + c4
return part1 + part2
}
Do you really need all particles in system RAM? e.g. for some physics collision calculation in relation to other objects in the scene? Otherwise you could just create one particle, send it to the GPU and do the calculations in a GPU shader.
Ok so after hours of tweaking the code for small bits in efficiency I have it running 500 particles at a fps of 28 which looks pretty smooth! I still have some ways to go. The best piece of advice had to do with allocating memory instead appending it. That saved tons of problems.
Special thanks to #Darko, #Marcelo_Cantos for coming up with the ideas that would ultimately optimize my code!
I am using SharpenLines3d in my projects to draw lines to connect objects in my Viewport3D. Problem is, when I'm adding points to ScreenSpaceLined3D, the program crashes, like this:
It crashes not in these lines when I'm adding points to ScreenSpaceLines3D, so it's something inside the library, I guess.
Here is my code:
for (int i = 0; i < MAX + 1; i++)
{
...
var bounds = this.points[i].Bounds;
var x = bounds.X + (bounds.SizeX / 2);
var y = bounds.Y + (bounds.SizeY / 2);
var z = bounds.Z + (bounds.SizeZ / 2);
coords[i] = new Point3D(x, y, z);
for (int j = 0; j < i; j++)
{
lines[i, j] = new ScreenSpaceLines3D();
lines[i, j].Color = Colors.Red;
lines[i, j].Thickness = 6;
lines[i, j].Points.Add(coords[i]);
lines[i, j].Points.Add(coords[j]);
}
}
I am sure that I am not passing null as argument to Add function (I tried to replace my Add line with this: lines[i, j].Points.Add(new Point3D(0, 0, 0));, and it still didn't work).
And I commented out all code that uses lines variable, so this variable is used only when a bunch of new ScreenSpaceLines3D is created. But my program crashes not on initializing.
When I comment out 2 strings of code where I'm adding points to lines, program starts working okay, but when I'm adding it again, result is as in screenshot.
How to deal with it?
UPD: Adding MainViewPort.Children.Add(lines[i, j]); after adding points made it work. It is getting more and more strage.
Somehow adding MainViewPort.Children.Add(lines[i, j]); solved the problem. Without it, program crashes, but with it, everything works okay.
I don't know how this works but this is it.