From 48d9fa43316099fb47138f72ea618dc731278c9c Mon Sep 17 00:00:00 2001 From: seungmi Date: Thu, 20 Jan 2022 21:54:32 +0900 Subject: [PATCH] terrarin modeling import (including height value) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 지형 모델링 추가 (지형 높이 반영) --- google_maps.py | 52 +++++------------------------------- google_maps_rd.py | 67 ++++++++++++++--------------------------------- 2 files changed, 25 insertions(+), 94 deletions(-) diff --git a/google_maps.py b/google_maps.py index 9967469..74baf4f 100644 --- a/google_maps.py +++ b/google_maps.py @@ -89,38 +89,7 @@ def extractUniforms(constants, refMatrix): # Extract constants, which have different names depending on the browser/GPU driver globUniforms = constants['$Globals'] postMatrix = None - if '_w' in globUniforms and '_s' in globUniforms: - [ou, ov, su, sv] = globUniforms['_w'] - ov -= 1.0 / sv - sv = -sv - uvOffsetScale = [ou, ov, su, sv] - matrix = makeMatrix(globUniforms['_s']) - elif 'webgl_fa7f624db8ab37d1' in globUniforms and 'webgl_3c7b7f37a9bd4c1d' in globUniforms: - uvOffsetScale = globUniforms['webgl_fa7f624db8ab37d1'] - matrix = makeMatrix(globUniforms['webgl_3c7b7f37a9bd4c1d']) - elif '_webgl_fa7f624db8ab37d1' in globUniforms and '_webgl_3c7b7f37a9bd4c1d' in globUniforms: - [ou, ov, su, sv] = globUniforms['_webgl_fa7f624db8ab37d1'] - ov -= 1.0 / sv - sv = -sv - uvOffsetScale = [ou, ov, su, sv] - matrix = makeMatrix(globUniforms['_webgl_3c7b7f37a9bd4c1d']) - elif '_uMeshToWorldMatrix' in globUniforms: - # Google Earth - uvOffsetScale = [0, -1, 1, -1] - matrix = makeMatrix(globUniforms['_uMeshToWorldMatrix']) - matrix[3] = [0, 0, 0, 1] - #matrix = makeMatrix(globUniforms['_uModelviewMatrix']) @ matrix - elif '_uMV' in globUniforms: - # Mapy CZ - uvOffsetScale = [0, -1, 1, -1] - matrix = makeMatrix(globUniforms['_uMV']) - postMatrix = Matrix( - ((0.682889997959137, 0.20221230387687683, 0.7019768357276917, -0.06431722640991211), - (0.07228320091962814, 0.9375065565109253, -0.3403771221637726, -0.11041564494371414), - (-0.7269363403320312, 0.28318125009536743, 0.6255972981452942, -1.349690556526184), - (0.0, 0.0, 0.0, 1.0)) - ) @ Matrix.Scale(500, 4) - elif '_i' in globUniforms: + if '_i' in globUniforms: # Google Chrome 85.0.4183.121 (64bit), RendorDoc 1.9, RTX 3090, https://smap.seoul.go.kr/ uvOffsetScale = [0, 0, 1, 1] matrix = makeMatrix(globUniforms['_i']) @@ -141,12 +110,8 @@ def extractUniforms(constants, refMatrix): return None, None, None if refMatrix is None: - if '_i' in globUniforms or '_f' in globUniforms: - # Rotate around Z, upside down for SMAP - refMatrix = Matrix.Rotation(-pi, 4, 'Z') @ matrix.inverted() - else: - # Rotate around Y because Google Maps uses X as up axis - refMatrix = Matrix.Rotation(-pi/2, 4, 'Y') @ matrix.inverted() + # Rotate around Z, upside down for SMAP + refMatrix = Matrix.Rotation(-pi, 4, 'Z') @ matrix.inverted() matrix = refMatrix @ matrix @@ -241,20 +206,15 @@ def filesToBlender(context, prefix, max_blocks=200): else: tris = [ [ indices[3*i+j] for j in range(3) ] for i in range(n//3) ] - if constants["DrawCall"]["type"] == 'Google Maps': - verts = [ [ p[0] * 256.0, p[1] * 256.0, p[2] * 256.0 ] for p in positions ] - else: - verts = [ [ p[0], p[1], p[2] ] for p in positions ] + verts = [ [ p[0], p[1], p[2] ] for p in positions ] [ou, ov, su, sv] = uvOffsetScale if uvs and len(uvs[0]) > 2: print(f"uvs[0][2] = {uvs[0][2]}") uvs = [u[:2] for u in uvs] - if constants["DrawCall"]["type"] == 'Google Maps': - uvs = [ [ (floor(u * 65535.0 + 0.5) + ou) * su, (floor(v * 65535.0 + 0.5) + ov) * sv ] for u, v in uvs ] - else: - uvs = [ [ (u + ou) * su, (v + ov) * sv ] for u, v in uvs ] + uvs = [ [ (u + ou) * su, (v + ov) * sv ] for u, v in uvs ] + if len(indices) == 0: continue diff --git a/google_maps_rd.py b/google_maps_rd.py index f871481..9528d4b 100644 --- a/google_maps_rd.py +++ b/google_maps_rd.py @@ -115,43 +115,11 @@ def extractRelevantCalls(self, drawcalls, _strategy=0): last_call = "glDrawArrays(4)" drawcall_prefix = "glDrawElements" min_drawcall = 0 - capture_type = "Google Maps" + capture_type = "SMAP" if _strategy == 0: - first_call = "glClear(Color = <0.000000, 0.000000, 0.000000, 1.000000>, Depth = <1.000000>)" - elif _strategy == 1: - first_call = "glClear(Color = <0.000000, 0.000000, 0.000000, 1.000000>, Depth = <1.000000>, Stencil = <0x00>)" - elif _strategy == 2: - first_call = "glClear(Color = <0.000000, 0.000000, 0.000000, 1.000000>, Depth = <0.000000>)" - elif _strategy == 3: - first_call = "glClear(Color = <0.000000, 0.000000, 0.000000, 1.000000>, Depth = <0.000000>, Stencil = <0x00>)" - elif _strategy == 4: - first_call = "" - last_call = "ClearDepthStencilView" - drawcall_prefix = "DrawIndexed" - capture_type = "Mapy CZ" - elif _strategy == 5: - # With Google Earth there are two batches of DrawIndexed calls, we are interested in the second one - first_call = "DrawIndexed" - last_call = "" - drawcall_prefix = "DrawIndexed" - capture_type = "Google Earth" - skipped_drawcalls, min_drawcall = self.findDrawcallBatch(drawcalls, first_call, drawcall_prefix, last_call) - if not skipped_drawcalls or not self.hasUniform(skipped_drawcalls[0], "_uProjModelviewMatrix"): - first_call = "INVALID CASE, SKIP ME" - elif _strategy == 6: - # Actually sometimes there's only one batch - first_call = "DrawIndexed" - last_call = "" - drawcall_prefix = "DrawIndexed" - capture_type = "Google Earth (single)" - elif _strategy == 7: first_call = "ClearRenderTargetView(0.000000, 0.000000, 0.000000" last_call = "Draw(4)" drawcall_prefix = "DrawIndexed" - elif _strategy == 8: - first_call = "" # Try from the beginning on - last_call = "Draw(4)" - drawcall_prefix = "DrawIndexed" else: print("Error: Could not find the beginning of the relevant 3D draw calls") return [], "none" @@ -166,15 +134,6 @@ def extractRelevantCalls(self, drawcalls, _strategy=0): if not relevant_drawcalls: return self.extractRelevantCalls(drawcalls, _strategy=_strategy+1) - if capture_type == "Mapy CZ" and not self.hasUniform(relevant_drawcalls[0], "_uMV"): - return self.extractRelevantCalls(drawcalls, _strategy=_strategy+1) - - if capture_type == "Google Earth (single)": - if not self.hasUniform(relevant_drawcalls[0], "_uMeshToWorldMatrix"): - return self.extractRelevantCalls(drawcalls, _strategy=_strategy+1) - else: - capture_type = "Google Earth" - return relevant_drawcalls, capture_type def run(self): @@ -198,7 +157,7 @@ def run(self): vbs = state.GetVBuffers() attrs = state.GetVertexInputs() meshes = [makeMeshData(attr, ib, vbs, draw) for attr in attrs] - + constants = self.getVertexShaderConstants(draw, state=state) try: if len(meshes)<2: @@ -212,8 +171,21 @@ def run(self): with open("{}{:05d}-indices.bin".format(FILEPREFIX, drawcallId), 'wb') as file: pickle.dump(indices, file) unpacked = m.fetchData(controller) + + bindpoints_vs = state.GetBindpointMapping(rd.ShaderStage.Vertex) + texture_bind_vs = bindpoints_vs.samplers[0].bind + resources_vs = state.GetReadOnlyResources(rd.ShaderStage.Vertex) + rid_vs = resources_vs[texture_bind_vs].resources[0].resourceId + sr = rd.Subresource() + sr.mip=0 for i in range(len(unpacked)): - unpacked[i]=(unpacked[i][0]/64, 1-unpacked[i][1]/64, 0, 1) + x = unpacked[i][0]+constants['$Globals']['_h'][0] + y = unpacked[i][1]+constants['$Globals']['_h'][1] + rgba= controller.PickPixel(rid_vs, int(x),int(y), sr, rd.CompType.Float).floatValue + z = (256*(240*rgba[0]+15*rgba[1]) + 240*rgba[2]+15*rgba[3])*0.0625 #vertex debugging 해석 결과 vs[0]에 대해 다음과 같이 z좌표 대입 + unpacked[i]=(unpacked[i][0]/64, unpacked[i][1]/64, z/64/5, 1) + + # print(unpacked) with open("{}{:05d}-positions.bin".format(FILEPREFIX, drawcallId), 'wb') as file: pickle.dump(unpacked, file) @@ -222,7 +194,7 @@ def run(self): m.fetchTriangle(controller) unpacked = m.fetchData(controller) for i in range(len(unpacked)): - unpacked[i]=(unpacked[i][0]/64, unpacked[i][1]/64) + unpacked[i]=(unpacked[i][0]/64, 1-unpacked[i][1]/64) with open("{}{:05d}-uv.bin".format(FILEPREFIX, drawcallId), 'wb') as file: pickle.dump(unpacked, file) meshtype= "terrain" @@ -234,7 +206,6 @@ def run(self): m.fetchTriangle(controller) unpacked = m.fetchData(controller) if len(unpacked[0])<4: continue - print("position "+str(len(unpacked[0]))) with open("{}{:05d}-positions.bin".format(FILEPREFIX, drawcallId), 'wb') as file: pickle.dump(unpacked, file) indices = m.fetchIndices(controller) @@ -279,14 +250,13 @@ def run(self): shader = state.GetShader(rd.ShaderStage.Vertex) ep = state.GetShaderEntryPoint(rd.ShaderStage.Vertex) ref = state.GetShaderReflection(rd.ShaderStage.Vertex) - constants = self.getVertexShaderConstants(draw, state=state) constants["DrawCall"] = { "topology": 'TRIANGLE_STRIP' if draw.topology == rd.Topology.TriangleStrip else 'TRIANGLES', "type": capture_type } with open("{}{:05d}-constants.bin".format(FILEPREFIX, drawcallId), 'wb') as file: pickle.dump(constants, file) - + texsave = rd.TextureSave() texsave.resourceId = rid texsave.mip = 0 @@ -295,6 +265,7 @@ def run(self): texsave.destType = rd.FileType.PNG controller.SaveTexture(texsave, "{}{:05d}-texture.png".format(FILEPREFIX, drawcallId)) + def main(controller): scraper = CaptureScraper(controller) scraper.run()