Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add: seoul map import capability #92

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

minostauros
Copy link

@minostauros minostauros commented Oct 1, 2020

Importing from https://smap.seoul.go.kr/

#87

seoul map shares strategy 7 with Google Maps

Tested on Google Chrome 85.0.4183.121 (64bit), RendorDoc 1.9, RTX 3090

@eliemichel
Copy link
Owner

Nice job! :) You're the first one to add a new map source ;) It must mean that despite all it starts to get readable. I'm having trouble with the global transform:

etire

It is not only the scale, there is some skewing in the matrices. I had a bit of a similar issue with maps.cz, yet unresolved. Reading the vertex shader, it looks like _f is also contain the projection matrix, while what is used for Google Maps is only the modelView matrix, so it is orthogonal.

(RD1.9, GTX 1070)

@minostauros
Copy link
Author

Didn't notice the skew as I tested with a few number buildings. Thanks for your quick review.
So the postMatrix for maps.cz is a kind of heuristic solution for such issue? What does it do?
As said, I'm not that fluent with graphics, so my guess is projection matrix is already multiplied and _f cannot be decomposed.

@eliemichel
Copy link
Owner

Well the postMatrix is a dirty hack that I'm neither proud nor happy with. Yes _f is premultiplied and there is mathematically no unique way of decomposing it, but 1. finding one plausible decomposition should be enough, as long as our _f = proj * view decomposition is such that view is a valid transform matrix, and 2. maybe we can use the important number of matrices _f_i = proj * view_i to find the constant projective part.

Another approach would be to notice that the website uses the https://openlayers.org/ (so do maps.cz and namur.be maps I believe) and extract info from their code. For instance, it seems they are using the default fov of 62°. Near and far planes are a bit more complicated to determine though as they depend on lods.

@minostauros
Copy link
Author

minostauros commented Oct 2, 2020

There are other constants that I thought useless for building the scene, which I excluded with if len(unpacked) < 1 or len(unpacked[0]) < 3: (length of positions). Those excluded stuff contain empty textures and positions are not 4-dim but 2-dim.

Worth to note, _d is consistent thoughout all captures, and _i is consistent within each capture.
And _h perhaps seems to be related to the screen resolution (using 4096x2160 display).

For example, from capture 1:

{"$Globals": 
{"_d": [0.0, 1.0, 0.0, 0.0, 0.007843137718737125, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
"_h": [3380.0, 0.0, 1.0, 64.0, 4095.0, 64.0, 64.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
"_i": [-128.86721801757812, 146.50613403320312, 3.7172875217708016e-15, 3.715873823781834e-15, 69.3901138305664, 272.08251953125, 6.903526466711099e-15, 6.900901511607558e-15, 0.0, 1.4782794866352394e-16, -1.0003803968429565, -1.0, 239.34097290039062, 177.24179077148438, 451.1508483886719, 460.20159912109375], 
"_j": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
"_k": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
"_l": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]}, 
"DrawCall": {"topology": "TRIANGLE_STRIP", "type": "SeoulMap"}}

and from capture 2:

{"$Globals": 
{"_d": [0.0, 1.0, 0.0, 0.0, 0.007843137718737125, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
"_h": [2470.0, 390.0, 1.0, 64.0, 4095.0, 64.0, 64.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
"_i": [-37.10361862182617, 130.9170684814453, 3.3215295883745957e-15, 3.320484349717684e-15, 59.193946838378906, 82.06069946289062, 2.0819826321538367e-15, 2.0813274521691355e-15, 0.0, 1.4782794866352394e-16, -1.0003148317337036, -1.0, -264.4698486328125, -209.93690490722656, 308.6745910644531, 314.89434814453125], 
"_j": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
"_k": [0.0, 0.0, 0.0, 0.0, 975.0, 357.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1170.0, 389.0, 2.0, 1.0], 
"_l": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]}, 
"DrawCall": {"topology": "TRIANGLE_STRIP", "type": "SeoulMap"}}

Will do some investigation with those. Just FYI, I attach captured constants in text format.
capture1.txt
capture2.txt

@eliemichel
Copy link
Owner

Interesting, those extra uniform seem to be present only for the ground planes, not for the building meshes, and in that case it looks like _i is the equivalent of _f. The 64 in _h may well be the camera fov angle in degrees. _h varies among blocks, and so does _k.

My best bet would be to use some least square regression on all matrices to extract the projection matrix.

@minostauros
Copy link
Author

minostauros commented Oct 2, 2020

And some more info from smap using javscript console using chrome devtools. Seems like fov is 45 * PI / 180 = 0.785?. I could manipulate the fov using application.mainMap().getView().setFov()

>>> application.mainMap().getView().getFov()
0.7853981633974483 // 45 * PI / 180
>>> application.mainMap().s.src.far // far and near changes with zoom in/out
66516.65499085707
>>> application.mainMap().s.src.near
6.046914858777795
>>> application.mainMap().s.src.qc // changes when window size changes
(4) [1920, 922, 0, 0]

The aspect ratio should be 1920:922 then.

@minostauros
Copy link
Author

minostauros commented Oct 3, 2020

Okay there was some progress.

  1. postMatrix = Matrix.Scale(3, 4, Vector((1.0, 0., 0.))) and refMatrix = Matrix.Rotation(-pi, 4, 'Z') @ matrix.inverted() are wrong and should be removed, and refMatrix must be specified only to be used for Google Maps as it contains matrix.inverted().
  2. projection matrix can be extracted from website with the following, by typing into javascript console of developer tools:
function rdoC(a,b,c,d,e,f,g,h,k,m,n,p,q,r,t,u,v){a[0]=b;a[1]=c;a[2]=d;a[3]=e;a[4]=f;a[5]=g;a[6]=h;a[7]=k;a[8]=m;a[9]=n;a[10]=p;a[11]=q;a[12]=r;a[13]=t;a[14]=u;a[15]=v;return a}function rdoz(){var a=Array(16);rdoC(a,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);return a}function rdrz(a,b,c,d,e){var f=b/2;b=e-d;var g=Math.sin(f);if(!b||!g||!c)return a;f=Math.cos(f)/g;return rdoC(a,f/c,0,0,0,0,f,0,0,0,0,-(e+d)/b,-1,0,0,-(2*d*e)/b,0)}pj=rdoz();
rdrz(pj,application.mainMap().s.src.fov,application.mainMap().s.src.jd,application.mainMap().s.src.near,application.mainMap().s.src.far);

the matrix changes when right button is used, so the user should be careful. Also the window size must be retained. But at least the right button isn't used and window size stays the same, the user can continously capture the maps. Example:

화면 캡처 2020-10-04 011554

  1. I could get clean modelview matrix using the projection matrix like:
extracted_projection_matrix_list = [1.1643550826861904, 0, 0, 0, 0, 2.414213562373095, 0, 0, 0, 0, -1.0004811657628294, -1, 0, 0, -14.763227768722993, 0]
matrix = makeMatrix(extracted_projection_matrix_list).inverted() @ makeMatrix(globUniforms['_f'])
print(matrix)

화면 캡처 2020-10-04 011728

  1. results show correct center, scale, and shapes:
    화면 캡처 2020-10-04 011906

Here are some concerns:

  • buildings' Z values seems to be highly negative like -1200m
  • how to get additional input from user

any suggestions?

@eliemichel
Copy link
Owner

Congrats for this retro-engineering.
The workflow for getting this additional user data would be a bit cumbersome anyway, I would suggest either:

  • Dirty but pragmatic: Add a string input to the import operator (here) and point the user to the documentation for more details and to find the snippet to paste in the js inspector.

  • Cleaner but longer to write and we likely don't need that much: Create a panel that explains the steps to follow, with a button that'll put in the user's clipboard the code snippet, a string field to paste the result etc.

@sk9288go
Copy link

sk9288go commented Apr 1, 2021

Hi minostauros! 한국분을 만나서 너무나 반갑습니다! ㅠㅠ
I was also trying with smap but I just couldn't figure out how to apply your script to the program. I tried many times using different versions of blender and importer but I was only able to work with Blender 2.82 and 0.3.3 of the importer. I tried copying your python script inside the Addon folder (where they are installed) just manually but once I paste not even just importing google map's rdc won't work. Is it possible to share step by step application of the script for smap?

@minostauros
Copy link
Author

@sk9288go 안녕하세요 :)
I kinda stopped working on this as SamScene3D started selling scenery for Seoul ( https://samscene.com/products/seoul-city-wow-for-msfs ).
The whole process for smap is currently fully manual, but as I remember the steps are not too deviated from the original guide.

@LiorArmiev
Copy link

Hi,
I try to do the same process for Israel with a 3D mapping existing for Jerusalem 3D Map
can I have you help with this project, please?

@ahj4119
Copy link

ahj4119 commented Sep 22, 2021

HI! I have done this spring, but now it doesn't run with this error message. Can you tell me what I should modify?
Traceback (most recent call last):
File "C:\Users\samsung\AppData\Roaming\Blender Foundation\Blender\2.90\scripts\addons\MapsModelsImporter\operators.py", line 54, in execute
importCapture(context, self.filepath, self.max_blocks, pref)
File "C:\Users\samsung\AppData\Roaming\Blender Foundation\Blender\2.90\scripts\addons\MapsModelsImporter\google_maps.py", line 280, in importCapture
filesToBlender(context, prefix, max_blocks)
File "C:\Users\samsung\AppData\Roaming\Blender Foundation\Blender\2.90\scripts\addons\MapsModelsImporter\google_maps.py", line 250, in filesToBlender
uvs = [ [ (u + ou) * su, (v + ov) * sv ] for u, v in uvs ]
File "C:\Users\samsung\AppData\Roaming\Blender Foundation\Blender\2.90\scripts\addons\MapsModelsImporter\google_maps.py", line 250, in
uvs = [ [ (u + ou) * su, (v + ov) * sv ] for u, v in uvs ]
ValueError: not enough values to unpack (expected 2, got 1)

location: :-1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants