class NodeConnector: def __init__(self, socketA, socketB): self.connectorID = uuid4() self.socketA = socketA self.socketB = socketB self.line = LineNodePath(ShowBaseGlobal.aspect2d, thickness=2, colorVec=(0.8, 0.8, 0.8, 1)) self.draw() def update(self): self.line.reset() self.draw() def draw(self): self.line.moveTo(self.socketA.plug.getPos(ShowBaseGlobal.aspect2d)) self.line.drawTo(self.socketB.plug.getPos(ShowBaseGlobal.aspect2d)) self.line.create() def has(self, socket): """Returns True if one of the sockets this connector connects is the given socket""" return socket == self.socketA or socket == self.socketB def connects(self, a, b): """Returns True if this connector connects socket a and b""" return (a == self.socketA or a == self.socketB) and (b == self.socketA or b == self.socketB) def disconnect(self): self.line.reset() self.socketA.setConnected(False) self.socketB.setConnected(False)
def line_model(self, r, g, b): line = LineNodePath(self.render2d, 'box', 2) line.reparentTo(self.render) line.setColor(r, g, b, 1.) line.setTransparency(TransparencyAttrib.MAlpha) line.setAlphaScale(0.5) return line
def draw_box(self, box): line_collection = LineNodePath(parent=render, thickness=1.0, colorVec=Vec4(1, 0, 0, 1)) pos = box.get_position() lengths = box.get_lengths() x = pos[0] y = pos[1] z = pos[2] half_width = lengths[0] / 2 half_length = lengths[1] / 2 half_height = lengths[2] / 2 lines = [ # Bottom Face ((x - half_width, y - half_length, z - half_height), (x + half_width, y - half_length, z - half_height)), ((x + half_width, y - half_length, z - half_height), (x + half_width, y + half_length, z - half_height)), ((x + half_width, y + half_length, z - half_height), (x - half_width, y + half_length, z - half_height)), ((x - half_width, y + half_length, z - half_height), (x - half_width, y - half_length, z - half_height)), # Top Face ((x - half_width, y - half_length, z + half_height), (x + half_width, y - half_length, z + half_height)), ((x + half_width, y - half_length, z + half_height), (x + half_width, y + half_length, z + half_height)), ((x + half_width, y + half_length, z + half_height), (x - half_width, y + half_length, z + half_height)), ((x - half_width, y + half_length, z + half_height), (x - half_width, y - half_length, z + half_height)), # Vertical Lines ((x - half_width, y - half_length, z - half_height), (x - half_width, y - half_length, z + half_height)), ((x + half_width, y - half_length, z - half_height), (x + half_width, y - half_length, z + half_height)), ((x + half_width, y + half_length, z - half_height), (x + half_width, y + half_length, z + half_height)), ((x - half_width, y + half_length, z - half_height), (x - half_width, y + half_length, z + half_height)), ] line_collection.drawLines(lines) line_collection.create()
def __init__(self, socketA, socketB): self.connectorID = uuid4() self.socketA = socketA self.socketB = socketB self.line = LineNodePath(ShowBaseGlobal.aspect2d, thickness=2, colorVec=(0.8, 0.8, 0.8, 1)) self.draw()
def createPitchLineOld(self,points=[0.5,0.25,-0.25,-0.5], tick=0.00,colour=None): """ create a line to hint at the pitch of the aircraft on the hud """ if colour is None: colour = self.colour l = LineNodePath(aspect2d,'pitchline',4,Vec4(colour[0],colour[1], colour[2],colour[3])) plist = [] for p in points: plist.append((p,0.0,0.0)) plist.insert(0,(points[0],0.0,tick)) plist.append((points[3],0.0,tick)) linelist = [] linelist = [[plist[p],plist[p+1]] for p in range(len(plist)-1)] linelist.pop(2) l.drawLines(linelist) l.create() # These lines are drawn from scratch rather than using a graphic file format = GeomVertexFormat.getV3() vdata = GeomVertexData("vertices",format,Geom.UHStatic) # create vertices to add to use in creating lines vertexWriter=GeomVertexWriter(vdata,"vertex") # here we define enough positions to create two separated lines for p in points: vertexWriter.addData3f(p,0.0,0.0) # and another two positions for the 'ticks' at the line ends vertexWriter.addData3f(points[0],0.0,tick) vertexWriter.addData3f(points[3],0.0,tick) # create the primitives line = GeomLines(Geom.UHStatic) line.addVertices(4,0) # the tick part line.addVertices(0,1) # part of the horizontal line line.closePrimitive() line2 = GeomLines(Geom.UHStatic) line2.addVertices(2,3) # other part of the horizontal line line2.addVertices(3,5) # second tick line2.closePrimitive() # add the lines to a geom object lineGeom = Geom(vdata) lineGeom.addPrimitive(line) lineGeom.addPrimitive(line2) # create the node.. lineGN=GeomNode("splitline") lineGN.addGeom(lineGeom) # and parent the node to aspect2d lineNP = aspect2d.attachNewNode(lineGN) return lineNP
def startLineDrawing(self, startPos): """Start a task that will draw a line from the given start position to the cursor""" self.line = LineNodePath(render2d, thickness=2, colorVec=(0.8, 0.8, 0.8, 1)) self.line.moveTo(startPos) t = self.taskMgr.add(self.drawLineTask, "drawLineTask") t.startPos = startPos
def P3DCreateAxes(length=0.5, arrowAngle=25, arrowLength=0.05): nodePath = LineNodePath() nodePath.reparentTo(render2d) #~ nodePath.drawArrow2d(Vec3(0, 0, 0), Vec3(0.5, 0, 0.5), 30, 0.1) nodePath.drawArrow2d(Vec3(0, 0, 0), Vec3(0., 0, length), arrowAngle, arrowLength) nodePath.create() return nodePath
def __init__(self,parent,gridSize=100.0,gridSpacing=5.0,planeColor=(0.5,0.5,0.5,0.5)): # Initialize superclass NodePath.__init__(self) self.assign(hidden.attachNewNode('DirectGrid')) # Don't wireframe or light #useDirectRenderStyle(self) self.setLightOff(0) self.setRenderModeFilled() self.parent = parent # Load up grid parts to initialize grid object # Polygon used to mark grid plane self.gridBack = loader.loadModel('models/misc/gridBack.egg.pz') self.gridBack.reparentTo(self) self.gridBack.setColor(*planeColor) # Grid Lines self.lines = self.attachNewNode('gridLines') self.minorLines = LineNodePath(self.lines) self.minorLines.lineNode.setName('minorLines') self.minorLines.setColor(VBase4(0.3, 0.55, 1, 1)) self.minorLines.setThickness(1) self.majorLines = LineNodePath(self.lines) self.majorLines.lineNode.setName('majorLines') self.majorLines.setColor(VBase4(0.3, 0.55, 1, 1)) self.majorLines.setThickness(5) self.centerLines = LineNodePath(self.lines) self.centerLines.lineNode.setName('centerLines') self.centerLines.setColor(VBase4(1, 0, 0, 0)) self.centerLines.setThickness(3) # Small marker to hilight snap-to-grid point self.snapMarker = loader.loadModel('models/misc/sphere.egg.pz') self.snapMarker.node().setName('gridSnapMarker') self.snapMarker.reparentTo(self) self.snapMarker.setColor(1, 0, 0, 1) self.snapMarker.setScale(0.3) self.snapPos = Point3(0) # Initialize Grid characteristics self.fXyzSnap = 1 self.fHprSnap = 1 self.gridSize = gridSize self.gridSpacing = gridSpacing self.snapAngle = 15.0 self.enable()
def __initSceneGraph(self): #load various texture stages of the planet self.forge_tex = TextureStage('forge') self.forge_tex.setMode(TextureStage.MDecal) self.nexus_tex = TextureStage('nexus') self.nexus_tex.setMode(TextureStage.MDecal) self.extractor_phylon_ge_tex = TextureStage('extractor_phylon_ge') self.extractor_phylon_ge_tex.setMode(TextureStage.MDecal) # Parent node for relative position (no scaling) self.point_path = self.parent_star.point_path.attachNewNode("planet_node") self.point_path.setPos(self.position) #Models & textures self.model_path = loader.loadModel("models/planets/planet_sphere") self.model_path.setTexture(SphericalBody.dead_planet_tex, 1) self.model_path.reparentTo(self.point_path) self.model_path.setScale(self.radius) self.model_path.setPythonTag('pyPlanet', self); cnode = CollisionNode("coll_sphere_node") cnode.setTag('planet', str(id(self))) #We use no displacement (0,0,0) and no scaling factor (1) cnode.addSolid(CollisionSphere(0,0,0,1)) cnode.setIntoCollideMask(BitMask32.bit(1)) # Reparenting the collision sphere so that it # matches the planet perfectly. self.cnode_path = self.model_path.attachNewNode(cnode) self.lines = LineNodePath(parent = self.parent_star.point_path, thickness = 4.0, colorVec = Vec4(1.0, 1.0, 1.0, 0.2)) self.quad_path = None
def __init__(self, flock=None, *a, **k): super(BoidEntityBase, self).__init__(*a, **k) self.flock = weakref.proxy(flock) self.flock.add_boid(self) self._debug_line = LineNodePath(self.entities.render, 'caca', 2, Vec4(1, 0, 0, 0))
def createPitchLine(self, points=[0.5, 0.25, -0.25, -0.5], tick=0.00, colour=None): """ create a line to hint at the pitch of the aircraft on the hud """ if colour is None: colour = self.colour pline = LineNodePath(aspect2d, "pitchline", 1, Vec4(colour[0], colour[1], colour[2], colour[3])) plist = [] for p in points: plist.append((p, 0.0, 0.0)) plist.insert(0, (points[0], 0.0, tick)) plist.append((points[3], 0.0, tick)) linelist = [] linelist = [[plist[p], plist[p + 1]] for p in range(len(plist) - 1)] linelist.pop(2) pline.drawLines(linelist) pline.create() return pline
def createCentreMark(self, colour=None): """ create a line to hint at the pitch of the aircraft on the hud """ if colour is None: colour = self.colour cmline = LineNodePath(aspect2d, "centremark", 1, Vec4(colour[0], colour[1], colour[2], colour[3])) plist = [] plist.append((0.15, 0.0, 0.0)) plist.append((0.10, 0.0, 0.0)) plist.append((0.05, 0.0, -0.025)) plist.append((0.00, 0.0, 0.025)) plist.append((-0.05, 0.0, -0.025)) plist.append((-0.10, 0.0, 0.0)) plist.append((-0.15, 0.0, 0.0)) linelist = [] linelist = [[plist[p], plist[p + 1]] for p in range(len(plist) - 1)] cmline.drawLines(linelist) cmline.create() return cmline
def __init__(self, parent, gridSize=100.0, gridSpacing=5.0, planeColor=(0.5, 0.5, 0.5, 0.5)): # Initialize superclass NodePath.__init__(self) self.assign(hidden.attachNewNode('DirectGrid')) # Don't wireframe or light #useDirectRenderStyle(self) self.setLightOff(0) self.setRenderModeFilled() self.parent = parent # Load up grid parts to initialize grid object # Polygon used to mark grid plane self.gridBack = loader.loadModel('models/misc/gridBack.egg.pz') self.gridBack.reparentTo(self) self.gridBack.setColor(*planeColor) # Grid Lines self.lines = self.attachNewNode('gridLines') self.minorLines = LineNodePath(self.lines) self.minorLines.lineNode.setName('minorLines') self.minorLines.setColor(VBase4(0.3, 0.55, 1, 1)) self.minorLines.setThickness(1) self.majorLines = LineNodePath(self.lines) self.majorLines.lineNode.setName('majorLines') self.majorLines.setColor(VBase4(0.3, 0.55, 1, 1)) self.majorLines.setThickness(5) self.centerLines = LineNodePath(self.lines) self.centerLines.lineNode.setName('centerLines') self.centerLines.setColor(VBase4(1, 0, 0, 0)) self.centerLines.setThickness(3) # Small marker to hilight snap-to-grid point self.snapMarker = loader.loadModel('models/misc/sphere.egg.pz') self.snapMarker.node().setName('gridSnapMarker') self.snapMarker.reparentTo(self) self.snapMarker.setColor(1, 0, 0, 1) self.snapMarker.setScale(0.3) self.snapPos = Point3(0) # Initialize Grid characteristics self.fXyzSnap = 1 self.fHprSnap = 1 self.gridSize = gridSize self.gridSpacing = gridSpacing self.snapAngle = 15.0 self.enable()
def __init__( self, world, space, name=NAME_DEFAULT, modelEgg=MODEL_EGG_DEFAULT, pos=POS_DEFAULT, scale=SCALE_DEFAULT, hpr=HPR_DEFAULT, ): self.limitedYMovement = False self.limitedYCoords = [-1, -1] self.limitedZMovement = False self.limitedZCoords = [-1, -1] self.name = name self.pos = pos self.hpr = hpr self.scale = scale self.world = world self.space = space self.jumping = False self.jumpStarted = 0.0 self.jumpLastUpdate = 0.0 self.lastCollisionTime = 0.0 self.lastCollisionIsGround = True self.lastGroundCollisionBodyPos = None self.jumpSound = loader.loadSfx(self.JUMP_SOUND_DEFAULT) self.bounceSound = loader.loadSfx(self.BOUNCE_SOUND_DEFAULT) if Ball.MOVEMENT_DEBUG: self.lastDrawTime = 0.0 self.lastDrawTime2 = 0.0 self.lines = LineNodePath(parent=render, thickness=3.0, colorVec=Vec4(1, 0, 0, 1)) self.lines2 = LineNodePath(parent=render, thickness=3.0, colorVec=Vec4(0, 0, 1, 1)) self.lines3 = LineNodePath(parent=render, thickness=3.0, colorVec=Vec4(0, 1, 0, 1)) if Ball.JUMP_DEBUG: self.lastTakeoffTime = 0.0 self.moveLeft = False self.moveRight = False self.modelNode = self.createModelNode(self.pos, self.hpr, self.scale, modelEgg) self.ballBody = self.createBallBody(self.modelNode, self.world) self.ballGeom = self.createBallGeom(self.modelNode, self.ballBody, self.space) self.modelNode.reparentTo(render)
def _build_cursor(self, shape="sphere"): if shape == "sphere": cursor = self._load("sphere.bam") elif shape == "cross": cursor = LineNodePath() lines = [[Point3(-0.5, 0, 0), Point3(0.5, 0, 0)], [Point3(0, 0, -0.5), Point3(0, 0, 0.5)]] cursor.drawLines(lines) cursor.setThickness(1) cursor.create() # cursor = NodePath("cross") # S = {"cylinderX.bam": ((0., 0., 0.), (1., 0.1, 0.1)), # "cylinderY.bam": ((0., 0., 0.), (0.1, 1., 0.1)), # "cylinderZ.bam": ((0., 0., 0.), (0.1, 0.1, 1.))} # for k, v in S.iteritems(): # m = self._load(k) # m.setName(k) # m.setPos(*v[0]) # m.setScale(*v[1]) # m.reparentTo(cursor) #BP() return cursor
def __init__(self, world, render, position, direction, side, torso, limits): radius = 0.15 bicep_length = 0.75 forearm_length = 0.75 in_limit, out_limit, forward_limit, backward_limit, twist_limit = limits torso_pos = torso.getPos() x, y, z = position bicep_y = y + direction * bicep_length / 2 forearm_y = y + direction * bicep_length + forearm_length / 2 bicep_node = BulletRigidBodyNode('Bicep') bicep_node.addShape(BulletCapsuleShape(radius, bicep_length, 1)) bicep_node.setMass(0.25) bicep_pointer = render.attachNewNode(bicep_node) bicep_pointer.setPos(x, bicep_y, z) world.attachRigidBody(bicep_node) forearm_node = BulletRigidBodyNode('Forearm') forearm_node.addShape(BulletCapsuleShape(radius, forearm_length, 1)) forearm_node.setMass(0.25) forearm_pointer = render.attachNewNode(forearm_node) forearm_pointer.setPos(x, forearm_y, z) world.attachRigidBody(forearm_node) rotation = LMatrix3((-direction, 0, 0), (0, 0, -side), (0, -side * direction, 0)) bicep_to_shoulder = Vec3(0, -direction * bicep_length / 2, 0) torso_to_shoulder = Vec3(0, y + torso_pos[1], z - torso_pos[2]) bicep_shoulder_frame = make_rigid_transform(rotation, bicep_to_shoulder) torso_shoulder_frame = make_rigid_transform(rotation, torso_to_shoulder) shoulder = BulletGenericConstraint(torso.node(), bicep_node, torso_shoulder_frame, bicep_shoulder_frame, True) shoulder.setDebugDrawSize(0.3) world.attachConstraint(shoulder, True) elbow_axis = Vec3(0, 0, side) forearm_to_elbow = Point3(0, -direction * forearm_length / 2, 0) bicep_to_elbow = Point3(0, direction * bicep_length / 2, 0) elbow = BulletHingeConstraint(bicep_node, forearm_node, bicep_to_elbow, forearm_to_elbow, elbow_axis, elbow_axis, True) elbow.setDebugDrawSize(0.3) world.attachConstraint(elbow, True) for axis in range(3): shoulder.getRotationalLimitMotor(axis).setMaxMotorForce(200) elbow.setMaxMotorImpulse(200) shoulder.setAngularLimit(0, -in_limit, out_limit) shoulder.setAngularLimit(1, -twist_limit, twist_limit) shoulder.setAngularLimit(2, -backward_limit, forward_limit) elbow.setLimit(0, 180) self.render = render self.position = position self.bicep = bicep_pointer self.forearm = forearm_pointer self.shoulder = shoulder self.elbow = elbow self.transform = LMatrix3(-side * direction, 0, 0, 0, -direction, 0, 0, 0, 1) self.side = side self.lines = LineNodePath(name='debug', parent=self.render, colorVec=VBase4(0.2, 0.2, 0.5, 1)) axes = LineNodePath(name='axes', parent=self.render) paths = [ dict(color=VBase4(1, 0, 0, 1)), dict(color=VBase4(0, 1, 0, 1)), dict(color=VBase4(0, 0, 1, 1)) ] for i in range(3): axis = shoulder.getAxis(i) * 0.25 paths[i]['points'] = [axis] draw_lines(axes, *paths, origin=position)
def draw_lines(lines: LineNodePath, *paths: dict, origin=None, relative=True): if origin is None: origin = lines.getCurrentPosition() lines.reset() for path in paths: if 'color' in path: lines.setColor(*path['color']) points = path['points'] lines.moveTo(*origin) for point in points: if relative: point += origin lines.drawTo(*point) lines.create()
def refresh(self): # sanity check so we don't get here to early if not hasattr(self, "bounds"): return self.frameInitialiseFunc() textLeftSizeArea = self['numberAreaWidth'] # get the left and right edge of our frame left = DGH.getRealLeft(self) right = DGH.getRealRight(self) diagramLeft = left + textLeftSizeArea xStep = (DGH.getRealWidth(self) - textLeftSizeArea) / (len(self['data']) - 1) posYRes = DGH.getRealTop(self) / (self['numPosSteps'] if self['numPosSteps'] > 0 else max( self['data'])) negYRes = DGH.getRealBottom(self) / (-self['numNegSteps'] if self['numNegSteps'] > 0 else min(self['data'])) # remove old content if self.lines is not None: self.lines.removeNode() if self.measureLines is not None: self.measureLines.removeNode() if self.centerLine is not None: self.centerLine.removeNode() for text in self.xDescriptions: text.removeNode() self.xDescriptions = [] for text in self.points: text.removeNode() self.points = [] # prepare the line drawings self.lines = LineNodePath(parent=self, thickness=3.0, colorVec=(1, 0, 0, 1)) self.measureLines = LineNodePath(parent=self, thickness=1.0, colorVec=(0, 0, 0, 1)) self.centerLine = LineNodePath(parent=self, thickness=2.0, colorVec=(0, 0, 0, 1)) # draw the center line self.centerLine.reset() self.centerLine.drawLines([((diagramLeft, 0, 0), (right, 0, 0))]) self.centerLine.create() self.xDescriptions.append( self.createcomponent('value0', (), None, DirectLabel, (self, ), text="0", text_scale=self['numtextScale'], text_align=TextNode.ARight, pos=(diagramLeft, 0, -0.01), relief=None, state='normal')) # calculate the positive measure lines and add the numbers measureLineData = [] numSteps = (self['numPosSteps'] if self['numPosSteps'] > 0 else math.floor(max(self['data']))) + 1 for i in range(1, numSteps, self['numPosStepsStep']): measureLineData.append( ((diagramLeft, 0, i * posYRes), (right, 0, i * posYRes))) calcBase = 1 / DGH.getRealTop(self) maxData = self['numPosSteps'] if self['numPosSteps'] > 0 else max( self['data']) value = self['stepFormat'](round(i * posYRes * calcBase * maxData, self['stepAccuracy'])) y = i * posYRes self.xDescriptions.append( self.createcomponent('value{}'.format(value), (), None, DirectLabel, (self, ), text=str(value), text_scale=self['numtextScale'], text_align=TextNode.ARight, pos=(diagramLeft, 0, y - 0.025), relief=None, state='normal')) # calculate the negative measure lines and add the numbers numSteps = (self['numNegSteps'] if self['numNegSteps'] > 0 else math.floor(abs(min(self['data'])))) + 1 for i in range(1, numSteps, self['numNegStepsStep']): measureLineData.append( ((diagramLeft, 0, -i * negYRes), (right, 0, -i * negYRes))) calcBase = 1 / DGH.getRealBottom(self) maxData = self['numPosSteps'] if self['numPosSteps'] > 0 else max( self['data']) value = self['stepFormat'](round(i * negYRes * calcBase * maxData, self['stepAccuracy'])) y = -i * negYRes self.xDescriptions.append( self.createcomponent('value{}'.format(value), (), None, DirectLabel, (self, ), text=str(value), text_scale=self['numtextScale'], text_align=TextNode.ARight, pos=(diagramLeft, 0, y + 0.01), relief=None, state='normal')) # Draw the lines self.measureLines.reset() self.measureLines.drawLines(measureLineData) self.measureLines.create() lineData = [] for i in range(1, len(self['data'])): yResA = posYRes if self['data'][i - 1] >= 0 else negYRes yResB = posYRes if self['data'][i] >= 0 else negYRes lineData.append(( # Point A (diagramLeft + (i - 1) * xStep, 0, self['data'][i - 1] * yResA ), # Point B (diagramLeft + i * xStep, 0, self['data'][i] * yResB))) if (self['showDataNumbers']): value = round(self['data'][i - 1], self['stepAccuracy']) self.points.append( self.createcomponent('value{}'.format(value), (), None, DirectLabel, (self, ), text=str(value), text_scale=self['dataNumtextScale'], text_align=TextNode.ARight, pos=(diagramLeft + (i - 1) * xStep, 0, self['data'][i - 1] * yResA), relief=None, state='normal')) # Draw the lines self.lines.reset() self.lines.drawLines(lineData) self.lines.create()
class DirectGrid(NodePath, DirectObject): def __init__(self, parent, gridSize=100.0, gridSpacing=5.0, planeColor=(0.5, 0.5, 0.5, 0.5)): # Initialize superclass NodePath.__init__(self) self.assign(hidden.attachNewNode('DirectGrid')) # Don't wireframe or light #useDirectRenderStyle(self) self.setLightOff(0) self.setRenderModeFilled() self.parent = parent # Load up grid parts to initialize grid object # Polygon used to mark grid plane self.gridBack = loader.loadModel('models/misc/gridBack.egg.pz') self.gridBack.reparentTo(self) self.gridBack.setColor(*planeColor) # Grid Lines self.lines = self.attachNewNode('gridLines') self.minorLines = LineNodePath(self.lines) self.minorLines.lineNode.setName('minorLines') self.minorLines.setColor(VBase4(0.3, 0.55, 1, 1)) self.minorLines.setThickness(1) self.majorLines = LineNodePath(self.lines) self.majorLines.lineNode.setName('majorLines') self.majorLines.setColor(VBase4(0.3, 0.55, 1, 1)) self.majorLines.setThickness(5) self.centerLines = LineNodePath(self.lines) self.centerLines.lineNode.setName('centerLines') self.centerLines.setColor(VBase4(1, 0, 0, 0)) self.centerLines.setThickness(3) # Small marker to hilight snap-to-grid point self.snapMarker = loader.loadModel('models/misc/sphere.egg.pz') self.snapMarker.node().setName('gridSnapMarker') self.snapMarker.reparentTo(self) self.snapMarker.setColor(1, 0, 0, 1) self.snapMarker.setScale(0.3) self.snapPos = Point3(0) # Initialize Grid characteristics self.fXyzSnap = 1 self.fHprSnap = 1 self.gridSize = gridSize self.gridSpacing = gridSpacing self.snapAngle = 15.0 self.enable() def enable(self): self.reparentTo(self.parent) self.updateGrid() self.fEnabled = 1 def disable(self): self.reparentTo(hidden) self.fEnabled = 0 def toggleGrid(self): if self.fEnabled: self.disable() else: self.enable() def isEnabled(self): return self.fEnabled def updateGrid(self): # Update grid lines based upon current grid spacing and grid size # First reset existing grid lines self.minorLines.reset() self.majorLines.reset() self.centerLines.reset() # Now redraw lines numLines = int(math.ceil(self.gridSize / self.gridSpacing)) scaledSize = numLines * self.gridSpacing center = self.centerLines minor = self.minorLines major = self.majorLines for i in range(-numLines, numLines + 1): if i == 0: center.moveTo(i * self.gridSpacing, -scaledSize, 0) center.drawTo(i * self.gridSpacing, scaledSize, 0) center.moveTo(-scaledSize, i * self.gridSpacing, 0) center.drawTo(scaledSize, i * self.gridSpacing, 0) else: if (i % 5) == 0: major.moveTo(i * self.gridSpacing, -scaledSize, 0) major.drawTo(i * self.gridSpacing, scaledSize, 0) major.moveTo(-scaledSize, i * self.gridSpacing, 0) major.drawTo(scaledSize, i * self.gridSpacing, 0) else: minor.moveTo(i * self.gridSpacing, -scaledSize, 0) minor.drawTo(i * self.gridSpacing, scaledSize, 0) minor.moveTo(-scaledSize, i * self.gridSpacing, 0) minor.drawTo(scaledSize, i * self.gridSpacing, 0) center.create() minor.create() major.create() if (self.gridBack): self.gridBack.setScale(scaledSize) def setXyzSnap(self, fSnap): self.fXyzSnap = fSnap def getXyzSnap(self): return self.fXyzSnap def setHprSnap(self, fSnap): self.fHprSnap = fSnap def getHprSnap(self): return self.fHprSnap def computeSnapPoint(self, point): # Start of with current point self.snapPos.assign(point) # Snap if necessary if self.fXyzSnap: self.snapPos.set(ROUND_TO(self.snapPos[0], self.gridSpacing), ROUND_TO(self.snapPos[1], self.gridSpacing), ROUND_TO(self.snapPos[2], self.gridSpacing)) # Move snap marker to this point self.snapMarker.setPos(self.snapPos) # Return the hit point return self.snapPos def computeSnapAngle(self, angle): return ROUND_TO(angle, self.snapAngle) def setSnapAngle(self, angle): self.snapAngle = angle def getSnapAngle(self): return self.snapAngle def setGridSpacing(self, spacing): self.gridSpacing = spacing self.updateGrid() def getGridSpacing(self): return self.gridSpacing def setGridSize(self, size): # Set size of grid back and redraw lines self.gridSize = size self.updateGrid() def getGridSize(self): return self.gridSize
def __init__(self): ShowBase.__init__(self) wp = core.WindowProperties() wp.setTitle("Dorfdelf") self.win.requestProperties(wp) self.render.setAntialias(core.AntialiasAttrib.MAuto) self.setBackgroundColor(0.5, 0.5, 0.5) self.disableMouse() self.enableParticles() font = self.loader.loadFont('media/calibri.ttf') font.setPixelsPerUnit(120) font.setPageSize(512, 1024) loading = OnscreenText(text='Loading...', scale=0.2, pos=(0.0, 0.0), fg=(1, 1, 1, 1), shadow=(0.3, 0.3, 0.3, 1.0), align=core.TextNode.ACenter, mayChange=True, font=font, parent=self.aspect2d) self.graphicsEngine.renderFrame() self.graphicsEngine.renderFrame() loading.setText('Generating world') self.graphicsEngine.renderFrame() self.graphicsEngine.renderFrame() self.world = world.World(128, 128, 100) self.world.generate() loading.setText('Creating world geometry') self.graphicsEngine.renderFrame() self.graphicsEngine.renderFrame() self.world_geometry = geometry.WorldGeometry(self.world) self.camLens.setFocalLength(1) self.camera.setPos(0, 0, 100) self.camera.lookAt(self.world.midpoint.x, self.world.midpoint.y, 100) self.cam.setPos(0, 0, 0) self.cam.setHpr(0, -45, 0) self.cc = camera.CameraController(self.world.size, self.mouseWatcherNode, self.camera, self.cam) self.gui = gui.GUI(self.pixel2d, font) self.world_geometry.node.setPos(0, 0, 0) self.world_geometry.node.reparentTo(self.render) self.explore_mode = True self.current_slice = int(self.world.midpoint.z) self.accept_keyboard() self.accept('mouse1', self.toggle_block) self.accept('console-command', self.console_command) self.designation = designation.Designation() self.dorfs = [] self.tool = lambda w, x, y, z: None self.toolargs = () self.tools = { 'bomb': tools.bomb, 'block': tools.block, 'd': self.designation.add } self.console = console.Console(self) self.picker = block_picker.BlockPicker(self.world, self) self.zmap = zmap.ZMap(self.world, self) self.change_slice(0) arrow = LineNodePath() arrow.reparentTo(self.render) arrow.drawArrow2d(Vec3(-5, -5, self.world.midpoint.z), Vec3(15, -5, self.world.midpoint.z), 30, 3) arrow.create() loading.hide()
class LabTask03(DirectObject): #define the state of the game and level gameState = 'INIT' gameLevel = 1 cameraState = 'STARTUP' count = 0 attempts = 3 posX = -200 posY = 20 posZ = 30 score = 0 contacts = 0 pause = False fire = True desiredCamPos = Vec3(-200,30,20) def __init__(self): self.imageObject = OnscreenImage(image = 'models/splashscreen.png', pos=(0,0,0), scale=(1.4,1,1)) preloader = Preloader() self.musicLoop = loader.loadSfx("music/loop/EndlessBliss.mp3") self.snowmansHit = loader.loadSfx("music/effects/snowball_hit.wav") self.candleThrow = loader.loadSfx("music/effects/snowball_throw.wav") self.presentHit = loader.loadSfx("music/effects/present_hit.wav") self.loseSound = loader.loadSfx("music/effects/Failure-WahWah.mp3") self.winSound = loader.loadSfx("music/effects/Ta Da-SoundBible.com-1884170640.mp3") self.nextLevelSound = loader.loadSfx("music/effects/button-17.wav") self.loseScreen = OnscreenImage(image = 'models/losescreen.png', pos=(0,0,0), scale=(1.4,1,1)) self.loseScreen.hide() self.winScreen = OnscreenImage(image = 'models/winscreen.png', pos=(0,0,0), scale=(1.4,1,1)) self.winScreen.hide() self.helpScreen = OnscreenImage(image = 'models/helpscreen.jpg', pos=(0,0,0.1), scale=(1,1,0.8)) self.helpScreen.hide() self.backBtn = DirectButton(text=("Back"), scale = 0.1, pos = (0,0,-0.8), command = self.doBack) self.retryBtn = DirectButton(text="Retry", scale = 0.1, pos = (0,0,0), command = self.doRetry) self.retryBtn.hide() self.menuBtn = DirectButton(text="Main Menu", scale = 0.1, pos = (0,0,0), command = self.doBack) self.menuBtn.hide() self.backBtn.hide() base.setBackgroundColor(0.1, 0.1, 0.8, 1) #base.setFrameRateMeter(True) # Position the camera base.cam.setPos(0, 30, 20) base.cam.lookAt(0, 30, 0) # Light alight = AmbientLight('ambientLight') alight.setColor(Vec4(0.5, 0.5, 0.5, 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) # Input self.accept('escape', self.doExit) self.accept('r', self.doReset) self.accept('f1', self.toggleWireframe) self.accept('f2', self.toggleTexture) self.accept('f3', self.toggleDebug) self.accept('f5', self.doScreenshot) self.accept('f', self.doShoot, [True]) self.accept('p', self.doPause) inputState.watchWithModifiers('forward', 'w') inputState.watchWithModifiers('left', 'a') inputState.watchWithModifiers('reverse', 's') inputState.watchWithModifiers('right', 'd') inputState.watchWithModifiers('turnLeft', 'q') inputState.watchWithModifiers('turnRight', 'e') inputState.watchWithModifiers('moveLineUp', 'i') inputState.watchWithModifiers('moveLineDown','k') inputState.watchWithModifiers('moveLineRight','l') inputState.watchWithModifiers('moveLineLeft','j') self.font = loader.loadFont('models/SHOWG.TTF') self.font.setPixelsPerUnit(60) self.attemptText = OnscreenText(text='', pos = (0.9,0.8), scale = 0.07, font = self.font) self.levelText = OnscreenText(text='', pos=(-0.9,0.9), scale = 0.07, font = self.font ) self.scoreText = OnscreenText(text='', pos = (0.9,0.9), scale = 0.07, font = self.font) self.text = OnscreenText(text = '', pos = (0, 0), scale = 0.07, font = self.font) self.pauseText = OnscreenText(text='P: Pause', pos= (0.9,0.7), scale = 0.05, font = self.font) self.pauseText.hide() # Task taskMgr.add(self.update, 'updateWorld') # Physics self.setup() # _____HANDLER_____ def doRetry(self): self.loseScreen.hide() self.levelText.clearText() self.scoreText.clearText() self.attemptText.clearText() self.playGame() self.retryBtn.hide() self.cleanup() self.setup() def doExit(self): self.cleanup() sys.exit(1) def doReset(self): self.attempts = 3 self.cameraState = 'STARTUP' base.cam.setPos(0,30,20) self.arrow.removeNode() self.scoreText.clearText() self.levelText.clearText() self.attemptText.clearText() self.cleanup() self.setup() def toggleWireframe(self): base.toggleWireframe() def toggleTexture(self): base.toggleTexture() def toggleDebug(self): if self.debugNP.isHidden(): self.debugNP.show() else: self.debugNP.hide() def doScreenshot(self): base.screenshot('Bullet') def doShoot(self, ccd): if(self.fire and self.attempts > 0 and self.gameState == 'PLAY'): self.cameraState = 'LOOK' self.fire = False self.candleThrow.play() self.attempts -= 1 #get from/to points from mouse click ## pMouse = base.mouseWatcherNode.getMouse() ## pFrom = Point3() ## pTo = Point3() ## base.camLens.extrude(pMouse, pFrom, pTo) ## pFrom = render.getRelativePoint(base.cam, pFrom) ## pTo = render.getRelativePoint(base.cam, pTo) # calculate initial velocity v = self.pTo - self.pFrom ratio = v.length() / 40 v.normalize() v *= 70.0 * ratio torqueOffset = random.random() * 10 #create bullet shape = BulletSphereShape(0.5) shape01 = BulletSphereShape(0.5) shape02 = BulletSphereShape(0.5) shape03 = BulletSphereShape(0.5) body = BulletRigidBodyNode('Candle') bodyNP = self.worldNP.attachNewNode(body) bodyNP.node().addShape(shape, TransformState.makePos(Point3(0,0,0))) bodyNP.node().addShape(shape01, TransformState.makePos(Point3(0,0.5,-0.5))) bodyNP.node().addShape(shape02,TransformState.makePos(Point3(0,1,-1))) bodyNP.node().addShape(shape03,TransformState.makePos(Point3(0,1.5,-1.5))) bodyNP.node().setMass(100) bodyNP.node().setFriction(1.0) bodyNP.node().setLinearVelocity(v) bodyNP.node().applyTorque(v*torqueOffset) bodyNP.setPos(self.pFrom) bodyNP.setCollideMask(BitMask32.allOn()) visNP = loader.loadModel('models/projectile.X') visNP.setScale(0.7) visNP.clearModelNodes() visNP.reparentTo(bodyNP) #self.bird = bodyNP.node() if ccd: bodyNP.node().setCcdMotionThreshold(1e-7) bodyNP.node().setCcdSweptSphereRadius(0.5) self.world.attachRigidBody(bodyNP.node()) #remove the bullet again after 1 sec self.bullets = bodyNP taskMgr.doMethodLater(5, self.removeBullet, 'removeBullet', extraArgs=[bodyNP], appendTask = True) def removeBullet(self, bulletNP, task): self.cameraState = 'STAY' self.fire = True self.world.removeRigidBody(bulletNP.node()) bulletNP.removeNode() if(self.attempts <= 0 and len(self.snowmans)>0): self.gameState = 'LOSE' self.doContinue() return task.done # ____TASK___ def processInput(self, dt): force = Vec3(0, 0, 0) torque = Vec3(0, 0, 0) #print self.pTo.getY() if inputState.isSet('forward'): if(self.pTo.getZ() < 40): self.pTo.addZ(0.5) if inputState.isSet('reverse'): if(self.pTo.getZ() > 0 ): self.pTo.addZ(-0.5) if inputState.isSet('left'): if(self.pTo.getY() < 100): self.pTo.addY(0.5) self.arrow.setScale(self.arrow.getSx(),self.arrow.getSy()-0.006,self.arrow.getSz()) if inputState.isSet('right'): if(self.pTo.getY() > 60): self.pTo.addY(-0.5) self.arrow.setScale(self.arrow.getSx(),self.arrow.getSy()+0.006,self.arrow.getSz()) self.arrow.lookAt(self.pTo) def processContacts(self, dt): for box in self.boxes: for snowman in self.snowmans: result = self.world.contactTestPair(box, snowman.node()) if (result.getNumContacts() > 0): self.snowmansHit.play() self.score += 100 self.text.setPos(0,0.7) self.text.setText("HIT") self.snowmans.remove(snowman) self.world.removeRigidBody(snowman.node()) snowman.removeNode() if(len(self.snowmans) <= 0): self.gameState = "NEXT" self.text.setText('Nice! Press space to continue') for box in self.boxes: for present in self.presents: result01 = self.world.contactTestPair(box,present.node()) if(result01.getNumContacts() > 0): self.presents.remove(present) self.world.removeRigidBody(present.node()) present.removeNode() self.presentHit.play() self.score += 500 def doContinue(self): if(self.gameState == 'INIT'): self.gameState = 'MENU' self.text.clearText() self.musicLoop.setLoop(True) self.musicLoop.setVolume(0.5) self.musicLoop.play() self.startBtn = DirectButton(text=("Play"), scale = 0.1, pos = (0,0,0),command=self.playGame) self.helpBtn = DirectButton(text=("Help"), scale = 0.1, pos = (0,0,-0.2),command=self.help) self.exitBtn = DirectButton(text=("Exit"), scale = 0.1, pos = (0,0,-0.4), command = self.doExit) return if self.gameState == 'NEXT': self.nextLevelSound.play() self.fire = True self.gameLevel += 1 self.score += (self.attempts * 100) self.doReset() self.gameState = 'PLAY' return if self.gameState == 'LOSE': self.loseSound.play() self.arrow.removeNode() self.loseScreen.show() self.levelText.hide() self.attemptText.hide() self.scoreText.hide() self.text.hide() self.pauseText.hide() self.retryBtn.show() return if self.gameState == 'WIN': self.levelText.hide() self.attemptText.hide() self.scoreText.clearText() self.scoreText.setPos(0,0.6) self.scoreText.setText("%s"%self.score) self.winScreen.show() self.winSound.play() self.menuBtn.show() self.pauseText.hide() return def playGame(self): print "Play Game" self.attempts = 3 self.score = 0 self.gameLevel = 1 self.gameState = 'PLAY' self.musicLoop.setVolume(0.3) self.imageObject.hide() self.startBtn.hide() self.exitBtn.hide() self.helpBtn.hide() self.cleanup() self.setup() def doBack(self): self.gameState = 'MENU' self.scoreText.setPos(0.9,0.9) self.scoreText.hide() self.imageObject.show() self.startBtn.show() self.exitBtn.show() self.helpBtn.show() self.helpScreen.hide() self.backBtn.hide() self.menuBtn.hide() self.winScreen.hide() def help(self): self.gameState = 'HELP' self.startBtn.hide() self.exitBtn.hide() self.helpBtn.hide() self.backBtn.show() self.helpScreen.show() return def doPause(self): self.pause = not self.pause if(self.pause): self.text.setText("Pause") else: self.text.clearText() def update(self, task): dt = globalClock.getDt() if(not self.pause): if self.gameState == 'INIT': self.text.setPos(0,0) self.text.setText('Press space to continue') self.accept('space',self.doContinue) if self.gameState == 'PLAY': #print self.posZ #if(self.posX < -120): # self.posX += 0.03 # self.posZ -= 0.02 #elif(self.posZ < 70): # self.posZ += 0.02; #elif(self.posZ > 70 and self.posX > -120): # self.posZ -= 0.02 # self.posX -= 0.03 #base.cam.setPos(self.posX, self.posZ, self.posY) self.levelText.setText('Level: %s'%self.gameLevel) self.attemptText.setText('Tries Left: %s'%self.attempts) self.scoreText.setText('Score: %s'%self.score) self.pauseText.show() self.processContacts(dt) self.world.doPhysics(dt, 20, 1.0/180.0) #self.drawLines() self.processInput(dt) if self.cameraState == 'STARTUP': oldPos = base.cam.getPos() pos = (oldPos*0.9) + (self.desiredCamPos*0.1) base.cam.setPos(pos) base.cam.lookAt(0,30,0) elif self.cameraState == 'STAY': #oldPos = base.cam.getPos() #currPos = (oldPos*0.9) + (self.desiredCamPos*0.1) #base.cam.setPos(currPos) base.cam.lookAt(0,30,0) elif self.cameraState == 'LOOK': base.cam.lookAt(self.bullets) #base.cam.setPos(-200,self.bullets.getZ(),20) if self.gameState == 'NEXT': self.world.doPhysics(dt, 20, 1.0/180.0) ## self.raycast() return task.cont def raycast(self): # Raycast for closest hit tsFrom = TransformState.makePos(Point3(0,0,0)) tsTo = TransformState.makePos(Point3(10,0,0)) shape = BulletSphereShape(0.5) penetration = 1.0 result = self.world.sweepTestClosest(shape, tsFrom, tsTo, penetration) if result.hasHit(): torque = Vec3(10,0,0) force = Vec3(0,0,100) ## for hit in result.getHits(): ## hit.getNode().applyTorque(torque) ## hit.getNode().applyCentralForce(force) result.getNode().applyTorque(torque) result.getNode().applyCentralForce(force) ## print result.getClosestHitFraction() ## print result.getHitFraction(), \ ## result.getNode(), \ ## result.getHitPos(), \ ## result.getHitNormal() def cleanup(self): self.world = None self.worldNP.removeNode() self.arrow.removeNode() self.lines.reset() self.text.clearText() def setup(self): self.attemptText.show() self.levelText.show() self.scoreText.show() self.text.show() self.worldNP = render.attachNewNode('World') # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) self.debugNP.show() self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setDebugNode(self.debugNP.node()) #arrow self.scaleY = 10 self.arrow = loader.loadModel('models/arrow.X') self.arrow.setScale(0.5,0.5,0.5) self.arrow.setAlphaScale(0.5) #self.arrow.setTransparency(TransparencyAttrib.MAlpha) self.arrow.reparentTo(render) #SkyBox skybox = loader.loadModel('models/skybox.X') skybox.reparentTo(render) # Ground shape = BulletPlaneShape(Vec3(0, 0, 1), 0) np = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground')) np.node().addShape(shape) np.setPos(0, 0, -1) np.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(np.node()) visualNP = loader.loadModel('models/ground.X') visualNP.clearModelNodes() visualNP.reparentTo(np) #some boxes self.boxes = [] self.snowmans = [] self.platforms = [] self.presents = [] #TODO: Make a table #Table Top #self.createBox(Vec3(),Vec3()) if(self.gameLevel == 1): self.createBox(Vec3(5,7,1),Vec3(0,5,10),1.0) #2 legs self.createBox(Vec3(4,1,4),Vec3(0,11,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-1,5),1.0) # Pigs self.createSnowman(2.0,Vec3(0, 5, 2.0),10.0) self.createSnowman(1.5, Vec3(0,-10,4.0),10.0) if(self.gameLevel == 2): #table01 self.createBox(Vec3(5,14,1),Vec3(0,-2,12),2.0) self.createBox(Vec3(5,7,1),Vec3(0,5,10),2.0) self.createBox(Vec3(4,1,4),Vec3(0,11,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-1,5),1.0) #table02 self.createBox(Vec3(5,7,1),Vec3(0,-9,10),2.0) self.createBox(Vec3(4,1,4),Vec3(0,-3,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-15,5),1.0) #table03 self.createBox(Vec3(1,1,1), Vec3(0,-1,14), 2.0) self.createBox(Vec3(1,1,1), Vec3(0,-3,14), 2.0) self.createBox(Vec3(1,1,1), Vec3(0,3,14), 2.0) self.createBox(Vec3(1,1,1), Vec3(0,-5,14), 2.0) self.createBox(Vec3(1,1,1), Vec3(0,5,14), 2.0) #pigs self.createSnowman(2.0,Vec3(0, 5, 2.0),10.0) self.createSnowman(2.0, Vec3(0,-9,2.0), 10.0) self.createSnowman(2.0,Vec3(0,-23,2.0),10.0) if(self.gameLevel == 3): #table01 self.createBox(Vec3(4,2,2),Vec3(0,12,12),1.0) self.createBox(Vec3(4,1,4),Vec3(0,11,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,13,5),1.0) #table02 self.createBox(Vec3(4,2,2),Vec3(0,-15,12),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-14,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-16,5),1.0) #table03 self.createBox(Vec3(4,10,1),Vec3(0,-1,12),1.0) self.createBox(Vec3(4,10,1),Vec3(0,-1,14),1.0) self.createBox(Vec3(4,2,4),Vec3(0,-2,5),0.1) #table04 self.createPlatform(Vec3(4,8,1),Vec3(0,7,16),1.0) self.createPlatform(Vec3(4,8,1),Vec3(0,-9,16),1.0) self.createBox(Vec3(4,1,3),Vec3(0,13,20),1.0) self.createBox(Vec3(4,1,3),Vec3(0,-16,20),1.0) #table05 self.createBox(Vec3(4,15,1),Vec3(0,-1,24),1.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,2,20),5.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,-2,20),5.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,4,20),5.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,8,20),5.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,6,20),5.0) #pigs self.createSnowman(2.0,Vec3(0, 5, 2.0),10.0) self.createSnowman(2.0,Vec3(0,-8.5,2.0),10.0) self.createSnowman(1.5, Vec3(0,-9,19.5), 7.0) #presents self.createPresent(Vec3(2,2,2),Vec3(0,-20,5)) if(self.gameLevel == 4): #wall self.createStoneBox(Vec3(4,1.5,10), Vec3(0,20,10),20) #table01 self.createBox(Vec3(4,1,5), Vec3(0,7,7),1) self.createBox(Vec3(4,1,5), Vec3(0,0,7),1) self.createBox(Vec3(4,1,4), Vec3(0,3,7),1) self.createPlatform(Vec3(5,8,1), Vec3(0,4,13),1) self.createBox(Vec3(4,1,3), Vec3(0,11,18),1) self.createBox(Vec3(4,1,3), Vec3(0,-3,18),1) self.createBox(Vec3(4,8,1), Vec3(0,4,25),1) self.createStoneBox(Vec3(1,1,1), Vec3(0,4,27),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,7,27),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,2,27),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,2,29),2) #stairs self.createPlatform(Vec3(4,50,4), Vec3(0,-55,5),100) #table02 self.createBox(Vec3(4,1,5), Vec3(0,-13,15),1) self.createBox(Vec3(4,1,5), Vec3(0,-20,15),1) self.createBox(Vec3(4,1,4), Vec3(0,-17,15),1) self.createPlatform(Vec3(4,8,1), Vec3(0,-16,22),1) self.createBox(Vec3(4,1,3), Vec3(0,-9,28),1) self.createBox(Vec3(4,1,3), Vec3(0,-23,28),1) self.createBox(Vec3(4,8,1), Vec3(0,-16,33),1) self.createStoneBox(Vec3(1,1,1), Vec3(0,-16,35),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,-13,35),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,-18,35),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,-18,37),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,-14,37),2) #snowman self.createSnowman(2.0,Vec3(0,30,5),1.0) self.createSnowman(1.5,Vec3(0,4,18),1.0) self.createSnowman(1.5,Vec3(0,-13,26),1.0) self.createSnowman(1.5,Vec3(0,-19,26),1.0) self.createSnowman(2.0,Vec3(0,12,5),1.0) self.createPresent(Vec3(2,2,2),Vec3(0,-25,13)) self.createPresent(Vec3(3,3,3),Vec3(0,-30,13)) self.createPresent(Vec3(4,4,4),Vec3(0,-36,13)) #self.createSnowman(1.5,Vec3(0,4,20),1.0) if(self.gameLevel == 5): #table01 self.createStoneBox(Vec3(4,7,3), Vec3(0,30,5),10.0) self.createStoneBox(Vec3(4,7,3), Vec3(0,-30,5),10.0) self.createBox(Vec3(4,1,3), Vec3(0,0,5), 1.0) self.createSnowman(1.5,Vec3(0,-6,5),1.0) self.createSnowman(1.5,Vec3(0,6,5),1.0) self.createBox(Vec3(4,1,3), Vec3(0,-12,5), 1.0) self.createBox(Vec3(4,1,3), Vec3(0,12,5), 1.0) self.createSnowman(1.5,Vec3(0,-18,5),1.0) self.createSnowman(1.5,Vec3(0,18,5),1.0) self.createStoneBox(Vec3(4,6,1),Vec3(0,-18,10), 0.1) self.createStoneBox(Vec3(4,6,1),Vec3(0,-6,10), 0.1) self.createStoneBox(Vec3(4,6,1),Vec3(0,6,10), 0.1) self.createStoneBox(Vec3(4,6,1),Vec3(0,18,10), 0.1) self.createStoneBox(Vec3(4,1,3),Vec3(0,23,14), 1.0) self.createStoneBox(Vec3(4,1,3),Vec3(0,-23,14), 1.0) self.createBox(Vec3(4,1,3),Vec3(0,18,14),1.0) self.createBox(Vec3(4,1,3),Vec3(0,-18,14),1.0) self.createStoneBox(Vec3(4,1,7),Vec3(0,13,20), 2.0) self.createStoneBox(Vec3(4,1,7),Vec3(0,-13,20), 2.0) self.createBox(Vec3(4,1,3),Vec3(0,8,14),1.0) self.createBox(Vec3(4,1,3),Vec3(0,-8,14),1.0) self.createStoneBox(Vec3(4,1,3),Vec3(0,3,14), 1.0) self.createStoneBox(Vec3(4,1,3),Vec3(0,-3,14), 1.0) self.createPlatform(Vec3(4,3.5,1),Vec3(0,-20 ,20), 1.0) self.createPlatform(Vec3(4,3.5,1),Vec3(0,20 ,20), 1.0) self.createPlatform(Vec3(4,3.5,1),Vec3(0,-5 ,20), 1.0) self.createPlatform(Vec3(4,3.5,1),Vec3(0,5 ,20), 1.0) self.createStoneBox(Vec3(4,1,3.5),Vec3(0,-18,25), 2.0) self.createStoneBox(Vec3(4,1,3.5),Vec3(0,18,25), 2.0) self.createStoneBox(Vec3(4,1,3.5),Vec3(0,-7.5,25), 2.0) self.createStoneBox(Vec3(4,1,3.5),Vec3(0,7.5,25), 2.0) self.createStoneBox(Vec3(4,6,1),Vec3(0,-12,30), 2.0) self.createStoneBox(Vec3(4,6,1),Vec3(0,12,30), 2.0) self.createBox(Vec3(4,1,5),Vec3(0,-5,30), 2.0) self.createBox(Vec3(4,1,5),Vec3(0,5,30), 2.0) self.createBox(Vec3(4,5,1),Vec3(0,0,40), 2.0) self.createPlatform(Vec3(4,2,0.5),Vec3(0,0,42), 2.0) self.createStoneBox(Vec3(4,0.5,2),Vec3(0,-3.5,45), 2.0) self.createStoneBox(Vec3(4,0.5,2),Vec3(0,3.5,45), 2.0) self.createStoneBox(Vec3(4,4,0.5),Vec3(0,0,48), 2.0) self.createPresent(Vec3(1.5,1.5,1.5),Vec3(0,22,30)) self.createPresent(Vec3(1.5,1.5,1.5),Vec3(0,-22,30)) self.createPresent(Vec3(2,2,1),Vec3(0,0,44)) self.createPresent(Vec3(3,3,4),Vec3(0,0,33)) if(self.gameLevel > 5): self.gameState = 'WIN' self.doContinue() return # drawing lines between the points ## self.lines = LineNodePath(parent = render, thickness = 3.0, colorVec = Vec4(1, 0, 0, 1)) ## self.pFrom = Point3(-4, 0, 0.5) ## self.pTo = Point3(4, 0, 0.5) # Aiming line self.lines = LineNodePath(parent = render, thickness = 3.0, colorVec = Vec4(1, 0, 0, 1)) self.pFrom = Point3(0, 100, 0.5) self.pTo = Point3(0, 60, 10) self.arrow.setPos(self.pFrom) def drawLines(self): # Draws lines for the ray. self.lines.reset() self.lines.drawLines([(self.pFrom,self.pTo)]) self.lines.create() def createBox(self,size,pos,mass): shape = BulletBoxShape(size) body = BulletRigidBodyNode('Obstacle') bodyNP = self.worldNP.attachNewNode(body) bodyNP.node().addShape(shape) bodyNP.node().setMass(mass) bodyNP.node().setFriction(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setPos(pos) bodyNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(bodyNP.node()) visNP = loader.loadModel('models/crate.X') visNP.setScale(size*2) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.boxes.append(body) def createStoneBox(self,size,pos,mass): shape = BulletBoxShape(size) body = BulletRigidBodyNode('Obstacle') bodyNP = self.worldNP.attachNewNode(body) bodyNP.node().addShape(shape) bodyNP.node().setMass(mass) bodyNP.node().setFriction(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setPos(pos) bodyNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(bodyNP.node()) visNP = loader.loadModel('models/stone.X') visNP.setScale(size*2) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.boxes.append(body) def createSnowman(self, size, pos, mass): shape = BulletBoxShape(Vec3(size,size,size)) shape01 = BulletSphereShape(size/2) body = BulletRigidBodyNode('Snowman') np = self.worldNP.attachNewNode(body) np.node().setMass(mass) np.node().addShape(shape, TransformState.makePos(Point3(0,0,-1))) np.node().addShape(shape01, TransformState.makePos(Point3(0,0,1))) np.node().setFriction(10.0) np.node().setDeactivationEnabled(False) np.setPos(pos) np.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(np.node()) visualNP = loader.loadModel('models/snowman.X') visualNP.setScale(size) visualNP.clearModelNodes() visualNP.reparentTo(np) self.snowmans.append(np) def createPlatform(self,size,pos,mass): shape = BulletBoxShape(size) body = BulletRigidBodyNode('Platform') bodyNP = self.worldNP.attachNewNode(body) bodyNP.node().addShape(shape) bodyNP.node().setMass(mass) bodyNP.node().setFriction(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setPos(pos) bodyNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(bodyNP.node()) visNP = loader.loadModel('models/crate.X') visNP.setScale(size*2) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.platforms.append(body) def createPresent(self,size,pos): shape = BulletBoxShape(size*0.7) body = BulletRigidBodyNode('Present') bodyNP = self.worldNP.attachNewNode(body) bodyNP.node().addShape(shape) bodyNP.node().setMass(1.0) bodyNP.node().setFriction(1.0) bodyNP.node().setDeactivationEnabled(False) bodyNP.setPos(pos) bodyNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(bodyNP.node()) visNP = loader.loadModel('models/present.X') visNP.setScale(size*2) visNP.clearModelNodes() visNP.reparentTo(bodyNP) self.presents.append(bodyNP)
def draw_axis(self, root, origin): PX = origin[0] PY = origin[1] PZ = origin[2] lengthX = PX + 1.5 lengthY = PY + 1.5 lengthZ = PZ + 1.5 q1 = PX + .5 q2 = -q1 arrowLENGHT = PX + .2 arrowXx1 = PY + .08 arrowXx2 = PY - .08 arrowXz2 = PX + 1.3 arrowYx1 = PX + .08 arrowYx2 = PX - .08 arrowYz2 = PY + 1.3 arrowZx1 = PX + .08 arrowZx2 = PX - .08 arrowZz2 = PZ + 1.3 PIVarX = LineNodePath(root, 'pivotX', 3, Vec4(1, 0, 0, 1)) PIVarY = LineNodePath(root, 'pivotY', 3, Vec4(0, 1, 1, 1)) PIVarZ = LineNodePath(root, 'pivotZ', 3, Vec4(1, 1, 0, 1)) PIVOThandler = LineNodePath(root, 'handler', 2, Vec4(1, 0, 1, 1)) PIVarX.reparentTo(PIVOThandler) PIVarY.reparentTo(PIVOThandler) PIVarZ.reparentTo(PIVOThandler) arrowX1 = (lengthX, PY, PZ) arrowX2 = (arrowXz2, arrowXx1, PZ) arrowX3 = (arrowXz2, arrowXx2, PZ) arrowY1 = (PX, lengthY, PZ) arrowY2 = (arrowYx1, arrowYz2, PZ) arrowY3 = (arrowYx2, arrowYz2, PZ) arrowZ1 = (PX, PY, lengthZ) arrowZ2 = (arrowZx1, PY, arrowZz2) arrowZ3 = (arrowZx2, PY, arrowZz2) PIVarX.drawLines([[(PX, PY, PZ), (lengthX, PY, PZ)], [arrowX1, arrowX2], [arrowX1, arrowX3]]) PIVarY.drawLines([[(PX, PY, PZ), (PX, lengthY, PZ)], [arrowY1, arrowY2], [arrowY1, arrowY3]]) PIVarZ.drawLines([[(PX, PY, PZ), (PX, PY, lengthZ)], [arrowZ1, arrowZ2], [arrowZ1, arrowZ3]]) PIVOThandler.drawLines([[(PX, PY, PZ), (PX + 0.5, PY, PZ)], [(PX + .5, PY, PZ), (PX, PY + .5, PZ)], [(PX, PY + .5, PZ), (PX, PY, PZ)]]) PIVarX.create() PIVarY.create() PIVarZ.create() PIVOThandler.create() return PIVOThandler
arrowLENGHT = PX + .2 arrowXx1 = PY + .08 arrowXx2 = PY - .08 arrowXz2 = PX + 1.3 arrowYx1 = PX + .08 arrowYx2 = PX - .08 arrowYz2 = PY + 1.3 arrowZx1 = PX + .08 arrowZx2 = PX - .08 arrowZz2 = PZ + 1.3 PIVarX = LineNodePath(render, 'pivotX', 3, Vec4(1, 0, 0, 1)) PIVarY = LineNodePath(render, 'pivotY', 3, Vec4(0, 1, 1, 1)) PIVarZ = LineNodePath(render, 'pivotZ', 3, Vec4(1, 1, 0, 1)) PIVOThandler = LineNodePath(render, 'handler', 2, Vec4(1, 0, 1, 1)) arrowX1 = (lengthX, PY, PZ) arrowX2 = (arrowXz2, arrowXx1, PZ) arrowX3 = (arrowXz2, arrowXx2, PZ) arrowY1 = (PX, lengthY, PZ) arrowY2 = (arrowYx1, arrowYz2, PZ) arrowY3 = (arrowYx2, arrowYz2, PZ) arrowZ1 = (PX, PY, lengthZ) arrowZ2 = (arrowZx1, PY, arrowZz2)
class Simulation(ShowBase): scale = 1 height = 500 lateralError = 200 dt = 0.1 steps = 0 #Test Controllers fuelPID = PID(10, 0.5, 10, 0, 100) heightPID = PID(0.08, 0, 0.3, 0.1, 1) pitchPID = PID(10, 0, 1000, -10, 10) rollPID = PID(10, 0, 1000, -10, 10) XPID = PID(0.2, 0, 0.8, -10, 10) YPID = PID(0.2, 0, 0.8, -10, 10) vulcain = NeuralNetwork() tau = 0.5 Valves=[] CONTROL = False EMPTY = False LANDED = False DONE = False gimbalX = 0 gimbalY = 0 targetAlt = 150 R = RE(200 * 9.806, 250 * 9.806, 7607000 / 9 * scale, 0.4) throttle = 0.0 fuelMass_full = 417000 * scale fuelMass_init = 0.10 radius = 1.8542 * scale length = 47 * scale Cd = 1.5 def __init__(self, VISUALIZE=False): self.VISUALIZE = VISUALIZE if VISUALIZE is True: ShowBase.__init__(self) self.setBackgroundColor(0.2, 0.2, 0.2, 1) self.setFrameRateMeter(True) self.render.setShaderAuto() self.cam.setPos(-120 * self.scale, -120 * self.scale, 120 * self.scale) self.cam.lookAt(0, 0, 10 * self.scale) alight = AmbientLight('ambientLight') alight.setColor(Vec4(0.5, 0.5, 0.5, 1)) alightNP = self.render.attachNewNode(alight) dlight = DirectionalLight('directionalLight') dlight.setDirection(Vec3(1, -1, -1)) dlight.setColor(Vec4(0.7, 0.7, 0.7, 1)) dlightNP = self.render.attachNewNode(dlight) self.render.clearLight() self.render.setLight(alightNP) self.render.setLight(dlightNP) self.accept('escape', self.doExit) self.accept('r', self.doReset) self.accept('f1', self.toggleWireframe) self.accept('f2', self.toggleTexture) self.accept('f3', self.toggleDebug) self.accept('f5', self.doScreenshot) inputState.watchWithModifiers('forward', 'w') inputState.watchWithModifiers('left', 'a') inputState.watchWithModifiers('reverse', 's') inputState.watchWithModifiers('right', 'd') inputState.watchWithModifiers('turnLeft', 'q') inputState.watchWithModifiers('turnRight', 'e') self.ostData = OnscreenText(text='ready', pos=(-1.3, 0.9), scale=0.07, fg=Vec4(1, 1, 1, 1), align=TextNode.ALeft) self.fuelMass = self.fuelMass_full * self.fuelMass_init self.vulcain.load_existing_model(path="LandingRockets/",model_name="140k_samples_1024neurons_3layers_l2-0.000001") # Physics self.setup() # _____HANDLER_____ def doExit(self): self.cleanup() sys.exit(1) def doReset(self): self.cleanup() self.setup() def toggleWireframe(self): ...#self.toggleWireframe() def toggleTexture(self): ...#self.toggleTexture() def toggleDebug(self): if self.debugNP.isHidden(): self.debugNP.show() else: self.debugNP.hide() def doScreenshot(self): self.screenshot('Bullet') # ____TASK___ def processInput(self): throttleChange = 0.0 if inputState.isSet('forward'): self.gimbalY = 10 if inputState.isSet('reverse'): self.gimbalY = -10 if inputState.isSet('left'): self.gimbalX = 10 if inputState.isSet('right'): self.gimbalX = -10 if inputState.isSet('turnLeft'): throttleChange = -1.0 if inputState.isSet('turnRight'): throttleChange = 1.0 self.throttle += throttleChange / 100.0 self.throttle = min(max(self.throttle, 0), 1) def processContacts(self): result = self.world.contactTestPair(self.rocketNP.node(), self.groundNP.node()) #print(result.getNumContacts()) if result.getNumContacts() != 0: self.LANDED = True #self.DONE = True def update(self,task): #self.control(0.1,0.1,0.1) #self.processInput() #self.processContacts() # self.terrain.update() return task.cont def cleanup(self): self.world.removeRigidBody(self.groundNP.node()) self.world.removeRigidBody(self.rocketNP.node()) self.world = None self.debugNP = None self.groundNP = None self.rocketNP = None self.worldNP.removeNode() self.LANDED = False self.EMPTY = False self.DONE = False self.steps = 0 self.fuelMass = self.fuelMass_full*self.fuelMass_init def setup(self): self.targetAlt = r.randrange(100,300) self.Valves = np.array([0.15,0.2,0.15]) self.EngObs = self.vulcain.predict_data_point(np.array(self.Valves).reshape(1,-1)) if self.VISUALIZE is True: self.worldNP = self.render.attachNewNode('World') else: self.root = NodePath(PandaNode("world root")) self.worldNP = self.root.attachNewNode('World') self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.80665)) # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) self.debugNP.node().showWireframe(True) self.debugNP.node().showConstraints(True) self.debugNP.node().showBoundingBoxes(False) self.debugNP.node().showNormals(True) self.debugNP.show() self.world.setDebugNode(self.debugNP.node()) # self.debugNP.showTightBounds() # self.debugNP.showBounds() # Ground (static) shape = BulletPlaneShape(Vec3(0, 0, 1), 1) self.groundNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground')) self.groundNP.node().addShape(shape) self.groundNP.setPos(0, 0, 0) self.groundNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.groundNP.node()) # Rocket shape = BulletCylinderShape(self.radius, self.length, ZUp) self.rocketNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Cylinder')) self.rocketNP.node().setMass(27200 * self.scale) self.rocketNP.node().addShape(shape) #self.rocketNP.setPos(20,20,250) self.rocketNP.setPos(20, 20, r.randrange(100, 300)+200) #self.rocketNP.setPos(r.randrange(-self.lateralError, self.lateralError, 1), r.randrange(-self.lateralError, self.lateralError, 1), self.height) # self.rocketNP.setPos(0, 0, self.length*10) self.rocketNP.setCollideMask(BitMask32.allOn()) # self.rocketNP.node().setCollisionResponse(0) self.rocketNP.node().notifyCollisions(True) self.world.attachRigidBody(self.rocketNP.node()) for i in range(4): leg = BulletCylinderShape(0.1 * self.radius, 0.5 * self.length, XUp) self.rocketNP.node().addShape(leg, TransformState.makePosHpr( Vec3(6 * self.radius * math.cos(i * math.pi / 2), 6 * self.radius * math.sin(i * math.pi / 2), -0.6 * self.length), Vec3(i * 90, 0, 30))) shape = BulletConeShape(0.75 * self.radius, 0.5 * self.radius, ZUp) self.rocketNP.node().addShape(shape, TransformState.makePosHpr(Vec3(0, 0, -1 / 2 * self.length), Vec3(0, 0, 0))) # Fuel self.fuelRadius = 0.9 * self.radius shape = BulletCylinderShape(self.fuelRadius, 0.01 * self.length, ZUp) self.fuelNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Cone')) self.fuelNP.node().setMass(self.fuelMass_full * self.fuelMass_init) self.fuelNP.node().addShape(shape) self.fuelNP.setPos(0, 0, self.rocketNP.getPos().getZ() - self.length * 0.5 * (1 - self.fuelMass_init)) self.fuelNP.setCollideMask(BitMask32.allOn()) self.fuelNP.node().setCollisionResponse(0) self.world.attachRigidBody(self.fuelNP.node()) frameA = TransformState.makePosHpr(Point3(0, 0, 0), Vec3(0, 0, 90)) frameB = TransformState.makePosHpr(Point3(0, 0, 0), Vec3(0, 0, 90)) self.fuelSlider = BulletSliderConstraint(self.rocketNP.node(), self.fuelNP.node(), frameA, frameB, 1) self.fuelSlider.setTargetLinearMotorVelocity(0) self.fuelSlider.setDebugDrawSize(2.0) self.fuelSlider.set_lower_linear_limit(0) self.fuelSlider.set_upper_linear_limit(0) self.world.attachConstraint(self.fuelSlider) self.npThrustForce = LineNodePath(self.rocketNP, 'Thrust', thickness=4, colorVec=Vec4(1, 0.5, 0, 1)) self.npDragForce = LineNodePath(self.rocketNP, 'Drag', thickness=4, colorVec=Vec4(1, 0, 0, 1)) self.npLiftForce = LineNodePath(self.rocketNP, 'Lift', thickness=4, colorVec=Vec4(0, 0, 1, 1)) self.npFuelState = LineNodePath(self.fuelNP, 'Fuel', thickness=20, colorVec=Vec4(0, 1, 0, 1)) self.rocketCSLon = self.radius ** 2 * math.pi self.rocketCSLat = self.length * 2 * self.radius if self.VISUALIZE is True: self.terrain = loader.loadModel("LZGrid2.egg") self.terrain.setScale(10) self.terrain.reparentTo(self.render) self.terrain.setColor(Vec4(0.1, 0.2, 0.1, 1)) self.toggleTexture() #self.fuelNP.setPos(0, 0, self.rocketNP.getPos().getZ() - self.length * 0.4 * (1 - self.fuelMass_init)) for i in range(5): self.world.doPhysics(self.dt, 5, 1.0 / 180.0) self.fuelSlider.set_lower_linear_limit(-self.length * 0.5 * (1 - self.fuelMass_init)) self.fuelSlider.set_upper_linear_limit(self.length * 0.5 * (1 - self.fuelMass_init)) for i in range(100): self.world.doPhysics(self.dt, 5, 1.0 / 180.0) self.rocketNP.node().applyForce(Vec3(0,0,300000), Vec3(0, 0, 0)) def updateRocket(self, mdot, dt): # Fuel Update self.fuelMass = self.fuelNP.node().getMass() - dt * mdot if self.fuelMass <= 0: self.EMPTY is True fuel_percent = self.fuelMass / self.fuelMass_full self.fuelNP.node().setMass(self.fuelMass) fuelHeight = self.length * fuel_percent I1 = 1 / 2 * self.fuelMass * self.fuelRadius ** 2 I2 = 1 / 4 * self.fuelMass * self.fuelRadius ** 2 + 1 / 12 * self.fuelMass * fuelHeight * fuelHeight self.fuelNP.node().setInertia(Vec3(I2, I2, I1)) # Shift fuel along slider constraint fuelTargetPos = 0.5 * (self.length - fuelHeight) fuelPos = self.fuelSlider.getLinearPos() self.fuelSlider.set_upper_linear_limit(fuelTargetPos) self.fuelSlider.set_lower_linear_limit(-fuelTargetPos) self.npFuelState.reset() self.npFuelState.drawArrow2d(Vec3(0, 0, -0.5 * fuelHeight), Vec3(0, 0, 0.5 * fuelHeight), 45, 2) self.npFuelState.create() def observe(self): pos = self.rocketNP.getPos() vel = self.rocketNP.node().getLinearVelocity() quat = self.rocketNP.getTransform().getQuat() Roll, Pitch, Yaw = quat.getHpr() rotVel = self.rocketNP.node().getAngularVelocity() offset = self.targetAlt-pos.getZ() return pos, vel, Roll, Pitch, Yaw, rotVel, self.fuelMass / self.fuelMass_full, self.EMPTY, self.DONE, self.LANDED, offset, self.EngObs[0], self.Valves def control(self,ValveCommands): self.gimbalX = 0 self.gimbalY = 0 self.Valves = ValveCommands-(ValveCommands-self.Valves)*np.exp(-self.dt/self.tau) self.EngObs = self.vulcain.predict_data_point(np.array(self.Valves).reshape(1,-1 )) #Brennkammerdruck, Gaskammertemp, H2Massenstrom, LOX MAssentrom, Schub #Bar,K,Kg/s,Kg/s,kN #self.dt = globalClock.getDt() pos = self.rocketNP.getPos() vel = self.rocketNP.node().getLinearVelocity() quat = self.rocketNP.getTransform().getQuat() Roll, Pitch, Yaw = quat.getHpr() rotVel = self.rocketNP.node().getAngularVelocity() # CHECK STATE if self.fuelMass <= 0: self.EMPTY = True #if pos.getZ() <= 36: # self.LANDED = True self.LANDED = False self.processContacts() P, T, rho = air_dens(pos[2]) rocketZWorld = quat.xform(Vec3(0, 0, 1)) AoA = math.acos(min(max(dot(norm(vel), norm(-rocketZWorld)), -1), 1)) dynPress = 0.5 * dot(vel, vel) * rho dragArea = self.rocketCSLon + (self.rocketCSLat - self.rocketCSLon) * math.sin(AoA) drag = norm(-vel) * dynPress * self.Cd * dragArea time = globalClock.getFrameTime() liftVec = norm(vel.project(rocketZWorld) - vel) if AoA > 0.5 * math.pi: liftVec = -liftVec lift = liftVec * (math.sin(AoA * 2) * self.rocketCSLat * dynPress) if self.CONTROL: self.throttle = self.heightPID.control(pos.getZ(), vel.getZ(), 33) pitchTgt = self.XPID.control(pos.getX(), vel.getX(), 0) self.gimbalX = -self.pitchPID.control(Yaw, rotVel.getY(), pitchTgt) rollTgt = self.YPID.control(pos.getY(), vel.getY(), 0) self.gimbalY = -self.rollPID.control(Pitch, rotVel.getX(), -rollTgt) self.thrust = self.EngObs[0][4]*1000 #print(self.EngObs) quat = self.rocketNP.getTransform().getQuat() quatGimbal = TransformState.makeHpr(Vec3(0, self.gimbalY, self.gimbalX)).getQuat() thrust = quatGimbal.xform(Vec3(0, 0, self.thrust)) thrustWorld = quat.xform(thrust) #print(thrustWorld) self.npDragForce.reset() self.npDragForce.drawArrow2d(Vec3(0, 0, 0), quat.conjugate().xform(drag) / 1000, 45, 2) self.npDragForce.create() self.npLiftForce.reset() self.npLiftForce.drawArrow2d(Vec3(0, 0, 0), quat.conjugate().xform(lift) / 1000, 45, 2) self.npLiftForce.create() self.npThrustForce.reset() if self.EMPTY is False & self.LANDED is False: self.npThrustForce.drawArrow2d(Vec3(0, 0, -0.5 * self.length), Vec3(0, 0, -0.5 * self.length) - thrust / 30000, 45, 2) self.npThrustForce.create() self.rocketNP.node().applyForce(drag, Vec3(0, 0, 0)) self.rocketNP.node().applyForce(lift, Vec3(0, 0, 0)) #print(self.EMPTY,self.LANDED) if self.EMPTY is False & self.LANDED is False: self.rocketNP.node().applyForce(thrustWorld, quat.xform(Vec3(0, 0, -1 / 2 * self.length))) self.updateRocket(self.EngObs[0][2]+self.EngObs[0][3], self.dt) self.rocketNP.node().setActive(True) self.fuelNP.node().setActive(True) self.processInput() self.world.doPhysics(self.dt) self.steps+=1 if self.steps > 1000: self.DONE = True telemetry = [] telemetry.append('Thrust: {}'.format(int(self.EngObs[0][4]))) telemetry.append('Fuel: {}%'.format(int(self.fuelMass / self.fuelMass_full * 100.0))) telemetry.append('Gimbal: {}'.format(int(self.gimbalX)) + ',{}'.format(int(self.gimbalY))) telemetry.append('AoA: {}'.format(int(AoA / math.pi * 180.0))) telemetry.append('\nPos: {},{}'.format(int(pos.getX()), int(pos.getY()))) telemetry.append('Height: {}'.format(int(pos.getZ()))) telemetry.append('RPY: {},{},{}'.format(int(Roll), int(Pitch), int(Yaw))) telemetry.append('Speed: {}'.format(int(np.linalg.norm(vel)))) telemetry.append('Vel: {},{},{}'.format(int(vel.getX()), int(vel.getY()), int(vel.getZ()))) telemetry.append('Rot: {},{},{}'.format(int(rotVel.getX()), int(rotVel.getY()), int(rotVel.getZ()))) telemetry.append('LANDED: {}'.format(self.LANDED)) telemetry.append('Time: {}'.format(self.steps*self.dt)) telemetry.append('TARGET: {}'.format(self.targetAlt)) #print(pos) if self.VISUALIZE is True: self.ostData.setText('\n'.join(telemetry)) self.cam.setPos(pos[0] - 120 * self.scale, pos[1] - 120 * self.scale, pos[2] + 80 * self.scale) self.cam.lookAt(pos[0], pos[1], pos[2]) self.taskMgr.step() """
from pandac.PandaModules import * from direct.directtools.DirectGeometry import LineNodePath import direct.directbase.DirectStart from pandac.PandaModules import Point3, Vec3, Vec4 raws1unit = 20 rawsfithunit = 100 d = 0 X1 = 10 X2 = -10 Y1 = 10 Y2 = -10 linesX = LineNodePath(render, 'quad', 2, Vec4(.3, .3, .3, .3)) linesXX = LineNodePath(render, 'quad', 1, Vec4(.3, .3, .3, .3)) axis = LineNodePath(render, 'axis', 4, Vec4(.2, .2, .2, .2)) quad = LineNodePath(render, 'quad', 4, Vec4(.2, .2, .2, .2)) x1 = (0, Y2, 0) x2 = (0, Y1, 0) x3 = (X2, 0, 0) x4 = (X1, 0, 0) axis.drawLines([[x1, x2], [x3, x4]]) axis.create() q1 = (X1, Y1, 0) q2 = (X1, Y2, 0) q3 = (q2)
class DirectGrid(NodePath, DirectObject): def __init__(self,parent,gridSize=100.0,gridSpacing=5.0,planeColor=(0.5,0.5,0.5,0.5)): # Initialize superclass NodePath.__init__(self) self.assign(hidden.attachNewNode('DirectGrid')) # Don't wireframe or light #useDirectRenderStyle(self) self.setLightOff(0) self.setRenderModeFilled() self.parent = parent # Load up grid parts to initialize grid object # Polygon used to mark grid plane self.gridBack = loader.loadModel('models/misc/gridBack.egg.pz') self.gridBack.reparentTo(self) self.gridBack.setColor(*planeColor) # Grid Lines self.lines = self.attachNewNode('gridLines') self.minorLines = LineNodePath(self.lines) self.minorLines.lineNode.setName('minorLines') self.minorLines.setColor(VBase4(0.3, 0.55, 1, 1)) self.minorLines.setThickness(1) self.majorLines = LineNodePath(self.lines) self.majorLines.lineNode.setName('majorLines') self.majorLines.setColor(VBase4(0.3, 0.55, 1, 1)) self.majorLines.setThickness(5) self.centerLines = LineNodePath(self.lines) self.centerLines.lineNode.setName('centerLines') self.centerLines.setColor(VBase4(1, 0, 0, 0)) self.centerLines.setThickness(3) # Small marker to hilight snap-to-grid point self.snapMarker = loader.loadModel('models/misc/sphere.egg.pz') self.snapMarker.node().setName('gridSnapMarker') self.snapMarker.reparentTo(self) self.snapMarker.setColor(1, 0, 0, 1) self.snapMarker.setScale(0.3) self.snapPos = Point3(0) # Initialize Grid characteristics self.fXyzSnap = 1 self.fHprSnap = 1 self.gridSize = gridSize self.gridSpacing = gridSpacing self.snapAngle = 15.0 self.enable() def enable(self): self.reparentTo(self.parent) self.updateGrid() self.fEnabled = 1 def disable(self): self.reparentTo(hidden) self.fEnabled = 0 def toggleGrid(self): if self.fEnabled: self.disable() else: self.enable() def isEnabled(self): return self.fEnabled def updateGrid(self): # Update grid lines based upon current grid spacing and grid size # First reset existing grid lines self.minorLines.reset() self.majorLines.reset() self.centerLines.reset() # Now redraw lines numLines = int(math.ceil(self.gridSize/self.gridSpacing)) scaledSize = numLines * self.gridSpacing center = self.centerLines minor = self.minorLines major = self.majorLines for i in range(-numLines, numLines + 1): if i == 0: center.moveTo(i * self.gridSpacing, -scaledSize, 0) center.drawTo(i * self.gridSpacing, scaledSize, 0) center.moveTo(-scaledSize, i * self.gridSpacing, 0) center.drawTo(scaledSize, i * self.gridSpacing, 0) else: if (i % 5) == 0: major.moveTo(i * self.gridSpacing, -scaledSize, 0) major.drawTo(i * self.gridSpacing, scaledSize, 0) major.moveTo(-scaledSize, i * self.gridSpacing, 0) major.drawTo(scaledSize, i * self.gridSpacing, 0) else: minor.moveTo(i * self.gridSpacing, -scaledSize, 0) minor.drawTo(i * self.gridSpacing, scaledSize, 0) minor.moveTo(-scaledSize, i * self.gridSpacing, 0) minor.drawTo(scaledSize, i * self.gridSpacing, 0) center.create() minor.create() major.create() if (self.gridBack): self.gridBack.setScale(scaledSize) def setXyzSnap(self, fSnap): self.fXyzSnap = fSnap def getXyzSnap(self): return self.fXyzSnap def setHprSnap(self, fSnap): self.fHprSnap = fSnap def getHprSnap(self): return self.fHprSnap def computeSnapPoint(self, point): # Start of with current point self.snapPos.assign(point) # Snap if necessary if self.fXyzSnap: self.snapPos.set( ROUND_TO(self.snapPos[0], self.gridSpacing), ROUND_TO(self.snapPos[1], self.gridSpacing), ROUND_TO(self.snapPos[2], self.gridSpacing)) # Move snap marker to this point self.snapMarker.setPos(self.snapPos) # Return the hit point return self.snapPos def computeSnapAngle(self, angle): return ROUND_TO(angle, self.snapAngle) def setSnapAngle(self, angle): self.snapAngle = angle def getSnapAngle(self): return self.snapAngle def setGridSpacing(self, spacing): self.gridSpacing = spacing self.updateGrid() def getGridSpacing(self): return self.gridSpacing def setGridSize(self, size): # Set size of grid back and redraw lines self.gridSize = size self.updateGrid() def getGridSize(self): return self.gridSize
class Rocket (Body): family = "rocket" species = "generic" longdes = _("generic") shortdes = _("G/RCK") cpitdes = {} against = [] mass = 150.0 diameter = 0.140 maxg = 20.0 vmaxalt = 12000.0 minspeed = 470.0 minspeed1 = 470.0 maxspeed = 650.0 maxspeed1 = 850.0 maxthracc = 300.0 maxthracc1 = 400.0 maxvdracc = 2.0 maxvdracc1 = 1.0 maxflighttime = 20.0 minlaunchdist = 1000.0 hitforce = 5.0 expforce = 50.0 seeker = "ir" flightmodes = ["intercept"] maxoffbore = radians(10.0) locktime = 2.0 decoyresist = 0.7 rcs = 0.00010 hitboxdata = [(Point3(0.0, 0.0, 0.0), 1.0)] modelpath = None texture = None normalmap = None glowmap = "models/weapons/_glowmap.png" glossmap = "models/weapons/_glossmap.png" modelscale = 1.0 modeloffset = Point3() modelrot = Vec3() engsoundname = None engvol = 0.3 launchvol = 0.5 expvol = 0.8 _seekers_local = set(("ir", "tv", "intv", "arh")) _seekers_remote = set(("sarh", "salh", "radio", "wire")) _seekers_none = set((None,)) _seekers_all = _seekers_local.union(_seekers_remote).union(_seekers_none) _flightmodes_all = set(("transfer", "intercept", "inertial")) def __init__ (self, world, name, side, pos=None, hpr=None, speed=None, dropvel=None, target=None, offset=None, extvis=True): if pos is None: pos = Vec3() if hpr is None: hpr = Vec3() if speed is None: d1, maxspeed = self.limspeeds(pos[2]) speed = maxspeed if False: # no point checking in every instance... if self.seeker not in Rocket._seekers_all: raise StandardError( "Unknown seeker type '%s' for '%s'." % (self.seeker, self.species)) unknown = set(self.flightmodes).difference(Rocket._flightmodes_all) if unknown: raise StandardError( "Unknown flight mode '%s' for '%s'." % (unknown.pop(), self.species)) if dropvel is not None: vel = hprtovec(hpr) * speed + dropvel else: vel = speed Body.__init__(self, world=world, family=self.family, species=self.species, hitforce=self.hitforce, modeldata=AutoProps( path=self.modelpath, texture=self.texture, normalmap=self.normalmap, glowmap=self.glowmap, glossmap=self.glossmap, scale=self.modelscale, offset=self.modeloffset, rot=self.modelrot), amblit=True, dirlit=True, pntlit=1, fogblend=True, ltrefl=(self.glossmap is not None), name=name, side=side, pos=pos, hpr=hpr, vel=vel) self.ming = -self.maxg if self.engsoundname: self.engine_sound = Sound3D( path=("audio/sounds/%s.ogg" % self.engsoundname), parent=self, limnum="hum", volume=self.engvol, loop=True) self.engine_sound.play() if 1: lnchsnd = Sound3D( "audio/sounds/%s.ogg" % "missile-launch", parent=self, volume=self.launchvol, fadetime=0.1) lnchsnd.play() self.target = target self.offset = offset self.must_hit_expforce = 0.0 self.proximity_fuze_active = True self._last_target = target self.path = None self.pspeed = None self._targeted_offset = (self.offset or (self.target and self.target.center) or Point3()) self._effective_offset = self._targeted_offset self._actdist = min(0.5 * self.minlaunchdist, 1000.0) self._active = False self._armdist = self.minlaunchdist self._armed = False self._state_info_text = None self._wait_time_state_info = 0.0 self._prev_path = None self._path_pos = 0.0 self.exhaust_trails = [] if side == "bstar": trcol = rgba(127, 0, 0, 1) elif side == "nato": trcol = rgba(0, 0, 127, 1) else: trcol = rgba(0, 127, 0, 1) self._trace = None if world.show_traces: self._trace = LineNodePath(parent=self.world.node, thickness=1.0, colorVec=trcol) self._trace_segs = [] self._trace_lens = [] self._trace_len = 0.0 self._trace_maxlen = 5000.0 self._trace_prevpos = pos self._trace_frameskip = 5 self._trace_accuframe = 0 self._flightdist = 0.0 self._flighttime = 0.0 self._updperiod_decoy = 0.053 self._updwait_decoy = 0.0 self._dtime_decoy_process = 0.0 self._eliminated_decoys = set() self._tracked_decoy = None self._no_target_selfdest_time = 1.0 self._no_target_time = 0.0 test_expforce = max(self.expforce * 0.9, self.expforce - 1.0) self._prox_dist = explosion_reach(test_expforce) self.proximity_fuzed = False # debug self.target_hit = False # debug if extvis: bx, by, bz = self.bbox bbox = Vec3(bx, by * 500.0, bz) EnhancedVisual(parent=self, bbox=bbox) self._fudge_player_manoeuver = True if self._fudge_player_manoeuver: self._plmanv_done_1 = False self._plmanv_done_2 = False base.taskMgr.add(self._loop, "rocket-loop-%s" % self.name) def _loop (self, task): if not self.alive: return task.done if self.target and not self.target.alive: self.target = None # Keep track of last known and alive target. # Needed e.g. to apply force explosion damage. if self.target and self.target.alive: self._last_target = self.target elif self._last_target and not self._last_target.alive: self._last_target = None dt = self.world.dt pos = self.pos() vel = self.vel() if self.world.below_surface(pos): posg = self.world.intersect_surface(pos - vel * dt, pos) self.explode(pos=posg) return task.done if self._flighttime >= self.maxflighttime: self.explode() return task.done if not self._active and (self._flightdist >= self._actdist or self.must_hit_expforce > 0.0): self._active = True # Initial autopilot state. self._ap_currctl = None self._ap_pause = 0.0 if not self._armed and self._flightdist >= self._armdist: self.set_hitboxes(hitboxdata=self.hitboxdata) self._armed = True # Update offset for decoys. if self.target: self._updwait_decoy -= dt self._dtime_decoy_process += dt if self._updwait_decoy <= 0.0: self._updwait_decoy += self._updperiod_decoy ret = self._process_decoys(self.target, self._targeted_offset, self._dtime_decoy_process) self._effective_offset = ret self._dtime_decoy_process = 0.0 # Activate proximity fuze if near miss. if (self._armed and self.proximity_fuze_active and self.target and not self.world.in_collision(self)): tdir = self.target.pos(refbody=self, offset=self._targeted_offset) # ...not self._effective_offset. tdist = tdir.length() #print_each(1350, 1.0, "--rck-prox-check tdist=%.0f[m]" % tdist) if tdist < self._prox_dist or self.must_hit_expforce > 0.0: tdir.normalize() offbore = acos(clamp(tdir[1], -1.0, 1.0)) if offbore > self.maxoffbore: #print "--rck-proxfuze", tdist, degrees(offbore) self.explode() self.proximity_fuzed = True # debug return task.done # Apply autopilot. if self._active: if not self.target: # TODO: Look for another target? if self.seeker not in Rocket._seekers_none: self._no_target_time += dt if self._no_target_time >= self._no_target_selfdest_time: self.explode() return task.done else: self._no_target_time = 0.0 self._ap_pause -= dt if self._ap_pause <= 0.0: self._ap_pause = self._ap_input(dt) if self._ap_pause is None: self.target = None self._ap_pause = 2.0 #for trail in self.exhaust_trails: #pass # Update trace (debugging). if self._trace is not None: self._trace_accuframe += 1 if self._trace_accuframe >= self._trace_frameskip: self._trace_accuframe = 0 while self._trace_len >= self._trace_maxlen and self._trace_segs: tseg = self._trace_segs.pop(0) tlen = self._trace_lens.pop(0) self._trace_len -= tlen self._trace_segs.append((self._trace_prevpos, pos)) self._trace_lens.append((pos - self._trace_prevpos).length()) self._trace_len += self._trace_lens[-1] self._trace.reset() self._trace.drawLines(self._trace_segs) #self._trace.drawTo(pos) self._trace.create() self._trace_prevpos = pos return task.cont def destroy (self): if not self.alive: return if self._trace is not None: self._trace.removeNode() Body.destroy(self) def collide (self, obody, chbx, cpos): inert = Body.collide(self, obody, chbx, cpos, silent=True) if inert: return True self.target_hit = (obody is self.target) # debug self.explode() return False def explode (self, pos=None): if not self.alive: return if pos is None: pos = self.pos() if self.world.otr_altitude(pos) < 20.0: debrispitch = (10, 80) else: debrispitch = (-90, 90) exp = PolyExplosion( world=self.world, pos=pos, sizefac=1.4, timefac=0.4, amplfac=0.8, smgray=pycv(py=(115, 150), c=(220, 255)), smred=0, firepeak=(0.5, 0.8), debrispart=(3, 6), debrispitch=debrispitch) snd = Sound3D( "audio/sounds/%s.ogg" % "explosion-missile", parent=exp, volume=self.expvol, fadetime=0.1) snd.play() self.shotdown = True self.destroy() touch = [] if self.must_hit_expforce > 0.0 and self._last_target: touch = [(self._last_target, self.must_hit_expforce)] self.world.explosion_damage(force=self.expforce, ref=self, touch=touch) def move (self, dt): # Base override. # Called by world at end of frame. if dt == 0.0: return pos = vtod(self.pos()) alt = pos[2] vel = vtod(self.vel()) vdir = unitv(vel) speed = vel.length() quat = qtod(self.quat()) udir = quat.getUp() fdir = quat.getForward() rdir = quat.getRight() angvel = vtod(self.angvel()) if self._prev_path is not self.path: # must come before next check self._prev_path = self.path self._path_pos = 0.0 if self.path is None or self.path.length() < self._path_pos: tdir = vdir ndir = udir if self.path is not None: tdir = self.path.tangent(self.path.length()) ndir = self.path.normal(self.path.length()) self.path = Segment(Vec3D(), tdir * 1e5, ndir) self._prev_path = self.path self._path_pos = 0.0 # ==================== # Translation. minspeed, maxspeed = self.limspeeds(alt) if self.pspeed is None: self.pspeed = maxspeed self.pspeed = clamp(self.pspeed, minspeed, maxspeed) minacc, maxacc = self.limaccs(alt=alt, speed=speed) dspeed = self.pspeed - speed if dspeed >= 0.0: tacc = min(dspeed * 1.0, maxacc) else: tacc = max(dspeed * 1.0, minacc) s = self._path_pos dp = self.path.point(s) t = self.path.tangent(s) tvel = vel.dot(t) s1 = s + tvel * dt + tacc * (0.5 * dt**2) dp1 = self.path.point(s1) tvel1 = tvel + tacc * dt t1 = self.path.tangent(s1) vel1 = t1 * tvel1 dpos = dp1 - dp #acc = (dpos - vel * dt) / (0.5 * dt**2) n1 = self.path.normal(s1) r1 = self.path.radius(s1) acc = t1 * tacc + n1 * (tvel1**2 / r1) self._path_pos = s1 self.node.setPos(vtof(pos + dpos)) self._prev_vel = Vec3(self._vel) # needed in base class self._vel = vtof(vel1) # needed in base class self._acc = vtof(acc) # needed in base class # ==================== # Rotation. fdir1 = t1 paxis = fdir.cross(fdir1) if paxis.length() > 1e-5: paxis.normalize() dspitch = fdir.signedAngleRad(fdir1, paxis) else: paxis = rdir dspitch = 0.0 pdang = dspitch pdquat = QuatD() pdquat.setFromAxisAngleRad(pdang, paxis) dquat = pdquat quat1 = quat * dquat angvel1 = (paxis * pdang) / dt angacc = (angvel1 - angvel) / dt self.node.setQuat(qtof(quat1)) self._angvel = vtof(angvel1) # needed in base class self._angacc = vtof(angacc) # needed in base class self._flighttime += dt self._flightdist += dpos.length() # print_each(105, 0.25, "--rck1", pos, speed, self._flighttime) def limspeeds (self, alt=None): if alt is None: alt = self.pos()[2] return self.limspeeds_st(self, alt) @staticmethod def limspeeds_st (clss, alt): minspeed0, minspeed0b = clss.minspeed, clss.minspeed1 maxspeed0, maxspeed0b = clss.maxspeed, clss.maxspeed1 alt0b = clss.vmaxalt if alt < alt0b: ifac = alt / alt0b minspeed = minspeed0 + (minspeed0b - minspeed0) * ifac maxspeed = maxspeed0 + (maxspeed0b - maxspeed0) * ifac else: minspeed = minspeed0b maxspeed = maxspeed0b return minspeed, maxspeed def limaccs (self, alt=None, speed=None): if alt is None: alt = self.pos()[2] if speed is None: speed = self.speed() return self.limaccs_st(self, alt, speed) @staticmethod def limaccs_st (clss, alt, speed): maxthracc0, maxthracc0b = clss.maxthracc, clss.maxthracc1 maxvdracc0, maxvdracc0b = clss.maxvdracc, clss.maxvdracc1 # Altitude influence. alt0b = clss.vmaxalt if alt < alt0b: afac = alt / alt0b maxthracc = maxthracc0 + afac * (maxthracc0b - maxthracc0) maxvdracc = maxvdracc0 + afac * (maxvdracc0b - maxvdracc0) else: maxthracc = maxthracc0b maxvdracc = maxvdracc0b # Speed influence. minspeed, maxspeed = clss.limspeeds_st(clss, alt) sfac = speed / maxspeed minacc0 = maxvdracc * -sfac maxacc0 = maxthracc * (1.0 - sfac) minacc = minacc0 maxacc = maxacc0 return minacc, maxacc def _ap_input (self, dt): w = self.world t = self.target #print "========== rck-ap-start (world-time=%.2f)" % (w.time) # Choose initial control and flight mode. if self._ap_currctl is None: if self.seeker in Rocket._seekers_local: self._ap_currctl = "local" elif self.seeker in Rocket._seekers_remote: self._ap_currctl = "remote" else: # self.seeker in Rocket._seekers_none self._ap_currctl = "continue" if "transfer" in self.flightmodes: self._ap_currflt = "transfer" elif "intercept" in self.flightmodes: self._ap_currflt = "intercept" else: # "inertial" in self.flightmodes self._ap_currflt = "inertial" pos = ptod(self.pos()) alt = pos[2] vel = vtod(self.vel()) vdir = unitv(vel) speed = vel.length() if t and t.alive: tpos = ptod(t.pos(offset=self._effective_offset)) tvel = vtod(t.vel()) tspeed = tvel.length() tacc = vtod(t.acc()) tabsacc = tacc.length() ppitch = self.ppitch() minspeed, maxspeed = self.limspeeds(alt) maxlfac = self.maxg minlfac = self.ming if t and t.alive: dpos = tpos - pos tdist = dpos.length() tdir = unitv(dpos) # Check if still tracking and return if not. havectl = False while not havectl: # control may switch if t and t.alive: if self._ap_currctl == "local": # Check if the target is still within seeker FOV. cosoffbore = tdir.dot(vdir) tracking = (cosoffbore > cos(self.maxoffbore) or self.must_hit_expforce > 0.0) if tracking: havectl = True else: if self.seeker in Rocket._seekers_remote: self._ap_currctl = "remote" # FIXME: What if no transfer mode? self._ap_currflt = "transfer" else: havectl = True elif self._ap_currctl == "remote": # TODO: Check if parent still tracks the target. tracking = True havectl = True elif self._ap_currctl == "continue": tracking = False havectl = True else: self._ap_currctl == "continue" tracking = False havectl = True if self._fudge_player_manoeuver: # Check special player manoeuvring to throw off the missile. player = self.world.player if tracking and player and t is player.ac: outer_time = 4.0 # as for outer pip on missile tracker inner_time = 2.0 # as for inner pip on missile tracker rel_reset_time = 1.2 lim_pitch_ang = radians(-20) rel_max_load = 0.8 lim_aspect_ang = radians(45) assert inner_time < outer_time assert rel_reset_time > 1.0 assert pi * -0.5 < lim_pitch_ang < 0.0 assert 0.0 < rel_max_load < 1.0 assert 0.0 < lim_aspect_ang < pi * 0.5 intc_time = tdist / speed pdq = player.ac.dynstate if intc_time > outer_time * rel_reset_time: self._plmanv_done_1 = False self._plmanv_done_2 = False if not self._plmanv_done_1: if intc_time < outer_time: udir = vtof(pdq.xit) pitch_ang = 0.5 * pi - acos(clamp(udir[2], -1.0, 1.0)) if pitch_ang < lim_pitch_ang: self._plmanv_done_1 = True if not self._plmanv_done_2: if intc_time < inner_time: ndir = pdq.xin aspect_ang = acos(clamp(ndir.dot(-tdir), -1.0, 1.0)) if aspect_ang < lim_aspect_ang: nmaxv = pdq.nmaxvab if pdq.hasab else pdq.nmaxv nmaxc = min(pdq.nmax, nmaxv) if pdq.n > nmaxc * rel_max_load: self._plmanv_done_2 = True if self._plmanv_done_1 and self._plmanv_done_2: tracking = False dbgval(1, "missile-avoid", (w.time, "%.2f", "time", "s"), (self.name, "%s", "name")) if tracking: # Compute location of the target at interception, # assuming that its acceleration is constant, # and that parent points in the exact direction. # Compute with higher precision when near enough. sfvel = Vec3D() sdvelp = speed sfacc = Vec3D() # or self.acc()? sdaccp = 0.0 ret = intercept_time(tpos, tvel, tacc, pos, sfvel, sdvelp, sfacc, sdaccp, finetime=2.0, epstime=(dt * 0.5), maxiter=5) if not ret: ret = 0.0, tpos, vdir inttime, tpos1, idir = ret # Modify intercept according to current state and mode. havemod = False while not havemod: # mode may switch if self._ap_currflt == "intercept": havemod = True adt = dt # Modify intercept to keep sufficiently within boresight. if self._ap_currctl == "local": safeoffbore = self.maxoffbore * 0.8 offbore1 = acos(clamp(idir.dot(tdir), -1.0, 1.0)) if offbore1 > safeoffbore: a1u = unitv(tpos1 - tpos) ang1 = acos(clamp(a1u.dot(-tdir), -1.0, 1.0)) ang2 = pi - ang1 - safeoffbore tdist1c = tdist * (sin(ang1) / sin(ang2)) anu = unitv(tdir.cross(idir)) q = QuatD() q.setFromAxisAngleRad(safeoffbore, anu) idirc = Vec3D(q.xform(tdir)) tpos1c = pos + idirc * tdist1c tpos1 = tpos1c elif self._ap_currflt == "transfer": tointtime = 15.0 #!!! if inttime < tointtime: offbore1 = acos(clamp(unitv(tpos - pos).dot(vdir), -1.0, 1.0)) safeoffbore = self.maxoffbore * 0.8 if offbore1 < safeoffbore: # FIXME: What if no intercept mode? self._ap_currflt = "intercept" if self.seeker in Rocket._seekers_local: self._ap_currctl = "local" if self._ap_currflt == "transfer": # mode not switched havemod = True maxadt = 1.0 if inttime < tointtime: adt = clamp((tointtime - inttime) * 0.1, dt, maxadt) # Direct towards intercept. tpos1 = tpos else: # Climb to best altitude, in direction of intercept. adt = maxadt dpos1 = tpos1 - pos tdir1 = unitv(dpos1) #maxlfac = max(maxlfac * 0.2, min(maxlfac, 6.0)) maxlfac = min(maxlfac, 12.0) mintrad = speed**2 / (maxlfac * w.absgravacc) tralt = max(self.vmaxalt, tpos[2]) daltopt = tralt - alt cpitch = (1.0 - (alt / tralt)**2) * (0.5 * pi) if self._ap_currctl == "local": # If local control in transfer, must keep in bore. safeoffbore = self.maxoffbore * 0.8 tpitch = atan(tdir1[2] / tdir1.getXy().length()) cpitch = clamp(cpitch, tpitch - safeoffbore, tpitch + safeoffbore) tdir1xy = unitv(Vec3D(tdir1[0], tdir1[1], 0.0)) dpos1mxy = tdir1xy * (daltopt / tan(cpitch)) dpos1m = dpos1mxy + Vec3D(0.0, 0.0, daltopt) tpos1 = pos + unitv(dpos1m) * (mintrad * 10.0) elif self._ap_currflt == "inertial": pass #print("--rck-ap-state ctl=%s flt=%s tdist=%.0f[m] alt=%.0f[m] ppitch=%.1f[deg] adt=%.3f[s]" % #(self._ap_currctl, self._ap_currflt, tdist, alt, degrees(ppitch), adt)) else: tpos1 = pos + vdir * (speed * 1.0) adt = None # Input path. dpos1 = tpos1 - pos tdist1 = dpos1.length() tdir1 = unitv(dpos1) ndir = vdir.cross(tdir1).cross(vdir) if ndir.length() > 1e-5: ndir.normalize() dpos1n = dpos1.dot(ndir) or 1e-10 maxturntime = 5.0 #!!! turndist = min(tdist1, maxspeed * maxturntime) trad = turndist**2 / (2 * dpos1n) lfac = (speed**2 / trad) / w.absgravacc if lfac > maxlfac: lfac = maxlfac trad = speed**2 / (lfac * w.absgravacc) else: ndir = vtod(self.quat().getUp()) trad = 1e6 if trad < 1e6: tang = 2 * asin(clamp(dpos1n / tdist1, -1.0, 1.0)) path = Arc(trad, tang, Vec3D(), vdir, ndir) #print "--hmap1 tdist=%.1f[m] speed=%.1f[m/s] trad=%.1f[m] tang=%.1f[deg] lfac=%.1f" % (tdist, speed, trad, degrees(tang), lfac) else: path = Segment(Vec3D(), vdir * 1e5, ndir) # print "--hmap2" self.path = path # # Input path. # vdir = unitv(vel) # dpos = tpos - pos # tdist = dpos.length() # tdir = unitv(dpos) # ndir = unitv(vdir.cross(tdir).cross(vdir)) # dposn = dpos.dot(ndir) or 1e-5 # dpost = dpos.dot(vdir) or 1e-5 # maxtrad = tdist**2 / (2 * dposn) # mrlfac = (speed**2 / maxtrad) / w.absgravacc # if mrlfac < maxlfac: # lfac1 = clamp((maxlfac * 1e3) / tdist, 2.0, maxlfac) # trad = speed**2 / (lfac1 * w.absgravacc) # tang = atan(dposn / dpost) # tang_p = 2 * tang # niter = 0 # maxiter = 10 # while abs(tang_p - tang) > 1e-4 and niter < maxiter: # tang_p = tang # k1 = tan(tang) # k2 = sqrt(1.0 + k1**2) # tang = atan(((dposn - trad) * k2 + trad) / (dpost * k2 - trad * k1)) # niter += 1 # path = Arc(trad, tang, Vec3D(), vdir, ndir) # print "--hmap1 maxiter=%d iter=%d tdist=%.1f speed=%.1f trad=%.1f tang=%.1f" % (maxiter, niter, tdist, speed, trad, degrees(tang)) # else: # path = Segment(Vec3D(), vdir * 1e5, ndir) # print "--hmap2" # self.path = path # Input speed. self.pspeed = maxspeed #print "========== rck-ap-end" return adt @staticmethod def check_launch_free (launcher=None): return True def exec_post_launch (self, launcher=None): pass def _process_decoys (self, target, toffset, dtime): target_dir = unitv(target.pos(refbody=self)) target_offbore = acos(clamp(target_dir[1], -1.0, 1.0)) if target_offbore < self.maxoffbore: target_fwd = target.quat(refbody=self).getForward() target_aspect = acos(clamp(target_dir.dot(target_fwd), -1.0, 1.0)) target_weight = intl01v((target_aspect / pi)**0.5, 1.0, 0.2) resist_mod = target_weight**((1.0 - self.decoyresist)**0.5) offset = toffset else: target_weight = 0.0 resist_mod = 1.0 offset = self._effective_offset # last offset while True: if not self._tracked_decoy: num_tested = 0 for decoy in target.decoys: if decoy.alive and decoy not in self._eliminated_decoys: tracked = False decoy_offbore = self.offbore(decoy) if decoy_offbore < self.maxoffbore: num_tested += 1 if randunit() > self.decoyresist * resist_mod: tracked = True if tracked: self._tracked_decoy = decoy break else: self._eliminated_decoys.add(decoy) else: num_tested = 1 decoy_reloffb = 0.0 decoy_effect = 0.0 if self._tracked_decoy: decoy = self._tracked_decoy tracked = False if decoy.alive: decoy_offbore = self.offbore(decoy) if decoy_offbore < self.maxoffbore: if target_weight and decoy_offbore > target_offbore: decoy_reloffb = (target_offbore / decoy_offbore)**0.5 else: decoy_reloffb = 1.0 decoy_effect = (1.0 - decoy.decay()) * decoy_reloffb if decoy_effect > self.decoyresist * resist_mod: offset = decoy.pos(refbody=target) tracked = True if not tracked: self._tracked_decoy = None self._eliminated_decoys.add(decoy) if self._tracked_decoy or num_tested == 0: break #vf = lambda v, d=3: "(%s)" % ", ".join(("%% .%df" % d) % e for e in v) #num_seen = len(self._eliminated_decoys) + int(bool(self._tracked_decoy)) #num_tracked = int(bool(self._tracked_decoy)) #target_dist = self.pos(refbody=target, offset=toffset).length() #doffset = offset - toffset #print ("--procdec num_seen=%d target_weight=%.2f " #"decoy_reloffb=%.2f decoy_effect=%.2f " #"target_dist=%.0f doffset=%s" #% (num_seen, target_weight, decoy_reloffb, decoy_effect, #target_dist, vf(doffset))) return offset @classmethod def launch_limits (cls, attacker, target, offset=None): weapon = cls apos = attacker.pos() pdir = attacker.quat().getForward() tpos = target.pos(offset=offset) tvel = target.vel() tspd = tvel.length() # Maximum range for non-manouevring target. malt = 0.5 * (apos[2] + tpos[2]) spds = weapon.limspeeds_st(weapon, malt) accs = weapon.limaccs_st(weapon, malt, 0.0) fltime = weapon.maxflighttime - 0.5 * (spds[1] / accs[1]) tvel1 = tvel fltime1 = fltime * 0.90 # safety rmax = max_intercept_range(tpos, tvel1, apos, spds[1], fltime1) # - correct once for bore-keeping (overcorrection) tpos1 = tpos + tvel1 * fltime1 tdir1 = unitv(tpos1 - apos) offbore1 = acos(clamp(tdir1.dot(pdir), -1.0, 1.0)) if offbore1 > weapon.maxoffbore: tdist1 = (tpos1 - apos).length() dbore1 = offbore1 - weapon.maxoffbore tarc1 = (tdist1 / sin(dbore1)) * dbore1 fltime2 = fltime1 * (tdist1 / tarc1) rmax = max_intercept_range(tpos, tvel1, apos, spds[1], fltime2) # Maximum range for manouevring target. if hasattr(target, "mass"): #tminmass = getattr(target, "minmass", target.mass) ##tspds = target.limspeeds(mass=tminmass, alt=tpos[2], withab=True) #taccs = target.limaccs(mass=tminmass, alt=tpos[2], speed=tspd, #climbrate=0.0, turnrate=0.0, #ppitch=radians(-30.0), withab=True) tdpos = tpos - apos tdist = tdpos.length() #fltime1 = min(fltime, tdist / spds[1]) tspd1 = tspd #+ 0.5 * fltime1 * taccs[1] tvel1 = unitv(tdpos) * tspd1 fltime1 = fltime * 0.75 # safety inc. manoeuvring rman = max_intercept_range(tpos, tvel1, apos, spds[1], fltime1) # - correct once for bore-keeping (overcorrection) tpos1 = tpos + tvel1 * fltime1 tdir1 = unitv(tpos1 - apos) offbore1 = acos(clamp(tdir1.dot(pdir), -1.0, 1.0)) if offbore1 > weapon.maxoffbore: tdist1 = (tpos1 - apos).length() dbore1 = offbore1 - weapon.maxoffbore tarc1 = (tdist1 / sin(dbore1)) * dbore1 fltime2 = fltime1 * (tdist1 / tarc1) rman1 = max_intercept_range(tpos, tvel1, apos, spds[1], fltime2) rman = rman1 else: rman = rmax # Minimum range. rmin = weapon.minlaunchdist return rmin, rman, rmax
class main(ShowBase): def __init__(self): ShowBase.__init__(self) # Disable the default camera movements self.disableMouse() # # VIEW SETTINGS # self.win.setClearColor((0.16, 0.16, 0.16, 1)) render.setAntialias(AntialiasAttrib.MAuto) render2d.setAntialias(AntialiasAttrib.MAuto) # # NODE VIEW # self.viewNP = aspect2d.attachNewNode("viewNP") self.viewNP.setScale(0.5) # # NODE MANAGER # self.nodeMgr = NodeManager(self.viewNP) # # NODE RELATED EVENTS # # Add nodes self.accept("addNode", self.nodeMgr.addNode) # Remove nodes self.accept("removeNode", self.nodeMgr.removeNode) self.accept("x", self.nodeMgr.removeNode) self.accept("delete", self.nodeMgr.removeNode) # Selecting self.accept("selectNode", self.nodeMgr.selectNode) # Deselecting self.accept("mouse3", self.nodeMgr.deselectAll) # Node Drag and Drop self.accept("dragNodeStart", self.setDraggedNode) self.accept("dragNodeMove", self.updateNodeMove) self.accept("dragNodeStop", self.updateNodeStop) # Duplicate/Copy nodes self.accept("shift-d", self.nodeMgr.copyNodes) self.accept("copyNodes", self.nodeMgr.copyNodes) # Refresh node logics self.accept("ctlr-r", self.nodeMgr.updateAllLeaveNodes) self.accept("refreshNodes", self.nodeMgr.updateAllLeaveNodes) # # SOCKET RELATED EVENTS # self.accept("updateConnectedNodes", self.nodeMgr.updateConnectedNodes) # Socket connection with drag and drop self.accept("startPlug", self.nodeMgr.setStartPlug) self.accept("endPlug", self.nodeMgr.setEndPlug) self.accept("connectPlugs", self.nodeMgr.connectPlugs) self.accept("cancelPlug", self.nodeMgr.cancelPlug) # Draw line while connecting sockets self.accept("startLineDrawing", self.startLineDrawing) self.accept("stopLineDrawing", self.stopLineDrawing) # # PROJECT MANAGEMENT # self.accept("new", self.newProject) self.accept("save", self.saveProject) self.accept("load", self.loadProject) self.accept("quit", exit) # # EDITOR VIEW # # Zooming self.accept("zoom", self.zoom) self.accept("zoom_reset", self.zoomReset) self.accept("wheel_up", self.zoom, [True]) self.accept("wheel_down", self.zoom, [False]) # Drag view self.mouseSpeed = 1 self.mousePos = None self.startCameraMovement = False self.accept("mouse2", self.setMoveCamera, [True]) self.accept("mouse2-up", self.setMoveCamera, [False]) # Box select # accept the 1st mouse button events to start and stop the draw self.accept("mouse1", self.startBoxDraw) self.accept("mouse1-up", self.stopBoxDraw) # variables to store the start and current pos of the mousepointer self.startPos = LPoint2f(0, 0) self.lastPos = LPoint2f(0, 0) # variables for the to be drawn box self.boxCardMaker = CardMaker("SelectionBox") self.boxCardMaker.setColor(1, 1, 1, 0.25) self.box = None # # WINDOW RELATED EVENTS # self.screenSize = base.getSize() self.accept("window-event", self.windowEventHandler) # # MENU BAR # self.menuBar = MenuBar() # # TASKS # # Task for handling dragging of the camera/view self.taskMgr.add(self.updateCam, "task_camActualisation", priority=-4) # ------------------------------------------------------------------ # PROJECT FUNCTIONS # ------------------------------------------------------------------ def newProject(self): self.nodeMgr.cleanup() def saveProject(self): Save(self.nodeList, self.connections) def loadProject(self): self.nodeMgr.cleanup() Load(self.nodeMgr) # ------------------------------------------------------------------ # CAMERA SPECIFIC FUNCTIONS # ------------------------------------------------------------------ def setMoveCamera(self, moveCamera): """Start dragging around the editor area/camera""" # store the mouse position if weh have a mouse if base.mouseWatcherNode.hasMouse(): x = base.mouseWatcherNode.getMouseX() y = base.mouseWatcherNode.getMouseY() self.mousePos = Point2(x, y) # set the variable according to if we want to move the camera or not self.startCameraMovement = moveCamera def updateCam(self, task): """Task that will move the editor area/camera around according to mouse movements""" # variables to store the mouses current x and y position x = 0.0 y = 0.0 if base.mouseWatcherNode.hasMouse(): # get the mouse position x = base.mouseWatcherNode.getMouseX() y = base.mouseWatcherNode.getMouseY() if base.mouseWatcherNode.hasMouse() \ and self.mousePos is not None \ and self.startCameraMovement: # Move the viewer node aspect independent wp = self.win.getProperties() aspX = 1.0 aspY = 1.0 wpXSize = wp.getXSize() wpYSize = wp.getYSize() if wpXSize > wpYSize: aspX = wpXSize / float(wpYSize) else: aspY = wpYSize / float(wpXSize) mouseMoveX = (self.mousePos.getX() - x) / self.viewNP.getScale( ).getX() * self.mouseSpeed * aspX mouseMoveY = (self.mousePos.getY() - y) / self.viewNP.getScale( ).getZ() * self.mouseSpeed * aspY self.mousePos = Point2(x, y) self.viewNP.setX(self.viewNP, -mouseMoveX) self.viewNP.setZ(self.viewNP, -mouseMoveY) self.nodeMgr.updateConnections() # continue the task until it got manually stopped return task.cont def zoom(self, zoomIn): """Zoom the editor in or out dependent on the value in zoomIn""" zoomFactor = 0.05 maxZoomIn = 2 maxZoomOut = 0.1 if zoomIn: s = self.viewNP.getScale() if s.getX() - zoomFactor < maxZoomIn and s.getY( ) - zoomFactor < maxZoomIn and s.getZ() - zoomFactor < maxZoomIn: self.viewNP.setScale(s.getX() + zoomFactor, s.getY() + zoomFactor, s.getZ() + zoomFactor) else: s = self.viewNP.getScale() if s.getX() - zoomFactor > maxZoomOut and s.getY( ) - zoomFactor > maxZoomOut and s.getZ() - zoomFactor > maxZoomOut: self.viewNP.setScale(s.getX() - zoomFactor, s.getY() - zoomFactor, s.getZ() - zoomFactor) self.nodeMgr.updateConnections() def zoomReset(self): """Set the zoom level back to the default""" self.viewNP.setScale(0.5) self.nodeMgr.updateConnections() # ------------------------------------------------------------------ # DRAG LINE # ------------------------------------------------------------------ def startLineDrawing(self, startPos): """Start a task that will draw a line from the given start position to the cursor""" self.line = LineNodePath(render2d, thickness=2, colorVec=(0.8, 0.8, 0.8, 1)) self.line.moveTo(startPos) t = self.taskMgr.add(self.drawLineTask, "drawLineTask") t.startPos = startPos def drawLineTask(self, task): """Draws a line from a given start position to the cursor""" mwn = base.mouseWatcherNode if mwn.hasMouse(): pos = Point3(mwn.getMouse()[0], 0, mwn.getMouse()[1]) self.line.reset() self.line.moveTo(task.startPos) self.line.drawTo(pos) self.line.create() return task.cont def stopLineDrawing(self): """Stop the task that draws a line to the cursor""" taskMgr.remove("drawLineTask") if self.line is not None: self.line.reset() self.line = None # ------------------------------------------------------------------ # EDITOR NODE DRAGGING UPDATE # ------------------------------------------------------------------ def setDraggedNode(self, node): """This will set the node that is currently dragged around as well as update other selected nodes which will be moved in addition to the main dragged node""" self.draggedNode = node self.tempNodePositions = {} for node in self.nodeMgr.selectedNodes: self.tempNodePositions[node] = node.frame.getPos(render2d) def updateNodeMove(self, mouseA, mouseB): """Will be called as long as a node is beeing dragged around""" for node in self.nodeMgr.selectedNodes: if node is not self.draggedNode and node in self.tempNodePositions.keys( ): editVec = Vec3(self.tempNodePositions[node] - mouseA) newPos = mouseB + editVec node.frame.setPos(render2d, newPos) self.nodeMgr.updateConnections() def updateNodeStop(self, node=None): """Will be called when a node dragging stopped""" self.draggedNode = None self.tempNodePositions = {} self.nodeMgr.updateConnections() # ------------------------------------------------------------------ # BASIC WINDOW HANDLING # ------------------------------------------------------------------ def windowEventHandler(self, window=None): """Custom handler for window events. We mostly use this for resizing.""" # call showBase windowEvent which would otherwise get overridden and breaking the app self.windowEvent(window) if window != self.win: # This event isn't about our window. return if window is not None: # window is none if panda3d is not started if self.screenSize == base.getSize(): return self.screenSize = base.getSize() # Resize all editor frames self.menuBar.resizeFrame() # ------------------------------------------------------------------ # SELECTION BOX # ------------------------------------------------------------------ def startBoxDraw(self): """Start drawing the box""" if self.mouseWatcherNode.hasMouse(): # get the mouse position self.startPos = LPoint2f(self.mouseWatcherNode.getMouse()) taskMgr.add(self.dragBoxDrawTask, "dragBoxDrawTask") def stopBoxDraw(self): """Stop the draw box task and remove the box""" if not taskMgr.hasTaskNamed("dragBoxDrawTask"): return taskMgr.remove("dragBoxDrawTask") if self.startPos is None or self.lastPos is None: return self.nodeMgr.deselectAll() if self.box is not None: for node in self.nodeMgr.getAllNodes(): # store some view scales for calculations viewXScale = self.viewNP.getScale().getX() viewZScale = self.viewNP.getScale().getZ() # calculate the node edges nodeLeft = node.getLeft() * viewXScale nodeRight = node.getRight() * viewXScale nodeBottom = node.getBottom() * viewZScale nodeTop = node.getTop() * viewZScale # calculate bounding box edges left = min(self.lastPos.getX(), self.startPos.getX()) right = max(self.lastPos.getX(), self.startPos.getX()) top = max(self.lastPos.getY(), self.startPos.getY()) bottom = min(self.lastPos.getY(), self.startPos.getY()) # check for hits xGood = yGood = False if left < nodeLeft and right > nodeLeft: xGood = True elif left < nodeRight and right > nodeRight: xGood = True if top > nodeTop and bottom < nodeTop: yGood = True elif top > nodeBottom and bottom < nodeBottom: yGood = True # check if we have any hits if xGood and yGood: self.nodeMgr.selectNode(node, True, True) # Cleanup the selection box self.box.removeNode() self.startPos = None self.lastPos = None def dragBoxDrawTask(self, task): """This task will track the mouse position and actualize the box's size according to the first click position of the mouse""" if self.mouseWatcherNode.hasMouse(): if self.startPos is None: self.startPos = LPoint2f(self.mouseWatcherNode.getMouse()) # get the current mouse position self.lastPos = LPoint2f(self.mouseWatcherNode.getMouse()) else: return task.cont # check if we already have a box if self.box != None: # if so, remove that old box self.box.removeNode() # set the box's size self.boxCardMaker.setFrame(self.lastPos.getX(), self.startPos.getX(), self.startPos.getY(), self.lastPos.getY()) # generate, setup and draw the box node = self.boxCardMaker.generate() self.box = render2d.attachNewNode(node) self.box.setBin("gui-popup", 25) self.box.setTransparency(TransparencyAttrib.M_alpha) # run until the task is manually stopped return task.cont
class Fisherman(Toon.Toon): numFishTypes = 3 def __init__(self, id, toNpcId=20001, fAutonomous=1): # Default NPC ID is Flippy Toon.Toon.__init__(self) self.id = id self.fAutonomous = fAutonomous npcInfo = NPCToons.NPCToonDict[toNpcId] dnaList = npcInfo[2] gender = npcInfo[3] dna = ToonDNA.ToonDNA() dna.newToonFromProperties(*dnaList) self.setDNA(dna) self.reparentTo(render) self.angleNP = self.find('**/actorGeom') # Create pole self.pole = Actor.Actor() self.pole.loadModel('phase_4/models/props/fishing-pole-mod') self.pole.loadAnims({'cast': 'phase_4/models/props/fishing-pole-chan'}) # Get the top of the pole. self.ptop = self.pole.find('**/joint_attachBill') self.pole.pose('cast', 0) # Prepare Pole self.poleNode = [] self.holdPole() self.createCastTrack() self.castIval = None # Prepare actor self.setupNeutralBlend() self.targetInterval = None # Start automatic casting or create cast button if self.fAutonomous: self.castButton = None self.targetButton = None self.startCasting() else: # Starts casting mode when mouse enters button region self.castButton = DirectButton(text='CAST', relief=None, scale=0.1, pos=(0, 0, -0.2)) self.castButton.bind(DGG.ENTER, self.showCancelFrame) # A big screen encompassing frame to catch the button releases self.cancelFrame = DirectFrame(parent=self.castButton, frameSize=(-1, 1, -1, 1), relief=None, state='normal') # Make sure this is on top of all the other widgets self.cancelFrame.setBin('gui-popup', 0) self.cancelFrame.bind(DGG.B1PRESS, self.startAdjustingCastTask) self.cancelFrame.bind(DGG.B1RELEASE, self.finishCast) self.cancelFrame.hide() # Create bob self.bob = loader.loadModel('phase_4/models/props/fishing_bob') self.bobSpot = Point3(0) # Parameters to control bob motion self.vZeroMax = 30.0 self.angleMax = 30.0 # Ripple effect self.ripples = Ripples.Ripples(self.angleNP) self.ripples.hide() # Target self.buttonFrame = DirectFrame() self.target = base.distributedFishingTarget.fishingTargetNode self.fishPivot = self.attachNewNode('fishPivot') self.fish = loader.loadModel('models/misc/smiley') self.fish.reparentTo(self.fishPivot) self.fish.setScale(0.3, 1, 0.3) self.wiggleIval = None self.circleIval = None self.initFish() self.targetButton = DirectButton(parent=self.buttonFrame, text='MOVE', relief=DGG.RAISED, scale=0.1, pos=(0, 0, -0.9), command=self.moveTarget) self.targetTypeButton = DirectCheckButton(parent=self.buttonFrame, text='MOVING', relief=DGG.RAISED, scale=0.085, pos=(0.4, 0, -0.895), command=self.setfMove) self.fMovingTarget = 0 self.targetModeButton = DirectCheckButton( parent=self.buttonFrame, text='dTASK', relief=DGG.RAISED, scale=0.085, pos=(0.8, 0, -0.895), command=self.setfTargetMode) self.fTargetMode = 0 # Vector line self.line = LineNodePath(render2d) self.line.setColor(VBase4(1, 0, 0, 1)) self.line.moveTo(0, 0, 0) self.line.drawTo(1, 0, 0) self.line.create() self.moveTarget() def showCancelFrame(self, event): # Also display cancel frame to catch clicks outside of the popup self.cancelFrame.show() def startAdjustingCastTask(self, event): # Start task to adjust power of cast self.getMouse() self.initMouseX = self.mouseX self.initMouseY = self.mouseY self.initMouseX = 0 self.initMouseY = -0.2 self.line.lineSegs.setVertex(0, self.initMouseX, 0, self.initMouseY) self.angleNP.setH(0) self.__hideBob() taskMgr.remove('distCheck') # Position and scale cancel frame to fill entire window self.cancelFrame.setPos(render2d, 0, 0, 0) self.cancelFrame.setScale(render2d, 1, 1, 1) self.castTrack.finish() self.castTrack.setT(0) self.castTrack.start(startT=0, endT=0.4) self.castIval = Sequence( Wait(0.4), Func(taskMgr.add, self.adjustingCastTask, 'adjustCastTask')) self.castIval.start() def adjustingCastTask(self, state): self.getMouse() deltaX = self.mouseX - self.initMouseX deltaY = self.mouseY - self.initMouseY self.line.lineSegs.setVertex(1, self.mouseX, 0, self.mouseY) dist = math.sqrt(deltaX * deltaX + deltaY * deltaY) delta = (dist / 0.5) if deltaY > 0: delta *= -1 p = max(min(delta, 1.0), 0.0) self.power = p self.castTrack.setT(0.4 + p * 0.5) self.bobSpot = Point3(0, 6.5 + p * 25.0, -1.9) # Calc angle if deltaY == 0: angle = 0 else: angle = rad2Deg(math.atan(deltaX / deltaY)) self.angleNP.setH(-angle) return Task.cont def stopAdjustingCastTask(self): taskMgr.remove('adjustingTask') def setupNeutralBlend(self): self.stop() self.loop('neutral') self.enableBlend() self.pose('cast', 0) self.setControlEffect('neutral', 0.2) self.setControlEffect('cast', 0.8) def startCasting(self): if self.fAutonomous: self.castIval = Sequence( ActorInterval(self, 'cast'), Func(self.catchFish), Parallel( ActorInterval(self, 'neutral', loop=1, duration=100), Sequence( Wait(random.random() * 20.0), Func(self.startCasting), ))) else: self.castIval = Sequence( ActorInterval(self, 'cast'), Func(self.catchFish), ActorInterval(self, 'neutral', loop=1, duration=100)) self.castIval.play() def stopCasting(self): if self.castIval: self.castIval.pause() if self.targetInterval: self.stopTargetInterval() taskMgr.remove('distCheck') def catchFish(self): fishNum = int(round(random.random() * self.numFishTypes)) messenger.send('caughtFish', sentArgs=[self.id, fishNum]) def setupNeutralBlend(self): self.stop() self.loop('neutral') self.enableBlend() self.pose('cast', 0) self.setControlEffect('neutral', 0.2) self.setControlEffect('cast', 0.8) def getPole(self): toonTrack = Sequence( # Blend in neutral anim Func(self.setupNeutralBlend), # Pull out pole Func(self.holdPole), Parallel( ActorInterval(self, 'cast', playRate=0.5, duration=27. / 12.), ActorInterval(self.pole, 'cast', playRate=0.5, duration=27. / 12.), LerpScaleInterval(self.pole, duration=2.0, scale=1.0, startScale=0.01)), ) toonTrack.play() def putAwayPole(self): Sequence( Parallel( ActorInterval(self, 'cast', duration=1.0, startTime=1.0, endTime=0.0), ActorInterval(self.pole, 'cast', duration=1.0, startTime=1.0, endTime=0.0), LerpScaleInterval(self.pole, duration=0.5, scale=0.01, startScale=1.0)), Func(self.dropPole)).start() def holdPole(self): if self.poleNode != []: self.dropPole() # One node, instanced to each of the toon's three right hands, # will hold the pole. np = NodePath('pole-holder') hands = self.getRightHands() for h in hands: self.poleNode.append(np.instanceTo(h)) self.pole.reparentTo(self.poleNode[0]) def dropPole(self): self.__hideBob() #self.__hideLine() if self.pole != None: self.pole.clearMat() self.pole.detachNode() for pn in self.poleNode: pn.removeNode() self.poleNode = [] def createCastTrack(self): self.castTrack = Sequence( Parallel( ActorInterval(self, 'cast', duration=2.0, startTime=1.0), ActorInterval(self.pole, 'cast', duration=2.0, startTime=1.0), )) def cast(self): self.castTrack.start() def finishCast(self, event=None): #self.line.lineSegs.setVertex(1,self.initMouseX,0,self.initMouseY) self.cancelFrame.hide() if not self.castTrack: self.createCastTrack() self.castIval.finish() taskMgr.remove('adjustCastTask') taskMgr.remove('moveBobTask') self.castTrack.pause() #self.castTrack.start(self.castTrack.getT()) p = self.power startT = 0.9 + (1 - p) * 0.3 self.castTrack.start(startT) self.bobStartPos = Point3(0.017568, 7.90371, 6.489) Sequence(Wait(1.2 - startT), Func(self.startMoveBobTask)).start() def startMoveBobTask(self): self.__showBob() self.bobStartT = globalClock.getFrameTime() taskMgr.add(self.moveBobTask, 'moveBobTask') def moveBobTask(self, state): # Accel due to gravity g = 32.2 # Elapsed time of cast t = globalClock.getFrameTime() - self.bobStartT # Scale bob velocity and angle based on power of cast vZero = self.power * self.vZeroMax angle = deg2Rad(self.power * self.angleMax) # How far has bob moved from start point? deltaY = vZero * math.cos(angle) * t deltaZ = vZero * math.sin(angle) * t - (g * t * t) / 2.0 deltaPos = Point3(0, deltaY, deltaZ) # Current bob position pos = self.bobStartPos + deltaPos # Have we reached end condition? if pos[2] < -1.9: pos.setZ(-1.9) self.ripples.reparentTo(self.angleNP) self.ripples.setPos(pos) self.ripples.play() returnVal = Task.done if self.fTargetMode: taskMgr.add(self.distCheck, 'distCheck') else: self.distCheck() else: returnVal = Task.cont self.bob.setPos(pos) return returnVal def distCheck(self, state=None): # Check to see if we hit the target bPos = self.bob.getPos() # Check target returnVal = self.__distCheck(bPos, self.target) if returnVal == Task.done: return returnVal # Check fish return self.__distCheck(bPos, self.fish) def __distCheck(self, bPos, target): def flashTarget(): self.stopTargetInterval() self.target.getChild(0).setColor(0, 0, 1) def flashFish(): taskMgr.remove('turnTask') self.fish.lerpScale(Point3(0.01), 0.5, task='flashFish') tPos = target.getPos(self.angleNP) tDist = Vec3(tPos - bPos) tDist.setZ(0) dist = tDist.length() if target == self.target: flashFunc = flashTarget moveFunc = self.moveTarget else: flashFunc = flashFish moveFunc = self.turnFish if dist < 2.5: fBite = (random.random() < 0.4) or (not self.fTargetMode) delay = self.fTargetMode * 0.25 if fBite: print('BITE') Sequence( Wait(random.random() * delay), Func(flashFunc), Func(self.catchFish), Wait(2.0), Func(moveFunc), ).play() else: print('MISS') def moveIt(): moveFunc(targetPos=target.getPos()) Sequence(Wait(random.random() * delay), Func(moveIt)).play() return Task.done return Task.cont def stopTargetInterval(self): if self.targetInterval: self.targetInterval.pause() self.targetInterval = None def __showBob(self): # Put the bob in the water and make it gently float. self.__hideBob() self.bob.reparentTo(self.angleNP) self.bob.setPos(self.ptop, 0, 0, 0) def __hideBob(self): if self.bob != None: self.bob.detachNode() def getMouse(self): if (base.mouseWatcherNode.hasMouse()): self.mouseX = base.mouseWatcherNode.getMouseX() self.mouseY = base.mouseWatcherNode.getMouseY() else: self.mouseX = 0 self.mouseY = 0 def setfMove(self, fMoving): self.fMovingTarget = fMoving def setfTargetMode(self, fTargetMode): self.fTargetMode = fTargetMode def moveTarget(self, targetPos=None): base.distributedFishingTarget.sendUpdate('bobEnter', []) # self.stopTargetInterval() # self.target.clearColor() # if not targetPos: # x = -87.0 + random.random() * 15.0 # y = 25.0 + random.random() * 20.0 # z = -4.8 # self.targetPos = Point3(x,y,z) # else: # self.targetPos.assign(targetPos) # if self.fMovingTarget: # self.makeTargetInterval() # else: # #self.target.setPos(self.targetPos) def initFish(self): x = -10.0 + random.random() * 20.0 y = 00.0 + random.random() * 30.0 z = -1.6 self.fishPivot.setPos(x, y, z) self.turningRadius = 5.0 + random.random() * 5.0 self.fish.setPos(self.turningRadius, 0, -0.4) if self.wiggleIval: self.wiggleIval.pause() self.wiggleIval = Sequence( self.fish.hprInterval(0.5, hpr=Point3(10, 0, 0), startHpr=Point3(-10, 0, 0), blendType='easeInOut'), self.fish.hprInterval(0.5, hpr=Point3(-10, 0, 0), startHpr=Point3(10, 0, 0), blendType='easeInOut')) self.wiggleIval.loop() if self.circleIval: self.circleIval.pause() self.circleIval = self.fishPivot.hprInterval(20, Point3(360, 0, 0), startHpr=Point3(0)) self.circleIval.loop() taskMgr.remove('turnTask') taskMgr.doMethodLater(3.0 + random.random() * 3.0, self.turnFish, 'turnTask') taskMgr.remove('fishBoundsCheck') taskMgr.add(self.fishBoundsCheck, 'fishBoundsCheck') def fishBoundsCheck(self, state): pos = self.fish.getPos(self) if pos[0] < -20: self.fishPivot.setX(self.fishPivot.getX() + 40.0) elif pos[0] > 20: self.fishPivot.setX(self.fishPivot.getX() - 40.0) if pos[1] < -10: self.fishPivot.setY(self.fishPivot.getY() + 50.0) elif pos[1] > 40: self.fishPivot.setY(self.fishPivot.getY() - 50.0) return Task.cont def turnFish(self, state=None, targetPos=None): self.fish.setScale(0.3, 1, 0.3) if self.circleIval: self.circleIval.pause() newTurningRadius = 5.0 + random.random() * 5.0 fRightTurn = random.random() < 0.5 if fRightTurn: newTurningRadius *= -1.0 offset = self.turningRadius - newTurningRadius self.fishPivot.setX(self.fishPivot, offset) self.turningRadius = newTurningRadius self.fish.setX(self.turningRadius) currH = self.fishPivot.getH() % 360.0 if fRightTurn: self.circleIval = self.fishPivot.hprInterval( 20, Point3(currH - 360, 0, 0), startHpr=Point3(currH, 0, 0)) else: self.circleIval = self.fishPivot.hprInterval( 20, Point3(currH + 360, 0, 0), startHpr=Point3(currH, 0, 0)) self.circleIval.loop() taskMgr.doMethodLater(3.0 + random.random() * 3.0, self.turnFish, 'turnTask') return Task.done def makeTargetInterval(self): x = -10.0 + random.random() * 20.0 y = 0.0 + random.random() * 30.0 z = -1.6 self.targetEndPos = Point3(x, y, z) dist = Vec3(self.targetEndPos - self.targetPos).length() dur = dist / 1.5 dur = dur * (0.75 + random.random() * 0.5) self.targetInterval = Sequence( self.target.posInterval(dur, self.targetEndPos, startPos=self.targetPos, blendType='easeInOut'), self.target.posInterval(dur, self.targetPos, startPos=self.targetEndPos, blendType='easeInOut'), name='moveInterval') offsetDur = dur / random.randint(1, 4) amplitude = 0.1 + random.random() * 1.0 self.targetInterval.loop() def destroy(self): if not self.fAutonomous: self.castButton.destroy() self.buttonFrame.destroy() self.line.removeNode() taskMgr.remove('turnTask') taskMgr.remove('fishBoundsCheck') self.stopCasting() self.removeNode()
def draw_grid(self): raws1unit = 20 rawsHALFunit = 100 X1 = 10 X2 = -10 Y1 = 10 Y2 = -10 linesX = LineNodePath(self.render, 'lines1', 2, Vec4(.3, .3, .3, 0)) linesXXX = LineNodePath(self.render, 'lines1', .4, Vec4(.35, .35, .35, 0)) axis = LineNodePath(self.render, 'axis', 4, Vec4(.2, .2, .2, 0)) quad = LineNodePath(self.render, 'quad', 4, Vec4(.2, .2, .2, 0)) x1 = (0, Y2, 0) x2 = (0, Y1, 0) x3 = (X2, 0, 0) x4 = (X1, 0, 0) axis.drawLines([[x1, x2], [x3, x4]]) axis.create() q1 = (X1, Y1, 0) q2 = (X1, Y2, 0) q3 = (q2) q4 = (X2, Y2, 0) q5 = (q4) q6 = (X2, Y1, 0) q7 = (q6) q8 = (X1, Y1, 0) quad.drawLines([[q1, q2], [q3, q4], [q5, q6], [q7, q8]]) quad.create() gfOutput = [1] d = 0 for l in range(raws1unit - 1): lO = len(gfOutput) lO1 = lO - 1 global field field1 = gfOutput[lO1] field = float(field1) print(field) d += field l1 = (X2 + d, Y1, 0) l2 = (X2 + d, Y2, 0) l3 = (X2, Y1 - d, 0) l4 = (X1, Y1 - d, 0) linesX.drawLines([[l1, l2], [l3, l4]]) linesX.create()
def __init__(self, id, toNpcId=20001, fAutonomous=1): # Default NPC ID is Flippy Toon.Toon.__init__(self) self.id = id self.fAutonomous = fAutonomous npcInfo = NPCToons.NPCToonDict[toNpcId] dnaList = npcInfo[2] gender = npcInfo[3] dna = ToonDNA.ToonDNA() dna.newToonFromProperties(*dnaList) self.setDNA(dna) self.reparentTo(render) self.angleNP = self.find('**/actorGeom') # Create pole self.pole = Actor.Actor() self.pole.loadModel('phase_4/models/props/fishing-pole-mod') self.pole.loadAnims({'cast': 'phase_4/models/props/fishing-pole-chan'}) # Get the top of the pole. self.ptop = self.pole.find('**/joint_attachBill') self.pole.pose('cast', 0) # Prepare Pole self.poleNode = [] self.holdPole() self.createCastTrack() self.castIval = None # Prepare actor self.setupNeutralBlend() self.targetInterval = None # Start automatic casting or create cast button if self.fAutonomous: self.castButton = None self.targetButton = None self.startCasting() else: # Starts casting mode when mouse enters button region self.castButton = DirectButton(text='CAST', relief=None, scale=0.1, pos=(0, 0, -0.2)) self.castButton.bind(DGG.ENTER, self.showCancelFrame) # A big screen encompassing frame to catch the button releases self.cancelFrame = DirectFrame(parent=self.castButton, frameSize=(-1, 1, -1, 1), relief=None, state='normal') # Make sure this is on top of all the other widgets self.cancelFrame.setBin('gui-popup', 0) self.cancelFrame.bind(DGG.B1PRESS, self.startAdjustingCastTask) self.cancelFrame.bind(DGG.B1RELEASE, self.finishCast) self.cancelFrame.hide() # Create bob self.bob = loader.loadModel('phase_4/models/props/fishing_bob') self.bobSpot = Point3(0) # Parameters to control bob motion self.vZeroMax = 30.0 self.angleMax = 30.0 # Ripple effect self.ripples = Ripples.Ripples(self.angleNP) self.ripples.hide() # Target self.buttonFrame = DirectFrame() self.target = base.distributedFishingTarget.fishingTargetNode self.fishPivot = self.attachNewNode('fishPivot') self.fish = loader.loadModel('models/misc/smiley') self.fish.reparentTo(self.fishPivot) self.fish.setScale(0.3, 1, 0.3) self.wiggleIval = None self.circleIval = None self.initFish() self.targetButton = DirectButton(parent=self.buttonFrame, text='MOVE', relief=DGG.RAISED, scale=0.1, pos=(0, 0, -0.9), command=self.moveTarget) self.targetTypeButton = DirectCheckButton(parent=self.buttonFrame, text='MOVING', relief=DGG.RAISED, scale=0.085, pos=(0.4, 0, -0.895), command=self.setfMove) self.fMovingTarget = 0 self.targetModeButton = DirectCheckButton( parent=self.buttonFrame, text='dTASK', relief=DGG.RAISED, scale=0.085, pos=(0.8, 0, -0.895), command=self.setfTargetMode) self.fTargetMode = 0 # Vector line self.line = LineNodePath(render2d) self.line.setColor(VBase4(1, 0, 0, 1)) self.line.moveTo(0, 0, 0) self.line.drawTo(1, 0, 0) self.line.create() self.moveTarget()
from direct.gui.DirectGui import * from pandac.PandaModules import * from direct.directtools.DirectGeometry import LineNodePath from direct.gui.OnscreenText import OnscreenText import buttonsGRID global output output = [1] textObject = OnscreenText(text="gridUNITS", pos=(-1.23, .94), scale=0.04, fg=(0, 0, 0, .8)) textObject.setTransparency(TransparencyAttrib.MAlpha) line = LineNodePath(render2d, 'line', 2, Vec4(.3, .3, .3, 0)) line.drawLines([[(-.76, 0, 1), (-.76, 0, -1)]]) line.create() def react(input): output.append(input) print output def clear(): gU.enterText('') gU = DirectEntry(text="",
def __init__(self, width=6.78, length=5.82, simulation=True, video=True): ShowBase.__init__(self) width *= 100 length *= 100 self.room_dimentions = [width, length] self.simulation = simulation self.wall1 = self.wall_model(0, 0, 0, width, 0) self.wall2 = self.wall_model(0, 0, 0, length, 90) self.wall3 = self.wall_model(width, length, 0, width, 180) self.wall4 = self.wall_model(width, length, 0, length, -90) self.root_3d = self.marker_model(position=[0., 0., 0.], orientation=[90, 90, 0]) self.drone = self.drone_model() self.drone_instance = Drone(simulation=simulation, video=video) self.lx_drone = LineNodePath(self.render2d, 'box', 2) self.lx_drone.reparentTo(self.drone) self.lx_drone.setColor(1., 0., 0., 1.) self.lx_drone.setTransparency(TransparencyAttrib.MAlpha) self.lx_drone.setAlphaScale(0.5) self.lx_drone.drawLines([[(0., 0., 0.), (4., 0., 0.)]]) self.lx_drone.create() self.ly_drone = LineNodePath(self.render2d, 'box', 2) self.ly_drone.reparentTo(self.drone) self.ly_drone.setColor(0., 1., 0., 1.) self.ly_drone.setTransparency(TransparencyAttrib.MAlpha) self.ly_drone.setAlphaScale(0.5) self.ly_drone.drawLines([[(0., 0., 0.), (0., 0., 4.)]]) self.ly_drone.create() self.lz_drone = LineNodePath(self.render2d, 'box', 2) self.lz_drone.reparentTo(self.drone) self.lz_drone.setColor(0., 0., 1., 1.) self.lz_drone.setTransparency(TransparencyAttrib.MAlpha) self.lz_drone.setAlphaScale(0.5) self.lz_drone.drawLines([[(0., 0., 0.), (0., 4., 0.)]]) self.lz_drone.create() try: self.joy = xbox.Joystick() joy_ready = False if not self.joy.A(): joy_ready = True if not joy_ready: raise Exception("Joy not ready!") else: print("ready") except: pass # Add the spinCameraTask procedure to the task manager. self.tick_loop = self.taskMgr.add(self.tick, "tick_loop") self.accept("space", self.control_drone, [" "]) self.accept("c", self.control_drone, ["c"]) self.accept("x", self.control_drone, ["x"]) self.accept("w", self.control_drone, ["w"]) self.accept("a", self.control_drone, ["a"]) self.accept("s", self.control_drone, ["s"]) self.accept("d", self.control_drone, ["d"]) self.accept("q", self.control_drone, ["q"]) self.accept("e", self.control_drone, ["e"]) self.accept("m", self.control_drone, ["m"]) self.accept("r", self.control_drone, ["r"]) self.accept("f", self.control_drone, ["f"]) self.keypress_repeat("4", self.move_camera, ["x", -1]) self.keypress_repeat("6", self.move_camera, ["x", 1]) self.keypress_repeat("8", self.move_camera, ["y", 1]) self.keypress_repeat("5", self.move_camera, ["y", -1]) self.keypress_repeat("1", self.move_camera, ["z", 1]) self.keypress_repeat("3", self.move_camera, ["z", -1]) self.keypress_repeat("7", self.move_camera, ["h", -1]) self.keypress_repeat("9", self.move_camera, ["h", 1]) self.keypress_repeat("arrow_up", self.move_camera, ["p", 1]) self.keypress_repeat("arrow_down", self.move_camera, ["p", -1])
def drawAxis(self, root, origin): PX = origin[0] PY = origin[1] PZ = origin[2] lengthX = PX + 1.5 lengthY = PY + 1.5 lengthZ = PZ + 1.5 q1 = PX + 0.5 q2 = -q1 arrowLENGHT = PX + 0.2 arrowXx1 = PY + 0.08 arrowXx2 = PY - 0.08 arrowXz2 = PX + 1.3 arrowYx1 = PX + 0.08 arrowYx2 = PX - 0.08 arrowYz2 = PY + 1.3 arrowZx1 = PX + 0.08 arrowZx2 = PX - 0.08 arrowZz2 = PZ + 1.3 PIVarX = LineNodePath(root, "pivotX", 3, Vec4(1, 0, 0, 1)) PIVarY = LineNodePath(root, "pivotY", 3, Vec4(0, 1, 1, 1)) PIVarZ = LineNodePath(root, "pivotZ", 3, Vec4(1, 1, 0, 1)) PIVOThandler = LineNodePath(root, "handler", 2, Vec4(1, 0, 1, 1)) PIVarX.reparentTo(PIVOThandler) PIVarY.reparentTo(PIVOThandler) PIVarZ.reparentTo(PIVOThandler) arrowX1 = (lengthX, PY, PZ) arrowX2 = (arrowXz2, arrowXx1, PZ) arrowX3 = (arrowXz2, arrowXx2, PZ) arrowY1 = (PX, lengthY, PZ) arrowY2 = (arrowYx1, arrowYz2, PZ) arrowY3 = (arrowYx2, arrowYz2, PZ) arrowZ1 = (PX, PY, lengthZ) arrowZ2 = (arrowZx1, PY, arrowZz2) arrowZ3 = (arrowZx2, PY, arrowZz2) PIVarX.drawLines([[(PX, PY, PZ), (lengthX, PY, PZ)], [arrowX1, arrowX2], [arrowX1, arrowX3]]) PIVarY.drawLines([[(PX, PY, PZ), (PX, lengthY, PZ)], [arrowY1, arrowY2], [arrowY1, arrowY3]]) PIVarZ.drawLines([[(PX, PY, PZ), (PX, PY, lengthZ)], [arrowZ1, arrowZ2], [arrowZ1, arrowZ3]]) PIVOThandler.drawLines( [ [(PX, PY, PZ), (PX + 0.5, PY, PZ)], [(PX + 0.5, PY, PZ), (PX, PY + 0.5, PZ)], [(PX, PY + 0.5, PZ), (PX, PY, PZ)], ] ) PIVarX.create() PIVarY.create() PIVarZ.create() PIVOThandler.create() return PIVOThandler
def setup(self): self.attemptText.show() self.levelText.show() self.scoreText.show() self.text.show() self.worldNP = render.attachNewNode('World') # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) self.debugNP.show() self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setDebugNode(self.debugNP.node()) #arrow self.scaleY = 10 self.arrow = loader.loadModel('models/arrow.X') self.arrow.setScale(0.5,0.5,0.5) self.arrow.setAlphaScale(0.5) #self.arrow.setTransparency(TransparencyAttrib.MAlpha) self.arrow.reparentTo(render) #SkyBox skybox = loader.loadModel('models/skybox.X') skybox.reparentTo(render) # Ground shape = BulletPlaneShape(Vec3(0, 0, 1), 0) np = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground')) np.node().addShape(shape) np.setPos(0, 0, -1) np.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(np.node()) visualNP = loader.loadModel('models/ground.X') visualNP.clearModelNodes() visualNP.reparentTo(np) #some boxes self.boxes = [] self.snowmans = [] self.platforms = [] self.presents = [] #TODO: Make a table #Table Top #self.createBox(Vec3(),Vec3()) if(self.gameLevel == 1): self.createBox(Vec3(5,7,1),Vec3(0,5,10),1.0) #2 legs self.createBox(Vec3(4,1,4),Vec3(0,11,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-1,5),1.0) # Pigs self.createSnowman(2.0,Vec3(0, 5, 2.0),10.0) self.createSnowman(1.5, Vec3(0,-10,4.0),10.0) if(self.gameLevel == 2): #table01 self.createBox(Vec3(5,14,1),Vec3(0,-2,12),2.0) self.createBox(Vec3(5,7,1),Vec3(0,5,10),2.0) self.createBox(Vec3(4,1,4),Vec3(0,11,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-1,5),1.0) #table02 self.createBox(Vec3(5,7,1),Vec3(0,-9,10),2.0) self.createBox(Vec3(4,1,4),Vec3(0,-3,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-15,5),1.0) #table03 self.createBox(Vec3(1,1,1), Vec3(0,-1,14), 2.0) self.createBox(Vec3(1,1,1), Vec3(0,-3,14), 2.0) self.createBox(Vec3(1,1,1), Vec3(0,3,14), 2.0) self.createBox(Vec3(1,1,1), Vec3(0,-5,14), 2.0) self.createBox(Vec3(1,1,1), Vec3(0,5,14), 2.0) #pigs self.createSnowman(2.0,Vec3(0, 5, 2.0),10.0) self.createSnowman(2.0, Vec3(0,-9,2.0), 10.0) self.createSnowman(2.0,Vec3(0,-23,2.0),10.0) if(self.gameLevel == 3): #table01 self.createBox(Vec3(4,2,2),Vec3(0,12,12),1.0) self.createBox(Vec3(4,1,4),Vec3(0,11,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,13,5),1.0) #table02 self.createBox(Vec3(4,2,2),Vec3(0,-15,12),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-14,5),1.0) self.createBox(Vec3(4,1,4),Vec3(0,-16,5),1.0) #table03 self.createBox(Vec3(4,10,1),Vec3(0,-1,12),1.0) self.createBox(Vec3(4,10,1),Vec3(0,-1,14),1.0) self.createBox(Vec3(4,2,4),Vec3(0,-2,5),0.1) #table04 self.createPlatform(Vec3(4,8,1),Vec3(0,7,16),1.0) self.createPlatform(Vec3(4,8,1),Vec3(0,-9,16),1.0) self.createBox(Vec3(4,1,3),Vec3(0,13,20),1.0) self.createBox(Vec3(4,1,3),Vec3(0,-16,20),1.0) #table05 self.createBox(Vec3(4,15,1),Vec3(0,-1,24),1.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,2,20),5.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,-2,20),5.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,4,20),5.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,8,20),5.0) self.createStoneBox(Vec3(1,1,1),Vec3(0,6,20),5.0) #pigs self.createSnowman(2.0,Vec3(0, 5, 2.0),10.0) self.createSnowman(2.0,Vec3(0,-8.5,2.0),10.0) self.createSnowman(1.5, Vec3(0,-9,19.5), 7.0) #presents self.createPresent(Vec3(2,2,2),Vec3(0,-20,5)) if(self.gameLevel == 4): #wall self.createStoneBox(Vec3(4,1.5,10), Vec3(0,20,10),20) #table01 self.createBox(Vec3(4,1,5), Vec3(0,7,7),1) self.createBox(Vec3(4,1,5), Vec3(0,0,7),1) self.createBox(Vec3(4,1,4), Vec3(0,3,7),1) self.createPlatform(Vec3(5,8,1), Vec3(0,4,13),1) self.createBox(Vec3(4,1,3), Vec3(0,11,18),1) self.createBox(Vec3(4,1,3), Vec3(0,-3,18),1) self.createBox(Vec3(4,8,1), Vec3(0,4,25),1) self.createStoneBox(Vec3(1,1,1), Vec3(0,4,27),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,7,27),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,2,27),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,2,29),2) #stairs self.createPlatform(Vec3(4,50,4), Vec3(0,-55,5),100) #table02 self.createBox(Vec3(4,1,5), Vec3(0,-13,15),1) self.createBox(Vec3(4,1,5), Vec3(0,-20,15),1) self.createBox(Vec3(4,1,4), Vec3(0,-17,15),1) self.createPlatform(Vec3(4,8,1), Vec3(0,-16,22),1) self.createBox(Vec3(4,1,3), Vec3(0,-9,28),1) self.createBox(Vec3(4,1,3), Vec3(0,-23,28),1) self.createBox(Vec3(4,8,1), Vec3(0,-16,33),1) self.createStoneBox(Vec3(1,1,1), Vec3(0,-16,35),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,-13,35),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,-18,35),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,-18,37),2) self.createStoneBox(Vec3(1,1,1), Vec3(0,-14,37),2) #snowman self.createSnowman(2.0,Vec3(0,30,5),1.0) self.createSnowman(1.5,Vec3(0,4,18),1.0) self.createSnowman(1.5,Vec3(0,-13,26),1.0) self.createSnowman(1.5,Vec3(0,-19,26),1.0) self.createSnowman(2.0,Vec3(0,12,5),1.0) self.createPresent(Vec3(2,2,2),Vec3(0,-25,13)) self.createPresent(Vec3(3,3,3),Vec3(0,-30,13)) self.createPresent(Vec3(4,4,4),Vec3(0,-36,13)) #self.createSnowman(1.5,Vec3(0,4,20),1.0) if(self.gameLevel == 5): #table01 self.createStoneBox(Vec3(4,7,3), Vec3(0,30,5),10.0) self.createStoneBox(Vec3(4,7,3), Vec3(0,-30,5),10.0) self.createBox(Vec3(4,1,3), Vec3(0,0,5), 1.0) self.createSnowman(1.5,Vec3(0,-6,5),1.0) self.createSnowman(1.5,Vec3(0,6,5),1.0) self.createBox(Vec3(4,1,3), Vec3(0,-12,5), 1.0) self.createBox(Vec3(4,1,3), Vec3(0,12,5), 1.0) self.createSnowman(1.5,Vec3(0,-18,5),1.0) self.createSnowman(1.5,Vec3(0,18,5),1.0) self.createStoneBox(Vec3(4,6,1),Vec3(0,-18,10), 0.1) self.createStoneBox(Vec3(4,6,1),Vec3(0,-6,10), 0.1) self.createStoneBox(Vec3(4,6,1),Vec3(0,6,10), 0.1) self.createStoneBox(Vec3(4,6,1),Vec3(0,18,10), 0.1) self.createStoneBox(Vec3(4,1,3),Vec3(0,23,14), 1.0) self.createStoneBox(Vec3(4,1,3),Vec3(0,-23,14), 1.0) self.createBox(Vec3(4,1,3),Vec3(0,18,14),1.0) self.createBox(Vec3(4,1,3),Vec3(0,-18,14),1.0) self.createStoneBox(Vec3(4,1,7),Vec3(0,13,20), 2.0) self.createStoneBox(Vec3(4,1,7),Vec3(0,-13,20), 2.0) self.createBox(Vec3(4,1,3),Vec3(0,8,14),1.0) self.createBox(Vec3(4,1,3),Vec3(0,-8,14),1.0) self.createStoneBox(Vec3(4,1,3),Vec3(0,3,14), 1.0) self.createStoneBox(Vec3(4,1,3),Vec3(0,-3,14), 1.0) self.createPlatform(Vec3(4,3.5,1),Vec3(0,-20 ,20), 1.0) self.createPlatform(Vec3(4,3.5,1),Vec3(0,20 ,20), 1.0) self.createPlatform(Vec3(4,3.5,1),Vec3(0,-5 ,20), 1.0) self.createPlatform(Vec3(4,3.5,1),Vec3(0,5 ,20), 1.0) self.createStoneBox(Vec3(4,1,3.5),Vec3(0,-18,25), 2.0) self.createStoneBox(Vec3(4,1,3.5),Vec3(0,18,25), 2.0) self.createStoneBox(Vec3(4,1,3.5),Vec3(0,-7.5,25), 2.0) self.createStoneBox(Vec3(4,1,3.5),Vec3(0,7.5,25), 2.0) self.createStoneBox(Vec3(4,6,1),Vec3(0,-12,30), 2.0) self.createStoneBox(Vec3(4,6,1),Vec3(0,12,30), 2.0) self.createBox(Vec3(4,1,5),Vec3(0,-5,30), 2.0) self.createBox(Vec3(4,1,5),Vec3(0,5,30), 2.0) self.createBox(Vec3(4,5,1),Vec3(0,0,40), 2.0) self.createPlatform(Vec3(4,2,0.5),Vec3(0,0,42), 2.0) self.createStoneBox(Vec3(4,0.5,2),Vec3(0,-3.5,45), 2.0) self.createStoneBox(Vec3(4,0.5,2),Vec3(0,3.5,45), 2.0) self.createStoneBox(Vec3(4,4,0.5),Vec3(0,0,48), 2.0) self.createPresent(Vec3(1.5,1.5,1.5),Vec3(0,22,30)) self.createPresent(Vec3(1.5,1.5,1.5),Vec3(0,-22,30)) self.createPresent(Vec3(2,2,1),Vec3(0,0,44)) self.createPresent(Vec3(3,3,4),Vec3(0,0,33)) if(self.gameLevel > 5): self.gameState = 'WIN' self.doContinue() return # drawing lines between the points ## self.lines = LineNodePath(parent = render, thickness = 3.0, colorVec = Vec4(1, 0, 0, 1)) ## self.pFrom = Point3(-4, 0, 0.5) ## self.pTo = Point3(4, 0, 0.5) # Aiming line self.lines = LineNodePath(parent = render, thickness = 3.0, colorVec = Vec4(1, 0, 0, 1)) self.pFrom = Point3(0, 100, 0.5) self.pTo = Point3(0, 60, 10) self.arrow.setPos(self.pFrom)
def drawGrid(self): raws1unit = 20 rawsHALFunit = 100 X1 = 10 X2 = -10 Y1 = 10 Y2 = -10 linesX = LineNodePath(render, "lines1", 2, Vec4(0.3, 0.3, 0.3, 0)) linesXXX = LineNodePath(render, "lines1", 0.4, Vec4(0.35, 0.35, 0.35, 0)) axis = LineNodePath(render, "axis", 4, Vec4(0.2, 0.2, 0.2, 0)) quad = LineNodePath(render, "quad", 4, Vec4(0.2, 0.2, 0.2, 0)) x1 = (0, Y2, 0) x2 = (0, Y1, 0) x3 = (X2, 0, 0) x4 = (X1, 0, 0) axis.drawLines([[x1, x2], [x3, x4]]) axis.create() q1 = (X1, Y1, 0) q2 = (X1, Y2, 0) q3 = q2 q4 = (X2, Y2, 0) q5 = q4 q6 = (X2, Y1, 0) q7 = q6 q8 = (X1, Y1, 0) quad.drawLines([[q1, q2], [q3, q4], [q5, q6], [q7, q8]]) quad.create() gfOutput = [1] d = 0 for l in range(raws1unit - 1): lO = len(gfOutput) lO1 = lO - 1 global field field1 = gfOutput[lO1] field = float(field1) print field d += field l1 = (X2 + d, Y1, 0) l2 = (X2 + d, Y2, 0) l3 = (X2, Y1 - d, 0) l4 = (X1, Y1 - d, 0) linesX.drawLines([[l1, l2], [l3, l4]]) linesX.create()
def __init__ (self, world, name, side, pos=None, hpr=None, speed=None, dropvel=None, target=None, offset=None, extvis=True): if pos is None: pos = Vec3() if hpr is None: hpr = Vec3() if speed is None: d1, maxspeed = self.limspeeds(pos[2]) speed = maxspeed if False: # no point checking in every instance... if self.seeker not in Rocket._seekers_all: raise StandardError( "Unknown seeker type '%s' for '%s'." % (self.seeker, self.species)) unknown = set(self.flightmodes).difference(Rocket._flightmodes_all) if unknown: raise StandardError( "Unknown flight mode '%s' for '%s'." % (unknown.pop(), self.species)) if dropvel is not None: vel = hprtovec(hpr) * speed + dropvel else: vel = speed Body.__init__(self, world=world, family=self.family, species=self.species, hitforce=self.hitforce, modeldata=AutoProps( path=self.modelpath, texture=self.texture, normalmap=self.normalmap, glowmap=self.glowmap, glossmap=self.glossmap, scale=self.modelscale, offset=self.modeloffset, rot=self.modelrot), amblit=True, dirlit=True, pntlit=1, fogblend=True, ltrefl=(self.glossmap is not None), name=name, side=side, pos=pos, hpr=hpr, vel=vel) self.ming = -self.maxg if self.engsoundname: self.engine_sound = Sound3D( path=("audio/sounds/%s.ogg" % self.engsoundname), parent=self, limnum="hum", volume=self.engvol, loop=True) self.engine_sound.play() if 1: lnchsnd = Sound3D( "audio/sounds/%s.ogg" % "missile-launch", parent=self, volume=self.launchvol, fadetime=0.1) lnchsnd.play() self.target = target self.offset = offset self.must_hit_expforce = 0.0 self.proximity_fuze_active = True self._last_target = target self.path = None self.pspeed = None self._targeted_offset = (self.offset or (self.target and self.target.center) or Point3()) self._effective_offset = self._targeted_offset self._actdist = min(0.5 * self.minlaunchdist, 1000.0) self._active = False self._armdist = self.minlaunchdist self._armed = False self._state_info_text = None self._wait_time_state_info = 0.0 self._prev_path = None self._path_pos = 0.0 self.exhaust_trails = [] if side == "bstar": trcol = rgba(127, 0, 0, 1) elif side == "nato": trcol = rgba(0, 0, 127, 1) else: trcol = rgba(0, 127, 0, 1) self._trace = None if world.show_traces: self._trace = LineNodePath(parent=self.world.node, thickness=1.0, colorVec=trcol) self._trace_segs = [] self._trace_lens = [] self._trace_len = 0.0 self._trace_maxlen = 5000.0 self._trace_prevpos = pos self._trace_frameskip = 5 self._trace_accuframe = 0 self._flightdist = 0.0 self._flighttime = 0.0 self._updperiod_decoy = 0.053 self._updwait_decoy = 0.0 self._dtime_decoy_process = 0.0 self._eliminated_decoys = set() self._tracked_decoy = None self._no_target_selfdest_time = 1.0 self._no_target_time = 0.0 test_expforce = max(self.expforce * 0.9, self.expforce - 1.0) self._prox_dist = explosion_reach(test_expforce) self.proximity_fuzed = False # debug self.target_hit = False # debug if extvis: bx, by, bz = self.bbox bbox = Vec3(bx, by * 500.0, bz) EnhancedVisual(parent=self, bbox=bbox) self._fudge_player_manoeuver = True if self._fudge_player_manoeuver: self._plmanv_done_1 = False self._plmanv_done_2 = False base.taskMgr.add(self._loop, "rocket-loop-%s" % self.name)
def setup(self): self.worldNP = render.attachNewNode('World') # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) self.debugNP.show() self.debugNP.node().showWireframe(True) self.debugNP.node().showConstraints(True) self.debugNP.node().showBoundingBoxes(False) self.debugNP.node().showNormals(True) #self.debugNP.showTightBounds() #self.debugNP.showBounds() self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.81)) self.world.setDebugNode(self.debugNP.node()) # Ground (static) shape = BulletPlaneShape(Vec3(0, 0, 1), 1) self.groundNP = self.worldNP.attachNewNode( BulletRigidBodyNode('Ground')) self.groundNP.node().addShape(shape) self.groundNP.setPos(0, 0, -2) self.groundNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.groundNP.node()) #Rocket shape = BulletCylinderShape(0.2 * self.scale, 2 * self.scale, ZUp) self.rocketNP = self.worldNP.attachNewNode( BulletRigidBodyNode('Cylinder')) self.rocketNP.node().setMass(3.0) self.rocketNP.node().addShape(shape) self.rocketNP.setPos(0, 0, 2 * self.scale) self.rocketNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.rocketNP.node()) for i in range(4): leg = BulletCylinderShape(0.02 * self.scale, 1 * self.scale, XUp) self.rocketNP.node().addShape( leg, TransformState.makePosHpr( Vec3(0.6 * self.scale * math.cos(i * math.pi / 2), 0.6 * self.scale * math.sin(i * math.pi / 2), -1.2 * self.scale), Vec3(i * 90, 0, 30))) shape = BulletConeShape(0.15 * self.scale, 0.3 * self.scale, ZUp) self.rocketNozzle = self.worldNP.attachNewNode( BulletRigidBodyNode('Cone')) self.rocketNozzle.node().setMass(1) self.rocketNozzle.node().addShape(shape) self.rocketNozzle.setPos(0, 0, 0.8 * self.scale) self.rocketNozzle.setCollideMask(BitMask32.allOn()) self.rocketNozzle.node().setCollisionResponse(0) self.world.attachRigidBody(self.rocketNozzle.node()) frameA = TransformState.makePosHpr(Point3(0, 0, -1 * self.scale), Vec3(0, 0, 90)) frameB = TransformState.makePosHpr(Point3(0, 0, 0.2 * self.scale), Vec3(0, 0, 90)) self.cone = BulletConeTwistConstraint(self.rocketNP.node(), self.rocketNozzle.node(), frameA, frameB) self.cone.enableMotor(1) #self.cone.setMaxMotorImpulse(2) #self.cone.setDamping(1000) self.cone.setDebugDrawSize(2.0) self.cone.setLimit(20, 20, 0, softness=1.0, bias=1.0, relaxation=10.0) self.world.attachConstraint(self.cone) self.npThrustForce = LineNodePath(self.render, 'Thrust', thickness=4, colorVec=VBase4(1, 0.5, 0, 1))
def setup(self): self.targetAlt = r.randrange(100,300) self.Valves = np.array([0.15,0.2,0.15]) self.EngObs = self.vulcain.predict_data_point(np.array(self.Valves).reshape(1,-1)) if self.VISUALIZE is True: self.worldNP = self.render.attachNewNode('World') else: self.root = NodePath(PandaNode("world root")) self.worldNP = self.root.attachNewNode('World') self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.80665)) # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) self.debugNP.node().showWireframe(True) self.debugNP.node().showConstraints(True) self.debugNP.node().showBoundingBoxes(False) self.debugNP.node().showNormals(True) self.debugNP.show() self.world.setDebugNode(self.debugNP.node()) # self.debugNP.showTightBounds() # self.debugNP.showBounds() # Ground (static) shape = BulletPlaneShape(Vec3(0, 0, 1), 1) self.groundNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Ground')) self.groundNP.node().addShape(shape) self.groundNP.setPos(0, 0, 0) self.groundNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.groundNP.node()) # Rocket shape = BulletCylinderShape(self.radius, self.length, ZUp) self.rocketNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Cylinder')) self.rocketNP.node().setMass(27200 * self.scale) self.rocketNP.node().addShape(shape) #self.rocketNP.setPos(20,20,250) self.rocketNP.setPos(20, 20, r.randrange(100, 300)+200) #self.rocketNP.setPos(r.randrange(-self.lateralError, self.lateralError, 1), r.randrange(-self.lateralError, self.lateralError, 1), self.height) # self.rocketNP.setPos(0, 0, self.length*10) self.rocketNP.setCollideMask(BitMask32.allOn()) # self.rocketNP.node().setCollisionResponse(0) self.rocketNP.node().notifyCollisions(True) self.world.attachRigidBody(self.rocketNP.node()) for i in range(4): leg = BulletCylinderShape(0.1 * self.radius, 0.5 * self.length, XUp) self.rocketNP.node().addShape(leg, TransformState.makePosHpr( Vec3(6 * self.radius * math.cos(i * math.pi / 2), 6 * self.radius * math.sin(i * math.pi / 2), -0.6 * self.length), Vec3(i * 90, 0, 30))) shape = BulletConeShape(0.75 * self.radius, 0.5 * self.radius, ZUp) self.rocketNP.node().addShape(shape, TransformState.makePosHpr(Vec3(0, 0, -1 / 2 * self.length), Vec3(0, 0, 0))) # Fuel self.fuelRadius = 0.9 * self.radius shape = BulletCylinderShape(self.fuelRadius, 0.01 * self.length, ZUp) self.fuelNP = self.worldNP.attachNewNode(BulletRigidBodyNode('Cone')) self.fuelNP.node().setMass(self.fuelMass_full * self.fuelMass_init) self.fuelNP.node().addShape(shape) self.fuelNP.setPos(0, 0, self.rocketNP.getPos().getZ() - self.length * 0.5 * (1 - self.fuelMass_init)) self.fuelNP.setCollideMask(BitMask32.allOn()) self.fuelNP.node().setCollisionResponse(0) self.world.attachRigidBody(self.fuelNP.node()) frameA = TransformState.makePosHpr(Point3(0, 0, 0), Vec3(0, 0, 90)) frameB = TransformState.makePosHpr(Point3(0, 0, 0), Vec3(0, 0, 90)) self.fuelSlider = BulletSliderConstraint(self.rocketNP.node(), self.fuelNP.node(), frameA, frameB, 1) self.fuelSlider.setTargetLinearMotorVelocity(0) self.fuelSlider.setDebugDrawSize(2.0) self.fuelSlider.set_lower_linear_limit(0) self.fuelSlider.set_upper_linear_limit(0) self.world.attachConstraint(self.fuelSlider) self.npThrustForce = LineNodePath(self.rocketNP, 'Thrust', thickness=4, colorVec=Vec4(1, 0.5, 0, 1)) self.npDragForce = LineNodePath(self.rocketNP, 'Drag', thickness=4, colorVec=Vec4(1, 0, 0, 1)) self.npLiftForce = LineNodePath(self.rocketNP, 'Lift', thickness=4, colorVec=Vec4(0, 0, 1, 1)) self.npFuelState = LineNodePath(self.fuelNP, 'Fuel', thickness=20, colorVec=Vec4(0, 1, 0, 1)) self.rocketCSLon = self.radius ** 2 * math.pi self.rocketCSLat = self.length * 2 * self.radius if self.VISUALIZE is True: self.terrain = loader.loadModel("LZGrid2.egg") self.terrain.setScale(10) self.terrain.reparentTo(self.render) self.terrain.setColor(Vec4(0.1, 0.2, 0.1, 1)) self.toggleTexture() #self.fuelNP.setPos(0, 0, self.rocketNP.getPos().getZ() - self.length * 0.4 * (1 - self.fuelMass_init)) for i in range(5): self.world.doPhysics(self.dt, 5, 1.0 / 180.0) self.fuelSlider.set_lower_linear_limit(-self.length * 0.5 * (1 - self.fuelMass_init)) self.fuelSlider.set_upper_linear_limit(self.length * 0.5 * (1 - self.fuelMass_init)) for i in range(100): self.world.doPhysics(self.dt, 5, 1.0 / 180.0) self.rocketNP.node().applyForce(Vec3(0,0,300000), Vec3(0, 0, 0))
def grid(self): raws1unit = 20 rawsfithunit = 10 d = 0 X1 = 10 X2 = -10 Y1 = 10 Y2 = -10 linesX = LineNodePath(render, 'quad', 2, Vec4(.3, .3, .3, .3)) linesXX = LineNodePath(render, 'quad', 1, Vec4(.3, .3, .3, .3)) axis = LineNodePath(render, 'axis', 4, Vec4(.2, .2, .2, .2)) quad = LineNodePath(render, 'quad', 4, Vec4(.2, .2, .2, .2)) x1 = (0, Y2, 0) x2 = (0, Y1, 0) x3 = (X2, 0, 0) x4 = (X1, 0, 0) axis.drawLines([[x1, x2], [x3, x4]]) axis.create() q1 = (X1, Y1, 0) q2 = (X1, Y2, 0) q3 = (q2) q4 = (X2, Y2, 0) q5 = (q4) q6 = (X2, Y1, 0) q7 = (q6) q8 = (X1, Y1, 0) quad.drawLines([[q1, q2], [q3, q4], [q5, q6], [q7, q8]]) quad.create() for l in range(raws1unit - 1): d += 1 l1 = (X2 + d, Y1, 0) l2 = (X2 + d, Y2, 0) l3 = (X2, Y1 - d, 0) l4 = (X1, Y1 - d, 0) linesX.drawLines([[l1, l2], [l3, l4]]) linesX.create() for l in range(rawsfithunit): d -= .2 lx1 = (X2 + 1 + d, Y1, 0) lx2 = (X2 + 1 + d, Y2, 0) lx3 = (X2, Y1 - 1 - d, 0) lx4 = (X1, Y1 - 1 - d, 0) linesXX.drawLines([[lx1, lx2], [lx3, lx4]]) linesXX.create()
def setup(self): #self.targetAlt = r.randrange(100,300) self.Valves = np.array([0.15, 0.2, 0.15]) self.EngObs = self.vulcain.predict_data_point( np.array(self.Valves).reshape(1, -1)) if self.VISUALIZE is True: self.worldNP = self.render.attachNewNode('World') else: self.root = NodePath(PandaNode("world root")) self.worldNP = self.root.attachNewNode('World') self.world = BulletWorld() self.world.setGravity(Vec3(0, 0, -9.80665)) # World self.debugNP = self.worldNP.attachNewNode(BulletDebugNode('Debug')) self.debugNP.node().showWireframe(True) self.debugNP.node().showConstraints(True) self.debugNP.node().showBoundingBoxes(False) self.debugNP.node().showNormals(True) self.debugNP.show() self.world.setDebugNode(self.debugNP.node()) # self.debugNP.showTightBounds() # self.debugNP.showBounds() # Ground (static) shape = BulletPlaneShape(Vec3(0, 0, 1), 1) self.groundNP = self.worldNP.attachNewNode( BulletRigidBodyNode('Ground')) self.groundNP.node().addShape(shape) self.groundNP.setPos(0, 0, 0) self.groundNP.setCollideMask(BitMask32.allOn()) self.world.attachRigidBody(self.groundNP.node()) # Rocket shape = BulletCylinderShape(self.radius, self.length, ZUp) self.rocketNP = self.worldNP.attachNewNode( BulletRigidBodyNode('Cylinder')) self.rocketNP.node().setMass(self.drymass + self.fuelAmount_LH2 + self.fuelAmount_LOX) self.rocketNP.node().addShape(shape) #self.rocketNP.setPos(20,20,250) self.rocketNP.setPos(r.randrange(-200, 200), 20, 350) #r.randrange(300, 500)) #self.rocketNP.setPos(r.randrange(-self.lateralError, self.lateralError, 1), r.randrange(-self.lateralError, self.lateralError, 1), self.height) # self.rocketNP.setPos(0, 0, self.length*10) self.rocketNP.setCollideMask(BitMask32.allOn()) # self.rocketNP.node().setCollisionResponse(0) self.rocketNP.node().notifyCollisions(True) self.world.attachRigidBody(self.rocketNP.node()) for i in range(4): leg = BulletCylinderShape(0.1 * self.radius, 0.5 * self.length, XUp) self.rocketNP.node().addShape( leg, TransformState.makePosHpr( Vec3(6 * self.radius * math.cos(i * math.pi / 2), 6 * self.radius * math.sin(i * math.pi / 2), -0.6 * self.length), Vec3(i * 90, 0, 30))) shape = BulletConeShape(0.75 * self.radius, 0.5 * self.radius, ZUp) self.rocketNP.node().addShape( shape, TransformState.makePosHpr(Vec3(0, 0, -1 / 2 * self.length), Vec3(0, 0, 0))) self.npThrustForce = LineNodePath(self.rocketNP, 'Thrust', thickness=4, colorVec=Vec4(1, 0.5, 0, 1)) self.npDragForce = LineNodePath(self.rocketNP, 'Drag', thickness=4, colorVec=Vec4(1, 0, 0, 1)) self.npLiftForce = LineNodePath(self.rocketNP, 'Lift', thickness=4, colorVec=Vec4(0, 0, 1, 1)) self.rocketCSLon = self.radius**2 * math.pi self.rocketCSLat = self.length * 2 * self.radius if self.VISUALIZE is True: self.terrain = loader.loadModel("../LZGrid2.egg") self.terrain.setScale(10) self.terrain.reparentTo(self.render) self.terrain.setColor(Vec4(0.1, 0.2, 0.1, 1)) self.toggleTexture()
def __init__(self): ShowBase.__init__(self) wp = core.WindowProperties() wp.setTitle("Dorfdelf") self.win.requestProperties(wp) self.render.setAntialias(core.AntialiasAttrib.MAuto) self.setBackgroundColor(0.5, 0.5, 0.5) self.disableMouse() self.enableParticles() font = self.loader.loadFont('media/Carlito-Regular.ttf') font.setPixelsPerUnit(120) font.setPageSize(512, 1024) loading = OnscreenText(text='Loading...', scale=0.2, pos=(0.0, 0.0), fg=(1, 1, 1, 1), shadow=(0.3, 0.3, 0.3, 1.0), align=core.TextNode.ACenter, mayChange=True, font=font, parent=self.aspect2d) self.graphicsEngine.renderFrame() self.graphicsEngine.renderFrame() loading.setText('Generating world') self.graphicsEngine.renderFrame() self.graphicsEngine.renderFrame() self.world = world.World(128, 128, 100) self.world.generate() loading.setText('Creating world geometry') self.graphicsEngine.renderFrame() self.graphicsEngine.renderFrame() self.world_geometry = geometry.WorldGeometry(self.world) self.camLens.setFocalLength(1) self.camera.setPos(0, 0, 100) self.camera.lookAt(self.world.midpoint.x, self.world.midpoint.y, 100) self.cam.setPos(0, 0, 0) self.cam.setHpr(0, -45, 0) self.cc = camera.CameraController(self.world.size, self.mouseWatcherNode, self.camera, self.cam) self.gui = gui.GUI(self.pixel2d, font) self.world_geometry.node.setPos(0, 0, 0) self.world_geometry.node.reparentTo(self.render) self.explore_mode = True self.current_slice = int(self.world.midpoint.z) self.accept_keyboard() self.accept('mouse1', self.toggle_block) self.accept('console-command', self.console_command) self.designation = designation.Designation() self.dorfs = [] self.tool = lambda w, x, y, z: None self.toolargs = () self.tools = { 'bomb': tools.bomb, 'block': tools.block, 'd': self.designation.add } self.console = console.Console(self) self.picker = block_picker.BlockPicker(self.world, self) self.zmap = zmap.ZMap(self.world, self) self.change_slice(0) arrow = LineNodePath() arrow.reparentTo(self.render) arrow.drawArrow2d(Vec3(-5, -5, self.world.midpoint.z), Vec3(15, -5, self.world.midpoint.z), 30, 3) arrow.create() loading.hide()
# Create the joints smileyJoint = OdeBallJoint(world) smileyJoint.attach(smileyBody, None) # Attach it to the environment smileyJoint.setAnchor(0, 0, 0) frowneyJoint = OdeBallJoint(world) frowneyJoint.attach(smileyBody, frowneyBody) frowneyJoint.setAnchor(-5, 0, -5) # Set the camera position base.disableMouse() base.camera.setPos(0, 50, -7.5) base.camera.lookAt(0, 0, -7.5) # We are going to be drawing some lines between the anchor points and the joints lines = LineNodePath(parent=render, thickness=3.0, colorVec=Vec4(1, 0, 0, 1)) def drawLines(): # Draws lines between the smiley and frowney. lines.reset() lines.drawLines([((frowney.getX(), frowney.getY(), frowney.getZ()), (smiley.getX(), smiley.getY(), smiley.getZ())), ((smiley.getX(), smiley.getY(), smiley.getZ()), (0, 0, 0)) ]) lines.create() # The task for our simulation def simulationTask(task): # Step the simulation and set the new positions
class Planet(SphericalBody): ''' Planet contains units and structures ''' def __init__(self, orbital_radius, orbital_angle, radius, parent_star, prev_planet=None, player=None): ''' Constructor for class planet. @param position: Point3D, position in space @param radius: float, body radius @param player: Player, the owner of the planet @param parent_star: Star, the specific star the planet is orbiting around @param prev_planet: previous planet in the star system, if None then the planet is the first ''' position = Point3(orbital_radius * math.cos(orbital_angle), orbital_radius * math.sin(orbital_angle), 0) super(Planet, self).__init__(position, radius, False, player) self.orbital_velocity = 0 self.max_orbital_velocity = 0 self.orbital_radius = orbital_radius self.orbital_angle = orbital_angle self.parent_star = parent_star self.prev_planet = prev_planet self.next_planet = None self._orbiting_units = [] self._surface_structures = [] self.__initSceneGraph() '''For the Player''' self.task_structure_timer = None self.task_unit_timer = None '''For the AI''' self.task_structure_timers = [] self.task_unit_timers = [] def __initSceneGraph(self): #load various texture stages of the planet self.forge_tex = TextureStage('forge') self.forge_tex.setMode(TextureStage.MDecal) self.nexus_tex = TextureStage('nexus') self.nexus_tex.setMode(TextureStage.MDecal) self.extractor_phylon_ge_tex = TextureStage('extractor_phylon_ge') self.extractor_phylon_ge_tex.setMode(TextureStage.MDecal) # Parent node for relative position (no scaling) self.point_path = self.parent_star.point_path.attachNewNode("planet_node") self.point_path.setPos(self.position) #Models & textures self.model_path = loader.loadModel("models/planets/planet_sphere") self.model_path.setTexture(SphericalBody.dead_planet_tex, 1) self.model_path.reparentTo(self.point_path) self.model_path.setScale(self.radius) self.model_path.setPythonTag('pyPlanet', self); cnode = CollisionNode("coll_sphere_node") cnode.setTag('planet', str(id(self))) #We use no displacement (0,0,0) and no scaling factor (1) cnode.addSolid(CollisionSphere(0,0,0,1)) cnode.setIntoCollideMask(BitMask32.bit(1)) # Reparenting the collision sphere so that it # matches the planet perfectly. self.cnode_path = self.model_path.attachNewNode(cnode) self.lines = LineNodePath(parent = self.parent_star.point_path, thickness = 4.0, colorVec = Vec4(1.0, 1.0, 1.0, 0.2)) self.quad_path = None def setTexture(self, structureType): ''' Used whenever a structure is built on the planet @ StructureType is a string specifying the type of the structure ''' if(structureType == "forge"): #SphericalBody.planet_forge_tex.setWrapU(Texture.WMInvalid) #SphericalBody.planet_forge_tex.setWrapV(Texture.WMInvalid) self.model_path.setTexture(self.forge_tex, SphericalBody.planet_forge_tex) #self.model_path.getTexture().setWrapU(Texture.WMClamp) #self.model_path.getTexture().setWrapV(Texture.WMClamp) self.model_path.setTexOffset(self.forge_tex, 0, 0) #self.model_path.setTexScale(self.forge_tex, -4, -2) elif(structureType == "nexus"): self.model_path.setTexture(self.nexus_tex, SphericalBody.planet_nexus_tex) self.model_path.setTexOffset(self.nexus_tex, 0, 10) elif(structureType == "extractor"): self.model_path.setTexture(self.extractor_phylon_ge_tex, SphericalBody.planet_extractor_tex) self.model_path.setTexOffset(self.extractor_phylon_ge_tex, 0, 20) elif(structureType == "phylon"): self.model_path.setTexture(self.extractor_phylon_ge_tex, SphericalBody.planet_phylon_tex) self.model_path.setTexOffset(self.extractor_phylon_ge_tex, 0, 20) elif(structureType == "generatorCore"): self.model_path.setTexture(self.extractor_phylon_ge_tex, SphericalBody.planet_generatorCore_tex) self.model_path.setTexOffset(self.extractor_phylon_ge_tex, 0, 20) def activateHighlight(self, thin): if thin: flare_tex = base.loader.loadTexture("models/billboards/thin_ring.png") else: flare_tex = base.loader.loadTexture("models/billboards/ring.png") cm = CardMaker('quad') cm.setFrameFullscreenQuad() # so that the center acts as the origin (from -1 to 1) self.quad_path = self.point_path.attachNewNode(cm.generate()) self.quad_path.setTransparency(TransparencyAttrib.MAlpha) self.quad_path.setTexture(flare_tex) if thin: self.quad_path.setColor(Vec4(1,1,1, 1)) else: self.quad_path.setColor(Vec4(0.2, 0.3, 1.0, 1)) self.quad_path.setScale(5) self.quad_path.setPos(Vec3(0,0,0)) self.quad_path.setBillboardPointEye() def deactivateHighlight(self): if self.quad_path: self.quad_path.detachNode() self.quad_path = None def select(self, player): ''' This method observes the events on the planet and calls the related methods and notifies the corresponding objects based on the state of the planet @param player, the player who has selected ''' player.selected_star = None if(not self.activated and player.selected_planet == self): if((self.prev_planet == None or self.prev_planet.activated) and \ self.parent_star.activated and self.parent_star.player == player): self.activatePlanet(player) else: # from gameEngine.gameEngine import all_stars # for star in all_stars: # star.deactivateHighlight() from gameEngine.gameEngine import all_planets for planet in all_planets: if(self != planet or self.next_planet != planet or self.prev_planet != planet): planet.deactivateHighlight() if self.next_planet != None: self.next_planet.activateHighlight(True) if self.prev_planet != None: self.prev_planet.activateHighlight(True) self.activateHighlight(False) player.selected_planet = self from gameEngine.gameEngine import updateGUI updateGUI.refreshUnitsAndConstructions(self) def selectRight(self, player): ''' This method observes the events on the planet and calls the related methods and notifies the corresponding objects based on the state of the planet @param player, the player who has selected with right mouse click ''' move_occured = False for selected_unit in player.selected_units: if(selected_unit != None and selected_unit.player == player): '''movement is inside the solar system''' if(selected_unit.host_planet.parent_star == self.parent_star): if(selected_unit.host_planet == self.prev_planet): selected_unit.moveUnitNext() move_occured = True if(selected_unit.host_planet == self.next_planet): selected_unit.moveUnitPrev() move_occured = True else: '''movement is between solar systems in deep space''' if(self.next_planet == None and selected_unit.host_planet.next_planet == None): selected_unit.moveDeepSpace(self) move_occured = True if(len(player.selected_units)!=0 and move_occured): if(player.selected_units[0] != None and player.selected_units[0].move_unit != None): base.sfxManagerList[0].update() player.selected_units[0].move_unit.play() def activatePlanet(self, player): ''' Activates a constructed dead planet object, starting the orbital movement with the assigned value while the Game Engine calls the graphic engine to display the corresponding animation. @param player: Player, the player who controls the planet @precondition: MIN_PLANET_VELOCITY < orbital_velocity < MAX_PLANET_VELOCITY ''' self.activated = True player.planets.append(self) self.player = player planet_created_sound = base.loader.loadSfx("sound/effects/planet/planetCreation.wav") planet_created_sound.setVolume(0.3) planet_created_sound.play() # base.sfxManagerList[0].update() # SphericalBody.planet_created_sound.play() self.radius = MAX_PLANET_RADIUS self.model_path.setScale(self.radius) '''TODO : display planet creation animation ''' #rand = random.randrange(1,8,1) self.model_path.setTexture(SphericalBody.planet_activated_tex, 1) self.startSpin() # We want to avoid adding this task when the 'collapseOrbit' is already running if self.parent_star.lifetime != 0: taskMgr.add(self._accelerateOrbit, 'accelerateOrbit') self.orbit_path = shapes.makeArc(self.player.color, 360, int(self.orbital_radius)) self.orbit_path.reparentTo(self.parent_star.point_path) self.orbit_path.setScale(self.orbital_radius) from gameModel.ai import AI if(type(self.player) != AI): from gameEngine.gameEngine import updateGUI updateGUI.refreshUnitsAndConstructions(self) def startSpin(self): self.day_period = self.model_path.hprInterval(PLANET_SPIN_VELOCITY, Vec3(360, 0, 0)) self.day_period.loop() def startCollapse(self): try: if self.orbit_task: taskMgr.remove(self.orbit_task) except AttributeError: pass # no orbit on this planet (has not been activated) taskMgr.add(self._collapseOrbit, 'collapseOrbit') # taskMgr.setupTaskChain('collapseChain') # taskMgr.add(self._collapseOrbit, 'collapseOrbit')#, taskChain='collapseChain') # taskMgr.add(self._consume, 'consumePlanet', taskChain='collapseChain') # self.orbitTask = None def _consume(self): self._consumeUnits() self._consumeStructures() self.removeFromGame() def _accelerateOrbit(self, task): self.orbital_angle = self.orbital_angle + self.orbital_velocity self.orbital_angle = math.fmod(self.orbital_angle, 2.0*math.pi); self.point_path.setPos(self.orbital_radius * math.cos(self.orbital_angle), self.orbital_radius * math.sin(self.orbital_angle), 0) self.position = self.point_path.getPos() self.orbital_velocity = self.orbital_velocity + 0.0001 if self.orbital_velocity > self.max_orbital_velocity: self.orbit_task = taskMgr.add(self._stepOrbit, 'stepOrbit') return task.done else: return task.cont def _stepOrbit(self, task): self.orbital_angle = self.orbital_angle + self.orbital_velocity self.orbital_angle = math.fmod(self.orbital_angle, 2.0*math.pi) self.point_path.setPos(self.orbital_radius * math.cos(self.orbital_angle), self.orbital_radius * math.sin(self.orbital_angle), 0) self.position = self.point_path.getPos() return task.cont def _collapseOrbit(self, task): self.orbital_radius = self.orbital_radius - 0.23 self.orbital_angle = self.orbital_angle + self.orbital_velocity self.orbital_angle = math.fmod(self.orbital_angle, 2.0*math.pi) self.point_path.setPos(self.orbital_radius * math.cos(self.orbital_angle), self.orbital_radius * math.sin(self.orbital_angle), 0) self.position = self.point_path.getPos() # if self.orbital_velocity < 0.01: if self.orbital_radius != 0: self.orbital_velocity = self.orbital_velocity + 0.01/(self.orbital_radius**2) try: self.orbit_path.setScale(self.orbital_radius) except AttributeError: pass # no orbit on this planet (has not been activated) if self.orbital_radius <= 0: self._consume() return task.done else: return task.cont def drawLines(self): # put some lighting on the line # for some reason the ambient and directional light in the environment drain out # all other colors in the scene # this is a temporary solution just so we can view the lines... the light can be removed and #a glow effect will be added later # alight = AmbientLight('alight') # alnp = render.attachNewNode(alight) # alight.setColor(Vec4(0.2, 0.2, 0.2, 1)) # render.setLight(alnp) self.lines.reset() self.lines.drawLines([((0,0, 0), (self.point_path.getX(), self.point_path.getY(), 0))]) self.lines.create() def drawConnections(self, task): # cur_pos = self.point_path.getPos() # paired_pos = pairedPlanetDraw.point_path.getPos() # paired_pos = self.point_path.getRelativePoint(pairedPlanetDraw.point_path, pairedPlanetDraw.point_path.getPos()) # print pairedPlanetDraw.point_path.getX(), pairedPlanetDraw.point_path.getY(), pairedPlanetDraw.point_path.getZ() self.connections.reset() if(self.next_planet): point_list = [] point_list.append((self.point_path.getPos(), self.next_planet.point_path.getPos())) self.connections.drawLines(point_list) self.connections.create() return task.cont def changePlayer(self, player): ''' Change the control of the planet from the self.player to the parameter player @param player: Player, the player who has captured the planet by swarms @precondition: the player must have used the capture ability of a swarm type unit on the planet ''' '''TODO: Use makeArc to change the color of the orbit''' ''' stop any constructions on the planet ''' if(self.task_structure_timer != None): taskMgr.remove(self.task_structure_timer) self.task_structure_timer = None if(self.task_unit_timer != None): taskMgr.remove(self.task_unit_timer) self.task_unit_timer = None if(self.task_structure_timers != None): taskMgr.remove(self.task_structure_timers) self.task_structure_timers = None if(self.task_unit_timers != None): taskMgr.remove(self.task_unit_timers) self.task_unit_timers = None ''' remove previous player's control from the planet ''' for structure in self.structures(): self.player.structures.remove(structure) ''' set control of the planet to the new player ''' for structure in self.structures(): player.structures.append(structure) ''' update the construction panel for the human player''' from gameModel.ai import AI ''' if human player is the previous owner ''' if(type(self.player) != AI): from gameEngine.gameEngine import updateGUI updateGUI.refreshUnitsAndConstructions(self) ''' give total control to new player ''' self.player = player ''' if human player is the new owner ''' if(type(player) != AI): from gameEngine.gameEngine import updateGUI updateGUI.refreshUnitsAndConstructions(self) def addOrbitingUnit(self, unit): ''' Add a unit to the hosted units by the planet @param unit: Orbiting unit object ''' self._orbiting_units.append(unit) def addOrbitingUnits(self, units): ''' Add a list of units to be hosted by the planet @param units: iterable of units ''' self._orbiting_units.extend(units) def removeOrbitingUnit(self, unit): ''' Remove the hosted unit from the planet @param unit: Orbiting unit object ''' self._orbiting_units.remove(unit) def removeOrbitingUnits(self, units): ''' Remove many hosted units from the planet @param units: List of unit objects ''' self._orbiting_units[:] = [u for u in self._orbiting_units if u not in units] def units(self): ''' Generator that iterates over the hosted units. ''' for unit in self._orbiting_units: yield unit def unitsOfPlayer(self, player): ''' Generator that iterates over the hosted units belonging to the player. @param player, the owner of the units ''' for unit in self._orbiting_units: if unit.player == player: yield unit def unitsOfEnemy(self, player): ''' Generator that iterates over the hosted units not belonging to the player. @param player, the owner of the units ''' for unit in self._orbiting_units: if unit.player != player: yield unit def unitsOfEnemyLowestEnergy(self, player): ''' Generator that iterates over the hosted units not belonging to the player sorted by lowest energy. @param player, the owner of the units ''' energyList = sorted(self._orbiting_units, key=lambda unit: unit.energy) for unit in energyList: if unit.player != player: yield unit def getNumberOfUnits(self): ''' Returns the number of hosted units from the planet ''' return len(self._orbiting_units) def getNumberOfUnitsOfPlayer(self, player): ''' Returns the number of hosted units from the planet that belongs to the player @param player, the owner of the units ''' num = 0 for unit in self._orbiting_units: if(unit.player == player): num = num + 1 return num def _task_unit_timers(self): ''' Generator that iterates over the hosted units construction tasks. ''' for task_unit in self.task_unit_timers: yield task_unit def _task_structure_timers(self): ''' Generator that iterates over the surface structure construction tasks. ''' for task_structure in self.task_structure_timers: yield task_structure def _consumeUnits(self): if(self.task_unit_timer!=None): taskMgr.remove(self.task_unit_timer) self.task_unit_timer = None for task in self.task_unit_timers: taskMgr.remove(task) del self.task_unit_timers[:] from gameModel.ai import AI for unit in self._orbiting_units: unit.player.units.remove(unit) if(type(unit.player) != AI): try: unit.player.selected_units.remove(unit) print "selected unit" except ValueError: pass unit.removeFromGame() del self._orbiting_units[:] def _consumeStructures(self): if(self.task_structure_timer!=None): taskMgr.remove(self.task_structure_timer) self.task_structure_timer = None for task in self.task_structure_timers: taskMgr.remove(task) del self.task_structure_timers[:] for structure in self._surface_structures: self.player.structures.remove(structure) del self._surface_structures[:] def addSurfaceStructure(self, structure): ''' Add a structure to the surface structures by the planet @param structure: Surface structure object ''' if(len(self._surface_structures) < MAX_NUMBER_OF_STRUCTURE): self._surface_structures.append(structure) def addSurfaceStructures(self, structures): ''' Add a list of structures to be hosted by the planet @param structures: iterable of structure ''' if(len(self._surface_structures) + len(structures) <= MAX_NUMBER_OF_STRUCTURE): self._surface_structures.extend(structures) def removeSurfaceStructure(self, structure): ''' Remove the surface structure from the planet @param structure: Surface structure object ''' self._surface_structures.remove(structure) def removeSurfaceStructures(self, structures): ''' Remove many surface structures from the planet @param structures: List of structure objects ''' self._surface_structures[:] = [s for s in self._surface_structures if s not in structures] def structures(self): ''' Generator that iterates over the surface structures. ''' for structure in self._surface_structures: yield structure def getNumberOfStructures(self): ''' Returns the number of surface structures from the planet ''' return len(self._surface_structures) def hasStructure(self, structure): ''' Returns true if a type of the structure already exists on the planet @structure: String, the desired structure type ''' from structures import Forge, Nexus, Extractor, Phylon, GeneratorCore,\ PlanetaryDefenseI, PlanetaryDefenseII, PlanetaryDefenseIII, PlanetaryDefenseIV for surface_structure in self._surface_structures: if(structure == "forge" and type(surface_structure) == Forge): return True elif(structure == "nexus" and type(surface_structure) == Nexus): return True elif(structure == "extractor" and type(surface_structure) == Extractor): return True elif(structure == "phylon" and type(surface_structure) == Phylon): return True elif(structure == "generatorCore" and type(surface_structure) == GeneratorCore): return True elif(structure == "pd1" and type(surface_structure) == PlanetaryDefenseI): return True elif(structure == "pd2" and type(surface_structure) == PlanetaryDefenseII): return True elif(structure == "pd3" and type(surface_structure) == PlanetaryDefenseIII): return True elif(structure == "pd4" and type(surface_structure) == PlanetaryDefenseIV): return True return False def removeFromGame(self): if(self.next_planet != None): self.next_planet.prev_planet = None self.point_path.removeNode() from player import Player if type(self.player) == Player and self.player.selected_planet == self: self.player.selected_planet = None if(self.player != None): self.player.planets.remove(self) self.parent_star.removePlanet(self)