Spaces:
Sleeping
Sleeping
| from math import pi, sin, cos | |
| from panda3d.core import * | |
| from direct.showbase.ShowBase import ShowBase | |
| from direct.task import Task | |
| from floorplan import Floorplan | |
| import numpy as np | |
| import random | |
| import copy | |
| class Viewer(ShowBase): | |
| def __init__(self): | |
| ShowBase.__init__(self) | |
| #self.scene = self.loader.loadModel("floorplan_1.txt-floor.obj") | |
| #self.scene = base.loader.loadModel("floorplan_1.txt-floor.egg") | |
| #self.scene = base.loader.loadModel("panda.egg") | |
| #self.scene = base.loader.loadModel("environment") | |
| base.setBackgroundColor(0, 0, 0) | |
| self.angle = 0.0 | |
| lens = PerspectiveLens() | |
| lens.setFov(60) | |
| lens.setNear(0.01) | |
| lens.setFar(100000) | |
| base.cam.node().setLens(lens) | |
| floorplan = Floorplan('test/floorplan_7') | |
| #floorplan.setFilename('test/floorplan_2') | |
| floorplan.read() | |
| self.scene = floorplan.generateEggModel() | |
| self.scene.reparentTo(self.render) | |
| #self.scene.setScale(0.01, 0.01, 0.01) | |
| #self.scene.setTwoSided(True) | |
| self.scene.setTwoSided(True) | |
| #self.scene.setPos(0, 0, 3) | |
| #texture = loader.loadTexture("floorplan_1.png") | |
| #self.scene.setTexture(texture) | |
| #self.scene.setHpr(0, 0, 0) | |
| # angleDegrees = 0 | |
| # angleRadians = angleDegrees * (pi / 180.0) | |
| # self.camera.setPos(20 * sin(angleRadians), -20 * cos(angleRadians), 3) | |
| # self.camera.setHpr(angleDegrees, 0, 0) | |
| #self.camera.lookAt(0, 0, 0) | |
| 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) | |
| dlight = DirectionalLight('dlight') | |
| dlight.setColor(VBase4(1, 1, 1, 1)) | |
| dlnp = self.render.attachNewNode(dlight) | |
| #dlnp.setHpr(0, -90, 0) | |
| dlnp.setPos(0.5, 0.5, 3) | |
| dlnp.lookAt(0.5, 0.5, 2) | |
| self.render.setLight(dlnp) | |
| for i in xrange(10): | |
| plight = PointLight('plight') | |
| plight.setAttenuation((1, 0, 1)) | |
| color = random.randint(10, 15) | |
| plight.setColor(VBase4(color, color, color, 1)) | |
| plnp = self.render.attachNewNode(plight) | |
| if i == 0: | |
| plnp.setPos(0.5, 0.5, 3) | |
| else: | |
| plnp.setPos(1 * random.random(), 1 * random.random(), 0.3) | |
| pass | |
| self.render.setLight(plnp) | |
| #base.useTrackball() | |
| #base.trackball.node().setPos(2.0, 0, 3) | |
| #base.trackball.node().setHpr(0, 0, 3) | |
| #base.enableMouse() | |
| #base.useDrive() | |
| base.disableMouse() | |
| self.taskMgr.add(self.spinCameraTask, "SpinCameraTask") | |
| #self.accept('arrow_up', self.moveForward) | |
| #self.accept('arrow_up_-repeat', self.moveForward) | |
| self.topDownCameraPos = [0.5, 0.5, 1.5] | |
| self.topDownTarget = [0.5, 0.499, 0.5] | |
| self.topDownH = 0 | |
| self.startCameraPos = floorplan.startCameraPos | |
| self.startTarget = floorplan.startTarget | |
| self.startH = 0 | |
| self.cameraPos = self.topDownCameraPos | |
| self.target = self.topDownTarget | |
| self.H = self.topDownH | |
| self.accept('space', self.openDoor) | |
| self.accept('enter', self.startChangingView) | |
| self.viewMode = 'T' | |
| self.viewChangingProgress = 1.02 | |
| ceiling = self.scene.find("**/ceiling") | |
| ceiling.hide() | |
| return | |
| def moveForward(self): | |
| self.cameraPos[0] -= 0.1 | |
| def openDoor(self): | |
| minDistance = 10000 | |
| doors = self.scene.find("**/doors") | |
| for door in doors.getChildren(): | |
| mins, maxs = door.getTightBounds() | |
| vec_1 = (mins + maxs) / 2 - Vec3(self.target[0], self.target[1], (mins[2] + maxs[2]) / 2) | |
| vec_2 = (mins + maxs) / 2 - Vec3(self.cameraPos[0], self.cameraPos[1], (mins[2] + maxs[2]) / 2) | |
| if (vec_1.dot(vec_2) > 0 and vec_1.length() > vec_2.length()) or np.arccos(abs(vec_1.dot(vec_2)) / (vec_1.length() * vec_2.length())) > np.pi / 4: | |
| continue | |
| distance = pow(pow(self.cameraPos[0] - (mins[0] + maxs[0]) / 2, 2) + pow(self.cameraPos[1] - (mins[1] + maxs[1]) / 2, 2) + pow(self.cameraPos[2] - (mins[2] + maxs[2]) / 2, 2), 0.5) | |
| if distance < minDistance: | |
| minDistanceDoor = door | |
| minDistance = distance | |
| pass | |
| continue | |
| if minDistance > 1: | |
| return | |
| mins, maxs = minDistanceDoor.getTightBounds() | |
| if abs(maxs[0] - mins[0]) > abs(maxs[1] - mins[1]): | |
| minsExpected = Vec3(mins[0] - (maxs[1] - mins[1]), mins[1], mins[2]) | |
| maxsExpected = Vec3(mins[0], mins[1] + (maxs[0] - mins[0]), maxs[2]) | |
| else: | |
| minsExpected = Vec3(mins[0] - (maxs[1] - mins[1]) + (maxs[0] - mins[0]), mins[1] - (maxs[0] - mins[0]), mins[2]) | |
| maxsExpected = Vec3(mins[0] + (maxs[0] - mins[0]), mins[1] + (maxs[0] - mins[0]) - (maxs[0] - mins[0]), maxs[2]) | |
| pass | |
| minDistanceDoor.setH(minDistanceDoor, 90) | |
| mins, maxs = minDistanceDoor.getTightBounds() | |
| minDistanceDoor.setPos(minDistanceDoor, minsExpected[1] - mins[1], -minsExpected[0] + mins[0], 0) | |
| #print(scene.findAllMatches('doors')) | |
| return | |
| def startChangingView(self): | |
| self.viewChangingProgress = 0 | |
| self.prevCameraPos = copy.deepcopy(self.cameraPos) | |
| self.prevTarget = copy.deepcopy(self.target) | |
| self.prevH = self.camera.getR() | |
| if self.viewMode == 'T': | |
| self.newCameraPos = self.startCameraPos | |
| self.newTarget = self.startTarget | |
| self.newH = self.startH | |
| self.viewMode = 'C' | |
| else: | |
| self.newCameraPos = self.topDownCameraPos | |
| self.newTarget = self.topDownTarget | |
| self.newH = self.topDownH | |
| self.startCameraPos = copy.deepcopy(self.cameraPos) | |
| self.startTarget = copy.deepcopy(self.target) | |
| self.startH = self.camera.getR() | |
| self.viewMode = 'T' | |
| pass | |
| return | |
| def changeView(self): | |
| self.cameraPos = [] | |
| self.target = [] | |
| for c in xrange(3): | |
| self.cameraPos.append(self.prevCameraPos[c] + (self.newCameraPos[c] - self.prevCameraPos[c]) * self.viewChangingProgress) | |
| self.target.append(self.prevTarget[c] + (self.newTarget[c] - self.prevTarget[c]) * self.viewChangingProgress) | |
| continue | |
| self.H = self.prevH + (self.newH - self.prevH) * self.viewChangingProgress | |
| if self.viewChangingProgress + 0.02 >= 1 and self.viewMode == 'C': | |
| ceiling = self.scene.find("**/ceiling") | |
| ceiling.show() | |
| pass | |
| if self.viewChangingProgress <= 0.02 and self.viewMode == 'T': | |
| ceiling = self.scene.find("**/ceiling") | |
| ceiling.hide() | |
| pass | |
| return | |
| def spinCameraTask(self, task): | |
| #print(task.time) | |
| #angleDegrees = task.time * 6.0 | |
| movementStep = 0.003 | |
| if self.viewChangingProgress <= 1.01: | |
| self.changeView() | |
| self.viewChangingProgress += 0.02 | |
| pass | |
| if base.mouseWatcherNode.is_button_down('w'): | |
| for c in xrange(2): | |
| step = movementStep * (self.target[c] - self.cameraPos[c]) | |
| self.cameraPos[c] += step | |
| self.target[c] += step | |
| continue | |
| pass | |
| if base.mouseWatcherNode.is_button_down('s'): | |
| for c in xrange(2): | |
| step = movementStep * (self.target[c] - self.cameraPos[c]) | |
| self.cameraPos[c] -= step | |
| self.target[c] -= step | |
| continue | |
| pass | |
| if base.mouseWatcherNode.is_button_down('a'): | |
| step = movementStep * (self.target[0] - self.cameraPos[0]) | |
| self.cameraPos[1] += step | |
| self.target[1] += step | |
| step = movementStep * (self.target[1] - self.cameraPos[1]) | |
| self.cameraPos[0] -= step | |
| self.target[0] -= step | |
| pass | |
| if base.mouseWatcherNode.is_button_down('d'): | |
| step = movementStep * (self.target[0] - self.cameraPos[0]) | |
| self.cameraPos[1] -= step | |
| self.target[1] -= step | |
| step = movementStep * (self.target[1] - self.cameraPos[1]) | |
| self.cameraPos[0] += step | |
| self.target[0] += step | |
| pass | |
| rotationStep = 0.02 | |
| if base.mouseWatcherNode.is_button_down('arrow_left'): | |
| angle = np.angle(complex(self.target[0] - self.cameraPos[0], self.target[1] - self.cameraPos[1])) | |
| angle += rotationStep | |
| self.target[0] = self.cameraPos[0] + np.cos(angle) | |
| self.target[1] = self.cameraPos[1] + np.sin(angle) | |
| pass | |
| if base.mouseWatcherNode.is_button_down('arrow_right'): | |
| angle = np.angle(complex(self.target[0] - self.cameraPos[0], self.target[1] - self.cameraPos[1])) | |
| angle -= rotationStep | |
| self.target[0] = self.cameraPos[0] + np.cos(angle) | |
| self.target[1] = self.cameraPos[1] + np.sin(angle) | |
| pass | |
| if base.mouseWatcherNode.is_button_down('arrow_up'): | |
| angle = np.arcsin(self.target[2] - self.cameraPos[2]) | |
| angle += rotationStep | |
| self.target[2] = self.cameraPos[2] + np.sin(angle) | |
| pass | |
| if base.mouseWatcherNode.is_button_down('arrow_down'): | |
| angle = np.arcsin(self.target[2] - self.cameraPos[2]) | |
| angle -= rotationStep | |
| self.target[2] = self.cameraPos[2] + np.sin(angle) | |
| pass | |
| angleDegrees = self.angle | |
| angleRadians = angleDegrees * (pi / 180.0) | |
| #self.camera.setPos(2.0 * sin(angleRadians), -2.0 * cos(angleRadians), 3) | |
| self.camera.setPos(self.cameraPos[0], self.cameraPos[1], self.cameraPos[2]) | |
| #self.camera.setHpr(angleDegrees, 0, 0) | |
| #self.camera.lookAt(0, 0, 0) | |
| self.camera.lookAt(self.target[0], self.target[1], self.target[2]) | |
| self.camera.setR(self.H) | |
| #if base.mouseWatcherNode.hasMouse() | |
| return Task.cont | |
| app = Viewer() | |
| app.run() | |