def __init__(self): ShowBase.__init__(self) self.camera.setPos(0, 0, 3) self.fm = FlyMove(self) self.scene = self.loader.loadModel('models/environment') self.disable_mouse() self.scene.reparentTo(self.render) self.scene.setScale(0.25, 0.25, 0.25) self.scene.setPos(-8, 42, 0) pandaMat = Material() pandaMat.setEmission((1, 0.4, 0, 1)) colour = (0.5, 0.8, 0.8) expfog = Fog("Scene-wide exponential Fog object") expfog.setColor(*colour) expfog.setExpDensity(0.005) self.render.setFog(expfog) self.pandaActor = Actor('models/panda-model', {'walk': 'models/panda-walk4'}) self.pandaActor.set_material(pandaMat) self.pandaActor.setScale(0.005, 0.005, 0.005) self.pandaActor.loop('walk') line = NodePath('pandaline') for i in range(50): placeholder = line.attachNewNode('line-panda') placeholder.setPos(i * 2, 0, 0) self.pandaActor.instanceTo(placeholder) line.reparentTo(self.render) pandaPosIntervalInterval1 = self.pandaActor.posInterval( 13, Point3(0, -10, 0), startPos=Point3(0, 10, 0)) pandaPosIntervalInterval2 = self.pandaActor.posInterval( 13, Point3(0, 10, 0), startPos=Point3(0, -10, 0)) pandaHprIntervalInterval1 = self.pandaActor.hprInterval( 2, Point3(180, 0, 0), startHpr=Point3(0, 0, 0)) pandaHprIntervalInterval2 = self.pandaActor.hprInterval( 2, Point3(0, 0, 0), startHpr=Point3(180, 0, 0)) self.pandaPace = Sequence(pandaPosIntervalInterval1, pandaHprIntervalInterval1, pandaPosIntervalInterval2, pandaHprIntervalInterval2) self.pandaPace.loop() light = DirectionalLight('pl') light.set_color_temperature(2000) np = self.render.attachNewNode(light) np.set_pos(0, 0, 5) light.set_shadow_caster(True, 512, 512) self.render.setLight(np) # np.place() alight = AmbientLight('alight') alight.setColor(VBase4(0.3, 0.1, 0.1, 1)) alnp = self.render.attachNewNode(alight) self.render.setLight(alnp)
def _add_visualization(self): if self.render: [path, scale, x_y_z_offset, H] = self.path[self.np_random.randint(0, len(self.path))] if path not in BaseVehicle.model_collection: car_model = self.loader.loadModel( AssetLoader.file_path("models", path)) BaseVehicle.model_collection[path] = car_model else: car_model = BaseVehicle.model_collection[path] car_model.setScale(scale) car_model.setH(H) car_model.setPos(x_y_z_offset) car_model.setZ(-self.TIRE_RADIUS - self.CHASSIS_TO_WHEEL_AXIS + x_y_z_offset[-1]) car_model.instanceTo(self.origin) if self.config["random_color"]: material = Material() material.setBaseColor( (self.panda_color[0] * self.MATERIAL_COLOR_COEFF, self.panda_color[1] * self.MATERIAL_COLOR_COEFF, self.panda_color[2] * self.MATERIAL_COLOR_COEFF, 0.2)) material.setMetallic(self.MATERIAL_METAL_COEFF) material.setSpecular(self.MATERIAL_SPECULAR_COLOR) material.setRefractiveIndex(1.5) material.setRoughness(self.MATERIAL_ROUGHNESS) material.setShininess(self.MATERIAL_SHININESS) material.setTwoside(False) self.origin.setMaterial(material, True)
def set_material(self, root_path, name, color=None, texture_path=''): """Override material of a node. Arguments: root_path {str} -- path to the group's root node name {str} -- node name within a group color {Vec4} -- color RGBA Keyword Arguments: texture {str | np.ndarray} -- path to the texture file on disk (default: {None}) """ node = self._groups[root_path].find(name) if color is not None: node.set_color(Vec4(*color)) material = Material() material.set_ambient(Vec4(*color)) material.set_diffuse(Vec4(*color)) material.set_specular(Vec3(1, 1, 1)) material.set_roughness(0.4) node.set_material(material, 1) if color[3] < 1: node.set_transparency(TransparencyAttrib.M_alpha) if texture_path: texture = self.loader.load_texture(texture_path) node.set_texture(texture)
def defaultMaterial(): material = Material() material.setShininess(0.0) material.setAmbient((0.2, 0, 0, 1)) rand = random.uniform(0, 1) material.setDiffuse((rand, rand, rand, 1)) return material
def updateSphero(self, node, pos, u, L, diameter): node.set_shader_input("L", L) node.set_shader_input("diameter", diameter) node.setPos(pos) # Theta is the amount to rotate about x, the 'roll' roll = math.acos(u[2]) * 180 / math.pi # Determine amount to rotate about z ('yaw' or 'heading') length_xy = math.sqrt(u[0]*u[0] + u[1]*u[1]) if length_xy > 0.0: yaw = math.acos(u[0] / length_xy) * 180 / math.pi if u[1] < 0.0: yaw = 360 - yaw else: yaw = 0.0 # Apply transforms (heading/yaw, pitch, roll) node.setHpr(yaw, 0.0, roll) # Make a diffuse material to color our spherocylinder myMaterial = Material() myMaterial.setAmbient((0.0, 0.0, 0.0, 0.0)) myMaterial.setDiffuse(self.spheroColor) node.setMaterial(myMaterial)
def __init__(self, loader, parentNodePath): w = loader.loadModel("plane") w.reparentTo(parentNodePath) size = 6 w.setPos(3.5, 15, size / 2 - 3) w.setColor(1, 0, 0) w.setHpr(0, 180, 0) w.setScale(size, 1, size / 1.33) w.setTwoSided(True) self.tx = Texture("video") self.tx.setup2dTexture(self.res, self.res, Texture.TUnsignedByte, Texture.FRgb8) # this makes some important setup call self.tx.load(PNMImage(self.res, self.res)) w.setTexture(self.tx) m = Material("vid") m.setTwoside(True) m.setEmission(VBase4(1, 1, 1, 1)) w.setMaterial(m) w.setFogOff()
def update_scene(self, scene_graph, materials_only): """Update a scene using scene_graph description Arguments: scene_graph {SceneGraph} -- scene description materials_only {bool} -- update only shape materials """ for k, v in scene_graph.nodes.items(): node = self.render.attachNewNode(f'node_{k:02d}') self.nodes[k] = node for shape in v.shapes: # load model if shape.type == ShapeType.Mesh: model = self.loader.load_model(shape.mesh.filename) else: mesh = Mesh.from_trimesh(primitive_mesh(shape)) model = node.attach_new_node(mesh) if shape.material is not None: # set material material = Material() material.setAmbient(Vec4(*shape.material.diffuse_color)) material.setDiffuse(Vec4(*shape.material.diffuse_color)) material.setSpecular(Vec3(*shape.material.specular_color)) material.setShininess(5.0) model.setMaterial(material, 1) # set relative position model.reparentTo(node) model.setPos(*shape.pose.origin) model.setQuat(Quat(*shape.pose.quat)) model.setScale(*shape.pose.scale)
def __set_material(self, nodePath): mat = Material() mat.setAmbient((.35, .35, .35, .5)) mat.setDiffuse((.35, .35, .35, .5)) mat.setSpecular((.35, .35, .35, .5)) mat.setShininess(12.5) nodePath.set_material(mat, 1)
def levelLoaded(self): if self.level == 'TT_maze': for model in self.models: if model.getName() == 'maze': brightenMat = Material() brightenMat.setShininess(2.0) brightenMat.setEmission((0, 0.25, 0.16, 1)) walls = model.find('**/maze_walls') walls.setSz(1.5) walls.setBSPMaterial('phase_4/maps/DGhedge.mat', 1) walls.setMaterial(brightenMat) floor = model.find('**/maze_floor') floor.setBSPMaterial('phase_4/maps/grass.mat', 1) model.setShaderAuto() elif model.getName() == 'maze_collisions': model.hide() model.setTransparency(1) model.setColorScale(1, 1, 1, 0) for node in model.findAllMatches('**'): node.setSz(1.5) elif model.getName() == 'tag_arena_bg': model.find('**/g1').removeNode()
def create_material_COLOR(self, materialname, color): if panda3d is None: raise ImportError("Cannot locate Panda3D") currblock = self.blocks[-1] assert materialname not in currblock.materials mat = Material() mat.setAmbient(VBase4(color[0], color[1], color[2], 1)) mat.setDiffuse(VBase4(color[0], color[1], color[2], 1)) currblock.materials[materialname] = mat
def getCharacterMaterial(name = "charMat", shininess = 250, rimColor = (1, 1, 1, 1.0), rimWidth = 10, specular = (1, 1, 1, 1), lightwarp = None):#"phase_3/maps/toon_lightwarp.jpg"): mat = Material(name) mat.setRimColor(rimColor) mat.setRimWidth(rimWidth) mat.setSpecular(specular) mat.setShininess(shininess) mat.setShadeModel(Material.SMHalfLambert) if lightwarp and hasattr(mat, 'setLightwarpTexture'): mat.setLightwarpTexture(loader.loadTexture(lightwarp)) return mat
def makeMaterial(ambient=(1, 1, 1, 1), diffuse=(1, 1, 1, 1), emission=(0, 0, 0, 1), shininess=0.0, specular=(0, 0, 0, 1)): m = Material() m.setAmbient(ambient) m.setDiffuse(diffuse) m.setEmission(emission) m.setShininess(shininess) m.setSpecular(specular) return m
def _make_floor(self): model = GeomNode('floor') model.add_geom(geometry.make_plane(size=(10, 10))) node = self.render.attach_new_node(model) node.set_color(Vec4(0.3, 0.3, 0.3, 1)) material = Material() material.set_ambient(Vec4(0, 0, 0, 1)) material.set_diffuse(Vec4(0.3, 0.3, 0.3, 1)) material.set_specular(Vec3(1, 1, 1)) material.set_roughness(0.8) node.set_material(material, 1) return node
def makeMaterial(ambient=(0, 0, 0, 1), diffuse=(1, 1, 1, 1), emission=(0.01, 0.01, 0.01, 1), shininess=1, specular=(0.2, 0.2, 0.2, 1)): m = Material() m.setAmbient(Vec4(ambient)) m.setDiffuse(Vec4(diffuse)) m.setEmission(Vec4(emission)) m.setShininess(shininess) m.setSpecular(Vec4(specular)) return m
def __init__(self): loadPrcFile("config/Config.prc") ShowBase.__init__(self) self.camera = self.makeCamera(self.win) #self.render.setAntialias(AntialiasAttrib.MMultisample) self.setBackgroundColor(0.0,0.0,0.0) #Mouse position text self.posText = OnscreenText(\ style=1, fg=(1,1,1,1), pos=(0.8,-0.95), scale = .07) #self.toggleWireframe() self._setupKeyboardEvents() # Load and transform the panda actor. self.render.setTransparency(TransparencyAttrib.MAlpha) self.tile1 = Tile("tile1",0.0,0.0) node1 = self.render.attachNewNode(self.tile1) self.tile2 = Tile("tile2",0.064,0.032) node2 = self.render.attachNewNode(self.tile2) texture = self.loader.loadTexture('artwork/sample.png') #node.setTwoSided(True) ts = TextureStage('ts') #ts.setMode(TextureStage.MNormal) node1.setTexture(ts, texture, 1) node2.setTexture(ts, texture, 1) myMaterial = Material() myMaterial.setShininess(0.0) #Make this material shiny myMaterial.setAmbient(VBase4(0.0,0.0,0.0,1)) #Make this material blue node1.setMaterial(myMaterial) node2.setMaterial(myMaterial) self.camera.setPos(0, 0, 2) self.camera.setHpr(0, -95, 0) plight = PointLight('plight') plight.setColor(VBase4(0.8, 0.8, 0.2, 1)) plnp = self.render.attachNewNode(plight) plnp.setPos(0.128, 0.064, -0.8) plight.setAttenuation(Point3(0.23, 0.23, 0.25)) self.render.setLight(plnp) self.alight = self.render.attachNewNode(AmbientLight("Ambient")) self.alight.node().setColor(Vec4(0.1, 0.1, 0.1, 1)) self.render.setLight(self.alight) self.render.setShaderAuto()
def __init__(self): self.root = render.attachNewNode("Root") base.setBackgroundColor(0, 0, 0) # This code puts the standard title and instruction text on screen self.title = OnscreenText(text="Ball In Maze", style=1, fg=(1, 1, 0, 1), pos=(0.7, -0.95), scale=.07) self.instructions = OnscreenText(text="Press Esc to exit", pos=(-1.3, .95), fg=(1, 1, 0, 1), align=TextNode.ALeft, scale=.05) self.central_msg = OnscreenText(text="", pos=(0, 0), fg=(1, 1, 0, 1), scale=.1) self.central_msg.hide() self.accept("escape", sys.exit) # Escape quits base.disableMouse() # Disable mouse-based camera control camera.setPosHpr(0, 0, 25, 0, -90, 0) # Place the camera # Load the maze and place it in the scene self.maze = loader.loadModel("models/maze") self.maze.reparentTo(render) # Load the ball and attach it to the scene # It is on a root dummy node so that we can rotate the ball itself without # rotating the ray that will be attached to it self.ballRoot = render.attachNewNode("ballRoot") self.ball = loader.loadModel("models/ball") self.ball.reparentTo(self.ballRoot) # This section deals with lighting for the ball. Only the ball was lit # because the maze has static lighting pregenerated by the modeler ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(.55, .55, .55, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(0, 0, -1)) directionalLight.setColor(Vec4(0.375, 0.375, 0.375, 1)) directionalLight.setSpecularColor(Vec4(1, 1, 1, 1)) self.ballRoot.setLight(render.attachNewNode(ambientLight)) self.ballRoot.setLight(render.attachNewNode(directionalLight)) # This section deals with adding a specular highlight to the ball to make # it look shiny m = Material() m.setSpecular(Vec4(1, 1, 1, 1)) m.setShininess(96) self.ball.setMaterial(m, 1)
def makeGround(self, parent): ground = self.base.loader.loadModel("cube") ground.setScale(20, 5, .2) ground.setPos(0, 0, -.2) ground.setColor(VBase4(.33, .42, .55, 1)) #*colorsys.hsv_to_rgb(.6, .4, .55)) ground.reparentTo(parent) m = Material("gnd") m.setDiffuse(VBase4(1, 1, 1, 1)) #ground.setMaterial(m) return ground
def bake(self): self.material = Material() if self.emissionColor != None: self.material.setEmission(self.emissionColor) if self.diffuseColor != None: self.material.setDiffuse(self.diffuseColor) if self.ambientColor != None: self.material.setAmbient(self.ambientColor) if self.specularColor != None: self.material.setSpecular(self.specularColor) if self.shininess != None: self.material.setShininess(self.shininess) self.check_specular_mask() self.calc_indexes()
def load_water(self): """ Loads the islands psuedo infinite water plane """ # Create a material for the PBR shaders water_material = Material() water_material.set_base_color(VBase4(0, 0.7, 0.9, 1)) water_card_maker = CardMaker('water_card') water_card_maker.set_frame(-200, 200, -150, 150) self.water_path = self.render.attach_new_node( water_card_maker.generate()) self.water_path.set_material(water_material, 1) self.water_path.set_scale(500)
def __init__texture(self): """ Methode bei der die Textur initialisert wird """ self.texture = loader.loadModel("models/planet_sphere") self.texture.reparentTo(self.orbit) self.chooseTexture() self.texture.setPos(self.position[0], self.position[1], self.position[2]) self.texture.setScale(2.5 * self.scale, 2.5 * self.scale, 2.5 * self.scale) myMaterial = Material() myMaterial.setEmission((1, 1, 1, 1)) #Make this material shiny self.texture.setMaterial( myMaterial) #Apply the material to this nodePath
def __init__(self, filePath): """ Initializes the object. The filePath argument represents the model to load for the sky geometry. """ self.sky = loader.loadModel(filePath) mat = Material() #mat.setAmbient( VBase4( 1, 1, 1, 1 )) mat.setEmission(VBase4(1, 1, 1, 1)) self.sky.setMaterial(mat) self.sky.setDepthWrite(False) self.sky.setDepthTest(False) self.sky.setBin('background', 0) self.sky.setEffect(CompassEffect.make(render)) self.sky.setLightOff() self.sky.reparentTo(base.cam) self.sky.setShaderOff()
def init(self): shaders = Shader.load(Shader.SLGLSL, 'planet_surface_vert.glsl', 'planet_surface_frag.glsl') self.node_path.setShader(shaders) tex = Texture() # create sane material defaults self.material = Material() self.material.set_ambient(VBase4(0.0, 0.0, 0.0, 0.0)) self.material.set_diffuse(VBase4(0.0, 0.0, 0.0, 0.0)) self.material.set_emission(VBase4(0.0, 0.0, 0.0, 0.0)) self.material.set_shininess(0) self.material.set_specular(VBase4(0.0, 0.0, 0.0, 0.0)) for m in self.sides: m.set_material(self.material) '''m.set_shader_input('colorTexture', tex)
def draw_spheres(self): # draw spheres self.spheres = [] for ball in self.box.particles: sphere = self.loader.loadModel("models/Sphere_HighPoly") # sphere = self.loader.loadModel("models/sphere") # model_radius = abs(sphere.getTightBounds()[0][0]) size1, size2 = sphere.getTightBounds() min_ = min(list(size1) + list(size2)) max_ = max(list(size1) + list(size2)) model_radius = (max_ - min_) / 2 # scale = ball.radius * 0.30 scale = ball.radius / model_radius color = [c / 255 for c in ball.color] color.append(1) sphere.setScale(scale, scale, scale) material = Material() material.setShininess(5) material.setAmbient(Vec4(*color)) material.setSpecular(Vec4(1, 1, 1, 1)) # transparent_color = color[:3] # transparent_color.append(0.1) # material.setDiffuse(Vec4(*transparent_color)) # material.setEmission(Vec4(*color)) sphere.setMaterial(material) sphere.setColor(*color) sphere.reparentTo(self.boxnode) position = ball.position if self.box.dimensions < 3: position = self._project3d(position) sphere.setPos(*position[:3]) if self.box.dimensions > 3: sphere.setTransparency(TransparencyAttrib.M_dual, 1) # if ball == self._dummy_ball: # sphere.setTransparency(TransparencyAttrib.M_dual, 1) # color = sphere.getColor() # color[3] = 0 # sphere.setColor(color) # sphere.setAntiAlias(8,1) ball.object = sphere # sphere.setColor(0, 100, 100, 10) self.spheres.append(sphere)
def load_3D_Model(self, position, hpr, color, metalic=False, scale=0.005, id=None, name=None, filename=None, parent=None, shininess=None, specular=None, texture=None): if parent is None: parent = render if name: filename = 'egg/%s_%s' % (self.device_id, name) model = loader.loadModel('%s/%s' % (self.layout_dir, filename)) if (id): container = parent.attachNewNode(id) model.reparentTo(container) else: model.reparentTo(parent) if texture: tex_node = loader.loadTexture(texture) model.setTexture(tex_node, 1) else: model.setColor(color) model.setPosHpr(position[0], position[1], position[2], hpr[0], hpr[1], hpr[2]) model.setScale(float(scale)) if metalic: m = Material() m.setShininess(shininess) m.setSpecular(specular) model.setMaterial(m) if id: self.nodes_by_id[id] = model return model
def update_scene(self, scene_graph, materials_only): """Update a scene using scene_graph description Arguments: scene_graph {SceneGraph} -- scene description materials_only {bool} -- update only shape materials """ for k, v in scene_graph.nodes.items(): node = self.render.attachNewNode(f'node_{k:02d}') self.nodes[k] = node for j, shape in enumerate(v.shapes): if shape.type == ShapeType.Mesh: filename = shape.mesh.filename elif shape.type == ShapeType.Cube: filename = 'cube.obj' else: print('Unknown shape type: {}'.format(shape.type)) continue # load model model = self.loader.load_model(filename) if shape.has_material: # set material material = Material() material.setAmbient(Vec4(*shape.material.diffuse_color)) material.setDiffuse(Vec4(*shape.material.diffuse_color)) material.setSpecular(Vec3(*shape.material.specular_color)) material.setShininess(5.0) model.setMaterial(material, 1) # set texture if shape.material.diffuse_texture > -1: tex = scene_graph.texture( shape.material.diffuse_texture) model.setTexture(tex.filename) # set relative position pose = shape.pose model.reparentTo(node) model.setPos(*shape.pose.origin) model.setQuat(Quat(*shape.pose.quat)) model.setScale(*shape.pose.scale)
def apply_instance(self, instance): if instance != self.instance: if self.instance is not None: self.instance.remove_node() self.instance = instance self.shape.set_clickable(self.clickable) self.shape.apply_owner() self.instance.reparentTo(self.context.world) if self.parent.is_emissive(): #TODO: Should be done by the owner of the shape myMaterial = Material() myMaterial.setEmission((1, 1, 1, 1)) self.instance.setMaterial(myMaterial, 1) if self.appearance is not None: #TODO: should be done somewhere else self.appearance.bake() self.instance.node().setBounds(OmniBoundingVolume()) self.instance.node().setFinal(True) self.schedule_jobs()
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 load_sphere(self, position, directionalLight, ambientLight, color): # Load a sphere. pos = position self.sphere = self.loader.loadModel("ball") self.sphere.setScale(self.SPHERE_SIZE, self.SPHERE_SIZE, self.SPHERE_SIZE) self.sphere.setPos(pos) # Sets the sphere color. self.sphere.setColor(color) self.sphere.reparentTo(render) # Make the sphere a material (to behave with the light). material = Material() material.setShininess(10.0) self.sphere.setMaterial(material) # Set lighting on the sphere. self.sphere.setLight(self.sphere.attachNewNode(directionalLight)) self.sphere.setLight(self.sphere.attachNewNode(ambientLight))
def __init__(self): # Setup window size, title and so on load_prc_file_data( "", """ win-size 1600 900 window-title Render Pipeline - Lights demo """) # ------ Begin of render pipeline code ------ # Insert the pipeline path to the system path, this is required to be # able to import the pipeline classes pipeline_path = "../../" # Just a special case for my development setup, so I don't accidentally # commit a wrong path. You can remove this in your own programs. if not os.path.isfile(os.path.join(pipeline_path, "setup.py")): pipeline_path = "../../RenderPipeline/" sys.path.insert(0, pipeline_path) from rpcore import RenderPipeline, SpotLight self.render_pipeline = RenderPipeline() self.render_pipeline.create(self) # This is a helper class for better camera movement - its not really # a rendering element, but it included for convenience from rpcore.util.movement_controller import MovementController # ------ End of render pipeline code, thats it! ------ # Set time of day self.render_pipeline.daytime_mgr.time = "4:50" self.half_energy = 5000 self.lamp_fov = 70 self.lamp_radius = 10 # Load the scene model = loader.loadModel("scene/Scene.bam") model.reparent_to(render) # Animate balls, this is for testing the motion blur blend_type = "noBlend" np = model.find("**/MBRotate") np.hprInterval(1.5, Vec3(360, 360, 0), Vec3(0, 0, 0), blendType=blend_type).loop() np = model.find("**/MBUpDown") np_pos = np.get_pos() - Vec3(0, 0, 2) Sequence( np.posInterval(0.15, np_pos + Vec3(0, 0, 6), np_pos, blendType=blend_type), np.posInterval(0.15, np_pos, np_pos + Vec3(0, 0, 6), blendType=blend_type)).loop() np = model.find("**/MBFrontBack") np_pos = np.get_pos() - Vec3(0, 0, 2) Sequence( np.posInterval(0.15, np_pos + Vec3(0, 6, 0), np_pos, blendType=blend_type), np.posInterval(0.15, np_pos, np_pos + Vec3(0, 6, 0), blendType=blend_type)).loop() np = model.find("**/MBScale") Sequence( np.scaleInterval(0.2, Vec3(1.5), Vec3(1), blendType=blend_type), np.scaleInterval(0.2, Vec3(1), Vec3(1.5), blendType=blend_type)).loop() # Generate temperature lamps # This shows how to procedurally create lamps. In this case, we # base the lights positions on empties created in blender. self._lights = [] light_key = lambda light: int(light.get_name().split("LampLum")[-1]) lumlamps = sorted(model.find_all_matches("**/LampLum*"), key=light_key) for lumlamp in lumlamps: lum = float(lumlamp.get_name()[len("LampLum"):]) light = SpotLight() light.direction = (0, -1.5, -1) light.fov = self.lamp_fov light.set_color_from_temperature(lum * 1000.0) light.energy = self.half_energy light.pos = lumlamp.get_pos(self.render) light.radius = self.lamp_radius light.casts_shadows = False light.shadow_map_resolution = 256 self.render_pipeline.add_light(light) # Put Pandas on the edges if lumlamp in lumlamps[0:2] + lumlamps[-2:]: panda = loader.loadModel("panda") panda.reparent_to(render) panda_mat = Material("default") panda_mat.emission = 0 panda.set_material(panda_mat) panda.set_pos(light.pos) panda.set_z(0.65) panda.set_h(180 + randint(-60, 60)) panda.set_scale(0.2) panda.set_y(panda.get_y() - 3.0) self._lights.append(light) self.render_pipeline.prepare_scene(model) # Init movement controller self.controller = MovementController(self) self.controller.set_initial_position(Vec3(23.9, 42.5, 13.4), Vec3(23.8, 33.4, 10.8)) self.controller.setup() self.day_time = 0.3 self.time_direction = 0 # Keys to modify the time, disabled in the demo self.accept("k", self.reset) self.accept("p", self.set_time_direction, [ 1, ]) self.accept("p-up", self.set_time_direction, [ 0, ]) self.accept("i", self.set_time_direction, [ -1, ]) self.accept("i-up", self.set_time_direction, [ 0, ]) self.addTask(self.update, "update")
def __init__(self): # This code puts the standard title and instruction text on screen self.title = OnscreenText(text="Ball in Maze", style=1, fg=(1, 1, 1, 1), pos=(0.7, -0.95), scale=.07) self.instructions = OnscreenText(text="Press Esc to exit.", pos=(-1.3, .95), fg=(1, 1, 1, 1), align=TextNode.ALeft, scale=.05) base.setBackgroundColor(0, 0, 0) self.central_msg = OnscreenText(text="", pos=(0, 0), fg=(1, 1, 0, 1), scale=.1) self.central_msg.hide() self.accept("escape", sys.exit) # Escape quits base.disableMouse() # Disable mouse-based camera control camera.setPosHpr(0, 0, 25, 0, -90, 0) # Place the camera # Load the maze and place it in the scene self.maze = loader.loadModel("models/maze") self.maze.reparentTo(render) # Most times, you want collisions to be tested against invisible geometry # rather than every polygon. This is because testing against every polygon # in the scene is usually too slow. You can have simplified or approximate # geometry for the solids and still get good results. # # Sometimes you'll want to create and position your own collision solids in # code, but it's often easier to have them built automatically. This can be # done by adding special tags into an egg file. Check maze.egg and ball.egg # and look for lines starting with <Collide>. The part is brackets tells # Panda exactly what to do. Polyset means to use the polygons in that group # as solids, while Sphere tells panda to make a collision sphere around them # Keep means to keep the polygons in the group as visable geometry (good # for the ball, not for the triggers), and descend means to make sure that # the settings are applied to any subgroups. # # Once we have the collision tags in the models, we can get to them using # NodePath's find command # Find the collision node named wall_collide self.walls = self.maze.find("**/wall_collide") # Collision objects are sorted using BitMasks. BitMasks are ordinary numbers # with extra methods for working with them as binary bits. Every collision # solid has both a from mask and an into mask. Before Panda tests two # objects, it checks to make sure that the from and into collision masks # have at least one bit in common. That way things that shouldn't interact # won't. Normal model nodes have collision masks as well. By default they # are set to bit 20. If you want to collide against actual visable polygons, # set a from collide mask to include bit 20 # # For this example, we will make everything we want the ball to collide with # include bit 0 self.walls.node().setIntoCollideMask(BitMask32.bit(0)) # CollisionNodes are usually invisible but can be shown. Uncomment the next # line to see the collision walls # self.walls.show() # We will now find the triggers for the holes and set their masks to 0 as # well. We also set their names to make them easier to identify during # collisions self.loseTriggers = [] for i in range(6): trigger = self.maze.find("**/hole_collide" + str(i)) trigger.node().setIntoCollideMask(BitMask32.bit(0)) trigger.node().setName("loseTrigger") self.loseTriggers.append(trigger) # Uncomment this line to see the triggers # trigger.show() # Ground_collide is a single polygon on the same plane as the ground in the # maze. We will use a ray to collide with it so that we will know exactly # what height to put the ball at every frame. Since this is not something # that we want the ball itself to collide with, it has a different # bitmask. self.mazeGround = self.maze.find("**/ground_collide") self.mazeGround.node().setIntoCollideMask(BitMask32.bit(1)) # Load the ball and attach it to the scene # It is on a root dummy node so that we can rotate the ball itself without # rotating the ray that will be attached to it self.ballRoot = render.attachNewNode("ballRoot") self.ball = loader.loadModel("models/ball") self.ball.reparentTo(self.ballRoot) # Find the collison sphere for the ball which was created in the egg file # Notice that it has a from collision mask of bit 0, and an into collison # mask of no bits. This means that the ball can only cause collisions, not # be collided into self.ballSphere = self.ball.find("**/ball") self.ballSphere.node().setFromCollideMask(BitMask32.bit(0)) self.ballSphere.node().setIntoCollideMask(BitMask32.allOff()) # No we create a ray to start above the ball and cast down. This is to # Determine the height the ball should be at and the angle the floor is # tilting. We could have used the sphere around the ball itself, but it # would not be as reliable self.ballGroundRay = CollisionRay() # Create the ray self.ballGroundRay.setOrigin(0, 0, 10) # Set its origin self.ballGroundRay.setDirection(0, 0, -1) # And its direction # Collision solids go in CollisionNode self.ballGroundCol = CollisionNode( 'groundRay') # Create and name the node self.ballGroundCol.addSolid(self.ballGroundRay) # Add the ray self.ballGroundCol.setFromCollideMask( BitMask32.bit(1)) # Set its bitmasks self.ballGroundCol.setIntoCollideMask(BitMask32.allOff()) # Attach the node to the ballRoot so that the ray is relative to the ball # (it will always be 10 feet over the ball and point down) self.ballGroundColNp = self.ballRoot.attachNewNode(self.ballGroundCol) # Uncomment this line to see the ray # self.ballGroundColNp.show() # Finally, we create a CollisionTraverser. CollisionTraversers are what # do the job of calculating collisions self.cTrav = CollisionTraverser() # Collision traverservs tell collision handlers about collisions, and then # the handler decides what to do with the information. We are using a # CollisionHandlerQueue, which simply creates a list of all of the # collisions in a given pass. There are more sophisticated handlers like # one that sends events and another that tries to keep collided objects # apart, but the results are often better with a simple queue self.cHandler = CollisionHandlerQueue() # Now we add the collision nodes that can create a collision to the # traverser. The traverser will compare these to all others nodes in the # scene. There is a limit of 32 CollisionNodes per traverser # We add the collider, and the handler to use as a pair self.cTrav.addCollider(self.ballSphere, self.cHandler) self.cTrav.addCollider(self.ballGroundColNp, self.cHandler) # Collision traversers have a built in tool to help visualize collisions. # Uncomment the next line to see it. # self.cTrav.showCollisions(render) # This section deals with lighting for the ball. Only the ball was lit # because the maze has static lighting pregenerated by the modeler ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(.55, .55, .55, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(0, 0, -1)) directionalLight.setColor(Vec4(0.375, 0.375, 0.375, 1)) directionalLight.setSpecularColor(Vec4(1, 1, 1, 1)) self.ballRoot.setLight(render.attachNewNode(ambientLight)) self.ballRoot.setLight(render.attachNewNode(directionalLight)) # This section deals with adding a specular highlight to the ball to make # it look shiny m = Material() m.setSpecular(Vec4(1, 1, 1, 1)) m.setShininess(96) self.ball.setMaterial(m, 1) # Finally, we call start for more initialization self.start()