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): #self.scene = self.loader.loadModel("floorplan_1.txt-floor.obj") 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(1200, 1200) #cv2.imwrite('test/test.png', image.astype(np.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)