| | from panda3d.core import * |
| | from direct.showbase.ShowBase import ShowBase |
| | import cv2 |
| | from floorplan import Floorplan |
| | import numpy as np |
| | import random |
| | import math |
| |
|
| | class Renderer(ShowBase): |
| | def __init__(self): |
| | |
| | loadPrcFileData("", "window-type offscreen") |
| | loadPrcFileData("", "win-size 128 128") |
| | ShowBase.__init__(self) |
| | |
| | self.scene = NodePath("Scene") |
| | self.scene.reparentTo(self.render) |
| | self.scene.setScale(1, 1, 1) |
| | self.scene.setTwoSided(True) |
| | self.scene.setPos(0, 0, 0) |
| | self.scene.setHpr(0, 0, 0) |
| | self.near_plane = 0.1 |
| | self.far_plane = 5.0 |
| | self.resolution = 128 |
| | self.max_16bit_val = 65535 |
| | self.light_sources = [] |
| | self.light_nodes = [] |
| |
|
| | self.alight = AmbientLight('alight') |
| | self.alight.setColor(VBase4(0.2, 0.2, 0.2, 1)) |
| | self.alnp = self.render.attachNewNode(self.alight) |
| | self.render.setLight(self.alnp) |
| | self.attenuation = False |
| | |
| | base.camLens.setNear(self.near_plane) |
| | base.camLens.setFar(self.far_plane) |
| | |
| | self.generate_depth = True |
| | if self.generate_depth is True: |
| | self.depth_tex = Texture() |
| | self.depth_tex.setFormat(Texture.FDepthComponent) |
| | self.depth_buffer = base.win.makeTextureBuffer('depthmap', self.resolution, self.resolution, self.depth_tex, to_ram=True) |
| | self.depth_cam = self.makeCamera(self.depth_buffer, lens = base.camLens) |
| | print(self.depth_cam.node().getLens().getFilmSize()) |
| | self.depth_cam.reparentTo(base.render) |
| | pass |
| |
|
| | self.models = [] |
| | self.backgrounds = [] |
| | self.model = None |
| |
|
| | self.createLightSources() |
| | return |
| | |
| | def delete(self): |
| | self.alnp.removeNode() |
| | for n in self.light_nodes: |
| | n.removeNode() |
| | continue |
| | for m in self.models: |
| | self.loader.unloadModel(m) |
| | continue |
| | base.destroy() |
| | return |
| |
|
| | def selectModel(self, model_ind): |
| | self.model = self.models[model_ind] |
| | self.model.reparentTo(self.scene) |
| | |
| | def unselectModel(self, model_ind): |
| | self.model.detachNode() |
| | self.model = None |
| | |
| | def loadModels(self, filenames): |
| | self.models = [] |
| | for filename in filenames: |
| | floorplan = Floorplan(filename) |
| | floorplan.read() |
| | floorplan.segmentRooms() |
| | exit(1) |
| | self.models.append(floorplan.generateEggModel()) |
| | continue |
| | return |
| |
|
| | def createLightSources(self): |
| | for i in range(0, 7): |
| | plight = PointLight('plight') |
| | if self.attenuation is True: |
| | plight.setAttenuation((1, 0, 1)) |
| | pass |
| | plight.setColor(VBase4(0, 0, 0, 0)) |
| | self.light_sources.append(plight) |
| | plnp = self.render.attachNewNode(plight) |
| | plnp.setPos(3, 3, 3) |
| | render.setLight(plnp) |
| | self.light_nodes.append(plnp) |
| | continue |
| | return |
| |
|
| | def activateLightSources(self, light_sources, spher=True): |
| | i = 0 |
| | for lght in light_sources: |
| | lp_rad = lght[0] |
| | lp_el = lght[1] |
| | lp_az = lght[2] |
| | lp_int = lght[3] |
| | if spher: |
| | self.light_nodes[i].setPos( |
| | lp_rad*math.cos(lp_el)*math.cos(lp_az), |
| | lp_rad*math.cos(lp_el)*math.sin(lp_az), |
| | lp_rad*math.sin(lp_el)) |
| | else: |
| | self.light_nodes[i].setPos(lp_rad, lp_el, lp_az) |
| | pass |
| | self.light_sources[i].setColor(VBase4(lp_int, lp_int, lp_int, 1)) |
| | i += 1 |
| | continue |
| | return |
| | |
| | def deactivateLightSources(self): |
| | for i in range(0, 7): |
| | self.light_sources[i].setColor(VBase4(0, 0, 0, 0)) |
| | continue |
| | return |
| |
|
| | def textureToImage(self, texture): |
| | im = texture.getRamImageAs("RGB") |
| | strim = im.getData() |
| | image = np.fromstring(strim, dtype='uint8') |
| | |
| | |
| | image = image.reshape(self.resolution, self.resolution, 3) |
| | image = np.flipud(image) |
| | return image |
| |
|
| | def setCameraPosition(self, pos, target): |
| | self.camera.setPos(pos[0], pos[1], pos[2]) |
| | self.camera.lookAt(target[0], target[1], target[2]) |
| |
|
| | if self.generate_depth is True: |
| | self.depth_cam.setPos(pos[0], pos[1], pos[2]) |
| | self.depth_cam.lookAt(target[0], target[1], target[2]) |
| | pass |
| | return |
| | |
| | def renderView(self, camera_pos, light_sources): |
| | angle = math.radians(random.randint(0, 360)) |
| | target = (camera_pos[0] + math.sin(angle), camera_pos[1] + math.cos(angle), camera_pos[2]) |
| | self.setCameraPosition(camera_pos, target) |
| |
|
| | self.activateLightSources(light_sources) |
| |
|
| | base.graphicsEngine.renderFrame() |
| | tex = base.win.getScreenshot() |
| | im = self.textureToImage(tex) |
| | |
| | dm_uint = False |
| | |
| | if self.generate_depth is True: |
| | depth_im = PNMImage() |
| | self.depth_tex.store(depth_im) |
| | |
| | depth_map = np.zeros([self.resolution, self.resolution], dtype='float') |
| | for i in range(0, self.resolution): |
| | for j in range(0, self.resolution): |
| | depth_val = depth_im.getGray(j, i) |
| | depth_map[i, j] = self.far_plane * self.near_plane / (self.far_plane - depth_val * (self.far_plane - self.near_plane)) |
| | depth_map[i, j] = depth_map[i, j] / self.far_plane |
| | continue |
| | continue |
| | dm_uint = np.round(depth_map * self.max_16bit_val).astype('uint16') |
| | pass |
| | |
| | |
| | im = im.astype(dtype=np.uint8) |
| | self.deactivateLightSources() |
| | return im, dm_uint |
| |
|
| |
|
| | renderer = Renderer() |
| | renderer.loadModels(['test/floorplan_2', ]) |
| | renderer.selectModel(0) |
| |
|
| | num_light = random.randint(2, 4) |
| | lights = [] |
| | for nl in range(0, num_light): |
| | light_pos = [random.random()*2. + 2.5, |
| | random.randint(-90, 90), |
| | random.randint(0, 360), |
| | random.randint(10, 15)] |
| | lights.append(light_pos) |
| | continue |
| |
|
| | for im_num in range(0, 20): |
| | x = random.random() |
| | y = random.random() |
| | z = 0.15 |
| | im, dm = renderer.renderView([x, y, z], lights) |
| | cv2.imwrite('test/rendering_' + str(im_num) + '.png', (np.asarray(im)).astype(np.uint8)) |
| | cv2.imwrite('test/depth_' + str(im_num) + '.png', (np.asarray(1 / (dm / 65535.0) * 255)).astype(np.uint8)) |
| | continue |
| |
|
| | exit(1) |
| |
|