def doFade(self): TTC = render.find('**/TTC') skyFade = self.skybox.colorScaleInterval(4, Vec4(0.1, 0.1, 0.1, 1), startColorScale=Vec4( 1, 1, 1, 1), blendType='easeInOut') TTCFade = TTC.colorScaleInterval(3.8, Vec4(0.2509803921568627, 0.2509803921568627, 0.2509803921568627, 1), startColorScale=Vec4(1, 1, 1, 1), blendType='easeInOut') skyFade.start() TTCFade.start()
def __init__(self, parentFSM, doneEvent, dnaStore, hoodId): ToonHood.__init__(self, parentFSM, doneEvent, dnaStore, hoodId) # Load content pack ambience settings: ambience = contentPacksMgr.getAmbience('donalds-dock') color = ambience.get('underwater-color') if color is not None: try: self.underwaterColor = Vec4(color['r'], color['g'], color['b'], color['a']) except Exception as e: raise ContentPackError(e) elif self.underwaterColor is None: self.underwaterColor = Vec4(0, 0, 0.6, 1)
def __init__(self, doneEvent): DirectFrame.__init__(self) self.doneEvent = doneEvent self.gui = loader.loadModel('phase_4/models/parties/publicPartyGUI') self.setPos(0.1, 0.0, 0.1) self.doneStatus = None self.activityIconsModel = loader.loadModel( 'phase_4/models/parties/eventSignIcons') self.normalFrameColor = Vec4(130 / 255.0, 174 / 255.0, 249 / 255.0, 1.0) self.selectedFrameColor = Vec4(1.0, 1.0, 0.0, 1.0) self.load() self.gui.removeNode() self.accept('stoppedAsleep', self._close) return
def fadeOut(self): if self.fadeInTrack: self.fadeInTrack.finish() self.fadeInTrack = None self.visible = False self.fadeOutTrack = Sequence( Func(self.setTransparency, 1), LerpColorScaleInterval(self, 1, Vec4(1, 1, 1, 0), startColorScale=Vec4(1, 1, 1, 1)), Func(self.clearColorScale), Func(self.clearTransparency), Func(self.stash)) self.fadeOutTrack.start()
def setTime(self, time): """ Sets the timer's current time. """ # timer is only valid from 0 to 999 time = bound(time, 0, 999) if time == self.currentTime: # No need to do anything if the new time to display is the # same as the last value. return self.currentTime = time timeStr = str(time) timeStrLen = len(timeStr) if timeStrLen == 1: if time <= 5 and self.highlightNearEnd: self.setTimeStr(timeStr, 0.34, (-0.025, -0.125), Vec4(1, 0, 0, 1)) else: self.setTimeStr(timeStr, 0.34, (-0.025, -0.125)) elif timeStrLen == 2: self.setTimeStr(timeStr, 0.27, (-0.025, -0.10)) elif timeStrLen == 3: self.setTimeStr(timeStr, 0.2, (-0.01, -0.08))
def updateLamps(self): pos = self.agent.getPosition() for i in range(4): lamp = self.lamps[i] light = self.lighting.directionalLights[i] theta = self.thetas[i] phi = self.phis[i] materials = lamp.findAllMaterials() color = Vec4(light.color.getX() * light.intensity, light.color.getY() * light.intensity, light.color.getZ() * light.intensity, 0) materials[0].setEmission(color) radius = 9 lamp.setPos(-light.direction.getX() * radius + pos.getX(), -light.direction.getY() * radius + pos.getY(), -light.direction.getZ() * radius + pos.getZ()) lamp.setScale(0.5) lamp.setHpr(-theta * 180 / 3.1416, phi * 180 / 3.1416 - 90, 0) """characterIndex = self.character - 1 lamp.show(BitMask32.bit( characterIndex )) lamp.hide(BitMask32.bit( 1-characterIndex ))""" lamp.hide(BitMask32.bit(self.character))
def test_windows_setup(self): self.store.storeNode('files/node.bam', '', 'window_r') self.store.storeNode('files/hood_node.bam', '', 'window_l') windows = DNAWindows('windows') x = .1 y = .4 np = NodePath('window_root') code = 'window_l' scale = 1.25 color = Vec4(.842, .167, .361, 1) windows.makeWindows(x, y, np, code, scale, color, self.store, False) # Check if the nodes attributes are correct model = np.find('**/node') self.assertFalse(model.isEmpty()) self.assertEqual(model.getPos(np), Point3(x, 0, y)) self.assertEqual(model.getScale(np), Vec3(scale)) # Now test with flip = True np.removeNode() np = NodePath('window_root') windows.makeWindows(x, y, np, code, scale, color, self.store, True) # Check if the nodes attributes are correct model = np.find('**/hood_node') self.assertFalse(model.isEmpty()) self.assertEqual(model.getPos(np), Point3(x, 0, y)) self.assertEqual(model.getScale(np), Vec3(scale))
class AttackCursor(object): _EDGES = 40 _color = Vec4(0.8, 0.3, 0.3, 1) def __init__(self, parent, entity, foot=1): self.entity = entity self.pos = entity.pos self.attackRad = entity.attackRad self.footRad = foot self._footCircle = LineSegs() self._footCircleNP = NodePath("Movement Foot Circle Node") self._attackRadCircle = LineSegs() self._attackRadCircleNP = NodePath("Attack Radius Node") self._np = NodePath("Movement Node") self.attackables = Entity.EntityManager().getEntitiesWithin( self.pos, self.attackRad) for e in self.attackables: if isinstance( e, Entity.EntityShip ) and e != self.entity and e.owner != self.entity.owner: e.representation.setAttackable() def draw(self): # Draw attack radius attackRadLine = LineSegs() attackRadLine.setThickness(1) attackRadLine.setColor(self._color) attackRadLine.moveTo(self.attackRad, 0, 0) for i in range(self._EDGES + 1): newX = (self.attackRad * math.cos((2 * math.pi / self._EDGES) * i)) newY = (self.attackRad * math.sin((2 * math.pi / self._EDGES) * i)) attackRadLine.drawTo(newX, newY, 0) attackRadGeom = attackRadLine.create() self._attackRadCircleNP = NodePath(attackRadGeom) self._attackRadCircleNP.reparentTo(self._np) # Draw foot circle self._footCircle.setThickness(1) self._footCircle.setColor(self._color) self._footCircle.moveTo(self.footRad, 0, 0) for i in range(self._EDGES): newX = (self.footRad * math.cos((2 * math.pi / self._EDGES) * i)) newY = (self.footRad * math.sin((2 * math.pi / self._EDGES) * i)) self._footCircle.drawTo(newX, newY, 0) self._footCircle.drawTo(self.footRad, 0, 0) footCircleGeom = self._footCircle.create() self._footCircleNP = NodePath(footCircleGeom) self._footCircleNP.reparentTo(self._np) def removeNode(self): for e in self.attackables: if isinstance(e, Entity.EntityShip): e.representation.unsetAttackable() self._footCircleNP.removeNode() self._attackRadCircleNP.removeNode() self._np.removeNode() def __del__(self): self.removeNode()
def loadObject(self, tex=None, pos='default', depth=55, scale=1, transparency=True, parent='cam', model='plane', glow=0): if pos == 'default': pos = Point2(0,0) if parent == 'cam': parent = camera scaleX = 187.5 scaleZ = 117.1875 obj = loader.loadModelCopy('%s%s' % (self.guiMediaPath, model)) #default object uses the plane model if parent: obj.reparentTo(parent) #Everything is parented to the camera so #that it faces the screen obj.setPos(Point3(pos.getX(), depth, pos.getY())) #Set initial position obj.setSx(scaleX) obj.setSz(scaleZ) obj.setBin("unsorted", 0) #This tells Panda not to worry about the #order this is drawn in. (it prevents an #effect known as z-fighting) if transparency: obj.setTransparency(1) #All of our objects are trasnparent if tex: tex = loader.loadTexture('%s%s.png' % (self.guiMediaPath, tex)) #Load the texture obj.setTexture(tex, 1) #Set the texture self.sims.append(obj) obj.setShaderInput('glow',Vec4(glow,0,0,0),glow) return obj
def announceGenerate(self): self.plotType = GardenGlobals.whatCanBePlanted(self.ownerIndex, self.plot) self.stickUp = 0.0 if self.getOwnerId() != localAvatar.doId: self.defaultModel = None elif self.plotType == GardenGlobals.FLOWER_TYPE: self.collSphereRadius = 2.0 self.collSphereOffset = 0.0 self.plotScale = 0.6 self.stickUp = 1.1 elif self.plotType == GardenGlobals.GAG_TREE_TYPE: self.collSphereRadius = 3.0 self.plotScale = 1.5 self.colorScaler = Vec4(1.0, 1.0, 1.0, 1) elif self.plotType == GardenGlobals.STATUARY_TYPE: self.collSphereRadius = 3.0 self.plotScale = 0.075 self.stickUp = -0.0 self.defaultModel = 'phase_5.5/models/estate/garden_slab' else: self.collSphereOffset = 0.0 self.notify.debug('announceGenerate') DistributedLawnDecor.DistributedLawnDecor.announceGenerate(self) return
def generatePowerUps(): for powerupType, locName in Globals.Level.PowerupType2Loc.items(): gatherables = gatherableModel.findAllMatches('**/%s' % locName) for gatherable in gatherables: pickup = self._level.gatherableFactory.createPowerup( powerupType) pickup.reparentTo(parent) pickup.setPos(parent, gatherable.getPos(parent)) if Globals.Level.AddSparkleToPowerups: sparkles = self._level.gatherableFactory.createSparkles( Vec4(1, 1, 1, 1), Vec4(1, 1, 0, 1), 10.0) sparkles.reparentTo(pickup) sparkles.setPos(0, 0, 1) sparkles.start() self.gatherables.append(pickup) gatherable.removeNode()
def __init__(self, x, y, regionNumber, terrain, parent=aspect2d): size = 0.5 self.size = (-size, size, -size, size) self.frame = DirectFrame(frameColor=(0, 0, 0, 0), frameSize=self.size, pos=(x, 0, y), parent=parent ) self.regionNumber = regionNumber self.terrain = terrain self.currentRegion = Vec4(terrain.getShaderInput('region' + str(self.regionNumber) + 'Limits').getVector()) #logging.info( "shader control panel for region "+ str(regionNumber)+ ": "+ str(self.currentRegion)) self.minHeight = self.currentRegion[0] self.minHeightSlide = SlideControl(0, 0.6, parent=self.frame, range=(-0.1 * terrain.maxHeight, 1.1 * terrain.maxHeight), value=self.minHeight, name="Min Height", function=self.setMinHeight, ysize=1.5, xsize=1.5) self.maxHeight = self.currentRegion[1] self.maxHeightSlide = SlideControl(0, 0.2, parent=self.frame, range=(-0.1 * terrain.maxHeight, 1.1 * terrain.maxHeight), value=self.maxHeight, name="Max Height", function=self.setMaxHeight, ysize=1.5, xsize=1.5) self.minSlope = self.currentRegion[2] self.minSlopeSlide = SlideControl(0, -0.2, parent=self.frame, range=(0, 1), value=self.minSlope, name="Min Slope", function=self.setMinSlope, ysize=1.5, xsize=1.5) self.maxSlope = self.currentRegion[3] self.maxSlopeSlide = SlideControl(0, -0.6, parent=self.frame, range=(0, 1), value=self.maxSlope, name="Max Slope", function=self.setMaxSlope, ysize=1.5, xsize=1.5) self.resize(self.size)
def createBox(n): boxpoints = [] np1 = (-26, -26, 0) np2 = (-26, 26, 0) np3 = (26, 26, 0) np4 = (26, -26, 0) boxpoints.append(np1) boxpoints.append(np2) boxpoints.append(np3) boxpoints.append(np4) boxpoints.append(np1) boxsegs = LineSegs() boxsegs.setThickness(2.0) boxsegs.setColor(Vec4(0.002, 0.002, 0.002, 0.18)) boxsegs.moveTo(boxpoints[0]) for p in boxpoints[1:]: boxsegs.drawTo(p) gridPoints = [] l = float(52 / n) i = 1 while i < (n): np = (-26, (-26 + (l * i)), 0) np2 = (26, (-26 + (l * i)), 0) np3 = ((-26 + (l * i)), -26, 0) np4 = ((-26 + (l * i)), 26, 0) gridPoints.append((np, np2)) gridPoints.append((np3, np4)) i = i + 1 for p in gridPoints: boxsegs.moveTo(p[0]) boxsegs.drawTo(p[1]) return boxsegs.create()
def announceGenerate(self): #need to wait to do this until ownerindex and plot come in from the ai self.plotType = GardenGlobals.whatCanBePlanted(self.ownerIndex, self.plot) #differentiate the plot types here self.stickUp = 0.0 if self.getOwnerId() != localAvatar.doId: self.defaultModel = None elif self.plotType == GardenGlobals.FLOWER_TYPE: self.collSphereRadius = 2.0 self.collSphereOffset = 0.0 self.plotScale = .70 self.stickUp = 1.1 # self.defaultModel = "phase_5.5/models/estate/planterA" elif self.plotType == GardenGlobals.GAG_TREE_TYPE: self.collSphereRadius = 3.0 self.plotScale = 1.5 self.colorScaler = Vec4(1.0, 1.0, 1.0, 1) #self.defaultModel = "phase_5.5/models/estate/planterB" elif self.plotType == GardenGlobals.STATUARY_TYPE: self.collSphereRadius = 3.0 self.plotScale = 0.075 self.stickUp = -0.0 #self.defaultModel = "phase_5.5/models/estate/dirt_mound" self.defaultModel = "phase_5.5/models/estate/garden_slab" else: self.collSphereOffset = 0.0 self.notify.debug('announceGenerate') DistributedLawnDecor.DistributedLawnDecor.announceGenerate(self)
def generateNestPowerups(self, gatherableModel, parent): nests = gatherableModel.findAllMatches( '**/%s;+s' % Globals.Level.LegalEagleNestName) for nest in nests: offset = Globals.Level.LaffPowerupNestOffset pickup = self._level.gatherableFactory.createPowerup( Globals.Level.GatherableTypes.LaffPowerup) pickup.reparentTo(parent) pickup.setPos(parent, nest.getPos(parent) + offset) if Globals.Level.AddSparkleToPowerups: sparkles = self._level.gatherableFactory.createSparkles( Vec4(1, 1, 1, 1), Vec4(1, 1, 0, 1), 10.0) sparkles.reparentTo(pickup) sparkles.setPos(0, 0, 1) sparkles.start() self.gatherables.append(pickup)
def showHitScore(self, number, scale=1): if number <= 0: return if self.hpText: self.hideHitScore() self.HpTextGenerator.setFont(ToontownGlobals.getSignFont()) if number < 0: self.HpTextGenerator.setText(str(number)) else: self.HpTextGenerator.setText('+' + str(number)) self.HpTextGenerator.clearShadow() self.HpTextGenerator.setAlign(TextNode.ACenter) r = 1 g = 1 b = 0 a = 1 self.HpTextGenerator.setTextColor(r, g, b, a) self.hpTextNode = self.HpTextGenerator.generate() self.hpText = render.attachNewNode(self.hpTextNode) self.hpText.setScale(scale) self.hpText.setBillboardPointEye() self.hpText.setBin('fixed', 100) self.hpText.setPos(self.root, 0, 0, self.height / 2) seq = Sequence( self.hpText.posInterval( 0.25, Point3(self.root.getX(render), self.root.getY(render), self.root.getZ(render) + self.height + 1.0), blendType='easeOut'), Wait(0.25), self.hpText.colorInterval(0.1, Vec4(r, g, b, 0)), Func(self.hideHitScore)) seq.start()
def renderQuadInto(self, mul=1, div=1, align=1, depthtex=None, colortex=None, auxtex0=None, auxtex1=None): texgroup = (depthtex, colortex, auxtex0, auxtex1) (winx, winy) = self.getScaledSize(mul, div, align) depthbits = bool(depthtex != None) buffer = self.createBuffer('filter-stage', winx, winy, texgroup, depthbits) if buffer == None: return None cm = CardMaker('filter-stage-quad') cm.setFrameFullscreenQuad() quad = NodePath(cm.generate()) quad.setDepthTest(0) quad.setDepthWrite(0) quad.setColor(Vec4(1, 0.5, 0.5, 1)) quadcamnode = Camera('filter-quad-cam') lens = OrthographicLens() lens.setFilmSize(2, 2) lens.setFilmOffset(0, 0) lens.setNearFar(-1000, 1000) quadcamnode.setLens(lens) quadcam = quad.attachNewNode(quadcamnode) buffer.getDisplayRegion(0).setCamera(quadcam) buffer.getDisplayRegion(0).setActive(1) self.buffers.append(buffer) self.sizes.append((mul, div, align)) return quad
def getSwapVisibleIval(self, wait = 5.0, tFadeOut = 3.0, tFadeIn = 3.0): loader = base.cr.playGame.hood.loader npl = render.findAllMatches('**/=DNARoot=holiday_prop;+s') p = Parallel() for i in range(npl.getNumPaths()): np = npl.getPath(i) np.setTransparency(TransparencyAttrib.MDual, 1) if not np.hasTag('DNACode'): continue dnaCode = np.getTag('DNACode') dnaNode = self.dnaStore.findNode(dnaCode) if dnaNode.isEmpty(): continue newNP = dnaNode.copyTo(np.getParent()) newNP.setTag('DNARoot', 'holiday_prop') newNP.setTag('DNACode', dnaCode) newNP.setColorScale(1, 1, 1, 0) newNP.setTransparency(TransparencyAttrib.MDual, 1) if np.hasTag('transformIndex'): index = int(np.getTag('transformIndex')) transform = loader.holidayPropTransforms.get(index, TransformState.makeIdentity()) newNP.setTransform(NodePath(), transform) newNP.setTag('transformIndex', `index`) s = Sequence(Wait(wait), np.colorScaleInterval(tFadeOut, Vec4(1, 1, 1, 0), startColorScale=Vec4(1, 1, 1, 1), blendType='easeInOut'), Func(np.detachNode), Func(np.clearTransparency), newNP.colorScaleInterval(tFadeOut, Vec4(1, 1, 1, 1), startColorScale=Vec4(1, 1, 1, 0), blendType='easeInOut'), Func(newNP.clearTransparency), Func(newNP.clearColorScale)) p.append(s) return p
class SelectionIndicator(object): _np = NodePath() _currHpr = Vec3(0, 0, 0) _color = Vec4(0.3, 0.3, 0.8, 1) def __init__(self, parent, size=1): LOG.debug("[SelectionIndicator] Initializing") self.aaLevel = int(GameSettings().antiAlias) self.size = size self._np = loader.loadModelCopy("data/models/ribbon.egg") self._np.setScale(10) self._np.setHpr(self._currHpr) self._np.setTwoSided(True) if self.aaLevel > 0: self._np.setAntialias(AntialiasAttrib.MLine, self.aaLevel) self._np.reparentTo(parent) taskMgr.add(self.rotate, 'Selection Rotation Task') def rotate(self, Task): self._currHpr.setX(self._currHpr.getX() + 0.01) self._np.setHpr(self._currHpr) return Task.cont def removeNode(self): taskMgr.remove('Selection Rotation Task') self._np.removeNode() def __del__(self): self.removeNode()
def __init__(self, manager, xml): # Set the background color first background = xml.find("background") if background != None: self.bgColour = Vec4(float(background.get('r')), float(background.get('g')), float(background.get('b')), 1) else: self.bgColour = None # Get the path to load skies from... basePath = manager.get('paths').getConfig().find('skies').get('path') self.model = None skydome = xml.find('skydome') if skydome != None: self.model = loader.loadModel(posixpath.join(basePath, 'skydome')) self.model.setLightOff(1) self.model.setShaderOff(1) self.model.setCompass() self.model.setBin('background', 10) self.model.setDepthWrite(False) self.model.setDepthTest(False) self.model.setColor(1, 1, 1, 1) self.model.setTexture( loader.loadTexture( posixpath.join(basePath, skydome.get('filename')))) self.model.setTag('sun', 'True') self.model.reparentTo(base.cam) self.model.hide()
def updateLamps(self): self.shadowMap.setLighting(self.lighting, Vec3(7, 0, 0), 25) for i in range(4): lamp = self.lamps[i] light = self.lighting.directionalLights[i] theta = self.thetas[i] phi = self.phis[i] materials = lamp.findAllMaterials() #blub=0.5-theta color = Vec4(light.color.getX() * light.intensity, light.color.getY() * light.intensity, light.color.getZ() * light.intensity, 0) materials[0].setEmission(color) #lamp.setMaterial( materials[0] ) """material = Material("lamp"+str(i)) material.setAmbient( Vec4(0,0,0,0) ) material.setDiffuse( Vec4(0,0,0,0) ) material.setEmission( Vec4(1,1,0,0) ) material.setSpecular( Vec4(0,0,0,0) ) lamp.setMaterial( material )""" #print lamp.findAllMaterials() radius = 9 lamp.setPos(-light.direction.getX() * radius + 7, -light.direction.getY() * radius, -light.direction.getZ() * radius) lamp.setScale(0.5) lamp.setHpr(-theta * 180 / 3.1416, phi * 180 / 3.1416 - 90, 0)
def nextConfig(self): N = self.whichConfig = (self.whichConfig + 1) % NUM_CONFIGS if self.envNP != None: self.envNP.removeNode() if self.pathNP != None: self.pathNP.removeNode() self.environment = Environment(OBSTACLE_FILE,\ ALL_CONFIGS[N][0], ALL_CONFIGS[N][1], ALL_CONFIGS[N][2]) self.environment.dump() print("Start: " + self.environment.start.__str__()) print("End: " + self.environment.end.__str__()) print("Shooter: " + self.environment.shooterPos.__str__()) shortestPath = getShortestPath(self.environment) print("Path: ") print(shortestPath) self.envNP = render.attachNewNode(self.environment.produceRending()) self.pathNP = render.attachNewNode( self.environment.renderPath(shortestPath, Vec4(1.000, 0.647, 0.000, 1))) for i in range(len(self.environment.obstaclesWalls)): wall = self.environment.obstaclesWalls[i] ls = LineSegment(Point2(300, -300), Point2(-300, 400)) I = ls.intersectLines(wall) if I[1] == 1: print(i)
def __init__(self, useImage=True, highlightNearEnd=True): if useImage: image = self.getImage() else: image = None DirectFrame.__init__(self, state=DGG.DISABLED, relief=None, scale=0.45, image=image, image_pos=(0, 0, 0), text='0', text_fg=(0, 0, 0, 1), text_font=OTPGlobals.getInterfaceFont(), text_pos=(-0.01, -0.15), text_scale=0.35) self.initialiseoptions(OTPTimer) self.timerId = OTPTimer.TimerId OTPTimer.TimerId += 1 self.highlightNearEnd = highlightNearEnd self.countdownTask = None self.currentTime = 0 self.taskTime = 0.0 self.setFontColor(Vec4(0, 0, 0, 1)) return
def update(self, task): casterpos = Point2() base.camLens.project(self.sun.getPos(base.cam), casterpos) self.finalQuad.setShaderInput( 'casterpos', Vec4(casterpos.getX() * 0.5 + 0.5, (casterpos.getY() * 0.5 + 0.5), 0, 0)) return task.cont
def initStreamers(): obstacles = self._model.findAllMatches('**/%s' % Globals.Level.StreamerName) for obstacleLoc in obstacles: obstacle = self._level.obstacleFactory.createFan() obstacle.model.reparentTo(parent) obstacle.model.setPos(parent, obstacleLoc.getPos(parent)) obstacle.model.setHpr(parent, obstacleLoc.getHpr(parent)) obstacle.model.setScale(parent, obstacleLoc.getScale(parent)) obstacle.setBlowDirection() if Globals.Level.AddParticlesToStreamers: particles = self._level.obstacleFactory.createStreamerParticles( Vec4(1, 1, 1, 1), Vec4(1, 1, 1, 1), 10.0) particles.reparentTo(obstacle.model) particles.start() self.obstacles.append(obstacle) obstacleLoc.removeNode()
def fadeOut(self, duration = 2.0): if self.fader: self.fader.finish() self.fader = None self.modelRoot.setTransparency(1) self.fader = Sequence(self.modelRoot.colorScaleInterval(duration / 2.0, Vec4(0, 0, 0, 0), startColorScale = Vec4(1, 1, 1, 1)), Func(self.modelRoot.clearTransparency)) self.fader.start()
def writeToScreen(self, myText, x, z, scale=0.2, color='default', font=3, wordwrap=10): if color == 'default': color = Vec4(.1,.1,.8,.8) text = textonscreen.TextOnScreen(self.guiMediaPath, myText, scale,font=3) text.writeTextToScreen(x, self.depth, z, wordwrap=wordwrap) text.setColor(color) self.gui.append(text)
def get_quat_from_vector(v, normalize=True): """Get Quat object from 4-d vector""" quat = Quat(Vec4(*v)) if normalize: quat.normalize() return quat
def buildAmbientLight(self, color): """ Builds a Panda3D Ambient Light with the specified color. """ alight = render.attachNewNode(AmbientLight("Ambient")) alight.node().setColor(Vec4(*color)) render.setLight(alight) return alight
def backgroundColor(r=None, g=1, b=1, a=1): """ set the background color. Specify no arguments for the default background color. """ if r is None: r, g, b, a = OTPGlobals.DefaultBackgroundColor base.setBackgroundColor(Vec4(r, g, b, a)) return 'The background color has been changed.'