class Bullet(DirectObject): def __init__(self, ship, bulletPos, bulletVelocityVec, collisionHandler): self.model = game.loader.loadModel("Models/bullet.egg.pz") self.model.setPos(bulletPos) self.model.setScale(BULLET_SIZE) self.model.reparentTo(render) self.model.setPythonTag("owner", self) self.ship = ship finalPosition = bulletPos + (bulletVelocityVec * BULLET_TRAVEL_TIME) self.trajectory = self.model.posInterval(BULLET_TRAVEL_TIME, finalPosition).start() self.collisionNode = self.model.attachNewNode(CollisionNode("bullet")) self.collisionNode.node().addSolid(CollisionSphere(0, 0, 0, 1)) base.cTrav.addCollider(self.collisionNode, collisionHandler) # Add Point Light to the bullet self.plight = PointLight('plight' + str(random())) self.plight.setColor(Vec4(1, 1, 1, 1)) self.plight.setAttenuation(Vec3(0.7, 0.05, 0)) self.plnp = self.model.attachNewNode(self.plight) render.setLight(self.plnp) render.setShaderInput("light", self.plnp) ### # Bullet.remove # # Removes this asteroid from rendering and registering collisions. ## def remove(self): self.ignoreAll() self.model.remove() self.collisionNode.remove()
def setupLights(self): base.setBackgroundColor(0.0, 0.0, 0.0, 1) base.setFrameRateMeter(True) # Add a light to the scene. self.lightpivot = render.attachNewNode("lightpivot") self.lightpivot.setPos(0, 0, 5) self.lightpivot.hprInterval(10, Point3(360, 0, 0)).loop() plight = PointLight('plight') plight.setColor(Vec4(1, 0, 0, 1)) plight.setAttenuation(Vec3(0.37, 0.025, 0)) plnp = self.lightpivot.attachNewNode(plight) plnp.setPos(45, 0, 0) plnp.lookAt(*Vec3(0, 0, 0, )) # Light alight = AmbientLight('ambientLight') alight.setColor(Vec4(0.2, 0.2, 0.2, 1)) alightNP = render.attachNewNode(alight) # dlight = DirectionalLight('directionalLight') # dlight.setDirection(Vec3(1, 1, -1)) # dlight.setColor(Vec4(0.7, 0.7, 0.7, 1)) # dlightNP = render.attachNewNode(dlight) render.clearLight() render.setLight(alightNP) # render.setLight(dlightNP) render.setLight(plnp) # create a sphere to denote the light sphere = loader.loadModel("models/sphere") sphere.reparentTo(plnp) render.setShaderAuto()
def generate(self, helperInfo): color = self.mapObject.getPropertyValue("_light", default=Vec4( 255, 255, 255, 255)) color = CIGlobals.colorFromRGBScalar255(color) color = CIGlobals.vec3GammaToLinear(color) constant = float( self.mapObject.getPropertyValue("_constant_attn", default="0.0")) linear = float( self.mapObject.getPropertyValue("_linear_attn", default="0.0")) quadratic = float( self.mapObject.getPropertyValue("_quadratic_attn", default="1.0")) # Scale intensity for unit 100 distance ratio = (constant + 100 * linear + 100 * 100 * quadratic) if ratio > 0: color *= ratio pl = PointLight("lightHelper-light") pl.setColor(Vec4(color[0], color[1], color[2], 1.0)) pl.setAttenuation(Vec3(constant, linear, quadratic)) self.light = self.mapObject.helperRoot.attachNewNode(pl) if self.mapObject.doc.numlights < 128: self.mapObject.doc.render.setLight(self.light) self.mapObject.doc.numlights += 1 self.hasLight = True
def __init__(self): ShowBase.__init__(self) self.cap = cv2.VideoCapture(0) self.classifier = cv2.CascadeClassifier(self.haar) self.scene = self.loader.loadModel('models/abstractroom') self.scene.reparentTo(self.render) self.scene.setPos(-10, 100, 0) self.shaderenable = 1 self.scene.setShaderAuto() # Add ambient light alight = AmbientLight('alight') alight.setColor((0.1, 0.11, 0.11, 1)) alnp = self.render.attachNewNode(alight) self.scene.setLight(alnp) # Add point light. plight = PointLight('plight') plight.setColor((1, 1, 1, 1)) plight.setAttenuation(LVector3(0.1, 0.02, 0)) plnp = self.render.attachNewNode(plight) plnp.setPos(-27, 100, 0) self.scene.setLight(plnp) # Create a sphere to denote the light sphere = self.loader.loadModel("models/icosphere") sphere.reparentTo(plnp) self.taskMgr.add(self.display, 'Display') print("%.1f, %.1f, %.1f" % (self.x, self.y, self.z))
class Bullet(DirectObject): def __init__(self, ship, bulletPos, bulletVelocityVec, collisionHandler): self.model = game.loader.loadModel("Models/bullet.egg.pz") self.model.setPos(bulletPos) self.model.setScale(BULLET_SIZE) self.model.reparentTo(render) self.model.setPythonTag("owner", self) self.ship = ship finalPosition = bulletPos + (bulletVelocityVec * BULLET_TRAVEL_TIME) self.trajectory = self.model.posInterval(BULLET_TRAVEL_TIME, finalPosition).start() self.collisionNode = self.model.attachNewNode(CollisionNode("bullet")) self.collisionNode.node().addSolid(CollisionSphere(0,0,0,1)) base.cTrav.addCollider(self.collisionNode, collisionHandler) # Add Point Light to the bullet self.plight = PointLight('plight'+str(random())) self.plight.setColor(Vec4(1,1,1,1)) self.plight.setAttenuation(Vec3(0.7, 0.05, 0)) self.plnp = self.model.attachNewNode(self.plight) render.setLight(self.plnp) render.setShaderInput("light", self.plnp) ### # Bullet.remove # # Removes this asteroid from rendering and registering collisions. ## def remove(self): self.ignoreAll() self.model.remove() self.collisionNode.remove()
def __init__(self): super().__init__() self.set_background_color(0, 0, 0, 1) self.jack = self.loader.loadModel("models/jack") self.jack.setHpr(0, 180, 180) self.jack.setPos(0, 0, 0) self.jack.reparentTo(self.render) self.light_model = self.loader.loadModel('models/misc/sphere') self.light_model.setScale(0.2, 0.2, 0.2) self.light_model.setPos(4, 0, 0) self.light_model.reparentTo(self.render) self.cam.setPos(0, -12, 0) plight = PointLight("plight") plight.setColor((1, 1, 1, 1)) self.plnp = self.light_model.attachNewNode(plight) # self.plnp.setPos(2, 0, 0) plight.setAttenuation((1, 0, 0)) self.jack.setLight(self.plnp) alight = AmbientLight("aLight") alight.setColor((0.04, 0.04, 0.04, 1)) alnp = self.render.attachNewNode(alight) self.jack.setLight(alnp) self.taskMgr.add(self.move_light, "move-light")
def __init__(self): base.disableMouse() base.cam.node().getLens().setNear(10.0) base.cam.node().getLens().setFar(9999999) camera.setPos(0, -50, 0) # Check video card capabilities. if (base.win.getGsg().getSupportsBasicShaders() == 0): addTitle("Toon Shader: Video driver reports that shaders are not supported.") return # Enable a 'light ramp' - this discretizes the lighting, # which is half of what makes a model look like a cartoon. # Light ramps only work if shader generation is enabled, # so we call 'setShaderAuto'. tempnode = NodePath(PandaNode("temp node")) tempnode.setAttrib(LightRampAttrib.makeSingleThreshold(0.5, 0.4)) tempnode.setShaderAuto() base.cam.node().setInitialState(tempnode.getState()) # Use class 'CommonFilters' to enable a cartoon inking filter. # This can fail if the video card is not powerful enough, if so, # display an error and exit. self.separation = 1 # Pixels self.filters = CommonFilters(base.win, base.cam) filterok = self.filters.setCartoonInk(separation=self.separation) if (filterok == False): addTitle("Toon Shader: Video card not powerful enough to do image postprocessing") return # Create a non-attenuating point light and an ambient light. plightnode = PointLight("point light") plightnode.setAttenuation(Vec3(1,0,0)) plight = render.attachNewNode(plightnode) plight.setPos(30,-50,0) alightnode = AmbientLight("ambient light") alightnode.setColor(Vec4(0.8,0.8,0.8,1)) alight = render.attachNewNode(alightnode) render.setLight(alight) render.setLight(plight) # Panda contains a built-in viewer that lets you view the # results of all render-to-texture operations. This lets you # see what class CommonFilters is doing behind the scenes. self.accept("v", base.bufferViewer.toggleEnable) self.accept("V", base.bufferViewer.toggleEnable) base.bufferViewer.setPosition("llcorner") self.accept("s", self.filters.manager.resizeBuffers) # These allow you to change cartooning parameters in realtime self.accept("escape", sys.exit, [0])
def __init__(self, **kwargs): self.type = 'ambient' # ambient or directional for now self.color = color.rgb(0.3, 0.3, 0.3, 1) # a modest amount of full-spectrum light self.direction = Vec3( -1, -1, -1) # shining down from top-right corner, behind camera self.position = None self.attenuation = None self.node = None for key, value in kwargs.items(): if key == 'type': if value in ('ambient', 'directional', 'point'): self.type = value else: print("ERR Light type is not 'ambient' or 'directional'") elif key == 'color': self.color = value elif key == 'direction': self.direction = value elif key == 'attenuation': self.attenuation = value elif key == 'position': self.position = value else: print("Err ", key, " is not a valid keyword") scene.lights.append(self) # light added for all subsequent entities if self.type == 'ambient': ambientLight = AmbientLight('ambientLight') ambientLight.setColor(self.color) self.node = scene.attachNewNode(ambientLight) elif self.type == 'directional': directionalLight = DirectionalLight('directionalLight') directionalLight.setColor(self.color) self.node = scene.attachNewNode(directionalLight) # This light should be facing straight down, but clearly it isn't. self.node.setHpr( self.direction) # convert vector to Hpr (in degrees!?) first elif self.type == 'point': pointLight = PointLight('pointLight') pointLight.setColor(self.color) if self.attenuation is None: self.attenuation = Vec3(1, 0, 0) pointLight.setAttenuation(self.attenuation) if self.position is None: self.position = Vec3(0, 0, 0) self.node = scene.attachNewNode(pointLight) self.node.setPos(self.position)
def makePointLight(name, color, pos, falloff=1.0): point = PointLight(name + "-point") point.setColor(color) ATTN_FCTR = 0.0625 point.setAttenuation((0, 0, falloff * ATTN_FCTR)) pnp = render.attachNewNode(point) pnp.setPos(pos) if False: sm = loader.loadModel("models/smiley.egg.pz") sm.reparentTo(pnp) return pnp
def __init__(self): camera_hpr = base.camera.getHpr() self.name = "missle" self.core = loader.loadModel("./Models/sphere.egg") self.ttl = 2 # Time to live in seconds self.core.setPos(base.camera, (0, 0, 0)) self.core.setHpr(camera_hpr) self.core.setScale(600, 600, 600) self.glow = loader.loadModel("./Models/sphere.egg") self.core.setTransparency(TransparencyAttrib.MAlpha) self.glow.setScale(2, 2, 2) self.glow.reparentTo(self.core) self.core.setColor(colors.get("white")) self.glow.setColor(colors.get("white-transparent")) self.glow.setPos(0, 0, 0) #relative to parent self.core.setLightOff( ) # remove all other lights from missle so it is a bright white missle_total.append(self) #Create the light so the missle glows plight = PointLight('plight') plight.setColor(colors.get("white")) plight.setAttenuation(LVector3(0, 0.00008, 0)) plight.setMaxDistance(1000) self.plnp = self.core.attachNewNode(plight) #point light node point render.setLight(self.plnp) # Create hitsphere cNode = CollisionNode(self.name) cNode.addSolid(CollisionSphere(0, 0, 0, 1)) self.c_np = self.core.attachNewNode(cNode) # Create and run the missle animation end_location = Location(self.core).obj.getPos() start_location = base.camera.getPos() dt = globalClock.getDt() start_location[0] += spaceship_speed_x * dt start_location[1] += spaceship_speed_y * dt start_location[2] += spaceship_speed_z * dt self.asteroid_lerp = LerpPosInterval( self.core, # Object being manipulated. The missle in this case. 500, # How long it will take the missle to go from point a to b in seconds end_location, # future location at end of lerp start_location, # The start position of the missle fluid=1) # Allow for colisions during the lerp self.asteroid_lerp.start() del end_location self.core.reparentTo(render)
def __init__(self, game, duration=None, storage_path="storage/3d/frame", fps=30, as_gif=False, gif_name=None, size=(480, 480)): self.game = game self.duration = duration self.storage_path = storage_path self.fps = fps self.as_gif = as_gif self.gif_name = gif_name self.base = ShowBase(windowType='none') self.base.openWindow(type=('offscreen' if as_gif else 'onscreen'), size=size) depth, height, width = game.shape self.rhomdos = [] for z in range(depth): self.rhomdos.append([]) for y in range(height): self.rhomdos[-1].append([]) for x in range(width): rr = RhomdoRender((z, y, x), game.shape) render.attachNewNode(rr.geomnode) self.rhomdos[-1][-1].append(rr) plight = PointLight('plight') plight.setColor(VBase4(1, 1, 1, 1)) plight.setAttenuation((0, 0, .0005)) self.plnp = render.attachNewNode(plight) self.plnp.setPos(0, 0, (game.shape[0] * SR2) + 40) render.setLight(self.plnp) if self.as_gif: self.base.movie(self.storage_path, duration=self.duration, fps=self.fps) self.base.taskMgr.add(self.spinCameraTask, "SpinCameraTask") self.base.taskMgr.add(self.updateClock, "UpdateClock") self.frame = 0 self.game_step = 0
def basic_point_light(self, position, color, name, attenuation=(1, 0, 0.02)): light = PointLight(name) light.setColor(color) light.setAttenuation(attenuation) # light.setShadowCaster(True) # light.getLens().setNearFar(5, 20) plight = self.centerlight_np.attachNewNode(light) plight.setPos(position) self.render.setLight(plight) light_cube = self.loader.loadModel("cuby.gltf") light_cube.reparentTo(plight) light_cube.setScale(0.25) material = Material() material.setEmission(color) light_cube.setMaterial(material)
def _set_explosion_lights(self): """Prepare three explosion lights. Build a list-pool of light objects to be used in different explosions. Returns: list: List of lights to be used for explosions. """ lights = [] for num in range(3): light = PointLight("explosion_light_" + str(num)) light.setColor((1, 0.9, 0.55, 1)) light.setAttenuation((0, 0, 1)) light_np = render.attachNewNode(light) # noqa: F821 light_np.setPos(0, 0, -5) render.setLight(light_np) # noqa: F821 lights.append(light_np) return lights
def setupLightSources(self, base, scene): for np in self.model.findAllMatches('**/=Light'): if np.getTag('Light') == 'Point': light = PointLight('PointLight.%d' % (len(self.lights) + 1,)) elif np.getTag('Light') == 'Spot': light = Spotlight('Spotlight.%d' % (len(self.lights) + 1,)) fov = np.getTag('Fov') if fov: light.getLens().setFov(float(fov)) nf = np.getTag('NearFar').split(',') if len(nf) > 1: light.getLens().setNearFar(float(nf[0]), float(nf[1])) exp = np.getTag('Exponent') if exp: light.setExponent(float(exp)) elif np.getTag('Light') == 'Directional': light = DirectionalLight('DirectionalLight.%d' % (len(self.lights) + 1,)) materials = np.findAllMaterials() if len(materials) > 0: light.setColor(materials[0].getDiffuse()) attenuation = np.getTag('Attenuation').split(',') if len(attenuation) > 0 and not isinstance(light, DirectionalLight): light.setAttenuation(tuple([float(a) for a in attenuation])) # if np.getTag('Shadow'): # self.model.setShaderAuto() # light.setShadowCaster(True) self.lights.append(light) lightNP = self.model.attachNewNode(light) lightNP.setPos(np.getPos()) lightNP.setHpr(np.getHpr()) # lightNP.setCompass() self.model.setLight(lightNP)
def _set_lights(self): """Configure the locomotive lights. Sets the main locomotive lighter and lights above the doors. Returns: list: NodePath's of the Train lights. """ lens = PerspectiveLens() lens.setNearFar(0, 50) lens.setFov(60, 60) floodlight = Spotlight("train_main_lighter") floodlight.setColor((0.5, 0.5, 0.5, 1)) floodlight.setLens(lens) floodlight.setExponent(0.4) floodlight_np = self.model.attachNewNode(floodlight) floodlight_np.setPos(0, 0.34, 50) render.setLight(floodlight_np) # noqa: F821 train_lights = [floodlight_np] for name, coors in ( ("train_right_door_light", (0.073, -0.17, 50)), ("train_left_door_light", (-0.073, -0.17, 50)), ("train_back_door_light", (0, -0.63, 50)), ): lamp = PointLight(name) lamp.setColor((0.89, 0.81, 0.55, 1)) lamp.setAttenuation(3) lamp_np = self.model.attachNewNode(lamp) lamp_np.setPos(*coors) render.setLight(lamp_np) # noqa: F821 train_lights.append(lamp_np) return train_lights
def __init__(self, position, value): #Invisiible point so that both spheres have the same parent self.name = "pointball" self.center = NodePath(PandaNode("Pointball center")) self.ttl = 15 #Time to live in seconds self.ttl_max = 15 self.max_size = 9000 self.attraction_distance = 900000 self.center.setPos(position) self.center.setTag("value", str(value)) # Create 1st sphere self.one = loader.loadModel("./Models/sphere.egg") self.one.setColor(colors.get("blue-transparent")) self.one.setScale(self.max_size, self.max_size, self.max_size) self.one.setLightOff() self.one.reparentTo(self.center) #Create 2nd sphere self.two = loader.loadModel("./Models/sphere.egg") self.two.setColor(colors.get("lightblue-transparent")) self.two.setScale(self.max_size, self.max_size, self.max_size) self.two.setLightOff() self.two.reparentTo(self.center) #Create the light so the missle glows plight = PointLight('plight') plight.setColor(colors.get("blue")) plight.setAttenuation(LVector3(0, 0.000008, 0)) plight.setMaxDistance(100) self.plnp = self.center.attachNewNode(plight) #point light node point render.setLight(self.plnp) # Create Collision hitsphere cNode = CollisionNode(self.name) cNode.addSolid(CollisionSphere(0, 0, 0, self.max_size * 20)) self.c_np = self.center.attach_new_node(cNode) #Render to scene self.center.reparentTo(render)
def __init__(self): # Configure the parallax mapping settings (these are just the defaults) loadPrcFileData( "", "parallax-mapping-samples 3\n" "parallax-mapping-scale 0.1") # Initialize the ShowBase class from which we inherit, which will # create a window and set up everything we need for rendering into it. ShowBase.__init__(self) # Check video card capabilities. if not self.win.getGsg().getSupportsBasicShaders(): addTitle("Bump Mapping: " "Video driver reports that Cg shaders are not supported.") return # Post the instructions self.title = addTitle("Panda3D: Tutorial - Bump Mapping") self.inst1 = addInstructions(0.06, "Press ESC to exit") self.inst2 = addInstructions(0.12, "Move mouse to rotate camera") self.inst3 = addInstructions(0.18, "Left mouse button: Move forwards") self.inst4 = addInstructions(0.24, "Right mouse button: Move backwards") self.inst5 = addInstructions(0.30, "Enter: Turn bump maps Off") # Load the 'abstract room' model. This is a model of an # empty room containing a pillar, a pyramid, and a bunch # of exaggeratedly bumpy textures. self.room = loader.loadModel("models/abstractroom") self.room.reparentTo(render) # Make the mouse invisible, turn off normal mouse controls self.disableMouse() props = WindowProperties() props.setCursorHidden(True) self.win.requestProperties(props) self.camLens.setFov(60) # Set the current viewing target self.focus = LVector3(55, -55, 20) self.heading = 180 self.pitch = 0 self.mousex = 0 self.mousey = 0 self.last = 0 self.mousebtn = [0, 0, 0] # Start the camera control task: taskMgr.add(self.controlCamera, "camera-task") self.accept("escape", sys.exit, [0]) self.accept("mouse1", self.setMouseBtn, [0, 1]) self.accept("mouse1-up", self.setMouseBtn, [0, 0]) self.accept("mouse2", self.setMouseBtn, [1, 1]) self.accept("mouse2-up", self.setMouseBtn, [1, 0]) self.accept("mouse3", self.setMouseBtn, [2, 1]) self.accept("mouse3-up", self.setMouseBtn, [2, 0]) self.accept("enter", self.toggleShader) self.accept("j", self.rotateLight, [-1]) self.accept("k", self.rotateLight, [1]) self.accept("arrow_left", self.rotateCam, [-1]) self.accept("arrow_right", self.rotateCam, [1]) # Add a light to the scene. self.lightpivot = render.attachNewNode("lightpivot") self.lightpivot.setPos(0, 0, 25) self.lightpivot.hprInterval(10, LPoint3(360, 0, 0)).loop() plight = PointLight('plight') plight.setColor((1, 1, 1, 1)) plight.setAttenuation(LVector3(0.7, 0.05, 0)) plnp = self.lightpivot.attachNewNode(plight) plnp.setPos(45, 0, 0) self.room.setLight(plnp) # Add an ambient light alight = AmbientLight('alight') alight.setColor((0.2, 0.2, 0.2, 1)) alnp = render.attachNewNode(alight) self.room.setLight(alnp) # Create a sphere to denote the light sphere = loader.loadModel("models/icosphere") sphere.reparentTo(plnp) # Tell Panda that it should generate shaders performing per-pixel # lighting for the room. self.room.setShaderAuto() self.shaderenable = 1
def __init__(self): # Initialize the ShowBase class from which we inherit, which will # create a window and set up everything we need for rendering into it. ShowBase.__init__(self) self.disableMouse() self.cam.node().getLens().setNear(10.0) self.cam.node().getLens().setFar(200.0) camera.setPos(0, -50, 0) # Check video card capabilities. if not self.win.getGsg().getSupportsBasicShaders(): addTitle("Toon Shader: Video driver reports that Cg shaders are not supported.") return # Enable a 'light ramp' - this discretizes the lighting, # which is half of what makes a model look like a cartoon. # Light ramps only work if shader generation is enabled, # so we call 'setShaderAuto'. tempnode = NodePath(PandaNode("temp node")) tempnode.setAttrib(LightRampAttrib.makeSingleThreshold(0.5, 0.4)) tempnode.setShaderAuto() self.cam.node().setInitialState(tempnode.getState()) # Use class 'CommonFilters' to enable a cartoon inking filter. # This can fail if the video card is not powerful enough, if so, # display an error and exit. self.separation = 1 # Pixels self.filters = CommonFilters(self.win, self.cam) filterok = self.filters.setCartoonInk(separation=self.separation) if (filterok == False): addTitle( "Toon Shader: Video card not powerful enough to do image postprocessing") return # Show instructions in the corner of the window. self.title = addTitle( "Panda3D: Tutorial - Toon Shading with Normals-Based Inking") self.inst1 = addInstructions(0.06, "ESC: Quit") self.inst2 = addInstructions(0.12, "Up/Down: Increase/Decrease Line Thickness") self.inst3 = addInstructions(0.18, "V: View the render-to-texture results") # Load a dragon model and animate it. self.character = Actor() self.character.loadModel('models/nik-dragon') self.character.reparentTo(render) self.character.loadAnims({'win': 'models/nik-dragon'}) self.character.loop('win') self.character.hprInterval(15, (360, 0, 0)).loop() # Create a non-attenuating point light and an ambient light. plightnode = PointLight("point light") plightnode.setAttenuation((1, 0, 0)) plight = render.attachNewNode(plightnode) plight.setPos(30, -50, 0) alightnode = AmbientLight("ambient light") alightnode.setColor((0.8, 0.8, 0.8, 1)) alight = render.attachNewNode(alightnode) render.setLight(alight) render.setLight(plight) # Panda contains a built-in viewer that lets you view the # results of all render-to-texture operations. This lets you # see what class CommonFilters is doing behind the scenes. self.accept("v", self.bufferViewer.toggleEnable) self.accept("V", self.bufferViewer.toggleEnable) self.bufferViewer.setPosition("llcorner") self.accept("s", self.filters.manager.resizeBuffers) # These allow you to change cartooning parameters in realtime self.accept("escape", sys.exit, [0]) self.accept("arrow_up", self.increaseSeparation) self.accept("arrow_down", self.decreaseSeparation)
class MyApp(ShowBase): def __init__(self): ShowBase.__init__(self) dir(self) self.disableMouse() # Load the environment model. self.environ = self.loader.loadModel("../levels/level01.egg") # Reparent the model to render. self.environ.reparentTo(self.render) '''add a light''' self.light = PointLight("dLight") self.light.setAttenuation((.01, .01, .01)) self.light.setSpecularColor(VBase4(1, 1, 0, 1)) self.lightNode = render.attachNewNode(self.light) self.lightNode.setZ(10) render.setLight(self.lightNode) '''move light constants''' self.moveLightDirection = -1000 self.taskMgr.add(self.moveLight, "lightMove") self.taskMgr.add(self.fpsInput, "fpsInput") '''fps cam controls''' self.keymap = { "w": 0, "a": 0, "s": 0, "d": 0, "e": 0, "q": 0, "j": 0, "k": 0, "l": 0, "i": 0 } self.fps = FpsCam(self.camera) self.accept("a", self.setKey, ["a", 1]) self.accept("a-up", self.setKey, ['a', 0]) self.accept("w", self.setKey, ["w", 1]) self.accept("w-up", self.setKey, ["w", 0]) self.accept("s", self.setKey, ["s", 1]) self.accept("s-up", self.setKey, ["s", 0]) self.accept("d", self.setKey, ["d", 1]) self.accept("d-up", self.setKey, ["d", 0]) self.accept("e", self.setKey, ["e", 1]) self.accept("e-up", self.setKey, ["e", 0]) self.accept("q", self.setKey, ["q", 1]) self.accept("q-up", self.setKey, ["q", 0]) self.accept("j", self.setKey, ["j", 1]) self.accept("j-up", self.setKey, ["j", 0]) self.accept("k", self.setKey, ["k", 1]) self.accept("k-up", self.setKey, ["k", 0]) self.accept("l", self.setKey, ["l", 1]) self.accept("l-up", self.setKey, ["l", 0]) self.accept("i", self.setKey, ["i", 1]) self.accept("i-up", self.setKey, ["i", 0]) self.accept("escape", sys.exit) def setKey(self, key, value): self.keymap[key] = value return def fpsInput(self, task): self.fps.moveX(self.keymap["d"] - self.keymap["a"]) self.fps.moveY(self.keymap["w"] - self.keymap["s"]) self.fps.moveZ(self.keymap["e"] - self.keymap["q"]) self.fps.yaw(self.keymap["j"] - self.keymap["l"]) self.fps.pitch(self.keymap["i"] - self.keymap["k"]) return task.cont def moveLight(self, task): #print dir(self.lightNode) where = self.lightNode.getX() #print where self.lightNode.setX(where - task.getDt() * self.moveLightDirection) if self.lightNode.getX() < -10: self.moveLightDirection *= -1 elif self.lightNode.getX() > 10: self.moveLightDirection *= -1 return task.cont
def __init__(self, cad_file=None, output_size=(512, 512), light_on=True, cast_shadow=True): # acquire lock since showbase cannot be created twice Panda3DRenderer.__lock.acquire() # set output size and init the base loadPrcFileData('', f'win-size {output_size[0]} {output_size[1]}') base = ShowBase(windowType='offscreen') # coordinate for normalized and centered object obj_node = base.render.attach_new_node('normalized_obj') # ambient alight = AmbientLight('alight') alight.set_color(VBase4(0.5, 0.5, 0.5, 1.0)) alnp = base.render.attachNewNode(alight) base.render.setLight(alnp) # directional light for ambient dlight1 = DirectionalLight('dlight1') dlight1.set_color(VBase4(0.235, 0.235, 0.235, 1.0)) dlnp1 = base.render.attach_new_node(dlight1) dlnp1.set_pos(-2, 3, 1) dlnp1.look_at(obj_node) base.render.set_light(dlnp1) # point light for ambient plight1 = PointLight('plight1') plight1.set_color(VBase4(1.75, 1.75, 1.75, 1.0)) plight1.setAttenuation((1, 1, 1)) plnp1 = base.render.attach_new_node(plight1) plnp1.set_pos(0, 0, 3) plnp1.look_at(obj_node) base.render.set_light(plnp1) plight2 = PointLight('plight2') plight2.set_color(VBase4(1.5, 1.5, 1.5, 1.0)) plight2.setAttenuation((1, 0, 1)) plnp2 = base.render.attach_new_node(plight2) plnp2.set_pos(0, -3, 0) plnp2.look_at(obj_node) base.render.set_light(plnp2) dlight2 = DirectionalLight('dlight2') dlight2.set_color(VBase4(0.325, 0.325, 0.325, 1.0)) dlnp2 = base.render.attach_new_node(dlight2) dlnp2.set_pos(-1, 1, -1.65) dlnp2.look_at(obj_node) base.render.set_light(dlnp2) dlight3 = DirectionalLight('dlight3') dlight3.set_color(VBase4(0.15, 0.15, 0.15, 1.0)) dlnp3 = base.render.attach_new_node(dlight3) dlnp3.set_pos(-2.5, 2.5, 2.0) dlnp3.look_at(obj_node) base.render.set_light(dlnp3) if cast_shadow: lens = PerspectiveLens() dlight3.set_lens(lens) dlight3.set_shadow_caster(True, 1024, 1024) dlight4 = DirectionalLight('dlight4') dlight4.set_color(VBase4(0.17, 0.17, 0.17, 1.0)) dlnp4 = base.render.attach_new_node(dlight4) dlnp4.set_pos(1.2, -2.0, 2.5) dlnp4.look_at(obj_node) base.render.set_light(dlnp4) if cast_shadow: lens = PerspectiveLens() dlight4.set_lens(lens) dlight4.set_shadow_caster(True, 1024, 1024) self.direct_node = direct_node = base.render.attach_new_node( 'direct_light') dlnp2.reparent_to(direct_node) dlnp3.reparent_to(direct_node) dlnp4.reparent_to(direct_node) # auto shader for shadow if cast_shadow: base.render.setShaderAuto() # no culling base.render.set_two_sided(True) # anti-alias base.render.setAntialias(AntialiasAttrib.MMultisample, 8) # init camera position self.coverage = 0.5 # the default clear color self.clear_color = (0.0, 0.0, 0.0, 0.0) # translate in rendered image self.obj_translate = (0, 0) # light rotation self.light_hpr = (0, 0, 0) # object rotation self.obj_hpr = (0, 0, 0) self.base = base self.obj = None self.obj_node = obj_node self.cast_shadow = cast_shadow self.camera = base.camera if cad_file is not None: self.set_obj(cad_file) if not light_on: base.render.set_light_off()
class Light(PropertiesTableAbstract, XMLExportable): def __init__(self, attributes, parent): self.plnp = -1 self.parent = parent self.typeName = 'light' self.properties = { 'distance': '', 'attenuation': '', 'type': '', 'on': '', 'color': '', 'id': '' } self.propertiesUpdateFactor = {'distance': 0.1, 'attenuation': 0.01} if 'distance' in attributes: self.properties['distance'] = distance = float( attributes['distance'].value) else: distance = 1.0 if 'attenuation' in attributes: self.properties[ 'attenuation'] = self.attenuation = attenuation = float( attributes['attenuation'].value) else: self.properties[ 'attenuation'] = self.attenuation = attenuation = 0.0 if 'type' in attributes: self.properties['type'] = ltype = attributes['type'].value else: self.properties['type'] = ltype = 'point' if 'on' in attributes: if attributes['on'].value == "false": self.properties['on'] = 'false' self.on = False else: self.properties['on'] = 'true' self.on = True else: self.on = True if 'color' in attributes: self.properties['color'] = color = attributes['color'].value else: color = '1,1,1,1' if 'id' in attributes: self.properties['id'] = self.uid = uid = attributes['id'].value else: self.properties['id'] = self.uid = uid = 'light' self.generateNode() ''' Used in editor mode to add an object that visibly represents the light ''' def showVisibleObject(): pass #TODO IMPLEMENT!! def destroy(self): if self.plnp != -1: render.clearLight(self.plnp) def generateNode(self): rgba = self.properties['color'].split(',') if len(rgba) < 3: print( "ERROR: please define a correct color for light. (example: r,g,b,a in float values)!" ) realcolor = VBase4( float(rgba[0]) / 255, float(rgba[1]) / 255, float(rgba[2]) / 255, 1.0) if self.properties['type'] == 'spot': self.plight = Spotlight('slight') self.plight.setColor(realcolor) self.lens = PerspectiveLens() self.plight.setLens(self.lens) self.plnp = self.parent.attachNewNode(self.plight) self.plnp.setPos(0.5, -self.properties['distance'], 0.5) self.plnp.lookAt(Point3(0.5, 0, 0.5)) if self.properties['type'] == 'point': self.plight = PointLight('plight') self.plight.setColor(realcolor) if self.on == True: self.plight.setAttenuation(self.properties['attenuation']) else: self.plight.setAttenuation((1.0, 0, 1)) self.plnp = self.parent.getNode().attachNewNode(self.plight) self.plnp.setPos(0.5, -self.properties['distance'], 0.5) render.setLight(self.plnp) if self.on: self.setOn() #set unique id self.plnp.setTag("id", self.properties['id']) self.plnp.setPythonTag("gamenode", self) def getName(self): return 'Point Light: ' + self.properties['id'] def xmlAttributes(self): return self.properties def xmlTypeName(self): return self.typeName ''' Sanitize properties data to be of correct type from string ''' def sanitizeProperties(self): #sanitizing data self.properties['distance'] = float(self.properties['distance']) self.properties['attenuation'] = float(self.properties['attenuation']) #interface needed by PropertiesTable # regenerates the node at every change def onPropertiesUpdated(self): self.sanitizeProperties() rgba = self.properties['color'].split(',') if len(rgba) < 3: print( "ERROR: please define a correct color for light. (example: r,g,b,a in float values)!" ) realcolor = VBase4( float(rgba[0]) / 255, float(rgba[1]) / 255, float(rgba[2]) / 255, 1.0) self.plnp.setY(-self.properties['distance']) self.plight.setColor(realcolor) self.plight.setAttenuation((self.properties['attenuation'])) def getPropertyList(self): return self.properties def setProperty(self, key, value): self.properties[key] = value def increaseProperty(self, key, multiplier): if key in self.propertiesUpdateFactor: self.setProperty( key, self.properties[key] + self.propertiesUpdateFactor[key] * multiplier) def decreaseProperty(self, key, multiplier): if key in self.propertiesUpdateFactor: self.setProperty( key, self.properties[key] - self.propertiesUpdateFactor[key] * multiplier) def copyProperties(self): return self.getPropertyList() def pasteProperties(self, props): for key, value in props.items(): if key in self.properties: self.properties[key] = value self.onPropertiesUpdated() def getNode(self): return self.plnp def setOn(self): self.plight.setAttenuation(self.attenuation) self.on = True def setOff(self): self.plight.setAttenuation(1.0) self.on = False def toggle(self): if self.on: self.setOff() else: self.setOn()
class World(DirectObject): def __init__(self): self.last_mousex = 0 self.last_mousey = 0 self.zone = None self.zone_reload_name = None self.winprops = WindowProperties( ) # simple console output self.consoleNode = NodePath(PandaNode("console_root")) self.consoleNode.reparentTo(aspect2d) self.console_num_lines = 24 self.console_cur_line = -1 self.console_lines = [] for i in range(0, self.console_num_lines): self.console_lines.append(OnscreenText(text='', style=1, fg=(1,1,1,1), pos=(-1.3, .4-i*.05), align=TextNode.ALeft, scale = .035, parent = self.consoleNode)) # Configuration self.consoleOut('zonewalk v.%s loading configuration' % VERSION) self.configurator = Configurator(self) cfg = self.configurator.config resaveRes = False if 'xres' in cfg: self.xres = int(cfg['xres']) else: self.xres = 1024 resaveRes = True if 'yres' in cfg: self.yres = int(cfg['yres']) else: self.yres = 768 resaveRes = True if resaveRes: self.saveDefaultRes() self.xres_half = self.xres / 2 self.yres_half = self.yres / 2 self.mouse_accum = MouseAccume( lambda: (self.xres_half,self.yres_half)) self.eyeHeight = 7.0 self.rSpeed = 80 self.flyMode = 1 # application window setup base.win.setClearColor(Vec4(0,0,0,1)) self.winprops.setTitle( 'zonewalk') self.winprops.setSize(self.xres, self.yres) base.win.requestProperties( self.winprops ) base.disableMouse() # network test stuff self.login_client = None if 'testnet' in cfg: if cfg['testnet'] == '1': self.doLogin() # Post the instructions self.title = addTitle('zonewalk v.' + VERSION) self.inst0 = addInstructions(0.95, "[FLYMODE][1]") self.inst1 = addInstructions(-0.95, "Camera control with WSAD/mouselook. Press K for hotkey list, ESC to exit.") self.inst2 = addInstructions(0.9, "Loc:") self.inst3 = addInstructions(0.85, "Hdg:") self.error_inst = addInstructions(0, '') self.kh = [] self.campos = Point3(155.6, 41.2, 4.93) base.camera.setPos(self.campos) # Accept the application control keys: currently just esc to exit navgen self.accept("escape", self.exitGame) self.accept("window-event", self.resizeGame) # Create some lighting ambient_level = .6 ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(ambient_level, ambient_level, ambient_level, 1.0)) render.setLight(render.attachNewNode(ambientLight)) direct_level = 0.8 directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(0.0, 0.0, -1.0)) directionalLight.setColor(Vec4(direct_level, direct_level, direct_level, 1)) directionalLight.setSpecularColor(Vec4(direct_level, direct_level, direct_level, 1)) render.setLight(render.attachNewNode(directionalLight)) # create a point light that will follow our view point (the camera for now) # attenuation is set so that this point light has a torch like effect self.plight = PointLight('plight') self.plight.setColor(VBase4(0.8, 0.8, 0.8, 1.0)) self.plight.setAttenuation(Point3(0.0, 0.0, 0.0002)) self.plnp = base.camera.attachNewNode(self.plight) self.plnp.setPos(0, 0, 0) render.setLight(self.plnp) self.cam_light = 1 self.keyMap = {"left":0, "right":0, "forward":0, "backward":0, "cam-left":0, \ "cam-right":0, "mouse3":0, "flymode":1 } # setup FOG self.fog_colour = (0.8,0.8,0.8,1.0) self.linfog = Fog("A linear-mode Fog node") self.linfog.setColor(self.fog_colour) self.linfog.setLinearRange(700, 980) # onset, opaque distances as params # linfog.setLinearFallback(45,160,320) base.camera.attachNewNode(self.linfog) render.setFog(self.linfog) self.fog = 1 # camera control self.campos = Point3(0, 0, 0) self.camHeading = 0.0 self.camPitch = 0.0 base.camLens.setFov(65.0) base.camLens.setFar(1200) self.cam_speed = 0 # index into self.camp_speeds self.cam_speeds = [40.0, 80.0, 160.0, 320.0, 640.0] # Collision Detection for "WALKMODE" # We will detect the height of the terrain by creating a collision # ray and casting it downward toward the terrain. The ray will start above the camera. # A ray may hit the terrain, or it may hit a rock or a tree. If it # hits the terrain, we can detect the height. If it hits anything # else, we rule that the move is illegal. self.cTrav = CollisionTraverser() self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0.0, 0.0, 0.0) self.camGroundRay.setDirection(0,0,-1) # straight down self.camGroundCol = CollisionNode('camRay') self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(BitMask32.bit(0)) self.camGroundCol.setIntoCollideMask(BitMask32.allOff()) # attach the col node to the camCollider dummy node self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # Uncomment this line to see the collision rays # self.camGroundColNp.show() # Uncomment this line to show a visual representation of the # collisions occuring # self.cTrav.showCollisions(render) # Add the spinCameraTask procedure to the task manager. # taskMgr.add(self.spinCameraTask, "SpinCameraTask") taskMgr.add(self.camTask, "camTask") self.toggleControls(1) # need to step the task manager once to make our fake console work taskMgr.step() # CONSOLE --------------------------------------------------------------------- def consoleScroll(self): for i in range(0, self.console_num_lines-1): self.console_lines[i].setText(self.console_lines[i+1].getText()) def consoleOut(self, text): print text # output to stdout/log too if self.console_cur_line == self.console_num_lines-1: self.consoleScroll() elif self.console_cur_line < self.console_num_lines-1: self.console_cur_line += 1 self.console_lines[self.console_cur_line].setText(text) taskMgr.step() def consoleOn(self): self.consoleNode.show() def consoleOff(self): self.consoleNode.hide() # User controls ----------------------------------------------------------- def toggleControls(self, on): cfg = self.configurator.config if on == 1: self.accept("escape", self.exitGame) self.accept("1", self.setSpeed, ["speed", 0]) self.accept("2", self.setSpeed, ["speed", 1]) self.accept("3", self.setSpeed, ["speed", 2]) self.accept("4", self.setSpeed, ["speed", 3]) self.accept("5", self.setSpeed, ["speed", 4]) self.accept("alt-f", self.fogToggle) self.accept(cfg['control_lighting'], self.camLightToggle) self.accept(cfg['control_help'], self.displayKeyHelp) self.accept(cfg['control_flymode'], self.toggleFlymode) self.accept(cfg['control_reload-zone'], self.reloadZone) # Deactivate this for now #self.accept("z", self.saveDefaultZone) self.accept(cfg['control_cam-left'], self.setKey, ["cam-left",1]) self.accept(cfg['control_cam-right'], self.setKey, ["cam-right",1]) self.accept(cfg['control_forward'], self.setKey, ["forward",1]) # Mouse1 should be for clicking on objects #self.accept("mouse1", self.setKey, ["forward",1]) self.accept("mouse3", self.setKey, ["mouse3",1]) self.accept(cfg['control_backward'], self.setKey, ["backward",1]) self.accept("k-up", self.hideKeyHelp) self.accept(cfg['control_cam-left']+"-up", self.setKey, ["cam-left",0]) self.accept(cfg['control_cam-right']+"-up", self.setKey, ["cam-right",0]) self.accept(cfg['control_forward']+"-up", self.setKey, ["forward",0]) # Mouse1 should be for clicking on objects #self.accept("mouse1-up", self.setKey, ["forward",0]) self.accept("mouse3-up", self.setKey, ["mouse3",0]) self.accept(cfg['control_backward']+"-up", self.setKey, ["backward",0]) else: messenger.clear() def setSpeed(self, key, value): self.cam_speed = value self.setFlymodeText() def fogToggle(self): if self.fog == 1: render.clearFog() base.camLens.setFar(100000) self.fog = 0 else: render.setFog(self.linfog) base.camLens.setFar(1200) self.fog = 1 def camLightToggle(self): if self.cam_light == 0: render.setLight(self.plnp) self.cam_light = 1 else: render.clearLight(self.plnp) self.cam_light = 0 def displayKeyHelp(self): self.kh = [] msg = 'HOTKEYS:' pos = 0.75 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = '------------------' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'W: camera fwd, S: camera bck, A: rotate view left, D: rotate view right' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = '1-5: set camera movement speed' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'F: toggle Flymode/Walkmode' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'L: load a zone' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'ALT-F: toggle FOG and FAR plane on/off' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'T: toggle additional camera "torch" light on/off' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'Z: set currently loaded zone as new startup default' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'ESC: exit zonewalk' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) def hideKeyHelp(self): for n in self.kh: n.removeNode() def setFlymodeText(self): zname = '' if self.zone: zname = self.zone.name if self.flyMode == 0: self.inst0.setText("[WALKMODE][%i] %s" % (self.cam_speed+1, zname)) else: self.inst0.setText("[FLYMODE][%i] %s " % (self.cam_speed+1, zname)) def toggleFlymode(self): zname = '' if self.zone: zname = self.zone.name if self.flyMode == 0: self.flyMode = 1 else: self.flyMode = 0 self.setFlymodeText() # Define a procedure to move the camera. def spinCameraTask(self, task): angleDegrees = task.time * 6.0 angleRadians = angleDegrees * (pi / 180.0) base.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3) base.camera.setHpr(angleDegrees, 0, 0) return task.cont def camTask(self, task): # query the mouse mouse_dx = 0 mouse_dy = 0 # if we have a mouse and the right button is depressed if base.mouseWatcherNode.hasMouse(): if self.keyMap["mouse3"] != 0: self.mouse_accum.update() else: self.mouse_accum.reset() mouse_dx = self.mouse_accum.dx mouse_dy = self.mouse_accum.dy self.rXSpeed = fabs(self.mouse_accum.dx) * (self.cam_speed+1) * max(5 * 1000/self.xres,3) self.rYSpeed = fabs(self.mouse_accum.dy) * (self.cam_speed+1) * max(3 * 1000/self.yres,1) if (self.keyMap["cam-left"]!=0 or mouse_dx < 0): if self.rSpeed < 160: self.rSpeed += 80 * globalClock.getDt() if mouse_dx != 0: self.camHeading += self.rXSpeed * globalClock.getDt() else: self.camHeading += self.rSpeed * globalClock.getDt() if self.camHeading > 360.0: self.camHeading = self.camHeading - 360.0 elif (self.keyMap["cam-right"]!=0 or mouse_dx > 0): if self.rSpeed < 160: self.rSpeed += 80 * globalClock.getDt() if mouse_dx != 0: self.camHeading -= self.rXSpeed * globalClock.getDt() else: self.camHeading -= self.rSpeed * globalClock.getDt() if self.camHeading < 0.0: self.camHeading = self.camHeading + 360.0 else: self.rSpeed = 80 if mouse_dy > 0: self.camPitch += self.rYSpeed * globalClock.getDt() elif mouse_dy < 0: self.camPitch -= self.rYSpeed * globalClock.getDt() # set camera heading and pitch base.camera.setHpr(self.camHeading, self.camPitch, 0) # viewer position (camera) movement control v = render.getRelativeVector(base.camera, Vec3.forward()) if not self.flyMode: v.setZ(0.0) move_speed = self.cam_speeds[self.cam_speed] if self.keyMap["forward"] == 1: self.campos += v * move_speed * globalClock.getDt() if self.keyMap["backward"] == 1: self.campos -= v * move_speed * globalClock.getDt() # actually move the camera lastPos = base.camera.getPos() base.camera.setPos(self.campos) # self.plnp.setPos(self.campos) # move the point light with the viewer position # WALKMODE: simple collision detection # we simply check a ray from slightly below the "eye point" straight down # for geometry collisions and if there are any we detect the point of collision # and adjust the camera's Z accordingly if self.flyMode == 0: # move the camera to where it would be if it made the move # the colliderNode moves with it # base.camera.setPos(self.campos) # check for collissons self.cTrav.traverse(render) entries = [] for i in range(self.camGroundHandler.getNumEntries()): entry = self.camGroundHandler.getEntry(i) entries.append(entry) # print 'collision' entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(), x.getSurfacePoint(render).getZ())) if (len(entries) > 0): # and (entries[0].getIntoNode().getName() == "terrain"): # print len(entries) self.campos.setZ(entries[0].getSurfacePoint(render).getZ()+self.eyeHeight) else: self.campos = lastPos base.camera.setPos(self.campos) #if (base.camera.getZ() < self.player.getZ() + 2.0): # base.camera.setZ(self.player.getZ() + 2.0) # update loc and hpr display pos = base.camera.getPos() hpr = base.camera.getHpr() self.inst2.setText('Loc: %.2f, %.2f, %.2f' % (pos.getX(), pos.getY(), pos.getZ())) self.inst3.setText('Hdg: %.2f, %.2f, %.2f' % (hpr.getX(), hpr.getY(), hpr.getZ())) return task.cont def exitGame(self): sys.exit(0) def resizeGame(self,win): props = base.win.getProperties() self.xres = props.getXSize() self.yres = props.getYSize() self.xres_half = self.xres / 2 self.yres_half = self.yres / 2 self.saveDefaultRes() #Records the state of the arrow keys # this is used for camera control def setKey(self, key, value): self.keyMap[key] = value # ------------------------------------------------------------------------- # this is the mythical MAIN LOOP :) def update(self): if self.zone_reload_name != None: self.doReload(self.zone_reload_name) self.zone_reload_name = None if self.zone != None: self.zone.update() taskMgr.step() if self.login_client != None: self.login_client.update() # ZONE loading ------------------------------------------------------------ # general zone loader driver # removes existing zone (if any) and load the new one def loadZone(self, name, path): if path[len(path)-1] != '/': path += '/' if self.zone: self.zone.rootNode.removeNode() self.zone = Zone(self, name, path) error = self.zone.load() if error == 0: self.consoleOff() self.setFlymodeText() base.setBackgroundColor(self.fog_colour) def saveDefaultRes(self): cfg = self.configurator.config cfg['xres'] = str(self.xres) cfg['yres'] = str(self.yres) #self.configurator.saveConfig() # initial world load after bootup def load(self): cfg = self.configurator.config if self.login_client != None: return zone_name = cfg['default_zone'] basepath = cfg['basepath'] self.loadZone(zone_name, basepath) # config save user interfacce def saveDefaultZone(self): if self.zone: cfg = self.configurator.config cfg['default_zone'] = self.zone.name #self.configurator.saveConfig() # zone reload user interface # this gets called from our update loop when it detects that zone_reload_name has been set # we do this in this convoluted fashion in order to keep the main loop taskMgr updates ticking # because otherwise our status console output at various stages during the zone load would not # be displayed. Yes, this is hacky. def doReload(self, name): cfg = self.configurator.config basepath = cfg['basepath'] self.loadZone(name, basepath) # form dialog callback # this gets called from the form when the user has entered a something # (hopefully a correct zone short name) def reloadZoneDialogCB(self, name): self.frmDialog.end() self.zone_reload_name = name self.toggleControls(1) # this is called when the user presses "l" # it disables normal controls and fires up our query form dialog def reloadZone(self): base.setBackgroundColor((0,0,0)) self.toggleControls(0) self.consoleOn() self.frmDialog = FileDialog( "Please enter the shortname of the zone you wish to load:", "Examples: qrg, blackburrow, freportn, crushbone etc.", self.reloadZoneDialogCB) self.frmDialog.activate() # relies on the main update loop to run ############################### # EXPERIMENTAL def doLogin(self): self.login_client = UDPClientStream('127.0.0.1', 5998) ##################################### # Custom methods ##################################### # What happens when a user clicks on a model def onModelClick(): # Code adapted freely from http://www.panda3d.org/forums/viewtopic.php?t=12717 global picker, selected_model namedNode, thePoint, rawNode = picker.pick() if namedNode: if "_mesh" not in namedNode.getName(): # rough test to avoid printing infos on global zone mesh (ie: "freporte_mesh") name = namedNode.getName() p = namedNode.getParent() pos = p.getPos() selected_model = namedNode print namedNode.getName() print "Collision Point: ", thePoint namedNode.ls() else: print "Clicked location point (y, x, z):", thePoint #selected_model.setPos(thePoint.getX(), thePoint.getY(), thePoint.getZ()) m.setPos(thePoint.getX(), thePoint.getY(), thePoint.getZ()) print "Moved !" # Handles populating the zone with spawn data from the EQEmu DB # also makes each spawner model pickable def PopulateSpawns(self, cursor, numrows): spawn_coords = list() globals.model_list = list() for x in range(0, numrows): row = cursor.fetchone() point = Point3(long(row["Spawn2Y"]), long(row["Spawn2X"]), long(row["Spawn2Z"])) if point not in spawn_coords: s = loader.loadModel("models/cube.egg") s.reparentTo(render) s.setPos(row["Spawn2Y"], row["Spawn2X"], row["Spawn2Z"]) min,macks= s.getTightBounds() radius = max([macks.getY() - min.getY(), macks.getX() - min.getX()])/2 cs = CollisionSphere(row["Spawn2X"], row["Spawn2Y"], row["Spawn2Z"], radius) csNode = s.attachNewNode(CollisionNode("modelCollide")) csNode.node().addSolid(cs) s.setTag("name", row["name"]) picker.makePickable(s) globals.model_list.append(s) spawn_coords.append(point) # Establishes a connection to the EQEmu database def ConnectToDatabase(self): configurator = Configurator(world) cfg = configurator.config conn = MySQLdb.Connection( host=cfg['host'], user=cfg['user'], passwd=cfg['password'], db=cfg['db']) return conn # Queries the Database in order to get spawn data # (this should be refactored at some point) def GetDbSpawnData(self, connection): cursor = connection.cursor(MySQLdb.cursors.DictCursor) query = """SELECT nt.name, s2.zone, s2.x as Spawn2X, s2.y as Spawn2Y, s2.z as Spawn2Z, sg.name as spawngroup_name,sg.id as Spawngroup_id, sg.min_x as Spawngroup_minX, sg.max_x as Spawngroup_maxX, sg.min_y as Spawngroup_minY, sg.max_y as Spawngroup_maxY, sg.dist as Spawngroup_dist, sg.mindelay as Spawngroup_mindelay, sg.delay as Spawngroup_delay FROM spawn2 s2 JOIN spawngroup sg ON sg.id = s2.spawngroupid JOIN spawnentry se ON se.spawngroupid = sg.id JOIN npc_types nt ON nt.id = se.npcid WHERE s2.zone = 'freporte'""" cursor.execute(query) return cursor # Initializes the camera position upon startup def InitCameraPosition(self): world.campos = Point3(-155.6, 41.2, 4.9 + world.eyeHeight) world.camHeading = 270.0 base.camera.setPos(world.campos) def GetCamera(self): return base.camera
def __init__(self): ShowBase.__init__(self) """ SETUP CONFIG VARS """ # self.render.setShaderAuto() self.globalClock = ClockObject().getGlobalClock() self.bullet_world = BulletWorld() self.bullet_world.setGravity((0, 0, -9.81)) """ PLAYER SETUP """ # player camera self.ref_node = self.render.attachNewNode('camparent') self.debugNP = self.render.attachNewNode(BulletDebugNode('Debug')) self.debugNP.show() self.player_body_geom = make_cube_geom(geom_color=(1, 0, 0, 1)) player_body_geom_node = GeomNode('player') player_body_geom_node.addGeom(self.player_body_geom) self.player_body_geom_np = self.render.attachNewNode(player_body_geom_node) # Box shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5)) self.box_np = self.render.attachNewNode(BulletRigidBodyNode('Box')) self.box_np.node().setMass(1.0) self.box_np.node().addShape(shape) self.box_np.node().setDeactivationEnabled(False) self.player_body_geom_np.reparentTo(self.box_np) self.box_np.setPos(10, 10, 10) self.box_np.setCollideMask(BitMask32.allOn()) self.bullet_world.attachRigidBody(self.box_np.node()) # TODO: move player stuff to a new class # TODO: add cross hairs on player hud self.player_ray_end = NodePath('player-ray') self.player_ray_end.reparentTo(self.render) self.player_ray_end.reparentTo(self.ref_node) self.player_ray_end.setY(+10) # put this in front of the player self.ref_node.lookAt(self.player_ray_end) """ SETUP VARS AND USE UTIL CLASSES """ self.map_scale = 10 self.map_size = 100 self.camLens.setFov(90) total_size = 32 * 8 PlayerMovement(self) World(self, n_grids=32) # self.ref_node.reparentTo(self.box_np) """ SKY BOX SETUP """ skybox = GeomNode('skybox') skybox.addGeom(make_cube_geom(pos=(0, 0, 0), geom_color=(0.2, 0.2, 0.7, 1))) skybox_np = self.render.attachNewNode(skybox) skybox_np.reparentTo(self.ref_node) skybox_np.setPos((0, 1200, 0)) skybox_np.setScale(1200) """ ADD LIGHTS """ # ambient light ambientLight = AmbientLight('ambientLight') ambientLight.setColor((0.2, 0.2, 0.2, 1)) ambientLightNP = self.render.attachNewNode(ambientLight) self.render.setLight(ambientLightNP) # a geom to represent the sun sun_geom_node = GeomNode('sun') sun_geom_node.addGeom(make_cube_geom(geom_color=(0.5, 0.5, 0.3, 1))) sun_geom_node_path = self.render.attachNewNode(sun_geom_node) sun_geom_node_path.setScale(10) # sun sun = PointLight('sun') sun.setColor((0.4, 0.3, 0.27, 1)) sun.setAttenuation((0.1, 0, 0)) sun_np = self.render.attachNewNode(sun) sun_geom_node_path.reparentTo(sun_np) self.render.setLight(sun_np) sun_np.setPos(total_size / 2, total_size / 2, 200) """ SETUP FOR ONSCREEN TEXT """ # TODO: add chunk coords to display self.text = OnscreenText(text='fps', pos=(-1, -0.95), fg=(0, 1, 0, 1), align=TextNode.ALeft, scale=0.1) self.location_text = OnscreenText(text='location', pos=(-1, 0.8), fg=(0, 1, 0, 1), align=TextNode.ALeft, scale=0.1) self.previous_time = time.time() self.taskMgr.add(self.update_text, 'fps') self.taskMgr.add(self.update, 'physics')
class Player(GameObject): def __init__(self): GameObject.__init__( self, Vec3(0, 0, 0), "Models/PandaChan/act_p3d_chan", { "stand": "Models/PandaChan/a_p3d_chan_idle", "walk": "Models/PandaChan/a_p3d_chan_run" }, 5, 10, "player") self.actor.getChild(0).setH(180) mask = BitMask32() mask.setBit(1) self.collider.node().setIntoCollideMask(mask) mask = BitMask32() mask.setBit(1) self.collider.node().setFromCollideMask(mask) base.pusher.addCollider(self.collider, self.actor) base.cTrav.addCollider(self.collider, base.pusher) self.lastMousePos = Vec2(0, 0) self.groundPlane = Plane(Vec3(0, 0, 1), Vec3(0, 0, 0)) self.ray = CollisionRay(0, 0, 0, 0, 1, 0) rayNode = CollisionNode("playerRay") rayNode.addSolid(self.ray) mask = BitMask32() mask.setBit(2) rayNode.setFromCollideMask(mask) mask = BitMask32() rayNode.setIntoCollideMask(mask) self.rayNodePath = render.attachNewNode(rayNode) self.rayQueue = CollisionHandlerQueue() base.cTrav.addCollider(self.rayNodePath, self.rayQueue) self.beamModel = loader.loadModel("Models/Misc/bambooLaser") self.beamModel.reparentTo(self.actor) self.beamModel.setZ(1.5) self.beamModel.setLightOff() self.beamModel.hide() self.beamHitModel = loader.loadModel("Models/Misc/bambooLaserHit") self.beamHitModel.reparentTo(render) self.beamHitModel.setZ(1.5) self.beamHitModel.setLightOff() self.beamHitModel.hide() self.beamHitPulseRate = 0.15 self.beamHitTimer = 0 self.damagePerSecond = -5.0 self.score = 0 self.scoreUI = OnscreenText(text="0", pos=(-1.3, 0.825), mayChange=True, align=TextNode.ALeft) self.healthIcons = [] for i in range(self.maxHealth): icon = OnscreenImage(image="UI/health.png", pos=(-1.275 + i * 0.075, 0, 0.95), scale=0.04) icon.setTransparency(True) self.healthIcons.append(icon) self.damageTakenModel = loader.loadModel("Models/Misc/playerHit") self.damageTakenModel.setLightOff() self.damageTakenModel.setZ(1.0) self.damageTakenModel.reparentTo(self.actor) self.damageTakenModel.hide() self.damageTakenModelTimer = 0 self.damageTakenModelDuration = 0.15 self.laserSoundNoHit = loader.loadSfx("Sounds/laserNoHit.ogg") self.laserSoundNoHit.setLoop(True) self.laserSoundHit = loader.loadSfx("Sounds/laserHit.ogg") self.laserSoundHit.setLoop(True) self.beamHitLight = PointLight("beamHitLight") self.beamHitLight.setColor(Vec4(0.1, 1.0, 0.2, 1)) self.beamHitLight.setAttenuation((1.0, 0.1, 0.5)) self.beamHitLightNodePath = render.attachNewNode(self.beamHitLight) self.hurtSound = loader.loadSfx("Sounds/FemaleDmgNoise.ogg") self.yVector = Vec2(0, 1) self.actor.loop("stand") def update(self, keys, dt): GameObject.update(self, dt) self.walking = False if keys["up"]: self.walking = True self.velocity.addY(self.acceleration * dt) if keys["down"]: self.walking = True self.velocity.addY(-self.acceleration * dt) if keys["left"]: self.walking = True self.velocity.addX(-self.acceleration * dt) if keys["right"]: self.walking = True self.velocity.addX(self.acceleration * dt) if self.walking: standControl = self.actor.getAnimControl("stand") if standControl.isPlaying(): standControl.stop() walkControl = self.actor.getAnimControl("walk") if not walkControl.isPlaying(): self.actor.loop("walk") else: standControl = self.actor.getAnimControl("stand") if not standControl.isPlaying(): self.actor.stop("walk") self.actor.loop("stand") mouseWatcher = base.mouseWatcherNode if mouseWatcher.hasMouse(): mousePos = mouseWatcher.getMouse() else: mousePos = self.lastMousePos mousePos3D = Point3() nearPoint = Point3() farPoint = Point3() base.camLens.extrude(mousePos, nearPoint, farPoint) self.groundPlane.intersectsLine( mousePos3D, render.getRelativePoint(base.camera, nearPoint), render.getRelativePoint(base.camera, farPoint)) firingVector = Vec3(mousePos3D - self.actor.getPos()) firingVector2D = firingVector.getXy() firingVector2D.normalize() firingVector.normalize() heading = self.yVector.signedAngleDeg(firingVector2D) self.actor.setH(heading) self.beamHitTimer -= dt if self.beamHitTimer <= 0: self.beamHitTimer = self.beamHitPulseRate self.beamHitModel.setH(random.uniform(0.0, 360.0)) self.beamHitModel.setScale( math.sin(self.beamHitTimer * 3.142 / self.beamHitPulseRate) * 0.4 + 0.9) if keys["shoot"]: if self.rayQueue.getNumEntries() > 0: scoredHit = False self.rayQueue.sortEntries() rayHit = self.rayQueue.getEntry(0) hitPos = rayHit.getSurfacePoint(render) hitNodePath = rayHit.getIntoNodePath() if hitNodePath.hasPythonTag("owner"): hitObject = hitNodePath.getPythonTag("owner") if not isinstance(hitObject, TrapEnemy): hitObject.alterHealth(self.damagePerSecond * dt) scoredHit = True beamLength = (hitPos - self.actor.getPos()).length() self.beamModel.setSy(beamLength) self.beamModel.show() if scoredHit: if self.laserSoundNoHit.status() == AudioSound.PLAYING: self.laserSoundNoHit.stop() if self.laserSoundHit.status() != AudioSound.PLAYING: self.laserSoundHit.play() self.beamHitModel.show() self.beamHitModel.setPos(hitPos) self.beamHitLightNodePath.setPos(hitPos + Vec3(0, 0, 0.5)) if not render.hasLight(self.beamHitLightNodePath): render.setLight(self.beamHitLightNodePath) else: if self.laserSoundHit.status() == AudioSound.PLAYING: self.laserSoundHit.stop() if self.laserSoundNoHit.status() != AudioSound.PLAYING: self.laserSoundNoHit.play() if render.hasLight(self.beamHitLightNodePath): render.clearLight(self.beamHitLightNodePath) self.beamHitModel.hide() else: if render.hasLight(self.beamHitLightNodePath): render.clearLight(self.beamHitLightNodePath) self.beamModel.hide() self.beamHitModel.hide() if self.laserSoundNoHit.status() == AudioSound.PLAYING: self.laserSoundNoHit.stop() if self.laserSoundHit.status() == AudioSound.PLAYING: self.laserSoundHit.stop() if firingVector.length() > 0.001: self.ray.setOrigin(self.actor.getPos()) self.ray.setDirection(firingVector) self.lastMousePos = mousePos if self.damageTakenModelTimer > 0: self.damageTakenModelTimer -= dt self.damageTakenModel.setScale(2.0 - self.damageTakenModelTimer / self.damageTakenModelDuration) if self.damageTakenModelTimer <= 0: self.damageTakenModel.hide() def updateScore(self): self.scoreUI.setText(str(self.score)) def alterHealth(self, dHealth): GameObject.alterHealth(self, dHealth) self.updateHealthUI() self.damageTakenModel.show() self.damageTakenModel.setH(random.uniform(0.0, 360.0)) self.damageTakenModelTimer = self.damageTakenModelDuration self.hurtSound.play() def updateHealthUI(self): for index, icon in enumerate(self.healthIcons): if index < self.health: icon.show() else: icon.hide() def cleanup(self): self.scoreUI.removeNode() for icon in self.healthIcons: icon.removeNode() self.beamHitModel.removeNode() base.cTrav.removeCollider(self.rayNodePath) self.laserSoundHit.stop() self.laserSoundNoHit.stop() render.clearLight(self.beamHitLightNodePath) self.beamHitLightNodePath.removeNode() GameObject.cleanup(self)
def loadLights(self): # Set a simple light dlight = DirectionalLight('DirectLight') dlnp = render.attachNewNode(dlight) dlnp.setHpr(-30, 0, 0) render.setLight(dlnp) self.directLight = dlnp self.discoLights = [] p1 = PointLight("PointLight1") p1.setColor(VBase4(1, 0, 0, 1)) p1.setAttenuation((0.08, 0, 0.05)) p1np = render.attachNewNode(p1) p1np.setPos(0, -5, 0) render.setLight(p1np) self.discoLights.append(p1) p2 = PointLight("PointLight2") p2.setColor(VBase4(0, 1, 0, 1)) p2.setAttenuation((0.08, 0, 0.05)) p2np = render.attachNewNode(p2) p2np.setPos(5, -5, 0) render.setLight(p2np) self.discoLights.append(p2) p3 = PointLight("PointLight3") p3.setColor(VBase4(0, 0, 1, 1)) p3.setAttenuation((0.08, 0, 0.05)) p3np = render.attachNewNode(p3) p3np.setPos(-5, -5, 0) render.setLight(p3np) self.discoLights.append(p3) p4 = PointLight("PointLight4") p4.setColor(VBase4(0, 0, 1, 1)) p4.setAttenuation((0.08, 0, 0.05)) p4np = render.attachNewNode(p4) p4np.setPos(-5, -5, 5) render.setLight(p4np) self.discoLights.append(p4) p5 = PointLight("PointLight1") p5.setColor(VBase4(0, 0, 1, 1)) p5.setAttenuation((0.08, 0, 0.05)) p5np = render.attachNewNode(p5) p5np.setPos(0, -5, 5) render.setLight(p5np) self.discoLights.append(p5) p6 = PointLight("PointLight1") p6.setColor(VBase4(0, 0, 1, 1)) p6.setAttenuation((0.08, 0, 0.05)) p6np = render.attachNewNode(p6) p6np.setPos(5, -5, 5) render.setLight(p6np) self.discoLights.append(p6)
def __init__(self): # Check video card capabilities. if (base.win.getGsg().getSupportsBasicShaders() == 0): addTitle("Bump Mapping: Video driver reports that shaders are not supported.") return # Post the instructions self.title = addTitle("Panda3D: Tutorial - Bump Mapping") self.inst1 = addInstructions(0.95, "Press ESC to exit") self.inst2 = addInstructions(0.90, "Move mouse to rotate camera") self.inst3 = addInstructions(0.85, "Left mouse button: Move forwards") self.inst4 = addInstructions(0.80, "Right mouse button: Move backwards") self.inst5 = addInstructions(0.75, "Enter: Turn bump maps Off") # Load the 'abstract room' model. This is a model of an # empty room containing a pillar, a pyramid, and a bunch # of exaggeratedly bumpy textures. self.room = loader.loadModel("models/abstractroom") self.room.reparentTo(render) # Make the mouse invisible, turn off normal mouse controls base.disableMouse() props = WindowProperties() props.setCursorHidden(True) base.win.requestProperties(props) # Set the current viewing target self.focus = Vec3(55,-55,20) self.heading = 180 self.pitch = 0 self.mousex = 0 self.mousey = 0 self.last = 0 self.mousebtn = [0,0,0] # Start the camera control task: taskMgr.add(self.controlCamera, "camera-task") self.accept("escape", sys.exit, [0]) self.accept("mouse1", self.setMouseBtn, [0, 1]) self.accept("mouse1-up", self.setMouseBtn, [0, 0]) self.accept("mouse2", self.setMouseBtn, [1, 1]) self.accept("mouse2-up", self.setMouseBtn, [1, 0]) self.accept("mouse3", self.setMouseBtn, [2, 1]) self.accept("mouse3-up", self.setMouseBtn, [2, 0]) self.accept("enter", self.toggleShader) self.accept("j", self.rotateLight, [-1]) self.accept("k", self.rotateLight, [1]) self.accept("arrow_left", self.rotateCam, [-1]) self.accept("arrow_right", self.rotateCam, [1]) # Add a light to the scene. self.lightpivot = render.attachNewNode("lightpivot") self.lightpivot.setPos(0,0,25) self.lightpivot.hprInterval(10,Point3(360,0,0)).loop() plight = PointLight('plight') plight.setColor(Vec4(1, 1, 1, 1)) plight.setAttenuation(Vec3(0.7,0.05,0)) plnp = self.lightpivot.attachNewNode(plight) plnp.setPos(45, 0, 0) self.room.setLight(plnp) # Add an ambient light alight = AmbientLight('alight') alight.setColor(Vec4(0.2, 0.2, 0.2, 1)) alnp = render.attachNewNode(alight) self.room.setLight(alnp) # create a sphere to denote the light sphere = loader.loadModel("models/sphere") sphere.reparentTo(plnp) # load and apply the shader. This is using panda's # built-in shader generation capabilities to create the # shader for you. However, if desired, you can supply # the shader manually. Change this line of code to: # self.room.setShaderInput("light", plnp) # self.room.setShader(Shader.load("bumpMapper.sha")) self.room.setShaderAuto() self.shaderenable = 1
def __init__(self): # Configure the parallax mapping settings (these are just the defaults) loadPrcFileData("", "parallax-mapping-samples 3\n" "parallax-mapping-scale 0.1") # Initialize the ShowBase class from which we inherit, which will # create a window and set up everything we need for rendering into it. ShowBase.__init__(self) # Check video card capabilities. if not self.win.getGsg().getSupportsBasicShaders(): addTitle("Bump Mapping: " "Video driver reports that Cg shaders are not supported.") return # Post the instructions self.title = addTitle("Panda3D: Tutorial - Bump Mapping") self.inst1 = addInstructions(0.06, "Press ESC to exit") self.inst2 = addInstructions(0.12, "Move mouse to rotate camera") self.inst3 = addInstructions(0.18, "Left mouse button: Move forwards") self.inst4 = addInstructions(0.24, "Right mouse button: Move backwards") self.inst5 = addInstructions(0.30, "Enter: Turn bump maps Off") # Load the 'abstract room' model. This is a model of an # empty room containing a pillar, a pyramid, and a bunch # of exaggeratedly bumpy textures. self.room = loader.loadModel("models/abstractroom") self.room.reparentTo(render) # Make the mouse invisible, turn off normal mouse controls self.disableMouse() props = WindowProperties() props.setCursorHidden(True) self.win.requestProperties(props) self.camLens.setFov(60) # Set the current viewing target self.focus = LVector3(55, -55, 20) self.heading = 180 self.pitch = 0 self.mousex = 0 self.mousey = 0 self.last = 0 self.mousebtn = [0, 0, 0] # Start the camera control task: taskMgr.add(self.controlCamera, "camera-task") self.accept("escape", sys.exit, [0]) self.accept("mouse1", self.setMouseBtn, [0, 1]) self.accept("mouse1-up", self.setMouseBtn, [0, 0]) self.accept("mouse2", self.setMouseBtn, [1, 1]) self.accept("mouse2-up", self.setMouseBtn, [1, 0]) self.accept("mouse3", self.setMouseBtn, [2, 1]) self.accept("mouse3-up", self.setMouseBtn, [2, 0]) self.accept("enter", self.toggleShader) self.accept("j", self.rotateLight, [-1]) self.accept("k", self.rotateLight, [1]) self.accept("arrow_left", self.rotateCam, [-1]) self.accept("arrow_right", self.rotateCam, [1]) # Add a light to the scene. self.lightpivot = render.attachNewNode("lightpivot") self.lightpivot.setPos(0, 0, 25) self.lightpivot.hprInterval(10, LPoint3(360, 0, 0)).loop() plight = PointLight('plight') plight.setColor((1, 1, 1, 1)) plight.setAttenuation(LVector3(0.7, 0.05, 0)) plnp = self.lightpivot.attachNewNode(plight) plnp.setPos(45, 0, 0) self.room.setLight(plnp) # Add an ambient light alight = AmbientLight('alight') alight.setColor((0.2, 0.2, 0.2, 1)) alnp = render.attachNewNode(alight) self.room.setLight(alnp) # Create a sphere to denote the light sphere = loader.loadModel("models/icosphere") sphere.reparentTo(plnp) # Tell Panda that it should generate shaders performing per-pixel # lighting for the room. self.room.setShaderAuto() self.shaderenable = 1
def __init__(self, shipSpec): GameObject.__init__(self, Vec3(0, 0, 0), None, None, shipSpec.maxShields, shipSpec.maxSpeed, "player", MASK_INTO_PLAYER, 2) ArmedObject.__init__(self) self.acceleration = shipSpec.acceleration self.turnRate = shipSpec.turnRate self.numGuns = len(shipSpec.gunPositions) self.numMissiles = shipSpec.numMissiles self.maxEnergy = shipSpec.maxEnergy self.energyRechargeRate = shipSpec.energyRechargeRate self.shieldRechargeRate = shipSpec.shieldRechargeRate self.energy = shipSpec.maxEnergy for gunPos in shipSpec.gunPositions: np = self.actor.attachNewNode(PandaNode("gun node")) np.setPos(gunPos) gun = BlasterWeapon() self.addWeapon(gun, 0, np) missileSetCounter = 1 for missilePos in shipSpec.missilePositions: np = self.actor.attachNewNode(PandaNode("missile node")) np.setPos(missilePos) gun = RocketWeapon() self.addWeapon(gun, missileSetCounter, np) missileSetCounter += 1 self.numMissileSets = missileSetCounter - 1 self.missileSetIndex = 0 light = PointLight("basic light") light.setColor(Vec4(1, 1, 1, 1)) light.setAttenuation((1, 0.01, 0.001)) self.lightNP = self.root.attachNewNode(light) self.lightNP.setZ(1) Common.framework.showBase.render.setLight(self.lightNP) self.colliderNP.node().setFromCollideMask(MASK_WALLS | MASK_FROM_PLAYER) Common.framework.pusher.addCollider(self.colliderNP, self.root) Common.framework.traverser.addCollider(self.colliderNP, Common.framework.pusher) Common.framework.showBase.camera.reparentTo(self.actor) Common.framework.showBase.camera.setPos(0, 0, 0) Common.framework.showBase.camera.setHpr(0, 0, 0) lens = Common.framework.showBase.camLens lens.setNear(0.03) ratio = lens.getAspectRatio() lens.setFov(75 * ratio) self.lastMousePos = Vec2(0, 0) self.mouseSpeedHori = 50.0 self.mouseSpeedVert = 30.0 self.mouseSensitivity = 1.0 self.targetingRay = CollisionSegment(0, 0, 0, 0, 100, 0) self.targetingRayNode = CollisionNode("lock ray") self.targetingRayNode.addSolid(self.targetingRay) self.targetingRayNode.setFromCollideMask(MASK_ENEMY_LOCK_SPHERE) self.targetingRayNode.setIntoCollideMask(0) self.targetingRayNP = self.actor.attachNewNode(self.targetingRayNode) self.targetingQueue = CollisionHandlerQueue() self.prospectiveLockTarget = None self.lockTargetTimer = 0 self.lockDuration = 1 Common.framework.traverser.addCollider(self.targetingRayNP, self.targetingQueue) #rayNodePath.show() self.uiRoot = aspect2d.attachNewNode(PandaNode("player UI")) cardMaker = CardMaker("UI maker") cardMaker.setFrame(-1, 1, -1, 1) self.centreSpot = self.uiRoot.attachNewNode(cardMaker.generate()) self.centreSpot.setTexture( Common.framework.showBase.loader.loadTexture( "../Section2SpaceflightDocking/UI/spot.png")) self.centreSpot.setTransparency(True) self.centreSpot.setPos(0, 0, 0) self.centreSpot.setScale(0.01) self.centreSpot.setAlphaScale(0.5) self.directionIndicator = self.uiRoot.attachNewNode( cardMaker.generate()) self.directionIndicator.setTexture( Common.framework.showBase.loader.loadTexture( "../Section2SpaceflightDocking/UI/directionIndicator.png")) self.directionIndicator.setTransparency(True) self.directionIndicator.setScale(0.05) self.directionIndicator.hide() self.lockMarkerRoot = self.uiRoot.attachNewNode( PandaNode("lock marker root")) for i in range(4): markerRotationNP = self.lockMarkerRoot.attachNewNode( PandaNode("lock marker rotation")) marker = markerRotationNP.attachNewNode(cardMaker.generate()) marker.setTexture( Common.framework.showBase.loader.loadTexture( "../Section2SpaceflightDocking/UI/lockMarker.png")) marker.setTransparency(True) markerRotationNP.setScale(0.04) markerRotationNP.setR(i * 90) self.lockMarkerRoot.hide() self.lockBar = Common.framework.showBase.loader.loadModel( "../Section2SpaceflightDocking/UI/uiLockBar") self.lockBar.reparentTo(self.uiRoot) self.lockBar.setScale(0.15) #self.lockBar.hide() cardMaker.setFrame(-1, 1, 0, 1) self.cockpit = Common.framework.showBase.loader.loadModel( "../Section2SpaceflightDocking/Models/{0}".format( shipSpec.cockpitModelFile)) self.cockpit.reparentTo(self.actor) healthBarRoot = self.cockpit.find("**/healthBar") if healthBarRoot is None or healthBarRoot.isEmpty(): healthBarRoot = self.uiRoot.attachNewNode( PandaNode("health bar root")) print("No health bar root found!") energyBarRoot = self.cockpit.find("**/energyBar") if energyBarRoot is None or energyBarRoot.isEmpty(): energyBarRoot = self.uiRoot.attachNewNode( PandaNode("energy bar root")) print("No energy bar root found!") missileCounterRoot = self.cockpit.find("**/missileCounter") if missileCounterRoot is None or missileCounterRoot.isEmpty(): missileCounterRoot = self.uiRoot.attachNewNode( PandaNode("missile counter root")) print("No missile counter root found!") radarRoot = self.cockpit.find("**/radar") if radarRoot is None or radarRoot.isEmpty(): radarRoot = self.uiRoot.attachNewNode(PandaNode("radar root")) print("No radar root found!") speedometerRoot = self.cockpit.find("**/speedometer") if speedometerRoot is None or speedometerRoot.isEmpty(): speedometerRoot = self.uiRoot.attachNewNode( PandaNode("speedometer root")) print("No speedometer root found!") self.radarDrawer = MeshDrawer() self.radarDrawer.setBudget(4096) self.radarDrawerNP = self.radarDrawer.getRoot() self.radarDrawerNP.reparentTo(radarRoot) self.radarDrawerNP.setTwoSided(True) self.radarDrawerNP.setLightOff() self.radarDrawerNP.setDepthWrite(False) self.radarDrawerNP.setTransparency(True) self.healthBar = healthBarRoot.attachNewNode(cardMaker.generate()) self.healthBar.setSx(0.05) self.energyBar = energyBarRoot.attachNewNode(cardMaker.generate()) self.energyBar.setSx(0.05) self.healthBarScalar = 0.00175 self.energyBarScalar = 0.00175 self.missileCounter = DirectLabel(text="", text_mayChange=True, scale=0.09, relief=None, parent=missileCounterRoot) self.maxRadarRange = 700 self.radarSize = 0.3 self.speedometer = DirectLabel(text="", text_mayChange=True, scale=0.09, relief=None, parent=speedometerRoot) self.updateHealthUI() self.updateEnergyUI() self.updateMissileUI() self.updateRadar() self.updateSpeedometer() self.updatingEffects = []
class World(DirectObject): cfg = None def __init__(self): self.last_mousex = 0 self.last_mousey = 0 self.zone = None self.zone_reload_name = None self.winprops = WindowProperties( ) # simple console output self.consoleNode = NodePath(PandaNode("console_root")) self.consoleNode.reparentTo(aspect2d) self.console_num_lines = 24 self.console_cur_line = -1 self.console_lines = [] for i in range(0, self.console_num_lines): self.console_lines.append(OnscreenText(text='', style=1, fg=(1,1,1,1), pos=(-1.3, .4-i*.05), align=TextNode.ALeft, scale = .035, parent = self.consoleNode)) # Configuration self.consoleOut('World Forge v.%s loading configuration' % VERSION) self.configurator = Configurator(self) cfg = self.configurator.config resaveRes = False if 'xres' in cfg: self.xres = int(cfg['xres']) else: self.xres = 1024 resaveRes = True if 'yres' in cfg: self.yres = int(cfg['yres']) else: self.yres = 768 resaveRes = True if resaveRes: self.saveDefaultRes() self.xres_half = self.xres / 2 self.yres_half = self.yres / 2 self.mouse_accum = MouseAccume( lambda: (self.xres_half,self.yres_half)) self.eyeHeight = 7.0 self.rSpeed = 80 self.flyMode = 1 # application window setup base.win.setClearColor(Vec4(0,0,0,1)) self.winprops.setTitle( 'World Forge') self.winprops.setSize(self.xres, self.yres) base.win.requestProperties( self.winprops ) base.disableMouse() # Post the instructions self.title = addTitle('World Forge v.' + VERSION) self.inst0 = addInstructions(0.95, "[FLYMODE][1]") self.inst1 = addInstructions(-0.95, "Camera control with WSAD/mouselook. Press K for hotkey list, ESC to exit.") self.inst2 = addInstructions(0.9, "Loc:") self.inst3 = addInstructions(0.85, "Hdg:") self.error_inst = addInstructions(0, '') self.kh = [] self.campos = Point3(155.6, 41.2, 4.93) base.camera.setPos(self.campos) # Accept the application control keys: currently just esc to exit navgen self.accept("escape", self.exitGame) self.accept("window-event", self.resizeGame) # Create some lighting ambient_level = .6 ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(ambient_level, ambient_level, ambient_level, 1.0)) render.setLight(render.attachNewNode(ambientLight)) direct_level = 0.8 directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(0.0, 0.0, -1.0)) directionalLight.setColor(Vec4(direct_level, direct_level, direct_level, 1)) directionalLight.setSpecularColor(Vec4(direct_level, direct_level, direct_level, 1)) render.setLight(render.attachNewNode(directionalLight)) # create a point light that will follow our view point (the camera for now) # attenuation is set so that this point light has a torch like effect self.plight = PointLight('plight') self.plight.setColor(VBase4(0.8, 0.8, 0.8, 1.0)) self.plight.setAttenuation(Point3(0.0, 0.0, 0.0002)) self.plnp = base.camera.attachNewNode(self.plight) self.plnp.setPos(0, 0, 0) render.setLight(self.plnp) self.cam_light = 1 self.keyMap = {"left":0, "right":0, "forward":0, "backward":0, "cam-left":0, \ "cam-right":0, "mouse3":0, "flymode":1 } # setup FOG self.fog_colour = (0.8,0.8,0.8,1.0) self.linfog = Fog("A linear-mode Fog node") self.linfog.setColor(self.fog_colour) self.linfog.setLinearRange(700, 980) # onset, opaque distances as params # linfog.setLinearFallback(45,160,320) base.camera.attachNewNode(self.linfog) render.setFog(self.linfog) self.fog = 1 # camera control self.campos = Point3(0, 0, 0) self.camHeading = 0.0 self.camPitch = 0.0 base.camLens.setFov(65.0) base.camLens.setFar(1200) self.cam_speed = 0 # index into self.camp_speeds self.cam_speeds = [40.0, 80.0, 160.0, 320.0, 640.0] # Collision Detection for "WALKMODE" # We will detect the height of the terrain by creating a collision # ray and casting it downward toward the terrain. The ray will start above the camera. # A ray may hit the terrain, or it may hit a rock or a tree. If it # hits the terrain, we can detect the height. If it hits anything # else, we rule that the move is illegal. self.cTrav = CollisionTraverser() self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0.0, 0.0, 0.0) self.camGroundRay.setDirection(0,0,-1) # straight down self.camGroundCol = CollisionNode('camRay') self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(BitMask32.bit(0)) self.camGroundCol.setIntoCollideMask(BitMask32.allOff()) # attach the col node to the camCollider dummy node self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # Uncomment this line to see the collision rays # self.camGroundColNp.show() # Uncomment this line to show a visual representation of the # collisions occuring # self.cTrav.showCollisions(render) # Add the spinCameraTask procedure to the task manager. # taskMgr.add(self.spinCameraTask, "SpinCameraTask") globals.hasClickedSpawn = False; globals.hasClickedGrid = False; taskMgr.add(self.camTask, "camTask") self.toggleControls(1) # need to step the task manager once to make our fake console work taskMgr.step() # CONSOLE --------------------------------------------------------------------- def consoleScroll(self): for i in range(0, self.console_num_lines-1): self.console_lines[i].setText(self.console_lines[i+1].getText()) def consoleOut(self, text): print text # output to stdout/log too if self.console_cur_line == self.console_num_lines-1: self.consoleScroll() elif self.console_cur_line < self.console_num_lines-1: self.console_cur_line += 1 self.console_lines[self.console_cur_line].setText(text) taskMgr.step() def consoleOn(self): self.consoleNode.show() def consoleOff(self): self.consoleNode.hide() # User controls ----------------------------------------------------------- def toggleControls(self, on): cfg = self.configurator.config if on == 1: self.accept("escape", self.exitGame) self.accept("1", self.setSpeed, ["speed", 0]) self.accept("2", self.setSpeed, ["speed", 1]) self.accept("3", self.setSpeed, ["speed", 2]) self.accept("4", self.setSpeed, ["speed", 3]) self.accept("5", self.setSpeed, ["speed", 4]) self.accept("alt-f", self.fogToggle) self.accept(cfg['control_lighting'], self.camLightToggle) self.accept(cfg['control_help'], self.displayKeyHelp) self.accept(cfg['control_flymode'], self.toggleFlymode) self.accept(cfg['control_reload-zone'], self.reloadZone) self.accept(cfg['control_cam-left'], self.setKey, ["cam-left",1]) self.accept(cfg['control_cam-right'], self.setKey, ["cam-right",1]) self.accept(cfg['control_forward'], self.setKey, ["forward",1]) self.accept("mouse3", self.setKey, ["mouse3",1]) self.accept(cfg['control_backward'], self.setKey, ["backward",1]) self.accept("k-up", self.hideKeyHelp) self.accept(cfg['control_cam-left']+"-up", self.setKey, ["cam-left",0]) self.accept(cfg['control_cam-right']+"-up", self.setKey, ["cam-right",0]) self.accept(cfg['control_forward']+"-up", self.setKey, ["forward",0]) self.accept("mouse3-up", self.setKey, ["mouse3",0]) self.accept(cfg['control_backward']+"-up", self.setKey, ["backward",0]) self.accept(cfg['toggle_edit-mode'], self.toggleEditMode) self.accept(cfg['toggle_insert-mode'], self.toggleInsertMode) self.accept(cfg['toggle_explore-mode'], self.toggleExploreMode) self.accept(cfg['toggle_grid-mode'], self.toggleGridMode) # Accept both single-presses and long presses for rotating models self.accept(cfg['rotate-right'] + "-repeat", self.rotateModelRight) self.accept(cfg['rotate-left'] + "-repeat", self.rotateModelLeft) self.accept(cfg['rotate-right'], self.rotateModelRight) self.accept(cfg['rotate-left'], self.rotateModelLeft) self.accept(cfg['clear-selection'], self.clearSelection) else: messenger.clear() def rotateModelRight(self): if globals.editMode == True: if globals.selectedSpawn: cfg = self.configurator.config globals.selectedSpawn.model.setH(globals.selectedSpawn.model.getH() + int(cfg['rotation-amount'])) # Really not sure about that... if globals.selectedSpawn.model.getH() > 360: globals.selectedSpawn.model.setH(0) print globals.selectedSpawn.model.getH() globals.selectedSpawn.setheadingfromworld(globals.selectedSpawn.model.getH()) globals.spawndialog.m_spawnEntryHeadingTextCtrl.SetValue(str(globals.selectedSpawn.spawnentry_heading)) if globals.config['autosave_edit-mode'] == 'True': globals.database.UpdateSpawn(globals.selectedSpawn) print globals.selectedSpawn.spawnentry_heading def rotateModelLeft(self): if globals.editMode == True: if globals.selectedSpawn: cfg = self.configurator.config globals.selectedSpawn.model.setH(globals.selectedSpawn.model.getH() - int(cfg['rotation-amount'])) # Really not sure about that either... if globals.selectedSpawn.model.getH() < -360: globals.selectedSpawn.model.setH(0) print globals.selectedSpawn.model.getH() globals.selectedSpawn.setheadingfromworld(globals.selectedSpawn.model.getH()) globals.spawndialog.m_spawnEntryHeadingTextCtrl.SetValue(str(globals.selectedSpawn.spawnentry_heading)) if globals.config['autosave_edit-mode'] == 'True': globals.database.UpdateSpawn(globals.selectedSpawn) print globals.selectedSpawn.spawnentry_heading def clearSelection(self, eraseNpcId = True): globals.selectedspawn = None globals.selectedgrid = None globals.picker.lastSelectedObject = None if self.inst6: self.inst6.destroy() self.inst6 = addInstructions(0.7, "Current selection: None") npcid = globals.spawndialog.m_spawnEntryNpcIdTextCtrl.Value globals.spawndialog.Reset() # f*****g hacky shit man if eraseNpcId == False: globals.spawndialog.m_spawnEntryNpcIdTextCtrl.SetValue(npcid) gridmanager = GridpointManager() gridmanager.ResetGridList() print "Cleared all selections !" def toggleDefaultMode(self): globals.editMode = False globals.insertMode = False globals.exploreMode = True globals.gridMode = False print "STARTUP Explore mode ACTIVATED" print "STARTUP Grid mode DEACTIVATED" self.inst4 = addInstructions(0.8, "Explore mode ON") self.inst5 = addInstructions(0.75, "Grid mode OFF") self.inst6 = addInstructions(0.7, "Current selection: None") def toggleEditMode(self): globals.editMode = True globals.insertMode = False globals.exploreMode = False print "Edit mode ACTIVATED" if self.inst4: self.inst4.destroy() self.inst4 = addInstructions(0.8, "Edit mode ON") def toggleInsertMode(self): globals.editMode = False globals.insertMode = True globals.exploreMode = False print "Insert mode ACTIVATED" if self.inst4: self.inst4.destroy() self.inst4 = addInstructions(0.8, "Insert mode ON") def toggleExploreMode(self): globals.editMode = False globals.insertMode = False globals.exploreMode = True print "Explore mode ACTIVATED" if self.inst4: self.inst4.destroy() self.inst4 = addInstructions(0.8, "Explore mode ON") def toggleGridMode(self): if globals.gridMode == False: globals.gridMode = True print "Grid mode ACTIVATED" if self.inst5: self.inst5.destroy() self.inst5 = addInstructions(0.75, "Grid mode ON") else: globals.gridMode = False print "Grid mode DEACTIVATED" if self.inst5: self.inst5.destroy() self.inst5 = addInstructions(0.75, "Grid mode OFF") def setSpeed(self, key, value): self.cam_speed = value self.setFlymodeText() def fogToggle(self): if self.fog == 1: render.clearFog() base.camLens.setFar(100000) self.fog = 0 else: render.setFog(self.linfog) base.camLens.setFar(1200) self.fog = 1 def camLightToggle(self): if self.cam_light == 0: render.setLight(self.plnp) self.cam_light = 1 else: render.clearLight(self.plnp) self.cam_light = 0 def displayKeyHelp(self): self.kh = [] msg = 'HOTKEYS:' pos = 0.75 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = '------------------' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'W: camera fwd, S: camera bck, A: rotate view left, D: rotate view right' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = '1-5: set camera movement speed' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'F: toggle Flymode/Walkmode' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'L: load a zone' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'ALT-F: toggle FOG and FAR plane on/off' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'T: toggle additional camera "torch" light on/off' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'Z: set currently loaded zone as new startup default' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'ESC: exit World Forge' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) def hideKeyHelp(self): for n in self.kh: n.removeNode() def setFlymodeText(self): zname = '' if self.zone: zname = self.zone.name if self.flyMode == 0: self.inst0.setText("[WALKMODE][%i] %s" % (self.cam_speed+1, zname)) else: self.inst0.setText("[FLYMODE][%i] %s " % (self.cam_speed+1, zname)) def toggleFlymode(self): zname = '' if self.zone: zname = self.zone.name if self.flyMode == 0: self.flyMode = 1 else: self.flyMode = 0 self.setFlymodeText() # Define a procedure to move the camera. def spinCameraTask(self, task): angleDegrees = task.time * 6.0 angleRadians = angleDegrees * (pi / 180.0) base.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3) base.camera.setHpr(angleDegrees, 0, 0) return task.cont def camTask(self, task): if globals.hasClickedSpawn: base.camera.setPos(globals.selectedSpawnPoint3D) self.campos = globals.selectedSpawnPoint3D globals.hasClickedSpawn = False elif globals.hasClickedGrid: base.camera.setPos(globals.selectedGridPoint3D) self.campos = globals.selectedGridPoint3D globals.hasClickedGrid = False else: # query the mouse mouse_dx = 0 mouse_dy = 0 # if we have a mouse and the right button is depressed if base.mouseWatcherNode.hasMouse(): if self.keyMap["mouse3"] != 0: self.mouse_accum.update() else: self.mouse_accum.reset() mouse_dx = self.mouse_accum.dx mouse_dy = self.mouse_accum.dy self.rXSpeed = fabs(self.mouse_accum.dx) * (self.cam_speed+1) * max(5 * 1000/self.xres,3) self.rYSpeed = fabs(self.mouse_accum.dy) * (self.cam_speed+1) * max(3 * 1000/self.yres,1) if (self.keyMap["cam-left"]!=0 or mouse_dx < 0): if self.rSpeed < 160: self.rSpeed += 80 * globalClock.getDt() if mouse_dx != 0: self.camHeading += self.rXSpeed * globalClock.getDt() else: self.camHeading += self.rSpeed * globalClock.getDt() if self.camHeading > 360.0: self.camHeading = self.camHeading - 360.0 elif (self.keyMap["cam-right"]!=0 or mouse_dx > 0): if self.rSpeed < 160: self.rSpeed += 80 * globalClock.getDt() if mouse_dx != 0: self.camHeading -= self.rXSpeed * globalClock.getDt() else: self.camHeading -= self.rSpeed * globalClock.getDt() if self.camHeading < 0.0: self.camHeading = self.camHeading + 360.0 else: self.rSpeed = 80 if mouse_dy > 0: self.camPitch += self.rYSpeed * globalClock.getDt() elif mouse_dy < 0: self.camPitch -= self.rYSpeed * globalClock.getDt() # set camera heading and pitch base.camera.setHpr(self.camHeading, self.camPitch, 0) # viewer position (camera) movement control v = render.getRelativeVector(base.camera, Vec3.forward()) if not self.flyMode: v.setZ(0.0) move_speed = self.cam_speeds[self.cam_speed] if self.keyMap["forward"] == 1: self.campos += v * move_speed * globalClock.getDt() if self.keyMap["backward"] == 1: self.campos -= v * move_speed * globalClock.getDt() # actually move the camera lastPos = base.camera.getPos() base.camera.setPos(self.campos) # self.plnp.setPos(self.campos) # move the point light with the viewer position # WALKMODE: simple collision detection # we simply check a ray from slightly below the "eye point" straight down # for geometry collisions and if there are any we detect the point of collision # and adjust the camera's Z accordingly if self.flyMode == 0: # move the camera to where it would be if it made the move # the colliderNode moves with it # base.camera.setPos(self.campos) # check for collissons self.cTrav.traverse(render) entries = [] for i in range(self.camGroundHandler.getNumEntries()): entry = self.camGroundHandler.getEntry(i) entries.append(entry) # print 'collision' entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(), x.getSurfacePoint(render).getZ())) if (len(entries) > 0): # and (entries[0].getIntoNode().getName() == "terrain"): # print len(entries) self.campos.setZ(entries[0].getSurfacePoint(render).getZ()+self.eyeHeight) else: self.campos = lastPos base.camera.setPos(self.campos) #if (base.camera.getZ() < self.player.getZ() + 2.0): # base.camera.setZ(self.player.getZ() + 2.0) # update loc and hpr display pos = base.camera.getPos() hpr = base.camera.getHpr() self.inst2.setText('Loc: %.2f, %.2f, %.2f' % (pos.getX(), pos.getY(), pos.getZ())) self.inst3.setText('Hdg: %.2f, %.2f, %.2f' % (hpr.getX(), hpr.getY(), hpr.getZ())) return task.cont def exitGame(self): globals.database.conn.close() print "DB connection closed !" sys.exit(0) def resizeGame(self,win): props = base.win.getProperties() self.xres = props.getXSize() self.yres = props.getYSize() self.xres_half = self.xres / 2 self.yres_half = self.yres / 2 self.saveDefaultRes() #Records the state of the arrow keys # this is used for camera control def setKey(self, key, value): self.keyMap[key] = value # ------------------------------------------------------------------------- # this is the mythical MAIN LOOP :) def update(self): if self.zone_reload_name != None: self.doReload(self.zone_reload_name) self.zone_reload_name = None if self.zone != None: self.zone.update() taskMgr.step() # ZONE loading ------------------------------------------------------------ # general zone loader driver # removes existing zone (if any) and load the new one def loadZone(self, name, path): if path[len(path)-1] != '/': path += '/' if self.zone: self.zone.rootNode.removeNode() self.zone = Zone(self, name, path) error = self.zone.load() if error == 0: self.consoleOff() self.setFlymodeText() base.setBackgroundColor(self.fog_colour) def saveDefaultRes(self): cfg = self.configurator.config cfg['xres'] = str(self.xres) cfg['yres'] = str(self.yres) # initial world load after bootup def load(self): cfg = self.configurator.config zone_name = cfg['default_zone'] globals.currentZone = zone_name basepath = cfg['basepath'] self.loadZone(zone_name, basepath) # zone reload user interface # this gets called from our update loop when it detects that zone_reload_name has been set # we do this in this convoluted fashion in order to keep the main loop taskMgr updates ticking # because otherwise our status console output at various stages during the zone load would not # be displayed. Yes, this is hacky. def doReload(self, name): cfg = self.configurator.config basepath = cfg['basepath'] self.loadZone(name, basepath) # form dialog callback # this gets called from the form when the user has entered a something # (hopefully a correct zone short name) def reloadZoneDialogCB(self, name): self.frmDialog.end() self.zone_reload_name = name self.toggleControls(1) # this is called when the user presses "l" # it disables normal controls and fires up our query form dialog def reloadZone(self): base.setBackgroundColor((0,0,0)) self.toggleControls(0) self.consoleOn() self.frmDialog = FileDialog( "Please enter the shortname of the zone you wish to load:", "Examples: qrg, blackburrow, freportn, crushbone etc.", self.reloadZoneDialogCB) self.frmDialog.activate() # relies on the main update loop to run ##################################### # Custom methods ##################################### # Handles populating the zone with spawn data from the EQEmu DB # also makes each spawner model pickable def PopulateSpawns(self, cursor, numrows): spawn_coords = list() globals.spawn_list = list() cfg = self.configurator.config for x in range(0, numrows): row = cursor.fetchone() point = Point3(long(row["Spawn2Y"]), long(row["Spawn2X"]), long(row["Spawn2Z"])) if cfg['ignore_duplicate_spawns'] == 'True': if point not in spawn_coords: self.PlaceSpawnPointOn3dMap(row) spawn_coords.append(point) else: self.PlaceSpawnPointOn3dMap(row) def PlaceSpawnPointOn3dMap(self, row): spawn = Spawn() self.InitSpawnData(spawn, row) spawn.model = loader.loadModel(spawn.modelname) spawn.initmodel() spawn.model.reparentTo(render) spawn.initheadingfromdb(row["Spawn2Heading"]) spawn.placeintoworld(row["Spawn2Y"], row["Spawn2X"], row["Spawn2Z"]) min, macks = spawn.model.getTightBounds() radius = max([macks.getY() - min.getY(), macks.getX() - min.getX()]) / 2 cs = CollisionSphere(row["Spawn2X"], row["Spawn2Y"], row["Spawn2Z"], radius) csNode = spawn.model.attachNewNode(CollisionNode("modelCollide")) csNode.node().addSolid(cs) # TODO: ADD MORE TAGS?? spawn.model.setTag("name", row["NpcName"]) spawn.model.setTag("spawngroup_name", row["spawngroup_name"]) spawn.model.setTag("spawn2id", str(row["Spawn2Id"])) spawn.model.setTag("type", "spawn") globals.picker.makePickable(spawn.model) globals.spawn_list.append(spawn) # Initializes a spawn object with database values def InitSpawnData(self, spawn, row): spawn.spawngroup_id = row["Spawngroup_id"] spawn.spawngroup_name = row["spawngroup_name"] spawn.spawngroup_minx = row["Spawngroup_minX"] spawn.spawngroup_maxx= row["Spawngroup_maxX"] spawn.spawngroup_miny = row["Spawngroup_minY"] spawn.spawngroup_maxy = row["Spawngroup_maxY"] spawn.spawngroup_dist = row["Spawngroup_dist"] spawn.spawngroup_mindelay = row["Spawngroup_mindelay"] spawn.spawngroup_delay = row["Spawngroup_delay"] spawn.spawngroup_despawn = row["Spawngroup_despawntimer"] spawn.spawngroup_despawntimer = row["Spawngroup_despawntimer"] spawn.spawngroup_spawnlimit = row["Spawngroup_spawnlimit"] spawn.spawnentry_id = row["Spawn2Id"] spawn.spawnentry_npcid = row["NpcId"] spawn.spawnentry_npcname = row["NpcName"] spawn.spawnentry_chance = row["Spawnentry_chance"] spawn.spawnentry_x = row["Spawn2X"] spawn.spawnentry_y = row["Spawn2Y"] spawn.spawnentry_z = row["Spawn2Z"] spawn.spawnentry_heading = row["Spawn2Heading"] spawn.spawnentry_respawn = row["Spawn2Respawn"] spawn.spawnentry_variance = row["Spawn2Variance"] spawn.spawnentry_pathgrid = row["Spawn2Grid"] spawn.spawnentry_condition = row["Spawn2Condition"] spawn.spawnentry_condvalue = row["Spawn2CondValue"] spawn.spawnentry_version = row["Spawn2Version"] spawn.spawnentry_enabled = row["Spawn2Enabled"] spawn.spawnentry_animation = row["Spawn2Animation"] spawn.spawnentry_zone = row["Spawn2Zone"] spawn.spawnentry_originalx = row["Spawn2X"] spawn.spawnentry_originaly = row["Spawn2Y"] spawn.spawnentry_originalz = row["Spawn2Z"] spawn.spawnentry_originalheading = row["Spawn2Heading"] # Initializes the camera position upon startup def InitCameraPosition(self): world.campos = Point3(-155.6, 41.2, 4.9 + world.eyeHeight) world.camHeading = 270.0 base.camera.setPos(world.campos) def GetCamera(self): return base.camera
def runViewer(mesh): scene_members = getSceneMembers(mesh) loadPrcFileData('', 'win-size 300 300') base = ShowBase() globNode = GeomNode("collada") nodePath = base.render.attachNewNode(globNode) rotateNode = GeomNode("rotater") rotatePath = nodePath.attachNewNode(rotateNode) matrix = numpy.identity(4) if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP: r = collada.scene.RotateTransform(0, 1, 0, 90) matrix = r.matrix elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP: r = collada.scene.RotateTransform(1, 0, 0, 90) matrix = r.matrix rotatePath.setMat(Mat4(*matrix.T.flatten().tolist())) basecollada = GeomNode("basecollada") basecolladaNP = rotatePath.attachNewNode(basecollada) for geom, renderstate, mat4 in scene_members: node = GeomNode("primitive") node.addGeom(geom) if renderstate is not None: node.setGeomState(0, renderstate) geomPath = basecolladaNP.attachNewNode(node) geomPath.setMat(mat4) for boundlight in mesh.scene.objects('light'): if len(boundlight.color) == 3: color = (boundlight.color[0], boundlight.color[1], boundlight.color[2], 1) else: color = boundlight.color if isinstance(boundlight, collada.light.BoundDirectionalLight): dl = DirectionalLight('dirLight') dl.setColor(Vec4(color[0], color[1], color[2], color[3])) lightNP = rotatePath.attachNewNode(dl) lightNP.lookAt( Point3(boundlight.direction[0], boundlight.direction[1], boundlight.direction[2])) elif isinstance(boundlight, collada.light.BoundAmbientLight): ambientLight = AmbientLight('ambientLight') ambientLight.setColor(Vec4(color[0], color[1], color[2], color[3])) lightNP = rotatePath.attachNewNode(ambientLight) elif isinstance(boundlight, collada.light.BoundPointLight): pointLight = PointLight('pointLight') pointLight.setColor(Vec4(color[0], color[1], color[2], color[3])) pointLight.setAttenuation( Vec3(boundlight.constant_att, boundlight.linear_att, boundlight.quad_att)) lightNP = rotatePath.attachNewNode(pointLight) lightNP.setPos( Vec3(boundlight.position[0], boundlight.position[1], boundlight.position[2])) elif isinstance(boundlight, collada.light.BoundSpotLight): spotLight = Spotlight('spotLight') spotLight.setColor(Vec4(color[0], color[1], color[2], color[3])) spotLight.setAttenuation( Vec3(boundlight.constant_att, boundlight.linear_att, boundlight.quad_att)) spotLight.setExponent(boundlight.falloff_exp) lightNP = rotatePath.attachNewNode(spotLight) lightNP.setPos( Vec3(boundlight.position[0], boundlight.position[1], boundlight.position[2])) lightNP.lookAt( Point3(boundlight.direction[0], boundlight.direction[1], boundlight.direction[2]), Vec3(boundlight.up[0], boundlight.up[1], boundlight.up[2])) else: print 'Unknown light type', boundlight continue base.render.setLight(lightNP) for boundcam in mesh.scene.objects('camera'): if isinstance(boundcam, collada.camera.BoundPerspectiveCamera): base.camera.reparentTo(rotatePath) base.camLens.setNear(boundcam.znear) base.camLens.setFar(boundcam.zfar) if boundcam.xfov is not None and boundcam.yfov is not None: #xfov + yfov base.camLens.setFov(boundcam.xfov, boundcam.yfov) elif boundcam.xfov is not None and boundcam.aspect_ratio is not None: #xfov + aspect_ratio base.camLens.setFov(boundcam.xfov) base.camLens.setAspectRatio(boundcam.aspect_ratio) elif boundcam.yfov is not None and boundcam.aspect_ratio is not None: #yfov + aspect_ratio #aspect_ratio = tan(0.5*xfov) / tan(0.5*yfov) xfov = math.degrees( 2.0 * math.atan(boundcam.aspect_ratio * math.tan(math.radians(0.5 * boundcam.yfov)))) base.camLens.setFov(xfov, boundcam.yfov) elif boundcam.yfov is not None: #yfov only #aspect_ratio = tan(0.5*xfov) / tan(0.5*yfov) xfov = math.degrees( 2.0 * math.atan(base.camLens.getAspectRatio() * math.tan(math.radians(0.5 * boundcam.yfov)))) base.camLens.setFov(xfov, boundcam.yfov) elif boundcam.xfov is not None: base.camLens.setFov(boundcam.xfov) base.camera.setPos( Vec3(boundcam.position[0], boundcam.position[1], boundcam.position[2])) base.camera.lookAt( Point3(boundcam.direction[0], boundcam.direction[1], boundcam.direction[2]), Vec3(boundcam.up[0], boundcam.up[1], boundcam.up[2])) elif isinstance(boundcam, collada.camera.BoundOrthographicCamera): lens = OrthographicLens() base.cam.node().setLens(lens) base.camLens = lens base.camera.reparentTo(rotatePath) base.camLens.setNear(boundcam.znear) base.camLens.setFar(boundcam.zfar) if boundcam.xmag is not None and boundcam.ymag is not None: #xmag + ymag base.camLens.setFilmSize(boundcam.xmag, boundcam.ymag) elif boundcam.xmag is not None and boundcam.aspect_ratio is not None: #xmag + aspect_ratio base.camLens.setFilmSize(boundcam.xmag) base.camLens.setAspectRatio(boundcam.aspect_ratio) elif boundcam.ymag is not None and boundcam.aspect_ratio is not None: #ymag + aspect_ratio xmag = boundcam.aspect_ratio * boundcam.ymag base.camLens.setFilmSize(xmag, boundcam.ymag) elif boundcam.ymag is not None: #ymag only xmag = base.camLens.getAspectRatio() * boundcam.ymag base.camLens.setFilmSize(xmag, boundcam.ymag) elif boundcam.xmag is not None: base.camLens.setFilmSize(boundcam.xmag) base.camera.setPos( Vec3(boundcam.position[0], boundcam.position[1], boundcam.position[2])) base.camera.lookAt( Point3(boundcam.direction[0], boundcam.direction[1], boundcam.direction[2]), Vec3(boundcam.up[0], boundcam.up[1], boundcam.up[2])) else: print 'Unknown camera type', boundcam continue base.disableMouse() base.render.setShaderAuto() base.render.setTransparency(TransparencyAttrib.MDual, 1) KeyboardMovement() MouseDrag(basecolladaNP) MouseScaleZoom(basecolladaNP) base.run()
def __setPointLight(self, props): light = PointLight(props['name']) light.setAttenuation(props['attenuation']) return self.__createLight(light, props)
class Light(PropertiesTableAbstract, XMLExportable): def __init__(self, attributes, parent): self.plnp = -1 self.parent = parent self.typeName = 'light' self.properties = { 'distance': '', 'attenuation': '', 'type': '', 'on': '', 'color': '', 'id': '' } if attributes.has_key('distance'): self.properties['distance'] = distance = float( attributes['distance'].value) else: distance = 1.0 if attributes.has_key('attenuation'): self.properties[ 'attenuation'] = self.attenuation = attenuation = float( attributes['attenuation'].value) else: self.properties[ 'attenuation'] = self.attenuation = attenuation = 0.0 if attributes.has_key('type'): self.properties['type'] = ltype = attributes['type'].value else: self.properties['type'] = ltype = 'point' if attributes.has_key('on'): if attributes['on'].value == "false": self.properties['on'] = 'false' self.on = False else: self.properties['on'] = 'true' self.on = True else: self.on = True if attributes.has_key('color'): self.properties['color'] = color = attributes['color'].value else: color = '1,1,1,1' if attributes.has_key('id'): self.properties['id'] = self.uid = uid = attributes['id'].value else: self.properties['id'] = self.uid = uid = 'light' self.generateNode() def destroy(self): if self.plnp != -1: render.clearLight(self.plnp) def generateNode(self): rgba = self.properties['color'].split(',') if len(rgba) < 3: print "ERROR: please define a correct color for light. (example: r,g,b,a in float values)!" realcolor = VBase4( float(rgba[0]) / 255, float(rgba[1]) / 255, float(rgba[2]) / 255, 1.0) if self.properties['type'] == 'spot': self.plight = Spotlight('slight') self.plight.setColor(realcolor) self.lens = PerspectiveLens() self.plight.setLens(self.lens) self.plnp = self.parent.attachNewNode(self.plight) self.plnp.setPos(0.5, -self.properties['distance'], 0.5) self.plnp.lookAt(Point3(0.5, 0, 0.5)) if self.properties['type'] == 'point': self.plight = PointLight('plight') self.plight.setColor(realcolor) if self.on == True: self.plight.setAttenuation(self.properties['attenuation']) else: self.plight.setAttenuation((1.0, 0, 1)) self.plnp = self.parent.getNode().attachNewNode(self.plight) self.plnp.setPos(0.5, -self.properties['distance'], 0.5) render.setLight(self.plnp) if self.on: self.setOn() #set unique id self.plnp.setTag("id", self.properties['id']) self.plnp.setPythonTag("gamenode", self) def getName(self): return 'Point Light: ' + self.properties['id'] def xmlAttributes(self): return self.properties def xmlTypeName(self): return self.typeName ''' Sanitize properties data to be of correct type from string ''' def sanitizeProperties(self): #sanitizing data self.properties['distance'] = float(self.properties['distance']) self.properties['attenuation'] = float(self.properties['attenuation']) #interface needed by PropertiesTable # regenerates the node at every change def onPropertiesUpdated(self): self.sanitizeProperties() rgba = self.properties['color'].split(',') if len(rgba) < 3: print "ERROR: please define a correct color for light. (example: r,g,b,a in float values)!" realcolor = VBase4( float(rgba[0]) / 255, float(rgba[1]) / 255, float(rgba[2]) / 255, 1.0) self.plnp.setY(-self.properties['distance']) self.plight.setColor(realcolor) self.plight.setAttenuation((self.properties['attenuation'])) def getPropertyList(self): return self.properties def setProperty(self, key, value): self.properties[key] = value def getNode(self): return self.plnp def setOn(self): self.plight.setAttenuation(self.attenuation) self.on = True def setOff(self): self.plight.setAttenuation(1.0) self.on = False def toggle(self): if self.on: self.setOff() else: self.setOn()
class World(DirectObject): def __init__(self): self.last_mousex = 0 self.last_mousey = 0 self.zone = None self.zone_reload_name = None self.winprops = WindowProperties() # simple console output self.consoleNode = NodePath(PandaNode("console_root")) self.consoleNode.reparentTo(aspect2d) self.console_num_lines = 24 self.console_cur_line = -1 self.console_lines = [] for i in range(0, self.console_num_lines): self.console_lines.append( OnscreenText( text="", style=1, fg=(1, 1, 1, 1), pos=(-1.3, 0.4 - i * 0.05), align=TextNode.ALeft, scale=0.035, parent=self.consoleNode, ) ) # Configuration self.consoleOut("zonewalk v.%s loading configuration" % VERSION) self.configurator = Configurator(self) cfg = self.configurator.config resaveRes = False if "xres" in cfg: self.xres = int(cfg["xres"]) else: self.xres = 1024 resaveRes = True if "yres" in cfg: self.yres = int(cfg["yres"]) else: self.yres = 768 resaveRes = True if resaveRes: self.saveDefaultRes() self.xres_half = self.xres / 2 self.yres_half = self.yres / 2 self.mouse_accum = MouseAccume(lambda: (self.xres_half, self.yres_half)) self.eyeHeight = 7.0 self.rSpeed = 80 self.flyMode = 1 # application window setup base.win.setClearColor(Vec4(0, 0, 0, 1)) self.winprops.setTitle("zonewalk") self.winprops.setSize(self.xres, self.yres) base.win.requestProperties(self.winprops) base.disableMouse() # network test stuff self.login_client = None if "testnet" in cfg: if cfg["testnet"] == "1": self.doLogin() # Post the instructions self.title = addTitle("zonewalk v." + VERSION) self.inst0 = addInstructions(0.95, "[FLYMODE][1]") self.inst1 = addInstructions(-0.95, "Camera control with WSAD/mouselook. Press K for hotkey list, ESC to exit.") self.inst2 = addInstructions(0.9, "Loc:") self.inst3 = addInstructions(0.85, "Hdg:") self.error_inst = addInstructions(0, "") self.kh = [] self.campos = Point3(155.6, 41.2, 4.93) base.camera.setPos(self.campos) # Accept the application control keys: currently just esc to exit navgen self.accept("escape", self.exitGame) self.accept("window-event", self.resizeGame) # Create some lighting ambient_level = 0.6 ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(ambient_level, ambient_level, ambient_level, 1.0)) render.setLight(render.attachNewNode(ambientLight)) direct_level = 0.8 directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(0.0, 0.0, -1.0)) directionalLight.setColor(Vec4(direct_level, direct_level, direct_level, 1)) directionalLight.setSpecularColor(Vec4(direct_level, direct_level, direct_level, 1)) render.setLight(render.attachNewNode(directionalLight)) # create a point light that will follow our view point (the camera for now) # attenuation is set so that this point light has a torch like effect self.plight = PointLight("plight") self.plight.setColor(VBase4(0.8, 0.8, 0.8, 1.0)) self.plight.setAttenuation(Point3(0.0, 0.0, 0.0002)) self.plnp = base.camera.attachNewNode(self.plight) self.plnp.setPos(0, 0, 0) render.setLight(self.plnp) self.cam_light = 1 self.keyMap = { "left": 0, "right": 0, "forward": 0, "backward": 0, "cam-left": 0, "cam-right": 0, "mouse3": 0, "flymode": 1, } # setup FOG self.fog_colour = (0.8, 0.8, 0.8, 1.0) self.linfog = Fog("A linear-mode Fog node") self.linfog.setColor(self.fog_colour) self.linfog.setLinearRange(700, 980) # onset, opaque distances as params # linfog.setLinearFallback(45,160,320) base.camera.attachNewNode(self.linfog) render.setFog(self.linfog) self.fog = 1 # camera control self.campos = Point3(0, 0, 0) self.camHeading = 0.0 self.camPitch = 0.0 base.camLens.setFov(65.0) base.camLens.setFar(1200) self.cam_speed = 0 # index into self.camp_speeds self.cam_speeds = [40.0, 80.0, 160.0, 320.0, 640.0] # Collision Detection for "WALKMODE" # We will detect the height of the terrain by creating a collision # ray and casting it downward toward the terrain. The ray will start above the camera. # A ray may hit the terrain, or it may hit a rock or a tree. If it # hits the terrain, we can detect the height. If it hits anything # else, we rule that the move is illegal. self.cTrav = CollisionTraverser() self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0.0, 0.0, 0.0) self.camGroundRay.setDirection(0, 0, -1) # straight down self.camGroundCol = CollisionNode("camRay") self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(BitMask32.bit(0)) self.camGroundCol.setIntoCollideMask(BitMask32.allOff()) # attach the col node to the camCollider dummy node self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # Uncomment this line to see the collision rays # self.camGroundColNp.show() # Uncomment this line to show a visual representation of the # collisions occuring # self.cTrav.showCollisions(render) # Add the spinCameraTask procedure to the task manager. # taskMgr.add(self.spinCameraTask, "SpinCameraTask") taskMgr.add(self.camTask, "camTask") self.toggleControls(1) # need to step the task manager once to make our fake console work taskMgr.step() # CONSOLE --------------------------------------------------------------------- def consoleScroll(self): for i in range(0, self.console_num_lines - 1): self.console_lines[i].setText(self.console_lines[i + 1].getText()) def consoleOut(self, text): print text # output to stdout/log too if self.console_cur_line == self.console_num_lines - 1: self.consoleScroll() elif self.console_cur_line < self.console_num_lines - 1: self.console_cur_line += 1 self.console_lines[self.console_cur_line].setText(text) taskMgr.step() def consoleOn(self): self.consoleNode.show() def consoleOff(self): self.consoleNode.hide() # User controls ----------------------------------------------------------- def toggleControls(self, on): if on == 1: self.accept("escape", self.exitGame) self.accept("1", self.setSpeed, ["speed", 0]) self.accept("2", self.setSpeed, ["speed", 1]) self.accept("3", self.setSpeed, ["speed", 2]) self.accept("4", self.setSpeed, ["speed", 3]) self.accept("5", self.setSpeed, ["speed", 4]) self.accept("alt-f", self.fogToggle) self.accept("t", self.camLightToggle) self.accept("k", self.displayKeyHelp) self.accept("f", self.toggleFlymode) self.accept("l", self.reloadZone) self.accept("z", self.saveDefaultZone) self.accept("a", self.setKey, ["cam-left", 1]) self.accept("d", self.setKey, ["cam-right", 1]) self.accept("w", self.setKey, ["forward", 1]) self.accept("mouse1", self.setKey, ["forward", 1]) self.accept("mouse3", self.setKey, ["mouse3", 1]) self.accept("s", self.setKey, ["backward", 1]) self.accept("k-up", self.hideKeyHelp) self.accept("a-up", self.setKey, ["cam-left", 0]) self.accept("d-up", self.setKey, ["cam-right", 0]) self.accept("w-up", self.setKey, ["forward", 0]) self.accept("mouse1-up", self.setKey, ["forward", 0]) self.accept("mouse3-up", self.setKey, ["mouse3", 0]) self.accept("s-up", self.setKey, ["backward", 0]) else: messenger.clear() def setSpeed(self, key, value): self.cam_speed = value self.setFlymodeText() def fogToggle(self): if self.fog == 1: render.clearFog() base.camLens.setFar(100000) self.fog = 0 else: render.setFog(self.linfog) base.camLens.setFar(1200) self.fog = 1 def camLightToggle(self): if self.cam_light == 0: render.setLight(self.plnp) self.cam_light = 1 else: render.clearLight(self.plnp) self.cam_light = 0 def displayKeyHelp(self): self.kh = [] msg = "HOTKEYS:" pos = 0.75 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) msg = "------------------" pos -= 0.05 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) msg = "W: camera fwd, S: camera bck, A: rotate view left, D: rotate view right" pos -= 0.05 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) msg = "1-5: set camera movement speed" pos -= 0.05 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) msg = "F: toggle Flymode/Walkmode" pos -= 0.05 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) msg = "L: load a zone" pos -= 0.05 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) msg = "ALT-F: toggle FOG and FAR plane on/off" pos -= 0.05 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) msg = 'T: toggle additional camera "torch" light on/off' pos -= 0.05 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) msg = "Z: set currently loaded zone as new startup default" pos -= 0.05 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) msg = "ESC: exit zonewalk" pos -= 0.05 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) def hideKeyHelp(self): for n in self.kh: n.removeNode() def setFlymodeText(self): zname = "" if self.zone: zname = self.zone.name if self.flyMode == 0: self.inst0.setText("[WALKMODE][%i] %s" % (self.cam_speed + 1, zname)) else: self.inst0.setText("[FLYMODE][%i] %s " % (self.cam_speed + 1, zname)) def toggleFlymode(self): zname = "" if self.zone: zname = self.zone.name if self.flyMode == 0: self.flyMode = 1 else: self.flyMode = 0 self.setFlymodeText() # Define a procedure to move the camera. def spinCameraTask(self, task): angleDegrees = task.time * 6.0 angleRadians = angleDegrees * (pi / 180.0) base.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3) base.camera.setHpr(angleDegrees, 0, 0) return task.cont def camTask(self, task): # query the mouse mouse_dx = 0 mouse_dy = 0 # if we have a mouse and the right button is depressed if base.mouseWatcherNode.hasMouse(): if self.keyMap["mouse3"] != 0: self.mouse_accum.update() else: self.mouse_accum.reset() mouse_dx = self.mouse_accum.dx mouse_dy = self.mouse_accum.dy self.rXSpeed = fabs(self.mouse_accum.dx) * (self.cam_speed + 1) * max(5 * 1000 / self.xres, 3) self.rYSpeed = fabs(self.mouse_accum.dy) * (self.cam_speed + 1) * max(3 * 1000 / self.yres, 1) if self.keyMap["cam-left"] != 0 or mouse_dx < 0: if self.rSpeed < 160: self.rSpeed += 80 * globalClock.getDt() if mouse_dx != 0: self.camHeading += self.rXSpeed * globalClock.getDt() else: self.camHeading += self.rSpeed * globalClock.getDt() if self.camHeading > 360.0: self.camHeading = self.camHeading - 360.0 elif self.keyMap["cam-right"] != 0 or mouse_dx > 0: if self.rSpeed < 160: self.rSpeed += 80 * globalClock.getDt() if mouse_dx != 0: self.camHeading -= self.rXSpeed * globalClock.getDt() else: self.camHeading -= self.rSpeed * globalClock.getDt() if self.camHeading < 0.0: self.camHeading = self.camHeading + 360.0 else: self.rSpeed = 80 if mouse_dy > 0: self.camPitch += self.rYSpeed * globalClock.getDt() elif mouse_dy < 0: self.camPitch -= self.rYSpeed * globalClock.getDt() # set camera heading and pitch base.camera.setHpr(self.camHeading, self.camPitch, 0) # viewer position (camera) movement control v = render.getRelativeVector(base.camera, Vec3.forward()) if not self.flyMode: v.setZ(0.0) move_speed = self.cam_speeds[self.cam_speed] if self.keyMap["forward"] == 1: self.campos += v * move_speed * globalClock.getDt() if self.keyMap["backward"] == 1: self.campos -= v * move_speed * globalClock.getDt() # actually move the camera lastPos = base.camera.getPos() base.camera.setPos(self.campos) # self.plnp.setPos(self.campos) # move the point light with the viewer position # WALKMODE: simple collision detection # we simply check a ray from slightly below the "eye point" straight down # for geometry collisions and if there are any we detect the point of collision # and adjust the camera's Z accordingly if self.flyMode == 0: # move the camera to where it would be if it made the move # the colliderNode moves with it # base.camera.setPos(self.campos) # check for collissons self.cTrav.traverse(render) entries = [] for i in range(self.camGroundHandler.getNumEntries()): entry = self.camGroundHandler.getEntry(i) entries.append(entry) # print 'collision' entries.sort(lambda x, y: cmp(y.getSurfacePoint(render).getZ(), x.getSurfacePoint(render).getZ())) if len(entries) > 0: # and (entries[0].getIntoNode().getName() == "terrain"): # print len(entries) self.campos.setZ(entries[0].getSurfacePoint(render).getZ() + self.eyeHeight) else: self.campos = lastPos base.camera.setPos(self.campos) # if (base.camera.getZ() < self.player.getZ() + 2.0): # base.camera.setZ(self.player.getZ() + 2.0) # update loc and hpr display pos = base.camera.getPos() hpr = base.camera.getHpr() self.inst2.setText("Loc: %.2f, %.2f, %.2f" % (pos.getX(), pos.getY(), pos.getZ())) self.inst3.setText("Hdg: %.2f, %.2f, %.2f" % (hpr.getX(), hpr.getY(), hpr.getZ())) return task.cont def exitGame(self): sys.exit(0) def resizeGame(self, win): props = base.win.getProperties() self.xres = props.getXSize() self.yres = props.getYSize() self.xres_half = self.xres / 2 self.yres_half = self.yres / 2 self.saveDefaultRes() # Records the state of the arrow keys # this is used for camera control def setKey(self, key, value): self.keyMap[key] = value # ------------------------------------------------------------------------- # this is the mythical MAIN LOOP :) def update(self): if self.zone_reload_name != None: self.doReload(self.zone_reload_name) self.zone_reload_name = None if self.zone != None: self.zone.update() taskMgr.step() if self.login_client != None: self.login_client.update() # ZONE loading ------------------------------------------------------------ # general zone loader driver # removes existing zone (if any) and load the new one def loadZone(self, name, path): if path[len(path) - 1] != "/": path += "/" if self.zone: self.zone.rootNode.removeNode() self.zone = Zone(self, name, path) error = self.zone.load() if error == 0: self.consoleOff() self.setFlymodeText() base.setBackgroundColor(self.fog_colour) def saveDefaultRes(self): cfg = self.configurator.config cfg["xres"] = str(self.xres) cfg["yres"] = str(self.yres) self.configurator.saveConfig() # initial world load after bootup def load(self): cfg = self.configurator.config if self.login_client != None: return zone_name = cfg["default_zone"] basepath = cfg["basepath"] self.loadZone(zone_name, basepath) # config save user interfacce def saveDefaultZone(self): if self.zone: cfg = self.configurator.config cfg["default_zone"] = self.zone.name self.configurator.saveConfig() # zone reload user interface # this gets called from our update loop when it detects that zone_reload_name has been set # we do this in this convoluted fashion in order to keep the main loop taskMgr updates ticking # because otherwise our status console output at various stages during the zone load would not # be displayed. Yes, this is hacky. def doReload(self, name): cfg = self.configurator.config basepath = cfg["basepath"] self.loadZone(name, basepath) # form dialog callback # this gets called from the form when the user has entered a something # (hopefully a correct zone short name) def reloadZoneDialogCB(self, name): self.frmDialog.end() self.zone_reload_name = name self.toggleControls(1) # this is called when the user presses "l" # it disables normal controls and fires up our query form dialog def reloadZone(self): base.setBackgroundColor((0, 0, 0)) self.toggleControls(0) self.consoleOn() self.frmDialog = FileDialog( "Please enter the shortname of the zone you wish to load:", "Examples: qrg, blackburrow, freportn, crushbone etc.", self.reloadZoneDialogCB, ) self.frmDialog.activate() # relies on the main update loop to run ############################### # EXPERIMENTAL def doLogin(self): self.login_client = UDPClientStream("127.0.0.1", 5998)
def __init__(self): # Check video card capabilities. if base.win.getGsg().getSupportsBasicShaders() == 0: addTitle("Bump Mapping: Video driver reports that shaders are not supported.") return # Post the instructions self.title = addTitle("Panda3D: Tutorial - Bump Mapping") self.inst1 = addInstructions(0.95, "Press ESC to exit") self.inst2 = addInstructions(0.90, "Move mouse to rotate camera") self.inst3 = addInstructions(0.85, "Left mouse button: Move forwards") self.inst4 = addInstructions(0.80, "Right mouse button: Move backwards") self.inst5 = addInstructions(0.75, "Enter: Turn bump maps Off") # Load the 'abstract room' model. This is a model of an # empty room containing a pillar, a pyramid, and a bunch # of exaggeratedly bumpy textures. self.room = loader.loadModel("models/abstractroom") self.room.reparentTo(render) # Make the mouse invisible, turn off normal mouse controls base.disableMouse() props = WindowProperties() props.setCursorHidden(True) base.win.requestProperties(props) # Set the current viewing target self.focus = Vec3(55, -55, 20) self.heading = 180 self.pitch = 0 self.mousex = 0 self.mousey = 0 self.last = 0 self.mousebtn = [0, 0, 0] # Start the camera control task: taskMgr.add(self.controlCamera, "camera-task") self.accept("escape", sys.exit, [0]) self.accept("mouse1", self.setMouseBtn, [0, 1]) self.accept("mouse1-up", self.setMouseBtn, [0, 0]) self.accept("mouse2", self.setMouseBtn, [1, 1]) self.accept("mouse2-up", self.setMouseBtn, [1, 0]) self.accept("mouse3", self.setMouseBtn, [2, 1]) self.accept("mouse3-up", self.setMouseBtn, [2, 0]) self.accept("enter", self.toggleShader) self.accept("j", self.rotateLight, [-1]) self.accept("k", self.rotateLight, [1]) self.accept("arrow_left", self.rotateCam, [-1]) self.accept("arrow_right", self.rotateCam, [1]) # Add a light to the scene. self.lightpivot = render.attachNewNode("lightpivot") self.lightpivot.setPos(0, 0, 25) self.lightpivot.hprInterval(10, Point3(360, 0, 0)).loop() plight = PointLight("plight") plight.setColor(Vec4(1, 1, 1, 1)) plight.setAttenuation(Vec3(0.7, 0.05, 0)) plnp = self.lightpivot.attachNewNode(plight) plnp.setPos(45, 0, 0) self.room.setLight(plnp) # Add an ambient light alight = AmbientLight("alight") alight.setColor(Vec4(0.2, 0.2, 0.2, 1)) alnp = render.attachNewNode(alight) self.room.setLight(alnp) # create a sphere to denote the light sphere = loader.loadModel("models/sphere") sphere.reparentTo(plnp) # load and apply the shader. This is using panda's # built-in shader generation capabilities to create the # shader for you. However, if desired, you can supply # the shader manually. Change this line of code to: # self.room.setShaderInput("light", plnp) # self.room.setShader(Shader.load("bumpMapper.sha")) self.room.setShaderAuto() self.shaderenable = 1
class MyApp(ShowBase): def __init__(self): ShowBase.__init__(self) dir(self) self.disableMouse() # Load the environment model. self.environ = self.loader.loadModel("../levels/level01.egg") # Reparent the model to render. self.environ.reparentTo(self.render) '''add a light''' self.light = PointLight("dLight") self.light.setAttenuation( (.01,.01,.01 ) ) self.light.setSpecularColor ( VBase4(1,1,0,1 ) ) self.lightNode = render.attachNewNode(self.light) self.lightNode.setZ(10) render.setLight(self.lightNode) '''move light constants''' self.moveLightDirection = -1000 self.taskMgr.add(self.moveLight,"lightMove") self.taskMgr.add(self.fpsInput,"fpsInput") '''fps cam controls''' self.keymap={"w":0,"a":0,"s":0,"d":0,"e":0,"q":0, "j":0,"k":0,"l":0,"i":0} self.fps = FpsCam(self.camera) self.accept("a", self.setKey, ["a",1] ) self.accept("a-up", self.setKey, ['a',0] ) self.accept("w", self.setKey, ["w",1] ) self.accept("w-up", self.setKey, ["w",0] ) self.accept("s", self.setKey, ["s",1] ) self.accept("s-up", self.setKey, ["s",0] ) self.accept("d", self.setKey, ["d",1] ) self.accept("d-up", self.setKey, ["d",0] ) self.accept("e", self.setKey, ["e",1] ) self.accept("e-up", self.setKey, ["e",0] ) self.accept("q", self.setKey, ["q",1] ) self.accept("q-up", self.setKey, ["q",0] ) self.accept("j", self.setKey, ["j",1] ) self.accept("j-up", self.setKey, ["j",0] ) self.accept("k", self.setKey, ["k",1] ) self.accept("k-up", self.setKey, ["k",0] ) self.accept("l", self.setKey, ["l",1] ) self.accept("l-up", self.setKey, ["l",0] ) self.accept("i", self.setKey, ["i",1] ) self.accept("i-up", self.setKey, ["i",0] ) self.accept("escape",sys.exit ) def setKey(self,key,value): self.keymap[key]=value return def fpsInput(self,task): self.fps.moveX( self.keymap["d"]-self.keymap["a"]) self.fps.moveY( self.keymap["w"]-self.keymap["s"]) self.fps.moveZ( self.keymap["e"]-self.keymap["q"]) self.fps.yaw ( self.keymap["j"]-self.keymap["l"]) self.fps.pitch( self.keymap["i"]-self.keymap["k"]) return task.cont def moveLight(self,task): #print dir(self.lightNode) where = self.lightNode.getX() #print where self.lightNode.setX(where-task.getDt()*self.moveLightDirection) if self.lightNode.getX()< -10: self.moveLightDirection *= -1 elif self.lightNode.getX() > 10: self.moveLightDirection *= -1 return task.cont
def __init__(self): # Initialize the ShowBase class from which we inherit, which will # create a window and set up everything we need for rendering into it. ShowBase.__init__(self) self.disableMouse() self.cam.node().getLens().setNear(10.0) self.cam.node().getLens().setFar(200.0) camera.setPos(0, -50, 0) # Check video card capabilities. if not self.win.getGsg().getSupportsBasicShaders(): addTitle( "Toon Shader: Video driver reports that Cg shaders are not supported." ) return # Enable a 'light ramp' - this discretizes the lighting, # which is half of what makes a model look like a cartoon. # Light ramps only work if shader generation is enabled, # so we call 'setShaderAuto'. tempnode = NodePath(PandaNode("temp node")) tempnode.setAttrib(LightRampAttrib.makeSingleThreshold(0.5, 0.4)) tempnode.setShaderAuto() self.cam.node().setInitialState(tempnode.getState()) # Use class 'CommonFilters' to enable a cartoon inking filter. # This can fail if the video card is not powerful enough, if so, # display an error and exit. self.separation = 1 # Pixels self.filters = CommonFilters(self.win, self.cam) filterok = self.filters.setCartoonInk(separation=self.separation) if (filterok == False): addTitle( "Toon Shader: Video card not powerful enough to do image postprocessing" ) return # Show instructions in the corner of the window. self.title = addTitle( "Panda3D: Tutorial - Toon Shading with Normals-Based Inking") self.inst1 = addInstructions(0.06, "ESC: Quit") self.inst2 = addInstructions( 0.12, "Up/Down: Increase/Decrease Line Thickness") self.inst3 = addInstructions(0.18, "V: View the render-to-texture results") # Load a dragon model and animate it. self.character = Actor() self.character.loadModel('models/nik-dragon') self.character.reparentTo(render) self.character.loadAnims({'win': 'models/nik-dragon'}) self.character.loop('win') self.character.hprInterval(15, (360, 0, 0)).loop() # Create a non-attenuating point light and an ambient light. plightnode = PointLight("point light") plightnode.setAttenuation((1, 0, 0)) plight = render.attachNewNode(plightnode) plight.setPos(30, -50, 0) alightnode = AmbientLight("ambient light") alightnode.setColor((0.8, 0.8, 0.8, 1)) alight = render.attachNewNode(alightnode) render.setLight(alight) render.setLight(plight) # Panda contains a built-in viewer that lets you view the # results of all render-to-texture operations. This lets you # see what class CommonFilters is doing behind the scenes. self.accept("v", self.bufferViewer.toggleEnable) self.accept("V", self.bufferViewer.toggleEnable) self.bufferViewer.setPosition("llcorner") self.accept("s", self.filters.manager.resizeBuffers) # These allow you to change cartooning parameters in realtime self.accept("escape", sys.exit, [0]) self.accept("arrow_up", self.increaseSeparation) self.accept("arrow_down", self.decreaseSeparation)
def runViewer(mesh): scene_members = getSceneMembers(mesh) loadPrcFileData('', 'win-size 300 300') base = ShowBase() globNode = GeomNode("collada") nodePath = base.render.attachNewNode(globNode) rotateNode = GeomNode("rotater") rotatePath = nodePath.attachNewNode(rotateNode) matrix = numpy.identity(4) if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP: r = collada.scene.RotateTransform(0,1,0,90) matrix = r.matrix elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP: r = collada.scene.RotateTransform(1,0,0,90) matrix = r.matrix rotatePath.setMat(Mat4(*matrix.T.flatten().tolist())) basecollada = GeomNode("basecollada") basecolladaNP = rotatePath.attachNewNode(basecollada) for geom, renderstate, mat4 in scene_members: node = GeomNode("primitive") node.addGeom(geom) if renderstate is not None: node.setGeomState(0, renderstate) geomPath = basecolladaNP.attachNewNode(node) geomPath.setMat(mat4) for boundlight in mesh.scene.objects('light'): if len(boundlight.color) == 3: color = (boundlight.color[0], boundlight.color[1], boundlight.color[2], 1) else: color = boundlight.color if isinstance(boundlight, collada.light.BoundDirectionalLight): dl = DirectionalLight('dirLight') dl.setColor(Vec4(color[0], color[1], color[2], color[3])) lightNP = rotatePath.attachNewNode(dl) lightNP.lookAt(Point3(boundlight.direction[0],boundlight.direction[1],boundlight.direction[2])) elif isinstance(boundlight, collada.light.BoundAmbientLight): ambientLight = AmbientLight('ambientLight') ambientLight.setColor(Vec4(color[0], color[1], color[2], color[3])) lightNP = rotatePath.attachNewNode(ambientLight) elif isinstance(boundlight, collada.light.BoundPointLight): pointLight = PointLight('pointLight') pointLight.setColor(Vec4(color[0], color[1], color[2], color[3])) pointLight.setAttenuation(Vec3(boundlight.constant_att, boundlight.linear_att, boundlight.quad_att)) lightNP = rotatePath.attachNewNode(pointLight) lightNP.setPos(Vec3(boundlight.position[0], boundlight.position[1], boundlight.position[2])) elif isinstance(boundlight, collada.light.BoundSpotLight): spotLight = Spotlight('spotLight') spotLight.setColor(Vec4(color[0], color[1], color[2], color[3])) spotLight.setAttenuation(Vec3(boundlight.constant_att, boundlight.linear_att, boundlight.quad_att)) spotLight.setExponent(boundlight.falloff_exp) lightNP = rotatePath.attachNewNode(spotLight) lightNP.setPos(Vec3(boundlight.position[0], boundlight.position[1], boundlight.position[2])) lightNP.lookAt(Point3(boundlight.direction[0], boundlight.direction[1], boundlight.direction[2]), Vec3(boundlight.up[0], boundlight.up[1], boundlight.up[2])) else: print('Unknown light type', boundlight) continue base.render.setLight(lightNP) for boundcam in mesh.scene.objects('camera'): if isinstance(boundcam, collada.camera.BoundPerspectiveCamera): base.camera.reparentTo(rotatePath) base.camLens.setNear(boundcam.znear) base.camLens.setFar(boundcam.zfar) if boundcam.xfov is not None and boundcam.yfov is not None: #xfov + yfov base.camLens.setFov(boundcam.xfov, boundcam.yfov) elif boundcam.xfov is not None and boundcam.aspect_ratio is not None: #xfov + aspect_ratio base.camLens.setFov(boundcam.xfov) base.camLens.setAspectRatio(boundcam.aspect_ratio) elif boundcam.yfov is not None and boundcam.aspect_ratio is not None: #yfov + aspect_ratio #aspect_ratio = tan(0.5*xfov) / tan(0.5*yfov) xfov = math.degrees(2.0 * math.atan(boundcam.aspect_ratio * math.tan(math.radians(0.5 * boundcam.yfov)))) base.camLens.setFov(xfov, boundcam.yfov) elif boundcam.yfov is not None: #yfov only #aspect_ratio = tan(0.5*xfov) / tan(0.5*yfov) xfov = math.degrees(2.0 * math.atan(base.camLens.getAspectRatio() * math.tan(math.radians(0.5 * boundcam.yfov)))) base.camLens.setFov(xfov, boundcam.yfov) elif boundcam.xfov is not None: base.camLens.setFov(boundcam.xfov) base.camera.setPos(Vec3(boundcam.position[0], boundcam.position[1], boundcam.position[2])) base.camera.lookAt(Point3(boundcam.direction[0], boundcam.direction[1], boundcam.direction[2]), Vec3(boundcam.up[0], boundcam.up[1], boundcam.up[2])) elif isinstance(boundcam, collada.camera.BoundOrthographicCamera): lens = OrthographicLens() base.cam.node().setLens(lens) base.camLens = lens base.camera.reparentTo(rotatePath) base.camLens.setNear(boundcam.znear) base.camLens.setFar(boundcam.zfar) if boundcam.xmag is not None and boundcam.ymag is not None: #xmag + ymag base.camLens.setFilmSize(boundcam.xmag, boundcam.ymag) elif boundcam.xmag is not None and boundcam.aspect_ratio is not None: #xmag + aspect_ratio base.camLens.setFilmSize(boundcam.xmag) base.camLens.setAspectRatio(boundcam.aspect_ratio) elif boundcam.ymag is not None and boundcam.aspect_ratio is not None: #ymag + aspect_ratio xmag = boundcam.aspect_ratio * boundcam.ymag base.camLens.setFilmSize(xmag, boundcam.ymag) elif boundcam.ymag is not None: #ymag only xmag = base.camLens.getAspectRatio() * boundcam.ymag base.camLens.setFilmSize(xmag, boundcam.ymag) elif boundcam.xmag is not None: base.camLens.setFilmSize(boundcam.xmag) base.camera.setPos(Vec3(boundcam.position[0], boundcam.position[1], boundcam.position[2])) base.camera.lookAt(Point3(boundcam.direction[0], boundcam.direction[1], boundcam.direction[2]), Vec3(boundcam.up[0], boundcam.up[1], boundcam.up[2])) else: print('Unknown camera type', boundcam) continue base.disableMouse() base.render.setShaderAuto() base.render.setTransparency(TransparencyAttrib.MDual, 1) KeyboardMovement() MouseDrag(basecolladaNP) MouseScaleZoom(basecolladaNP) base.run()
def __init__(self, img_size=512, screen_off=True): self.img_size = img_size loadPrcFileData("", "transform-cache false") loadPrcFileData("", "audio-library-name null") # Prevent ALSA errors loadPrcFileData("", "win-size %d %d" % (img_size, img_size)) loadPrcFileData("", "parallax-mapping-samples 3\n" "parallax-mapping-scale 0.1") if screen_off: # Spawn an offscreen buffer loadPrcFileData("", "window-type offscreen") # Initialize the ShowBase class from which we inherit, which will # create a window and set up everything we need for rendering into it. ShowBase.__init__(self) # Load the 'abstract room' model. This is a model of an # empty room containing a pillar, a pyramid, and a bunch # of exaggeratedly bumpy textures. self.room = loader.loadModel("models/abstractroom") self.room.reparentTo(render) # Create the main character, Ralph self.ralph = Actor("models/ralph", {"run": "models/ralph-run", "walk": "models/ralph-walk"}) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.reset() self.pieces = [Piece(self.room) for _ in range(200)] ################################################## cnodePath = self.room.attachNewNode(CollisionNode('cnode')) plane = CollisionPlane(Plane(Vec3(1, 0, 0), Point3(-60, 0, 0))) # left cnodePath.node().addSolid(plane) plane = CollisionPlane( Plane(Vec3(-1, 0, 0), Point3(60, 0, 0))) # right cnodePath.node().addSolid(plane) plane = CollisionPlane(Plane(Vec3(0, 1, 0), Point3(0, -60, 0))) # back cnodePath.node().addSolid(plane) plane = CollisionPlane( Plane(Vec3(0, -1, 0), Point3(0, 60, 0))) # front cnodePath.node().addSolid(plane) sphere = CollisionSphere(-25, -25, 0, 12.5) cnodePath.node().addSolid(sphere) box = CollisionBox(Point3(5, 5, 0), Point3(45, 45, 10)) cnodePath.node().addSolid(box) # Make the mouse invisible, turn off normal mouse controls self.disableMouse() self.camLens.setFov(80) # Set the current viewing target self.focus = LVector3(55, -55, 20) self.heading = 180 self.pitch = 0 self.mousex = 0 self.mousey = 0 self.last = 0 self.mousebtn = [0, 0, 0] # Add a light to the scene. self.lightpivot = render.attachNewNode("lightpivot") self.lightpivot.setPos(0, 0, 25) self.lightpivot.hprInterval(10, LPoint3(360, 0, 0)).loop() plight = PointLight('plight') plight.setColor((5, 5, 5, 1)) plight.setAttenuation(LVector3(0.7, 0.05, 0)) plnp = self.lightpivot.attachNewNode(plight) plnp.setPos(45, 0, 0) self.room.setLight(plnp) # Add an ambient light alight = AmbientLight('alight') alight.setColor((0.2, 0.2, 0.2, 1)) alnp = render.attachNewNode(alight) self.room.setLight(alnp) # Create a sphere to denote the light sphere = loader.loadModel("models/icosphere") sphere.reparentTo(plnp) self.cameraModel = self.ralph camera.reparentTo(self.cameraModel) camera.setZ(2) self.cTrav = CollisionTraverser() cs = CollisionSphere(0, 0, 0, 1) cnodePath = self.ralph.attachNewNode(CollisionNode('cnode')) cnodePath.node().addSolid(cs) cnodePath.show() self.ralphGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(cnodePath, self.ralphGroundHandler) self.cnodePath = cnodePath # Tell Panda that it should generate shaders performing per-pixel # lighting for the room. self.room.setShaderAuto() self.shaderenable = 1 tex = Texture() self.depthmap = tex tex.setFormat(Texture.FDepthComponent) altBuffer = self.win.makeTextureBuffer( "hello", img_size, img_size, tex, True) self.altBuffer = altBuffer altCam = self.makeCamera(altBuffer) altCam.reparentTo(self.ralph) # altRender) altCam.setZ(2) l = altCam.node().getLens() l.setFov(80)
def __init__(self): GameObject.__init__(self, Vec3(0, 0, 0), None, None, 100, 15, "player", 1, MASK_INTO_PLAYER) Walker.__init__(self) ArmedObject.__init__(self) self.weaponNP = self.actor light = PointLight("basic light") light.setColor(Vec4(1, 1, 1, 1)) light.setAttenuation((1, 0.01, 0.005)) self.lightNP = self.root.attachNewNode(light) self.lightNP.setZ(1) render.setLight(self.lightNP) self.collider.node().setFromCollideMask(MASK_WALLS | MASK_FROM_PLAYER) self.actor.setZ(self.height) base.camera.reparentTo(self.actor) base.camera.setPos(0, 0, 0) base.camera.setHpr(0, 0, 0) lens = base.camLens ratio = lens.getAspectRatio() lens.setFov(80 * ratio) lens.setNear(0.03) self.lastMousePos = Vec2(0, 0) self.mouseSpeedHori = 50.0 self.mouseSpeedVert = 30.0 self.mouseSensitivity = 1.0 self.healthLeft = -0.9 self.healthRight = 0.9 self.healthWidth = self.healthRight - self.healthLeft self.uiRoot = base.a2dBottomCenter.attachNewNode( PandaNode("player UI")) self.healthBar = loader.loadModel("UI/healthBar") self.healthBar.reparentTo(self.uiRoot) self.healthBar.setZ(0.05) self.healthBar.setX(self.healthLeft) self.healthBar.getChild(0).setScale(self.healthWidth / 6.0) self.weaponUIRoot = self.uiRoot.attachNewNode( PandaNode("player weapon UI")) self.weaponUIRoot.setPos(0, 0, 0.1) self.addWeapon(RapidShotgunWeapon(self.weaponUIRoot)) self.addWeapon(BlasterWeapon(self.weaponUIRoot)) self.weapons[0].setAvailable(True) self.setCurrentWeapon(0) self.updateHealthUI() self.inventory = [] self.updatingEffects = [] self.interactionSegment = CollisionSegment(0, 0, 0, 0, 1.5, 0) rayNode = CollisionNode("player interaction ray") rayNode.addSolid(self.interactionSegment) rayNode.setFromCollideMask(MASK_WALLS | MASK_FLOORS | MASK_INTO_ENEMY) rayNode.setIntoCollideMask(0) self.interactionSegmentNodePath = self.actor.attachNewNode(rayNode) #self.interactionSegmentNodePath.show() self.interactionSegmentQueue = CollisionHandlerQueue() self.interactionSegmentTraverser = CollisionTraverser() self.interactionSegmentTraverser.addCollider( self.interactionSegmentNodePath, self.interactionSegmentQueue)
def __setPointLight(self,props): light = PointLight(props['name']) light.setAttenuation(props['attenuation']) return self.__createLight(light,props)
def __init__(self): # Set up the window, camera, etc. ShowBase.__init__(self) #self.setupCD() # Set the background color to black # self.win.setClearColor((0.6, 0.6, 1.0, 1.0)) # self.fog = Fog('myFog') # self.fog.setColor(0, 0, 0) # self.fog.setExpDensity(.05) # render.setFog(self.fog) # This is used to store which keys are currently pressed. self.keyMap = { "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0, "c":0, "back":0, "space":0} # Post the instructions #self.title = addTitle( # "Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)") self.inst1 = addInstructions(0.06, "[ESC]: Quit") self.inst2 = addInstructions(0.12, "[Left Arrow]: Rotate Ralph Left") self.inst3 = addInstructions(0.18, "[Right Arrow]: Rotate Ralph Right") self.inst4 = addInstructions(0.24, "[Up Arrow]: Run Ralph Forward") #self.inst6 = addInstructions(0.30, "[A]: Rotate Camera Left") #self.inst7 = addInstructions(0.36, "[S]: Rotate Camera Right") # Set up the environment # # This environment model contains collision meshes. If you look # in the egg file, you will see the following: # # <Collide> { Polyset keep descend } # # This tag causes the following mesh to be converted to a collision # mesh -- a mesh which is optimized for collision, not rendering. # It also keeps the original mesh, so there are now two copies --- # one optimized for rendering, one for collisions. self.environ = loader.loadModel("models/world") #self.environ.reparentTo(render) self.room = loader.loadModel("models/room2.egg") self.room.reparentTo(render) #self.room.setScale(.1) self.room.setPos(0,0,-5) self.room.setShaderAuto() #self.room.writeBamFile("myRoom1.bam") #self.room.setColor(1,.3,.3,1) self.room2 = loader.loadModel("models/abstractroom2") self.room2.reparentTo(render) self.room2.setScale(.1) self.room2.setPos(-12,0,0) # Create the main character, Ralph #ralphStartPos = LVecBase3F(0,0,0) #self.room.find("**/start_point").getPos() self.ralph = Actor("models/ralph", {"run": "models/ralph-run", "walk": "models/ralph-walk"}) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.ralph.setPos(0,0,0) #cs = CollisionSphere(0, 0, 0, 1) #cnodePath = self.ralph.attachNewNode(CollisionNode('cnode')) #cnodePath.node().addSolid(cs) #cnodePath.node().setPos(0,0,0) #cnodePath.show() self.gianteye = loader.loadModel("models/gianteye") self.gianteye.reparentTo(render) self.gianteye.setScale(.1) self.gianteye.setPos(10,10,0) #self.bluefinal = loader.loadModel("models/chrysalis") #self.bluefinal.reparentTo(render) #self.bluefinal.setScale(.1) #self.bluefinal.setPos(7,7,0) #self.blue = loader.loadModel("models/blue1") #self.blue.reparentTo(render) #self.blue.setScale(.1) #self.blue.setPos(10,5,0) self.chik = loader.loadModel("models/chik") self.chik.reparentTo(render) self.chik.setScale(.1) self.chik.setPos(3,13,0) self.pawn = loader.loadModel("pawn") self.pawn.reparentTo(render) self.pawn.setPos(0,0,0) self.shot = loader.loadModel("models/icosphere.egg") self.shot.reparentTo(render) self.shot.setScale(.5) self.shot.setPos(0,0,1) self.shot.setColor(1,.3,.3,1) self.myShot = loader.loadModel("models/icosphere.egg") #self.myShot.reparentTo(render) self.myShot.setScale(.1) self.myShot.setPos(0,0,1) self.myShotVec = LVector3(0,0,0) self.lightpivot3 = render.attachNewNode("lightpivot3") self.lightpivot3.setPos(0, 0, 0) self.lightpivot3.hprInterval(10, LPoint3(0, 0, 0)).loop() plight3 = PointLight('plight2') plight3.setColor((0, .3,0, 1)) plight3.setAttenuation(LVector3(0.7, 0.05, 0)) plnp3 = self.lightpivot3.attachNewNode(plight3) plnp3.setPos(0, 0, 0) self.room2.setLight(plnp3) self.room.setLight(plnp3) sphere3 = loader.loadModel("models/icosphere") sphere3.reparentTo(plnp3) sphere3.setScale(0.1) sphere3.setColor((0,1,0,1)) # Create a floater object, which floats 2 units above ralph. We # use this as a target for the camera to look at. self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(self.ralph) self.floater.setZ(8.0) # Accept the control keys for movement and rotation self.accept("escape", sys.exit) self.accept("arrow_left", self.setKey, ["left", True]) self.accept("arrow_right", self.setKey, ["right", True]) self.accept("arrow_up", self.setKey, ["forward", True]) self.accept("arrow_down", self.setKey, ["back", True]) self.accept("a", self.setKey, ["cam-left", True]) self.accept("s", self.setKey, ["cam-right", True]) self.accept("arrow_left-up", self.setKey, ["left", False]) self.accept("arrow_right-up", self.setKey, ["right", False]) self.accept("arrow_up-up", self.setKey, ["forward", False]) self.accept("arrow_down-up", self.setKey, ["back", False]) self.accept("a-up", self.setKey, ["cam-left", False]) self.accept("s-up", self.setKey, ["cam-right", False]) self.accept("space", self.setKey, ["space", True]) self.accept("space-up", self.setKey, ["space", False]) self.accept("c",self.setKey,["c",True]) self.accept("c-up",self.setKey,["c",False]) taskMgr.add(self.move, "moveTask") # Game state variables self.isMoving = False self.jumping = False self.vz = 0 # Set up the camera self.disableMouse() self.camera.setPos(self.ralph.getX(), self.ralph.getY() + 7, 3) self.camLens.setFov(60) # We will detect the height of the terrain by creating a collision # ray and casting it downward toward the terrain. One ray will # start above ralph's head, and the other will start above the camera. # A ray may hit the terrain, or it may hit a rock or a tree. If it # hits the terrain, we can detect the height. If it hits anything # else, we rule that the move is illegal. def setupCollision(self): cs = CollisionSphere(0,0,2,1) cnodePath = self.ralph.attachNewNode(CollisionNode('cnode')) cnodePath.node().addSolid(cs) cnodePath.show() #for o in self.OBS: #ct = CollisionTube(0,0,0, 0,0,1, 0.5) #cn = o.attachNewNode(CollisionNode('ocnode')) #cn.node().addSolid(ct) #cn.show() eyecs = CollisionSphere(0,0,4,5) cnodePath = self.gianteye.attachNewNode(CollisionNode('cnode')) cnodePath.node().addSolid(eyecs) cnodePath.show() eyecs = CollisionSphere(0,0,4,2) cnodePath = self.chik.attachNewNode(CollisionNode('cnode')) cnodePath.node().addSolid(eyecs) cnodePath.show() pusher = CollisionHandlerPusher() pusher.addCollider(cnodePath, self.player) self.cTrav = CollisionTraverser() self.cTrav.add_collider(cnodePath,pusher) self.cTrav.showCollisions(render) self.walls = self.room2.find("**/wall_collide") #self.walls.node().setIntoCollideMask(BitMask32.bit(0)) self.cTrav = CollisionTraverser() self.ralphGroundRay = CollisionRay() self.ralphGroundRay.setOrigin(0, 0, 9) self.ralphGroundRay.setDirection(0, 0, -1) self.ralphGroundCol = CollisionNode('ralphRay') self.ralphGroundCol.addSolid(self.ralphGroundRay) self.ralphGroundCol.setFromCollideMask(CollideMask.bit(0)) self.ralphGroundCol.setIntoCollideMask(CollideMask.allOff()) self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol) self.ralphGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0, 0, 9) self.camGroundRay.setDirection(0, 0, -1) self.camGroundCol = CollisionNode('camRay') self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(CollideMask.bit(0)) self.camGroundCol.setIntoCollideMask(CollideMask.allOff()) self.camGroundColNp = self.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) self.sphere = CollisionSphere(0,0,4,2) self.sphere2 = CollisionSphere(0,0,2,2) self.cnodePath = self.ralph.attachNewNode((CollisionNode('cnode'))) self.cnodePath.node().addSolid(self.sphere) self.cnodePath.node().addSolid(self.sphere2) self.cnodePath.show() self.pusher = CollisionHandlerPusher() self.pusher.addCollider(self.cnodePath, self.ralph) self.cTrav.add_collider(self.cnodePath, self.pusher) self.eyecs = CollisionSphere(0,0,22,25) self.cnodePath1 = self.gianteye.attachNewNode(CollisionNode('cnode')) self.cnodePath1.node().addSolid(self.eyecs) self.cnodePath1.show() self.pusher1 = CollisionHandlerPusher() self.pusher1.addCollider(self.cnodePath1, self.gianteye) self.cTrav.add_collider(self.cnodePath1, self.pusher1) self.cTrav.showCollisions(render) self.eyeGroundRay = CollisionRay() self.eyeGroundRay.setOrigin(0, 0, 9) self.eyeGroundRay.setDirection(0, 0, -1) self.eyeGroundCol = CollisionNode('eyeRay') self.eyeGroundCol.addSolid(self.eyeGroundRay) self.eyeGroundCol.setFromCollideMask(CollideMask.bit(0)) self.eyeGroundCol.setIntoCollideMask(CollideMask.allOff()) self.eyeGroundColNp = self.gianteye.attachNewNode(self.eyeGroundCol) self.eyeGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.eyeGroundColNp, self.eyeGroundHandler) self.chikcs = CollisionSphere(0,0,11,20) self.cnodePath2 = self.chik.attachNewNode(CollisionNode('cnode')) self.cnodePath2.node().addSolid(self.chikcs) self.cnodePath2.show() self.pusher2 = CollisionHandlerPusher() self.pusher2.addCollider(self.cnodePath, self.chik) self.cTrav.add_collider(self.cnodePath, self.pusher2) self.cTrav.showCollisions(render) self.chikGroundRay = CollisionRay() self.chikGroundRay.setOrigin(0, 0, 9) self.chikGroundRay.setDirection(0, 0, -1) self.chikGroundCol = CollisionNode('chikRay') self.chikGroundCol.addSolid(self.chikGroundRay) self.chikGroundCol.setFromCollideMask(CollideMask.bit(0)) self.chikGroundCol.setIntoCollideMask(CollideMask.allOff()) self.chikGroundColNp = self.chik.attachNewNode(self.chikGroundCol) self.chikGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.chikGroundColNp, self.chikGroundHandler) # Uncomment this line to see the collision rays self.ralphGroundColNp.show() self.camGroundColNp.show() #self.ralphroom1ColNp.show() # Uncomment this line to show a visual representation of the # collisions occuring #self.cTrav.showCollisions(render) # Create some lighting ambientLight = AmbientLight("ambientLight") ambientLight.setColor((.3, .3, .3, .4)) ambientLight2 = AmbientLight("ambientLight2") ambientLight2.setColor((1, 1, 1, 10)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection((0, 0, -2)) directionalLight.setColor((1, 1, 1, 1)) directionalLight.setSpecularColor((1, 1, 1, 1)) render.setLight(render.attachNewNode(ambientLight)) #self.environ.setLight(self.environ.attachNewNode(ambientLight2)) render.setLight(render.attachNewNode(directionalLight)) # Add a light to the scene. self.lightpivot = render.attachNewNode("lightpivot") self.lightpivot.setPos(0, 0, 1.6) self.lightpivot.hprInterval(20, LPoint3(360, 0, 0)).loop() plight = PointLight('plight') plight.setColor((.7, .3, 0, 1)) plight.setAttenuation(LVector3(0.7, 0.05, 0)) plnp = self.lightpivot.attachNewNode(plight) plnp.setPos(5, 0, 0) self.room.setLight(plnp) sphere = loader.loadModel("models/icosphere") sphere.reparentTo(plnp) sphere.setScale(0.1) sphere.setColor((1,1,0,1)) self.lightpivot2 = render.attachNewNode("lightpivot") self.lightpivot2.setPos(-16, 0, 1.6) self.lightpivot2.hprInterval(20, LPoint3(360, 0, 0)).loop() plight2 = PointLight('plight2') plight2.setColor((0, .4,.8, 1)) plight2.setAttenuation(LVector3(0.7, 0.05, 0)) plnp2 = self.lightpivot2.attachNewNode(plight2) plnp2.setPos(5, 0, 0) self.room2.setLight(plnp2) sphere2 = loader.loadModel("models/icosphere") sphere2.reparentTo(plnp2) sphere2.setScale(0.2) sphere2.setColor((0,0,1,1)) self.vec = LVector3(0,1,0)
def __init__(self, img_size=512, screen_off=True, target_area_radius=5, initial_area_radius=10, keyboard_input=False, random_reset_around_target=False, test=False): logging.info('random_reset_around_target :%s', random_reset_around_target) self.random_reset_around_target = random_reset_around_target self.keyboard_input = keyboard_input # Configure the parallax mapping settings (these are just the defaults) self.img_size = img_size self.initial_area_radius = initial_area_radius self.target_area_radius = target_area_radius loadPrcFileData("", "side-by-side-stereo 1") if test: loadPrcFileData("", "load-display p3tinydisplay") loadPrcFileData("", "transform-cache false") loadPrcFileData("", "audio-library-name null") # Prevent ALSA errors loadPrcFileData("", "win-size %d %d" % (2 * img_size, img_size)) loadPrcFileData("", "parallax-mapping-samples 3\n" "parallax-mapping-scale 0.1") if screen_off: # Spawn an offscreen buffer loadPrcFileData("", "window-type offscreen") # Initialize the ShowBase class from which we inherit, which will # create a window and set up everything we need for rendering into it. ShowBase.__init__(self) self.keyMap = { "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0} # Load the 'abstract room' model. This is a model of an # empty room containing a pillar, a pyramid, and a bunch # of exaggeratedly bumpy textures. self.room = loader.loadModel("models/abstractroom") self.room.reparentTo(render) # Create the main character, Ralph ghost = BulletGhostNode('Ghost') ghostNP = render.attachNewNode(ghost) # self.agent = Actor("models/agent", # {"run": "models/agent-run", # "walk": "models/agent-walk"}) self.agent = ghostNP self.agent.reparentTo(render) # self.agent.setScale(.2) target = BulletGhostNode('target') self.navigation_target = render.attachNewNode(target) self.navigation_target.reparentTo(render) # knghit=Knight((0,0,0),(0.3,.3,.3,1)) self.pieces = [Piece(self.room) for _ in range(200)] ################################################## cnodePath = self.room.attachNewNode(CollisionNode('room')) plane = CollisionPlane(Plane(Vec3(1, 0, 0), Point3(-60, 0, 0))) # left cnodePath.node().addSolid(plane) plane = CollisionPlane( Plane(Vec3(-1, 0, 0), Point3(60, 0, 0))) # right cnodePath.node().addSolid(plane) plane = CollisionPlane(Plane(Vec3(0, 1, 0), Point3(0, -60, 0))) # back cnodePath.node().addSolid(plane) plane = CollisionPlane( Plane(Vec3(0, -1, 0), Point3(0, 60, 0))) # front cnodePath.node().addSolid(plane) sphere = CollisionSphere(-25, -25, 0, 12.5) # tube = CollisionTube(-25, -25,0 , -25, -25, 1, 12.5) cnodePath.node().addSolid(sphere) box = CollisionBox(Point3(5, 5, 0), Point3(45, 45, 10)) cnodePath.node().addSolid(box) # cnodePath.show() # Make the mouse invisible, turn off normal mouse controls self.disableMouse() # props = WindowProperties() # props.setCursorHidden(True) # self.win.requestProperties(props) # self.camLens.setFov(60) self.camLens.setFov(80) # Set the current viewing target self.focus = LVector3(55, -55, 20) self.heading = 180 self.pitch = 0 self.mousex = 0 self.mousey = 0 self.last = 0 self.mousebtn = [0, 0, 0] # Start the camera control task: # taskMgr.add(self.controlCamera, "camera-task") # self.accept("escape", sys.exit, [0]) # self.accept("enter", self.toggleShader) # self.accept("j", self.rotateLight, [-1]) # self.accept("k", self.rotateLight, [1]) # self.accept("arrow_left", self.rotateCam, [-1]) # self.accept("arrow_right", self.rotateCam, [1]) # Accept the control keys for movement and rotation self.accept("escape", sys.exit) self.accept("arrow_left", self.setKey, ["left", True]) self.accept("arrow_right", self.setKey, ["right", True]) self.accept("arrow_up", self.setKey, ["forward", True]) self.accept("a", self.setKey, ["cam-left", True]) self.accept("s", self.setKey, ["cam-right", True]) self.accept("arrow_left-up", self.setKey, ["left", False]) self.accept("arrow_right-up", self.setKey, ["right", False]) self.accept("arrow_up-up", self.setKey, ["forward", False]) self.accept("a-up", self.setKey, ["cam-left", False]) self.accept("s-up", self.setKey, ["cam-right", False]) # Add a light to the scene. self.lightpivot = render.attachNewNode("lightpivot") self.lightpivot.setPos(0, 0, 25) self.lightpivot.hprInterval(10, LPoint3(360, 0, 0)).loop() plight = PointLight('plight') plight.setColor((5, 5, 5, 1)) plight.setAttenuation(LVector3(0.7, 0.05, 0)) plnp = self.lightpivot.attachNewNode(plight) plnp.setPos(45, 0, 0) self.room.setLight(plnp) # Add an ambient light alight = AmbientLight('alight') alight.setColor((0.2, 0.2, 0.2, 1)) alnp = render.attachNewNode(alight) self.room.setLight(alnp) # Create a sphere to denote the light sphere = loader.loadModel("models/icosphere") sphere.reparentTo(plnp) # self.cameraModel = self.agent # self.win2 = self.openWindow() # self.win2.removeAllDisplayRegions() # self.dr2 = self.win2.makeDisplayRegion() # camNode = Camera('cam') # camNP = NodePath(camNode) # camNP.reparentTo(self.cameraModel) # camNP.setZ(150) # camNP.lookAt(self.cameraModel) # self.dr2.setCamera(camNP) # self.cam2 = camNP # Camera('cam')p # We will detect the height of the terrain by creating a collision # ray and casting it downward toward the terrain. One ray will # start above agent's head, and the other will start above the camera. # A ray may hit the terrain, or it may hit a rock or a tree. If it # hits the terrain, we can detect the height. If it hits anything # else, we rule that the move is illegal. self.cTrav = CollisionTraverser() cs = CollisionSphere(0, 0, 0, 0.2) cnodePath = self.agent.attachNewNode(CollisionNode('agent')) cnodePath.node().addSolid(cs) # cnodePath.show() self.ralphGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(cnodePath, self.ralphGroundHandler) cnodePath = self.navigation_target.attachNewNode( CollisionNode('target')) cnodePath.node().addSolid(CollisionSphere(0, 0, 0, 2)) self.cTrav.addCollider(cnodePath, self.ralphGroundHandler) # Tell Panda that it should generate shaders performing per-pixel # lighting for the room. self.room.setShaderAuto() self.shaderenable = 1 # tex = self.win.getScreenshot() # tex.setFormat(Texture.FDepthComponent) tex = Texture() self.depthmap = tex tex.setFormat(Texture.FDepthComponent) altBuffer = self.win.makeTextureBuffer( "hello", img_size, img_size, tex, True) self.altBuffer = altBuffer altCam = self.makeCamera(altBuffer) altCam.reparentTo(self.agent) # altRender) altCam.setZ(0.4) l = altCam.node().getLens() l.setFov(80) l.setNear(.1) camera.reparentTo(self.agent) camera.setZ(0.4) l = self.camLens # l.setFov(80) l.setNear(.1)
class RacingGame(ShowBase): # method completely taken from RoamingRalph demo: def addInstructions(self, pos, msg): return OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), scale=.05, shadow=(0, 0, 0, 1), parent=base.a2dTopLeft, pos=(0.08, -pos - 0.04), align=TextNode.ALeft) def addWin(self, time): msg = ( "You finished the course in: \n%d seconds \n press z to race again" % (time)) self.winText = OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), scale=.2, shadow=(0, 0, 0, 1), parent=base.a2dTopLeft, pos=(0.10, -0.5), align=TextNode.ALeft) def destroyWin(self): if (self.winText != None): self.winText.destroy() def setUpFlyingInstructions(self): self.inst[0] = self.addInstructions(.06, "Arrow Keys to move around") self.inst[1] = self.addInstructions(.12, "w and s to control pitch") self.inst[2] = self.addInstructions(.18, "a and d to control yaw") self.inst[3] = self.addInstructions(.24, "h to switch to driving mode") self.inst[4] = self.addInstructions(.3, "mouse click to add object") self.inst[5] = self.addInstructions(.36, "m to go to main") def startMovement(self): taskMgr.add(self.move, "moveTask") def destroyInstructions(self): # got way to destroy text from: # https://www.panda3d.org/manual/index.php/OnscreenText for element in self.inst: element.destroy() def startCreating(self): self.switchToCreateMode() self.destroyStartScreenButtons() self.startMovement() def startDriving(self): self.switchToDrivingMode() self.destroyStartScreenButtons() self.startMovement() def startTutorial(self): self.mode = self.modeTutorial self.setUpTutorial() self.destroyStartScreenButtons() self.startMovement() def setUpStartScreenButtons(self): self.creatingButton = DirectButton(text="Start Creating", scale=.1, command=self.startCreating, pos=(0, 0, .2)) self.drivingButton = DirectButton(text="Start Driving", scale=.1, command=self.startDriving, pos=(0, 0, 0)) self.tutorialButton = DirectButton(text="Start Tutorial", scale=.1, command=self.startTutorial, pos=(0, 0, -.2)) def destroyStartScreenButtons(self): self.creatingButton.destroy() self.drivingButton.destroy() self.tutorialButton.destroy() def setAddObjectTree(self): self.createdObject = self.createTree def setAddObjectRock(self): self.createdObject = self.createRock def setAddObjectPole(self): self.createdObject = self.createPole def setUpCreateButtons(self): # todo: add toggle for instructions so that they do not always interfere with button self.treeButton = DirectButton(text="Add Block", scale=.1, command=self.setAddObjectTree, pos=(0, 0, .85)) #self.rockButton = DirectButton(text="Add Rock", scale=.1, command=self.setAddObjectRock, pos=(-.5,.9,.85)) self.poleButton = DirectButton(text="Add Pole", scale=.1, command=self.setAddObjectPole, pos=(.5, 0, .85)) def setUpCreateObjects(self): self.createdObject = 0 self.createTree = 0 self.createRock = 1 self.createPole = 2 def destroyCreateButtons(self): self.treeButton.destroy() #self.rockButton.destroy() self.poleButton.destroy() def setUpDrivingInstructions(self): self.inst[0] = self.addInstructions( .06, "Right arrow and left arrow to turn") self.inst[1] = self.addInstructions( .12, "Forward and Backward arrow to go forward and backward") self.inst[2] = self.addInstructions(.18, "h to switch to add object mode") self.inst[3] = self.addInstructions(.24, "z to switch to start the race") self.inst[4] = self.addInstructions(.30, "m to go to main") def setUpWindow(self): # set up the egg files needed # since this method is made for python 2.7 but these objects are made for python 3.5, seems to be incompatible #m = Mountain("TestMountain", 60) #m.editFile() #p = Pole("TestPole", 0, 0, 0) #p.editFile() #c = Car("TestCar", 0,0,0) #c.editFile() #b = BeaconLight("BeaconLight",0,0,0) #b.editFile() # Set up the window, camera, etc ShowBase.__init__(self) # Set the background color to black self.win.setClearColor((0, 1, 1, 1)) # this is the model I created using mountainMaker.py self.environ = loader.loadModel("TestMountain1") self.environ.reparentTo(render) self.car = loader.loadModel("TestCar") # found how to solve the problem of only being able to see objects from # certain angles with this: # http://www.panda3d.org/manual/index.php/Backface_Culling_and_Frontface_Culling self.car.setTwoSided(True) self.car.reparentTo(render) # Create some lighting # this is a part that is completely unchanged from demo ambientLight = AmbientLight("ambientLight") ambientLight.setColor((.3, .3, .3, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection((-5, -5, -5)) directionalLight.setColor((1, 1, 1, 1)) directionalLight.setSpecularColor((1, 1, 1, 1)) # to get light from other direction to light up things on both sides directionalLight2 = DirectionalLight("directionalLight") directionalLight2.setDirection((5, 5, 5)) directionalLight2.setColor((1, 1, 1, 1)) directionalLight2.setSpecularColor((1, 1, 1, 1)) render.setLight(render.attachNewNode(ambientLight)) render.setLight(render.attachNewNode(directionalLight)) render.setLight(render.attachNewNode(directionalLight2)) def setUpCar(self): # for adjusting so that the position is the center of the car self.adjustedXForCenter = 10 / 2 self.adjustedYForCenter = 20 / 2 # for some reason can't change this or the collisions do not work self.carPositionX = 20 self.carPositionY = 20 self.carPositionZ = 100 # note for rotating camera: from this website: # https://www.panda3d.org/manual/index.php/Common_State_Changes # setHpr(Yaw, Pitch, Roll) # setting up initial conditions for which way camera is rotated self.carYaw = 0 self.carPitch = 0 (actualXPos, actualYPos) = RacingGame.findActualCenter( self, self.carPositionX, self.carPositionY, self.adjustedXForCenter, self.adjustedYForCenter, self.carYaw) self.car.setX(actualXPos) self.car.setY(actualYPos) self.car.setZ(self.carPositionZ) self.car.setHpr(self.carYaw, self.carPitch, 0) def setUpCamera(self): # for flying mode self.cameraPositionX = 500 self.cameraPositionY = 500 self.cameraPositionZ = 40 # note for rotating camera: from this website: # https://www.panda3d.org/manual/index.php/Common_State_Changes # setHpr(Yaw, Pitch, Roll) # setting up initial conditions for which way camera is rotated self.cameraYaw = 0 self.cameraPitch = 0 # Set up the camera self.disableMouse() # should probably clean up these magic numbers self.camera.setPos(self.cameraPositionX, self.cameraPositionY, self.cameraPositionZ) def setUpKeyMap(self): # This is used to store which keys are currently pressed. self.keyMap = { "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0, "backward": 0, "cam-up": 0, "cam-down": 0, "add-car": 0, "switch-mode": 0, "mouse-click": 0, "race-start": 0, "to-main": 0 } # Accept the control keys for movement and rotation #setting up keys for movement self.accept("escape", sys.exit) self.accept("arrow_left", self.setKey, ["left", True]) self.accept("arrow_right", self.setKey, ["right", True]) self.accept("arrow_up", self.setKey, ["forward", True]) self.accept("arrow_down", self.setKey, ["backward", True]) self.accept("arrow_left-up", self.setKey, ["left", False]) self.accept("arrow_right-up", self.setKey, ["right", False]) self.accept("arrow_up-up", self.setKey, ["forward", False]) self.accept("arrow_down-up", self.setKey, ["backward", False]) self.accept("m", self.setKey, ["to-main", True]) self.accept("m-up", self.setKey, ["to-main", False]) # starting race self.accept("z", self.setKey, ["race-start", True]) self.accept("z-up", self.setKey, ["race-start", False]) # adding car self.accept("mouse1", self.setKey, ["mouse-click", True]) self.accept("mouse1-up", self.setKey, ["mouse-click", False]) # setting up orientation of the camera self.accept("a", self.setKey, ["cam-left", True]) self.accept("s", self.setKey, ["cam-down", True]) self.accept("a-up", self.setKey, ["cam-left", False]) self.accept("s-up", self.setKey, ["cam-down", False]) self.accept("d", self.setKey, ["cam-right", True]) self.accept("d-up", self.setKey, ["cam-right", False]) self.accept("w", self.setKey, ["cam-up", True]) self.accept("w-up", self.setKey, ["cam-up", False]) # to switch between tasks self.accept("h", self.setKey, ["switch-mode", True]) self.accept("h-up", self.setKey, ["switch-mode", False]) def __init__(self): self.setUpWindow() self.setUpKeyMap() #instructions self.inst = [""] * 6 self.setUpFlyingInstructions() self.mouseClicked = False self.winText = None # important for setting the size relative to everything else # found it here : https://www.panda3d.org/manual/index.php/Common_State_Changes # set the mode that the player is currently in self.mode = 0 self.modeFly = 2 self.modeRace = 1 self.modeStart = 0 self.modeTutorial = 3 # to ensure that when pressing h it only switches once each press self.hasSwitched = False self.raceBegan = False self.raceTime = 0 self.poleOn = 0 self.setUpCamera() self.setUpCar() self.setUpCarCollider() self.setUpMouseCollider() self.setUpStartScreenButtons() # make the rocks and other stuff that will show up self.setUpCreateObjects() self.objects = [] self.poles = [] self.beaconLight = None self.beaconLightZ = 50 self.target = None taskMgr.add(self.move, "moveTask") def findCollisionTube(self): # using bassically same formula as Y position # decided not to use this because possible problems with ground getting # hit instead of things in front degToRad = math.pi / 180 xAddition = ( self.adjustedXForCenter * math.cos(self.carYaw * degToRad) + self.adjustedYForCenter * math.sin(self.carYaw * degToRad)) / 2 yAddition = ( self.adjustedXForCenter * math.cos(self.carYaw * degToRad) + self.adjustedYForCenter * math.sin(self.carYaw * degToRad)) def findCarFrontDir(self): degToRad = math.pi / 180 xDir = -1 * math.sin(degToRad * self.carYaw) * math.cos( degToRad * self.carPitch) yDir = 1 * math.cos(degToRad * self.carYaw) * math.cos( degToRad * self.carPitch) zDir = 1 * math.sin(degToRad * self.carPitch) return (xDir, yDir, zDir) def setUpCarCollider(self): self.carCollideTrav = CollisionTraverser() base.cTrav = self.carCollideTrav self.handler = CollisionHandlerQueue() self.carRay = CollisionRay(self.carPositionX, self.carPositionY, self.carPositionZ, 0, 0, -1) self.carForwardHandler = CollisionHandlerQueue() # so that it doesn't collide with things forward and backward. degToRad = math.pi / 180 (xDir, yDir, zDir) = self.findCarFrontDir() self.carRayForward = CollisionRay(self.carPositionX, self.carPositionY, self.carPositionZ, xDir, yDir, zDir) self.carForwardCollision = CollisionNode("forwardCollision") self.carForwardCollision.addSolid(self.carRayForward) self.carForwardCollision.setIntoCollideMask(CollideMask.allOff()) self.carForwardCollisionNode = self.car.attachNewNode( self.carForwardCollision) (centerX, centerY) = self.findActualCenter(0, 0, self.adjustedXForCenter, self.adjustedYForCenter, self.carYaw) self.carRayForward.setOrigin(5, 10, 5) self.carCollision = CollisionNode("groundCollision") self.carCollision.addSolid(self.carRay) self.carCollision.setIntoCollideMask(CollideMask.allOff()) self.carCollisionNode = self.car.attachNewNode(self.carCollision) self.carCollideTrav.addCollider(self.carCollisionNode, self.handler) self.carCollideTrav.addCollider(self.carForwardCollisionNode, self.carForwardHandler) self.carForwardCollisionNode.show() def setUpMouseCollider(self): # clicking on objects stuff came from here: # https://www.panda3d.org/manual/index.php/Collision_Traversers # https://www.panda3d.org/manual/index.php/Collision_Handlers # will not use the traverser set up by car because slow # instead we will render each time clicked self.mouseCollideTrav = CollisionTraverser("mouseTraverse") self.mousehandler = CollisionHandlerQueue() # edit this so that from Object is the camera # self.mouseCollideTrav.addCollider(fromObject, queue) # self.mouseCollideTrav.traverse(render) # this next part came from: # https://www.panda3d.org/manual/index.php/Clicking_on_3D_Objects pickerNode = CollisionNode("mouseRay") pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) pickerNode.setIntoCollideMask(CollideMask.allOff()) self.pickerRay = CollisionRay() pickerNode.addSolid(self.pickerRay) pickerNp = camera.attachNewNode(pickerNode) self.mouseCollideTrav.addCollider(pickerNp, self.mousehandler) # Records the state of the arrow keys def setKey(self, key, value): self.keyMap[key] = value def switchToCreateMode(self): self.mode = self.modeFly self.destroyInstructions() self.setUpFlyingInstructions() self.hasSwitched = True self.setUpCreateButtons() def switchToDrivingMode(self): self.mode = self.modeRace self.destroyInstructions() self.setUpDrivingInstructions() self.hasSwitched = True def switchToMainMode(self): self.mode = 0 self.setUpStartScreenButtons() def setTutorialText(self, str): # reusing inst so that it is easy to erase self.inst[0] = self.addInstructions(.06, str) def move(self, task): if (self.keyMap["to-main"]): self.switchToMainMode() elif (self.mode == self.modeFly): if self.keyMap["switch-mode"] and not self.hasSwitched: self.switchToDrivingMode() self.destroyCreateButtons() elif not self.keyMap["switch-mode"]: # to ensure switch mode only happens once per button pressed self.hasSwitched = False self.findNewCameraPosition() self.checkAndAddNewObject() elif (self.mode == self.modeRace): if self.keyMap["switch-mode"] and not self.hasSwitched: self.destroyWin() self.switchToCreateMode() elif not self.keyMap["switch-mode"]: # this ensures that when key is pressed only switch states once self.hasSwitched = False self.findCarNewXandY() # when implementing the use of the mouse look here: # https://www.panda3d.org/manual/index.php/Clicking_on_3D_Objects self.setCarZ() self.setCameraPositionBehindCar() if (self.keyMap["race-start"] and not self.raceBegan and len(self.poles) >= 2): self.destroyWin() # try so that if there are not enough poles then the game # doesn't crash try: self.raceBegan = True self.raceTime = time.time() # puts in the car where the first two poles are # first col of poles is model, second x coord, thrid y coord, fourth z coord self.carPositionX = (self.poles[0][1] + self.poles[1][1]) / 2 self.carPositionY = (self.poles[0][2] + self.poles[1][2]) / 2 # meant to show where car should go # got info on how to do point lights from here: # https://www.panda3d.org/manual/index.php/Lighting self.beaconLight = PointLight("beaconLight") self.beaconLight.setColor((1, 1, 1, 1)) self.beaconLight.setAttenuation((0, 0, 1)) self.beaconLightHolder = render.attachNewNode( self.beaconLight) (beaconLightX, beaconLightY) = self.getNextGateCenter() # target for driver if (self.target == None): self.target = loader.loadModel("BeaconLight.egg") self.target.setTwoSided(True) self.target.reparentTo(render) if (beaconLightX != None): self.beaconLightHolder.setPos(beaconLightX, beaconLightY, self.beaconLightZ) render.setLight(self.beaconLightHolder) self.target.setPos(beaconLightX, beaconLightY, self.beaconLightZ) except: # not enough poles pass if (self.raceBegan): # minus 1 just in case non even if (self.poleOn + 1 >= len(self.poles)): self.raceBegan = False self.addWin(time.time() - self.raceTime) # since race ended try: self.target.destroy() except: pass self.beaconLight = None # use object + lights self.beaconLightHolder = None self.poleOn = 0 else: acceptableError = 100 # formula I created: (p2y-p1y)/(p2x-p1x)*(p2x-pAx)+p2y = # expected pAy # so if the actual car positionY is within acceptableError of # pAy then the car is between the two poles # if in between poles middleX = (self.poles[self.poleOn][1] + self.poles[self.poleOn + 1][1]) / 2 middleY = (self.poles[self.poleOn][2] + self.poles[self.poleOn + 1][2]) / 2 expectedCarY = ( (self.poles[self.poleOn][2] - self.poles[self.poleOn + 1][2]) / (self.poles[self.poleOn][1] - self.poles[self.poleOn + 1][1]) * (self.poles[self.poleOn][1] - self.carPositionX) + self.poles[self.poleOn][2]) # do not really care about car being inbetween pole in z axis # because 2 demensional if (expectedCarY + acceptableError > self.carPositionY and expectedCarY - acceptableError < self.carPositionY): self.poleOn += 2 # only when last pole found is it necesary to add light # to guide to next place elsewhere (beaconLightX, beaconLightY) = self.getNextGateCenter() if (beaconLightX != None): self.beaconLightHolder.setPos( beaconLightX, beaconLightY, self.beaconLightZ) self.target.setPos(beaconLightX, beaconLightY, self.beaconLightZ) elif (self.mode == self.modeTutorial): self.destroyWin() # do the tutorial part for the creating timeBeforeNext = 2 if (self.tutorialPause == True): if (time.time() - self.tutorialActionTime > timeBeforeNext): self.tutorialPause = False else: if (self.tutorialStep == -1): self.destroyInstructions() self.setTutorialText( "use w and s to move camera up and down") self.tutorialStep += 1 # do this until the user has completed all of the task self.checkTutorialStep( 0, (self.keyMap["cam-up"] or self.keyMap["cam-down"]), "use a and d to rotate camera right and left") self.checkTutorialStep( 1, (self.keyMap["cam-left"] or self.keyMap["cam-right"]), "use up-arrow and down-arrow to turn camera forward and backward" ) self.checkTutorialStep( 2, (self.keyMap["forward"] or self.keyMap["backward"]), "use left-arrow and right-arrow to slide camera left and right" ) self.checkTutorialStep( 3, (self.keyMap["left"] or self.keyMap["right"]), "use mouse click to place objects on terrain") self.checkTutorialStep( 4, (self.keyMap["mouse-click"]), "use up-arrow and down-arrow to move car forward and backward", (self.switchToDrivingMode, self.destroyInstructions)) # need to ensure that the mode stays as tutorial self.mode = self.modeTutorial # then tutorial part for the driving self.checkTutorialStep( 5, (self.keyMap["forward"] or self.keyMap["backward"]), "use right-arrow and left-arrow to rotate car left and right" ) self.checkTutorialStep( 6, (self.keyMap["left"] or self.keyMap["right"]), "Use poles to make the race course\n use z to start race") self.checkTutorialStep( 7, True, "Follow yellow block through the gates till you win") self.checkTutorialStep( 8, True, "Watch for high Terrain and blocks because you can not get through those" ) self.checkTutorialStep(9, True, "") if (self.tutorialStep > 9): # switch to main self.switchToMainMode() # for movement if (self.tutorialStep <= 4): self.findNewCameraPosition() self.checkAndAddNewObject() if (self.tutorialStep > 4 and self.tutorialStep <= 9): self.findCarNewXandY() self.setCarZ() self.setCameraPositionBehindCar() return task.cont def getNextGateCenter(self): if (len(self.poles) > self.poleOn + 1): positionX = (self.poles[self.poleOn][1] + self.poles[self.poleOn + 1][1]) / 2 positionY = (self.poles[self.poleOn][2] + self.poles[self.poleOn + 1][2]) / 2 return (positionX, positionY) else: return (None, None) def checkTutorialStep(self, step, keysNeeded, nextText, functions=None): if (self.tutorialStep == step and self.tutorialNextStep == True): if (functions != None): for func in functions: func() self.destroyInstructions() self.setTutorialText(nextText) self.tutorialStep += 1 self.tutorialNextStep = False elif (self.tutorialStep == step and keysNeeded): self.tutorialNextStep = True self.tutorialActionTime = time.time() self.tutorialPause = True def setUpTutorial(self): self.tutorialStep = -1 self.tutorialPause = False # this records when last tutorial action taken self.tutorialActionTime = 0 self.tutorialNextStep = False def checkAndAddNewObject(self): # clicking on 3D objects comes from here: # https://www.panda3d.org/manual/index.php/Clicking_on_3D_Objects # checks if it needs to add any objects: if (self.keyMap["mouse-click"] and self.mouseClicked == False): self.mouseClicked = True # found way to speed this up by only doing collision check # when mouse clicked by not using cTrav like in this method # the way I did it I found here: # https://www.panda3d.org/manual/index.php/Clicking_on_3D_Objects # self.mouseCollideTrav.traverse(render) if (base.mouseWatcherNode.hasMouse()): mousePos = base.mouseWatcherNode.getMouse() self.pickerRay.setFromLens(base.camNode, mousePos.getX(), mousePos.getY()) # do not put this before previous line, will get the coordinates # of last mouse click and where pickerRay was # ahhhhhhh!!!!!!!!!!! self.mouseCollideTrav.traverse(render) if (self.mousehandler.getNumEntries() > 0): entries = list(self.mousehandler.getEntries()) # pathagorean formula for sorting entries.sort( key=lambda x: ((x.getSurfacePoint(render).getX( ) - self.cameraPositionX)**2 + (x.getSurfacePoint( render).getY() - self.cameraPositionY)**2)**.5) newX = entries[0].getSurfacePoint(render).getX() newY = entries[0].getSurfacePoint(render).getY() newZ = entries[0].getSurfacePoint(render).getZ() adjustedX = 10 / 2 adjustedY = 20 / 2 yaw = 0 # have to adjust this once there are different sized # objects added (actualXPos, actualYPos) = RacingGame.findActualCenter( self, newX, newY, adjustedX, adjustedY, yaw) if (self.createdObject == self.createPole): self.poles.append([ loader.loadModel("TestPole.egg"), actualXPos, actualYPos, newZ ]) self.poles[len(self.poles) - 1][0].reparentTo(render) self.poles[len(self.poles) - 1][0].setTwoSided(True) self.poles[len(self.poles) - 1][0].setPos( actualXPos, actualYPos, newZ) else: newCar = loader.loadModel("TestCar.egg") newCar.reparentTo(render) newCar.setPos(actualXPos, actualYPos, newZ) # should take out because slow, but objects can not be # seen without this because only seen from one direction # even though normal vectors set up. newCar.setTwoSided(True) self.objects.append(newCar) elif (not self.keyMap["mouse-click"]): # elif because for some reason mouseClicked was becoming false # while click still pressed self.mouseClicked = False def findNewCameraPosition(self): # Get the time that elapsed since last frame. We multiply this with # the desired speed in order to find out with which distance to move # in order to achieve that desired speed. dt = globalClock.getDt() # the angle is in degrees with 360 equal to full rotation angleAdjustment = 100 if self.keyMap["cam-left"]: self.cameraYaw += angleAdjustment * dt if self.keyMap["cam-right"]: self.cameraYaw -= angleAdjustment * dt if self.keyMap["cam-up"]: self.cameraPitch += angleAdjustment * dt if self.keyMap["cam-down"]: self.cameraPitch -= angleAdjustment * dt positionAdjustment = 500 # should switch rad and Deg in variable name radToDeg = math.pi / 180 # the x and y component of left and right moves, do not need to # compensate in z axis because not doing any roll, so there should be # no zComponent xComponent = math.cos(self.cameraYaw * radToDeg) yComponent = math.sin(self.cameraYaw * radToDeg) if self.keyMap["left"]: self.cameraPositionX -= positionAdjustment * dt * xComponent self.cameraPositionY -= positionAdjustment * dt * yComponent if self.keyMap["right"]: self.cameraPositionX += positionAdjustment * dt * xComponent self.cameraPositionY += positionAdjustment * dt * yComponent # for going forward, the orientation is rotated 90 degrees so need to # change components xComponent = math.cos(self.cameraYaw * radToDeg + math.pi / 2) * math.cos(self.cameraPitch * radToDeg) yComponent = math.sin(self.cameraYaw * radToDeg + math.pi / 2) * math.cos(self.cameraPitch * radToDeg) zComponent = math.sin(self.cameraPitch * radToDeg) if self.keyMap["forward"]: self.cameraPositionX += positionAdjustment * dt * xComponent self.cameraPositionY += positionAdjustment * dt * yComponent self.cameraPositionZ += positionAdjustment * dt * zComponent if self.keyMap["backward"]: self.cameraPositionX -= positionAdjustment * dt * xComponent self.cameraPositionY -= positionAdjustment * dt * yComponent self.cameraPositionZ -= positionAdjustment * dt * zComponent self.camera.setX(self.cameraPositionX) self.camera.setY(self.cameraPositionY) self.camera.setZ(self.cameraPositionZ) self.camera.setHpr(self.cameraYaw, self.cameraPitch, 0) def carForwardImpact(self): # update position so that it is pointing right directions #(dirX, dirY, dirZ) = self.findCarFrontDir() #self.carRayForward.setDirection(dirX, dirY, dirZ) degToRad = math.pi / 180 # + math.pi since it is taking corner and going to center rather # than opposite that function actually does #(centerX,centerY) = self.findActualCenter(0,0,self.adjustedXForCenter, # self.adjustedYForCenter, self.carYaw # +math.pi) posAboveGround = 5 # need to update with new coordinates self.carCollideTrav.traverse(render) collisions = list(self.carForwardHandler.getEntries()) # closest collision using pythagorean formula collisions.sort( key=lambda x: (x.getSurfacePoint(render).getX() - self.carPositionX)**2 + (x.getSurfacePoint(render).getY() - self.carPositionY)**2) if (len(collisions) > 0): (actualX, actualY) = RacingGame.findActualCenter( self, self.carPositionX, self.carPositionY, self.adjustedXForCenter, self.adjustedYForCenter, self.carYaw) distance = ( (collisions[0].getSurfacePoint(render).getX() - actualX)**2 + (collisions[0].getSurfacePoint(render).getY() - actualY)** 2)**.5 error = .9 # so that the collisionray does not detect car itself return distance / 2 <= self.adjustedYForCenter * .9 else: return False def findCarNewXandY(self): # Get the time that elapsed since last frame. We multiply this with # the desired speed in order to find out with which distance to move # in order to achieve that desired speed. deltaTime = globalClock.getDt() degreeAdjustment = 60 positionAdjustment = 100 # should switch rad and Deg in variable name radToDeg = math.pi / 180 # the x and y component of left and right moves, do not need to # compensate in z axis because not doing any roll, so there should be # no zComponent xComponent = math.sin(self.carYaw * radToDeg) yComponent = math.cos(self.carYaw * radToDeg) if self.keyMap["left"]: self.carYaw += degreeAdjustment * deltaTime if self.keyMap["right"]: self.carYaw -= degreeAdjustment * deltaTime if (self.keyMap["forward"] and not self.carForwardImpact()): self.carPositionX -= positionAdjustment * deltaTime * xComponent self.carPositionY += positionAdjustment * deltaTime * yComponent if self.keyMap["backward"]: self.carPositionX += positionAdjustment * deltaTime * xComponent self.carPositionY -= positionAdjustment * deltaTime * yComponent # need to consider both the x and y component of offset for both # because x slowly changes to y as it turns (actualXPos, actualYPos) = RacingGame.findActualCenter( self, self.carPositionX, self.carPositionY, self.adjustedXForCenter, self.adjustedYForCenter, self.carYaw) self.car.setX(actualXPos) self.car.setY(actualYPos) self.car.setZ(self.carPositionZ) self.car.setHpr(self.carYaw, self.carPitch, 0) def setCarZ(self): # almost directly taken from ralph example entries = list(self.handler.getEntries()) entries.sort(key=lambda x: x.getSurfacePoint(render).getZ()) # worry about which thing it collides with later if (len(entries) > 0): # and entries[0].getIntoNode().getName() == "mountainCollide": self.carPositionZ = (entries[0].getSurfacePoint(render).getZ()) else: # because at 25 everything should be below car and do not want # to continually go up or else it may go up forever. self.carPositionZ = 25 self.setCameraPositionBehindCar() def setCameraPositionBehindCar(self): # Modify view of camera so that it is behind car # should be named degToRad radToDeg = math.pi / 180 distanceBehind = 200 distanceAbove = 60 self.camera.setHpr(self.carYaw, -.5, 0) (actualXPos, actualYPos) = self.findActualCenter( self.carPositionX, self.carPositionY, self.adjustedXForCenter, self.adjustedXForCenter, self.carYaw) camX = actualXPos + distanceBehind * math.sin(radToDeg * self.carYaw) camY = actualYPos - distanceBehind * math.cos(radToDeg * self.carYaw) camZ = self.carPositionZ + distanceAbove self.camera.setPos(camX, camY, camZ) def findActualCenter(self, positionX, positionY, adjustedX, adjustedY, yaw): # will need to fix this later, it seems to be adjusting wrong # so that it is puting box away from click instead of on it # update, I think this is fixed?!? degToRad = math.pi / 180 actualXPos = (positionX - adjustedX * math.cos(degToRad * yaw) + adjustedY * math.sin(degToRad * yaw)) actualYPos = (positionY - adjustedY * math.cos(degToRad * yaw) - adjustedX * math.sin(degToRad * yaw)) return (actualXPos, actualYPos)