def draw(self): # Draw attack radius attackRadLine = LineSegs() attackRadLine.setThickness(1) attackRadLine.setColor(self._color) attackRadLine.moveTo(self.attackRad, 0, 0) for i in range(self._EDGES + 1): newX = (self.attackRad * math.cos((2*math.pi/self._EDGES)*i)) newY = (self.attackRad * math.sin((2*math.pi/self._EDGES)*i)) attackRadLine.drawTo(newX, newY, 0) attackRadGeom = attackRadLine.create() self._attackRadCircleNP = NodePath(attackRadGeom) self._attackRadCircleNP.reparentTo(self._np) # Draw foot circle self._footCircle.setThickness(1) self._footCircle.setColor(self._color) self._footCircle.moveTo(self.footRad, 0, 0) for i in range(self._EDGES): newX = (self.footRad * math.cos((2*math.pi/self._EDGES)*i)) newY = (self.footRad * math.sin((2*math.pi/self._EDGES)*i)) self._footCircle.drawTo(newX, newY, 0) self._footCircle.drawTo(self.footRad, 0, 0) footCircleGeom = self._footCircle.create() self._footCircleNP = NodePath(footCircleGeom) self._footCircleNP.reparentTo(self._np)
def draw(self): # Draw attack radius attackRadLine = LineSegs() attackRadLine.setThickness(1) attackRadLine.setColor(self._color) attackRadLine.moveTo(self.attackRad, 0, 0) for i in range(self._EDGES + 1): newX = (self.attackRad * math.cos((2 * math.pi / self._EDGES) * i)) newY = (self.attackRad * math.sin((2 * math.pi / self._EDGES) * i)) attackRadLine.drawTo(newX, newY, 0) attackRadGeom = attackRadLine.create() self._attackRadCircleNP = NodePath(attackRadGeom) self._attackRadCircleNP.reparentTo(self._np) # Draw foot circle self._footCircle.setThickness(1) self._footCircle.setColor(self._color) self._footCircle.moveTo(self.footRad, 0, 0) for i in range(self._EDGES): newX = (self.footRad * math.cos((2 * math.pi / self._EDGES) * i)) newY = (self.footRad * math.sin((2 * math.pi / self._EDGES) * i)) self._footCircle.drawTo(newX, newY, 0) self._footCircle.drawTo(self.footRad, 0, 0) footCircleGeom = self._footCircle.create() self._footCircleNP = NodePath(footCircleGeom) self._footCircleNP.reparentTo(self._np)
class SelectionBox(NodePath): def __init__(self, width=1, depth=1, height=1, thickness=1.0, origin=Point3(0, 0, 0)): def __Get3dPoint(pt, origin, axis): p = Point3(pt.x, pt.y, 0) - origin return RotatePoint3(p, Vec3(0, 0, 1), axis) # Create line segments self.ls = LineSegs() self.ls.setThickness(thickness) # axes = [Vec3(1, 0, 0), Vec3(0, 1, 0), Vec3(0, 0, 1), Vec3(1, 0, 0), Vec3(0, 1, 0), Vec3(0, 0, 1)] # origins = [origin, origin, origin, origin + Point3(0, 0, -1), origin + Point3(0, 0, -1), origin + Point3(0, 0, 1)] axes = [Vec3(1, 0, 0), Vec3(0, 1, 0), Vec3(-1, 0, 0), Vec3(0, -1, 0)] origins = [origin, origin, origin, origin] for m in range(len(axes)): # Get the points for square, append the first one to the end to # complete the square pts = GetPointsForSquare2(width, height) pts.append(pts[0]) for i in range(len(pts) - 1): # Get the distance a third of the way along the edge dist = (pts[i + 1] - pts[i]) / 3 # Draw one square self.ls.moveTo(__Get3dPoint(pts[i], origins[m], axes[m])) self.ls.drawTo(__Get3dPoint(pts[i] + dist, origins[m], axes[m])) self.ls.moveTo(__Get3dPoint(pts[i] + dist + dist, origins[m], axes[m])) self.ls.drawTo(__Get3dPoint(pts[i + 1], origins[m], axes[m])) # Init the node path, wrapping the lines node = self.ls.create() NodePath.__init__(self, node)
def createBox(n): boxpoints = [] np1 = (-26, -26, 0) np2 = (-26, 26, 0) np3 = (26, 26, 0) np4 = (26, -26, 0) boxpoints.append(np1) boxpoints.append(np2) boxpoints.append(np3) boxpoints.append(np4) boxpoints.append(np1) boxsegs = LineSegs() boxsegs.setThickness(2.0) boxsegs.setColor(Vec4(0.002, 0.002, 0.002, 0.18)) boxsegs.moveTo(boxpoints[0]) for p in boxpoints[1:]: boxsegs.drawTo(p) gridPoints = [] l = float(52 / n) i = 1 while i < (n): np = (-26, (-26 + (l * i)), 0) np2 = (26, (-26 + (l * i)), 0) np3 = ((-26 + (l * i)), -26, 0) np4 = ((-26 + (l * i)), 26, 0) gridPoints.append((np, np2)) gridPoints.append((np3, np4)) i = i + 1 for p in gridPoints: boxsegs.moveTo(p[0]) boxsegs.drawTo(p[1]) return boxsegs.create()
class AttackCursor(object): _EDGES = 40 _color = Vec4(0.8, 0.3, 0.3, 1) def __init__(self, parent, entity, foot=1): self.entity = entity self.pos = entity.pos self.attackRad = entity.attackRad self.footRad = foot self._footCircle = LineSegs() self._footCircleNP = NodePath("Movement Foot Circle Node") self._attackRadCircle = LineSegs() self._attackRadCircleNP = NodePath("Attack Radius Node") self._np = NodePath("Movement Node") self.attackables = Entity.EntityManager().getEntitiesWithin( self.pos, self.attackRad) for e in self.attackables: if isinstance( e, Entity.EntityShip ) and e != self.entity and e.owner != self.entity.owner: e.representation.setAttackable() def draw(self): # Draw attack radius attackRadLine = LineSegs() attackRadLine.setThickness(1) attackRadLine.setColor(self._color) attackRadLine.moveTo(self.attackRad, 0, 0) for i in range(self._EDGES + 1): newX = (self.attackRad * math.cos((2 * math.pi / self._EDGES) * i)) newY = (self.attackRad * math.sin((2 * math.pi / self._EDGES) * i)) attackRadLine.drawTo(newX, newY, 0) attackRadGeom = attackRadLine.create() self._attackRadCircleNP = NodePath(attackRadGeom) self._attackRadCircleNP.reparentTo(self._np) # Draw foot circle self._footCircle.setThickness(1) self._footCircle.setColor(self._color) self._footCircle.moveTo(self.footRad, 0, 0) for i in range(self._EDGES): newX = (self.footRad * math.cos((2 * math.pi / self._EDGES) * i)) newY = (self.footRad * math.sin((2 * math.pi / self._EDGES) * i)) self._footCircle.drawTo(newX, newY, 0) self._footCircle.drawTo(self.footRad, 0, 0) footCircleGeom = self._footCircle.create() self._footCircleNP = NodePath(footCircleGeom) self._footCircleNP.reparentTo(self._np) def removeNode(self): for e in self.attackables: if isinstance(e, Entity.EntityShip): e.representation.unsetAttackable() self._footCircleNP.removeNode() self._attackRadCircleNP.removeNode() self._np.removeNode() def __del__(self): self.removeNode()
def __init__( self, *args, **kwargs ): colour = kwargs.pop( 'colour', (1, 1, 1, .2) ) p3d.SingleTask.__init__( self, *args, **kwargs ) # Create a card maker cm = CardMaker( self.name ) cm.setFrame( 0, 1, 0, 1 ) # Init the node path, wrapping the card maker to make a rectangle NodePath.__init__( self, cm.generate() ) self.setColor( colour ) self.setTransparency( 1 ) self.reparentTo( self.root2d ) self.hide() # Create the rectangle border ls = LineSegs() ls.moveTo( 0, 0, 0 ) ls.drawTo( 1, 0, 0 ) ls.drawTo( 1, 0, 1 ) ls.drawTo( 0, 0, 1 ) ls.drawTo( 0, 0, 0 ) # Attach border to rectangle self.attachNewNode( ls.create() )
class RepairSawingLine: def __init__(self, parent, thickness, color, lineSpawnDist=0.01): self.points = [] self.parent = parent self.thickness = thickness self.color = color self.lineNode = None self.lineDrawer = LineSegs() self.lineDrawer.setThickness(thickness) self.lineSpawnDist = lineSpawnDist self.currentPoint = None self.startPoint = None self.redraw() def redraw(self): self.clearLine() self.lineDrawer.reset() self.lineDrawer.setThickness(self.thickness) self.lineDrawer.setColor(self.color) if len(self.points) > 0: self.lineDrawer.moveTo(self.points[0]) for i in range(1, len(self.points)): p = self.points[i] self.lineDrawer.drawTo(p) self.currentPoint = p self.lineNode = NodePath(self.lineDrawer.create()) self.lineNode.reparentTo(self.parent) self.lineNode.setBin('fixed', 37) self.lineNode.setTransparency(True) def update(self, point): if self.currentPoint == None or ( point - self.currentPoint).length() >= self.lineSpawnDist: self.addPoint(point) self.redraw() def addPoint(self, p): if len(self.points) == 0: self.startPoint = p self.points.append(p) def clearLine(self): if self.lineNode != None: self.lineNode.removeNode() def reset(self): self.clearLine() self.points = [] self.redraw() self.currentPoint = None self.startPoint = None def show(self): self.lineNode.unstash() def hide(self): self.lineNode.stash()
def renderPath(self, path, color): segs = LineSegs() segs.setThickness(1.0) segs.setColor(color) segs.moveTo(Point3(path[0].getX(), path[0].getY(), 0)) for i in range(1, len(path)): segs.drawTo(Point3(path[i].getX(), path[i].getY(), 0)) return segs.create()
def add_line(self, rendering_node, color, thickness, start, end): linesegs = LineSegs() linesegs.setColor(*color) linesegs.setThickness(thickness) linesegs.drawTo((start[0], start[1], start[2])) linesegs.drawTo((end[0], end[1], end[2])) new_node = linesegs.create() rendering_node.attachNewNode(new_node)
class AttackCursor(object): _EDGES = 40 _color = Vec4(0.8, 0.3, 0.3, 1) def __init__(self, parent, entity, foot=1): self.entity = entity self.pos = entity.pos self.attackRad = entity.attackRad self.footRad = foot self._footCircle = LineSegs() self._footCircleNP = NodePath("Movement Foot Circle Node") self._attackRadCircle = LineSegs() self._attackRadCircleNP= NodePath("Attack Radius Node") self._np = NodePath("Movement Node") self.attackables = Entity.EntityManager().getEntitiesWithin(self.pos, self.attackRad) for e in self.attackables: if isinstance(e, Entity.EntityShip) and e != self.entity and e.owner != self.entity.owner: e.representation.setAttackable() def draw(self): # Draw attack radius attackRadLine = LineSegs() attackRadLine.setThickness(1) attackRadLine.setColor(self._color) attackRadLine.moveTo(self.attackRad, 0, 0) for i in range(self._EDGES + 1): newX = (self.attackRad * math.cos((2*math.pi/self._EDGES)*i)) newY = (self.attackRad * math.sin((2*math.pi/self._EDGES)*i)) attackRadLine.drawTo(newX, newY, 0) attackRadGeom = attackRadLine.create() self._attackRadCircleNP = NodePath(attackRadGeom) self._attackRadCircleNP.reparentTo(self._np) # Draw foot circle self._footCircle.setThickness(1) self._footCircle.setColor(self._color) self._footCircle.moveTo(self.footRad, 0, 0) for i in range(self._EDGES): newX = (self.footRad * math.cos((2*math.pi/self._EDGES)*i)) newY = (self.footRad * math.sin((2*math.pi/self._EDGES)*i)) self._footCircle.drawTo(newX, newY, 0) self._footCircle.drawTo(self.footRad, 0, 0) footCircleGeom = self._footCircle.create() self._footCircleNP = NodePath(footCircleGeom) self._footCircleNP.reparentTo(self._np) def removeNode(self): for e in self.attackables: if isinstance(e, Entity.EntityShip): e.representation.unsetAttackable() self._footCircleNP.removeNode() self._attackRadCircleNP.removeNode() self._np.removeNode() def __del__(self): self.removeNode()
def drawBorder(self, bounds, color): LS = LineSegs() LS.setColor(*color) LS.moveTo(bounds[0], 0, bounds[2]) LS.drawTo(bounds[0], 0, bounds[3]) LS.drawTo(bounds[1], 0, bounds[3]) LS.drawTo(bounds[1], 0, bounds[2]) LS.drawTo(bounds[0], 0, bounds[2]) return LS.create()
def drawLineToNeighbors(self): ls = LineSegs() ls.setThickness(1.0) for neighbor in self.neighbors: ls.setColor(1, 1, 1, 1) ls.moveTo(self.getPos(render)) ls.drawTo(neighbor.getPos(render)) self.np = NodePath(ls.create("Neighbor Line Segment")) self.np.reparentTo(render)
def __createLine(self, length=1, color=(1, 1, 1, 1), endColor=None): LS = LineSegs() LS.setColor(*color) LS.moveTo(0, 0, 0) LS.drawTo(length * 1, 0, 0) node = LS.create() if endColor: LS.setVertexColor(1, *endColor) return node
def drawLine(self, parent, source, target): line = LineSegs() line.setThickness(LINETHICKNESS) line.reset() line.setColor(*GRIDCOLOR) line.moveTo(source) line.drawTo(target) node = line.create() lineSegNP = NodePath(node).reparentTo(parent)
def __createLine(self, length=1, color=(1,1,1,1), endColor=None): LS=LineSegs() LS.setColor(*color) LS.moveTo(0,0,0) LS.drawTo(length*1,0,0) node=LS.create() if endColor: LS.setVertexColor(1,*endColor) return node
def drawLineToNeighbors(self): ls = LineSegs() ls.setThickness(1.0) for neighbor in self.neighbors: ls.setColor(1,1,1,1) ls.moveTo(self.getPos(render)) ls.drawTo(neighbor.getPos(render)) self.np = NodePath(ls.create("Neighbor Line Segment")) self.np.reparentTo(render)
def drawBestPath(self): if self.bestPath != None: ls = LineSegs() ls.setThickness(10.0) for i in range(len(self.bestPath) - 1): ls.setColor(0, 0, 1, 1) ls.moveTo(self.bestPath[i].getPos()) ls.drawTo(self.bestPath[i + 1].getPos()) np = NodePath(ls.create("aoeu")) np.reparentTo(render)
def sepLine(frame, styles): style = styles['menu separator'] ls = LineSegs('sepLine') ls.setColor(style['color']) ls.setThickness(style['thick']) hpad = (frame[1] - frame[0]) * .2 hh = frame[3] + (frame[3] - frame[2]) #/2 ls.moveTo(frame[0] + hpad, 0, hh) ls.drawTo(frame[1] - hpad, 0, hh) return ls.create()
def __init__(self, start, end, thickness=1.0): # Create line segments ls = LineSegs() ls.setThickness(thickness) ls.drawTo(Point3(start)) ls.drawTo(Point3(end)) # Init the node path, wrapping the lines NodePath.__init__(self, ls.create())
def __init__(self, name): GeomNode.__init__(self, name) ls = LineSegs() ls.setThickness(5) ls.drawTo(Point3(0, 0, 0)) ls.drawTo(Point3(100, 100, 100)) self.addGeomsFrom(ls.create()) print ls
def sepLine(frame, styles): style = styles['menu separator'] ls = LineSegs('sepLine') ls.setColor(style['color']) ls.setThickness(style['thick']) hpad = (frame[1]-frame[0])*.2 hh = frame[3]+(frame[3]-frame[2])#/2 ls.moveTo(frame[0]+hpad,0,hh) ls.drawTo(frame[1]-hpad,0,hh) return ls.create()
def makeArc(angleDegrees=360, numSteps=16, color=Vec4(1, 1, 1, 1)): ls = LineSegs() angleRadians = deg2Rad(angleDegrees) for i in range(numSteps + 1): a = angleRadians * i / numSteps y = math.sin(a) x = math.cos(a) ls.drawTo(x, y, 0) node = ls.create() if color != Vec4(1, 1, 1, 1): for i in range(numSteps + 1): ls.setVertexColor(i, color) pass return NodePath(node)
def __init__(self, listConsideration=[]): z = -0.05 self.plane = Plane(Vec3(0, 0, 1), Point3(0, 0, z)) cm = CardMaker("blah") cm.setFrame(-100, 100, -100, 100) render.attachNewNode(cm.generate()).lookAt(0, 0, -1) #Create a selection window using cardmaker #We will use the setScale function to dynamically scale the quad to the appropriate size in UpdateSelRect temp = CardMaker('') temp.setFrame(0, 1, 0, 1) #self.npSelRect is the actual selection rectangle that we dynamically hide/unhide and change size self.npSelRect = render2d.attachNewNode(temp.generate()) self.npSelRect.setColor(0.5,1,0,.3) self.npSelRect.setTransparency(1) self.npSelRect.hide() LS = LineSegs() LS.setColor(0.5,1,0,1) LS.moveTo(0,0,0) LS.drawTo(1,0,0) LS.drawTo(1,0,1) LS.drawTo(0,0,1) LS.drawTo(0,0,0) self.npSelRect.attachNewNode(LS.create()) self.listConsideration = listConsideration self.listSelected = [] self.listLastSelected = [] self.pt2InitialMousePos = (-12, -12) self.pt2LastMousePos = (-12, -12) ####----Used to differentiate between group selections and point selections #self.booMouseMoved = False self.fFovh, self.fFovv = base.camLens.getFov() ####--Used to control how frequently update_rect is updated; self.fTimeLastUpdateSelRect = 0 self.fTimeLastUpdateSelected = 0 self.UpdateTimeSelRect = 0.015 self.UpdateTimeSelected = 0.015 ####------Register the left-mouse-button to start selecting self.accept("mouse1", self.OnStartSelect) self.accept("control-mouse1", self.OnStartSelect) self.accept("mouse1-up", self.OnStopSelect) self.taskUpdateSelRect = 0 ####------otherThings self.booSelecting = False
def makeArc(initial_x, initial_y, angleDegrees=360, numSteps=16): ls = LineSegs() angleRadians = deg2Rad(angleDegrees) for i in range(numSteps + 1): a = angleRadians * i / numSteps y = initial_y + 0.01 * math.sin(a) x = initial_x + 0.01 * math.cos(a) ls.setThickness(3) ls.setColor(0, 0, 0, 1) ls.drawTo(x, 0, y) node = ls.create() return NodePath(node)
def makeArc(color, angle_degrees = 360, numsteps = 16, horizon_plane = 0,): ls = LineSegs() ls.setColor(color) angleRadians = deg2Rad(angle_degrees) for i in xrange(numsteps + 1): a = angleRadians * i / numsteps y = math.sin(a) x = math.cos(a) ls.drawTo(x, y, horizon_plane) ls.setThickness(2.0) ls.setColor(color) node = ls.create() return NodePath(node)
def makeArc(initial_x, initial_y, angleDegrees = 360, numSteps = 16): ls = LineSegs() angleRadians = deg2Rad(angleDegrees) for i in range(numSteps + 1): a = angleRadians * i / numSteps y = initial_y + 0.01*math.sin(a) x = initial_x + 0.01*math.cos(a) ls.setThickness(3) ls.setColor(0, 0, 0, 1) ls.drawTo(x, 0, y) node = ls.create() return NodePath(node)
def attach_to(self, render): '''creates Panda3D representation that can be attached to render this function is mainly used inside Render class and its derivatives and user not need to worry to call it''' new_line_seqs = LineSegs() new_line_seqs.setThickness(self.thickness) (r, g, b, a) = self.color new_line_seqs.setColor(Vec4(r, g, b, a)) (x, y, z) = self.points[0] new_line_seqs.moveTo(Point3(x, y, z)) for i in xrange(1, len(self.points)): (x, y, z) = self.points[i] new_line_seqs.drawTo(Point3(x, y, z)) lines = NodePath(new_line_seqs.create()) lines.reparentTo(render.render) return lines
def _voro_draw(self): new_line_seqs = LineSegs() new_line_seqs.setThickness(2.0) #TODO new_line_seqs.setColor(Vec4(1, 1, 0, 0.5)) #TODO n = 0 for (points, faces) in self.input.current.voro: if self.selected_cells[n]: for (poly, poly_data) in faces: (x, y, z, point_data) = points[poly[0][0]] new_line_seqs.moveTo(Point3(x, y, z)) for i in xrange(1, len(poly)): (x, y, z, point_data) = points[poly[i][0]] new_line_seqs.drawTo(Point3(x, y, z)) (x, y, z, point_data) = points[poly[0][0]] new_line_seqs.drawTo(Point3(x, y, z)) if (self.grow_particles): self.balls[n].setColor(1.0, 1.0, 1.0, 0.25) else: self.balls[n].setColor(1.0, 1.0, 1.0, 1.0) else: if (self.grow_particles): self.balls[n].setColor(1.0, 1.0, 1.0, 0.05) else: self.balls[n].setColor(1.0, 1.0, 1.0, 0.5) n = n + 1 if not (self.vertices is None): self.vertices.removeNode() self.vertices = None if not (self.sides is None): self.sides.removeNode() self.sides = None if not (self.lines_thin is None): self.lines_thin.removeNode() self.lines_thin = None if not (self.lines_thick is None): self.lines_thick.removeNode() self.lines_thick = None if not (self.lines is None): self.lines.removeNode() self.lines = NodePath(new_line_seqs.create()) self.lines.reparentTo(self.render)
def createRainDrop(self, x=0, y=0, doubleDrop=False, tripleDrop=False): # Set up line geometry for rain. id = str(uuid.uuid4()) dummy = NodePath('dummy' + id) lineSegs = LineSegs('line' + id) if self.tripleDrop: lineSegs.setThickness(3.0) elif self.doubleDrop: lineSegs.setThickness(2.0) else: lineSegs.setThickness(1.0) lineSegs.moveTo(0, 0, 0) lineSegs.drawTo(0, 0, self.deltaZ * .1) lineGeomNode = lineSegs.create() # True: gray; False: white and red. if True: lineSegs.setVertexColor(0, Vec4(1, 1, 1, .4)) lineSegs.setVertexColor(1, Vec4(.3, .3, .3, 0)) pass else: lineSegs.setVertexColor(0, Vec4(1, 1, 1, .4)) lineSegs.setVertexColor(1, Vec4(1, 0, 0, 1)) linePath = dummy.attachNewNode(lineGeomNode) linePath.setTransparency(True) linePath.reparentTo(render) # Add collision node with 'FROM' tag = 'rain' pickerNode = CollisionNode('linecnode' + id) pickerNode.setTag('FROM', 'rain') rayCollider = linePath.attachNewNode(pickerNode) # A small collision sphere is attached to the bottom of each rain drop. rayCollider.node().addSolid(CollisionSphere(0, 0, 0, .25)) #base.cTrav.addCollider(rayCollider, collisionHandler) # Sequence rain Sequence( LerpPosInterval(linePath, self.dropDuration, Point3(x, y, self.pt1.z), Point3(x, y, self.pt2.z), blendType='easeIn', fluid=1), Parallel(Func(dummy.removeNode), Func(linePath.removeNode))).start()
def __init__(self,pickableList = []): self.pickable = pickableList tempCard = CardMaker('') tempCard.setFrame(0,1,0,1) #Lets render our frame so we can hide / show /resize it as needed self.selectFrame = render2d.attachNewNode(tempCard.generate()) self.selectFrame.setColor(1,1,0,.2) self.selectFrame.setTransparency(1) self.selectFrame.hide() #Set up our line segmants for a border ls = LineSegs() ls.moveTo(0,0,0) ls.drawTo(1,0,0) ls.drawTo(1,0,1) ls.drawTo(0,0,1) ls.drawTo(0,0,0) self.selectFrame.attachNewNode(ls.create()) self.selected = [] self.previousSelect = [] self.selectable = [] #Init our mouse locations self.pt2InitMousePos = (-1,-1) self.pt2LastMousePos = (-1,-1) self.fFovh , self.fFovv = base.camLens.getFov() self.fTimeLastUpdateRect = 0 self.fTimeLastUpdateSelected = 0 self.UpdateTimeRect = 0.015 self.UpdateTimeSelected = 0.015 print "Running Select Tools" self.accept("mouse1",self.OnStartSelect) self.accept("control-mouse1",self.OnStartSelect) self.accept("mouse1-up",self.OnMouseRelease) self.taskUpdateSelectRect = 0
def __init__(self, pickableList=[]): self.pickable = pickableList tempCard = CardMaker('') tempCard.setFrame(0, 1, 0, 1) #Lets render our frame so we can hide / show /resize it as needed self.selectFrame = render2d.attachNewNode(tempCard.generate()) self.selectFrame.setColor(1, 1, 0, .2) self.selectFrame.setTransparency(1) self.selectFrame.hide() #Set up our line segmants for a border ls = LineSegs() ls.moveTo(0, 0, 0) ls.drawTo(1, 0, 0) ls.drawTo(1, 0, 1) ls.drawTo(0, 0, 1) ls.drawTo(0, 0, 0) self.selectFrame.attachNewNode(ls.create()) self.selected = [] self.previousSelect = [] self.selectable = [] #Init our mouse locations self.pt2InitMousePos = (-1, -1) self.pt2LastMousePos = (-1, -1) self.fFovh, self.fFovv = base.camLens.getFov() self.fTimeLastUpdateRect = 0 self.fTimeLastUpdateSelected = 0 self.UpdateTimeRect = 0.015 self.UpdateTimeSelected = 0.015 print "Running Select Tools" self.accept("mouse1", self.OnStartSelect) self.accept("control-mouse1", self.OnStartSelect) self.accept("mouse1-up", self.OnMouseRelease) self.taskUpdateSelectRect = 0
class Arc(NodePath): """NodePath class representing a wire arc.""" def __init__(self, radius=1.0, numSegs=16, degrees=360, axis=Vec3(1, 0, 0), thickness=1.0, origin=Point3(0, 0, 0)): # Create line segments self.ls = LineSegs() self.ls.setThickness(thickness) # Get the points for an arc for p in GetPointsForArc(degrees, numSegs): # Draw the point rotated around the desired axis p = Point3(p[0], p[1], 0) - origin p = RotatePoint3(p, Vec3(0, 0, 1), axis) self.ls.drawTo(p * radius) # Init the node path, wrapping the lines node = self.ls.create() NodePath.__init__(self, node)
class Square(NodePath): """NodePath class representing a wire square.""" def __init__(self, width=1, height=1, axis=Vec3(1, 0, 0), thickness=1.0, origin=Point3(0, 0, 0)): # Create line segments self.ls = LineSegs() self.ls.setThickness(thickness) # Get the points for an arc points = GetPointsForSquare(width, height) points.append(points[0]) for p in points: # Draw the point rotated around the desired axis p = Point3(p[0], p[1], 0) - origin p = RotatePoint3(p, Vec3(0, 0, 1), axis) self.ls.drawTo(p) # Init the node path, wrapping the lines node = self.ls.create() NodePath.__init__(self, node)
def __init__( self, name, colour=(1, 1, 1, .2) ): p3d.Object.__init__( self, name ) # Create a card maker cm = CardMaker( self.name ) cm.setFrame( 0, 1, 0, 1 ) # Init the node path, wrapping the card maker to make a rectangle NodePath.__init__( self, cm.generate() ) self.setColor( colour ) self.setTransparency( 1 ) self.reparentTo( render2d ) self.hide() # Create the rectangle border ls = LineSegs() ls.moveTo( 0, 0, 0 ) ls.drawTo( 1, 0, 0 ) ls.drawTo( 1, 0, 1 ) ls.drawTo( 0, 0, 1 ) ls.drawTo( 0, 0, 0 ) # Attach border to rectangle self.attachNewNode( ls.create() ) #== self.started = False
def createRainDrop(self, x=0, y=0, doubleDrop=False, tripleDrop=False): # Set up line geometry for rain. id = str(uuid.uuid4()) dummy = NodePath('dummy'+id) lineSegs = LineSegs('line'+id) if self.tripleDrop: lineSegs.setThickness(3.0) elif self.doubleDrop: lineSegs.setThickness(2.0) else: lineSegs.setThickness(1.0) lineSegs.moveTo(0, 0, 0) lineSegs.drawTo(0, 0, self.deltaZ*.1) lineGeomNode = lineSegs.create() # True: gray; False: white and red. if True: lineSegs.setVertexColor(0, Vec4(1, 1, 1, .4)) lineSegs.setVertexColor(1, Vec4(.3, .3, .3, 0)) pass else: lineSegs.setVertexColor(0, Vec4(1, 1, 1, .4)) lineSegs.setVertexColor(1, Vec4(1, 0, 0, 1)) linePath = dummy.attachNewNode(lineGeomNode) linePath.setTransparency(True) linePath.reparentTo(render) # Add collision node with 'FROM' tag = 'rain' pickerNode = CollisionNode('linecnode'+id) pickerNode.setTag('FROM', 'rain') rayCollider = linePath.attachNewNode(pickerNode) # A small collision sphere is attached to the bottom of each rain drop. rayCollider.node().addSolid(CollisionSphere(0, 0, 0, .25)) #base.cTrav.addCollider(rayCollider, collisionHandler) # Sequence rain Sequence( LerpPosInterval(linePath, self.dropDuration, Point3(x, y, self.pt1.z), Point3(x, y, self.pt2.z), blendType='easeIn', fluid=1), Parallel(Func(dummy.removeNode), Func(linePath.removeNode)) ).start()
def HCtest(): # bounds = [(-10, -16, 0), (-10, 11, 0), (17, 11, 0), (17, -16, 0)] bounds = [(0, -3, 0), (0, 16, 0), (19, 16, 0), (19, -3, 0)] finalHCPoints = createHilbertCurve(4, bounds) boxsegs = LineSegs() boxsegs.setThickness(2.0) boxsegs.setColor(Vec4(1, 1, 1, 1)) boxsegs.moveTo(bounds[0]) boxsegs.drawTo(bounds[1]) boxsegs.drawTo(bounds[2]) boxsegs.drawTo(bounds[3]) boxsegs.drawTo(bounds[0]) boxsegs.moveTo(finalHCPoints[0]) for p in finalHCPoints[1:]: boxsegs.drawTo(p) return boxsegs.create()
def __Create( self, thickness, length ): # Build line segments ls = LineSegs() ls.setThickness( thickness ) # X Axis - Red ls.setColor( 1.0, 0.0, 0.0, 1.0 ) ls.moveTo( 0.0, 0.0, 0.0 ) ls.drawTo( length, 0.0, 0.0 ) # Y Axis - Green ls.setColor( 0.0, 1.0, 0.0, 1.0 ) ls.moveTo( 0.0,0.0,0.0 ) ls.drawTo( 0.0, length, 0.0 ) # Z Axis - Blue ls.setColor( 0.0, 0.0, 1.0, 1.0 ) ls.moveTo( 0.0,0.0,0.0 ) ls.drawTo( 0.0, 0.0, length ) return ls.create()
class GolfScoreBoard: notify = directNotify.newCategory('GolfScoreBoard') def __init__(self, golfCourse): self.golfCourse = golfCourse self.numPlayas = len(golfCourse.avIdList) self.avIdList = golfCourse.avIdList self.playaTags = [] self.scoreTags = [] self.totalTags = [] self.scoreLabels = [] self.holeLabels = [] self.parLabels = [] self.numExited = 0 self.setup() def setup(self): self.scoreboard = DirectFrame(parent=aspect2d, relief=None, geom=DGG.getDefaultDialogGeom(), geom_color=ToontownGlobals.GlobalDialogColor, geom_scale=(1.9, 1, 1.05), pos=(0, 0, 0.375)) self.lines = LineSegs() self.lines.setColor(0, 0, 0, 1) self.lines.setThickness(2) guiModel = loader.loadModel('phase_6/models/golf/golf_gui') highlight = loader.loadModel('phase_6/models/golf/headPanel') self.maximizeB = DirectButton(parent=base.a2dBottomRight, pos=(-0.15, 0, 0.15), relief=None, state=DGG.NORMAL, image=(guiModel.find('**/score_card_icon'), guiModel.find('**/score_card_icon_rollover'), guiModel.find('**/score_card_icon_rollover')), image_scale=(0.2, 1, 0.2), command=self.showBoard) self.vertOffset = 0.13 self.playaTop = 0.12 horzOffset = 0.12 holeTop = 0.3 self.vCenter = 0.025 totScore = 0 totPar = 0 self.lineVStart = -0.465 self.lineHStart = 0.17 self.lineHorOffset = 0.13 self.lineVertOffset = 0.125 self.lineVCenter = 0.025 buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui') self.minimizeB = DirectButton(parent=self.scoreboard, pos=(0, 0, self.lineHStart - 0.59), relief=None, state=DGG.NORMAL, image=(buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr')), image_scale=(1, 1, 1), command=self.hideBoard, extraArgs=[None]) self.exitCourseB = DirectButton(parent=self.scoreboard, pos=(0, 0, self.lineHStart - 0.59), relief=None, state=DGG.NORMAL, image=(buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr')), image_scale=(1, 1, 1), text=TTLocalizer.GolfExitCourse, text_scale=0.04, text_pos=TTLocalizer.GSBexitCourseBPos, command=self.exitCourse) self.exitCourseB.hide() self.highlightCur = DirectLabel(parent=self.scoreboard, relief=None, pos=(-0.003, 0, 0.038), image=highlight, image_scale=(1.82, 1, 0.135)) self.titleBar = DirectLabel(parent=self.scoreboard, relief=None, pos=(-0.003, 0, 0.166), color=(0.7, 0.7, 0.7, 0.3), image=highlight, image_scale=(1.82, 1, 0.195)) self.titleBar.show() self.highlightCur.show() buttons.removeNode() guiModel.removeNode() title = GolfGlobals.getCourseName(self.golfCourse.courseId) + ' - ' + GolfGlobals.getHoleName(self.golfCourse.holeIds[self.golfCourse.curHoleIndex]) self.titleLabel = DirectLabel(parent=self.scoreboard, relief=None, pos=(0, 0, holeTop + 0.1), text_align=TextNode.ACenter, text=title, text_scale=TTLocalizer.GSBtitleLabel, text_font=ToontownGlobals.getSignFont(), text_fg=(0, 0.5, 0.125, 1)) self.playaLabel = DirectLabel(parent=self.scoreboard, relief=None, pos=(self.lineVStart - 0.23, 0, holeTop), text_align=TextNode.ACenter, text=TTLocalizer.GolfHole, text_font=ToontownGlobals.getMinnieFont(), text_scale=0.05) for holeLIndex in xrange(self.golfCourse.numHoles): holeLabel = DirectLabel(parent=self.scoreboard, relief=None, pos=(self.lineVStart + 0.055 + horzOffset * holeLIndex, 0, holeTop), text_align=TextNode.ACenter, text='%s' % (holeLIndex + 1), text_scale=0.05) self.holeLabels.append(holeLabel) self.totalLabel = DirectLabel(parent=self.scoreboard, relief=None, pos=(self.lineVStart + 0.1 + horzOffset * 9.5, 0, holeTop), text_align=TextNode.ACenter, text=TTLocalizer.GolfTotal, text_font=ToontownGlobals.getMinnieFont(), text_scale=0.05) self.parTitleLabel = DirectLabel(parent=self.scoreboard, relief=None, pos=(self.lineVStart - 0.23, 0, holeTop - 0.1), text_align=TextNode.ACenter, text=TTLocalizer.GolfPar, text_font=ToontownGlobals.getMinnieFont(), text_scale=0.05) for parHoleIndex in xrange(self.golfCourse.numHoles): parLabel = DirectLabel(parent=self.scoreboard, relief=None, pos=(self.lineVStart + 0.055 + horzOffset * parHoleIndex, 0, holeTop - 0.1), text_align=TextNode.ACenter, text='%s' % GolfGlobals.HoleInfo[self.golfCourse.holeIds[parHoleIndex]]['par'], text_scale=0.05, text_wordwrap=10) totPar = totPar + GolfGlobals.HoleInfo[self.golfCourse.holeIds[parHoleIndex]]['par'] self.parLabels.append(parLabel) parLabel = DirectLabel(parent=self.scoreboard, relief=None, pos=(self.lineVStart + 0.1 + horzOffset * 9.5, 0, holeTop - 0.1), text_align=TextNode.ACenter, text='%s' % totPar, text_scale=0.05, text_wordwrap=10) self.parLabels.append(parLabel) vert = 0.0 self.numPlayas = len(self.golfCourse.avIdList) for playaIndex in xrange(self.numPlayas): name = TTLocalizer.GolfUnknownPlayer av = base.cr.doId2do.get(self.golfCourse.avIdList[playaIndex]) if av: name = av.getName() playaLabel = DirectLabel(parent=self.scoreboard, relief=None, text_align=TextNode.ACenter, text=name, text_scale=0.05, text_wordwrap=9) self.playaTags.append(playaLabel) textN = playaLabel.component(playaLabel.components()[0]) if type(textN) == OnscreenText: try: if textN.textNode.getWordwrappedWtext() != name: vert = self.playaTop - self.vertOffset * playaIndex else: vert = self.playaTop - self.vertOffset * playaIndex - self.vCenter except: vert = self.playaTop - self.vertOffset * playaIndex self.playaTags[playaIndex].setPos(self.lineVStart - 0.23, 0, vert) self.notify.debug('self.text height = %f' % self.playaTags[playaIndex].getHeight()) holeIndex = 0 for holeIndex in xrange(self.golfCourse.numHoles): holeLabel = DirectLabel(parent=self.scoreboard, relief=None, pos=(self.lineVStart + 0.055 + horzOffset * holeIndex, 0, self.playaTop - self.vertOffset * playaIndex - self.vCenter), text_align=TextNode.ACenter, text='-', text_scale=0.05, text_wordwrap=10) self.scoreTags.append(holeLabel) holeLabel = DirectLabel(parent=self.scoreboard, relief=None, pos=(self.lineVStart + 0.1 + horzOffset * 9.5, 0, self.playaTop - self.vertOffset * playaIndex - self.vCenter), text_align=TextNode.ACenter, text='-', text_scale=0.05, text_wordwrap=10) self.totalTags.append(holeLabel) self.lines.moveTo(self.lineVStart - 0.45, 0, self.lineHStart + 0.19) self.lines.drawTo(self.lineVStart + 11 * self.lineVertOffset, 0, self.lineHStart + 0.19) self.lines.moveTo(self.lineVStart - 0.45, 0, self.lineHStart + 0.09) self.lines.drawTo(self.lineVStart + 11 * self.lineVertOffset, 0, self.lineHStart + 0.09) self.lines.moveTo(self.lineVStart - 0.45, 0, self.lineHStart) self.lines.drawTo(self.lineVStart + 11 * self.lineVertOffset, 0, self.lineHStart) self.lines.moveTo(self.lineVStart - 0.45, 0, self.lineHStart + 0.19) self.lines.drawTo(self.lineVStart - 0.45, 0, self.lineHStart - 4 * 0.13) self.lines.moveTo(self.lineVStart, 0, self.lineHStart + 0.19) self.lines.drawTo(self.lineVStart, 0, self.lineHStart - 4 * 0.13) for x in xrange(4): self.lines.moveTo(self.lineVStart - 0.45, 0, self.lineHStart - (x + 1) * self.lineHorOffset) self.lines.drawTo(self.lineVStart + 11 * self.lineVertOffset + 0.005, 0, self.lineHStart - (x + 1) * self.lineHorOffset) for y in xrange(10): self.lines.moveTo(self.lineVStart + y * self.lineVertOffset, 0, self.lineHStart + 0.19) self.lines.drawTo(self.lineVStart + y * self.lineVertOffset, 0, self.lineHStart - 4 * 0.13) self.lines.moveTo(self.lineVStart + 11 * self.lineVertOffset, 0, self.lineHStart + 0.19) self.lines.drawTo(self.lineVStart + 11 * self.lineVertOffset, 0, self.lineHStart - 4 * 0.13) self.scoreboard.attachNewNode(self.lines.create()) self.hide() return def getScoreLabel(self, avIdorIndex, holeNum): index = None if avIdorIndex < 100: index = avIdorIndex else: for playaIndex in xrange(self.numPlayas): if self.golfCourse.avIdList[playaIndex] == avIdorIndex: index = playaIndex return self.scoreTags[index * self.golfCourse.numHoles + holeNum] def update(self): self.showBoard() taskMgr.doMethodLater(AUTO_HIDE_TIMEOUT, self.hideBoard, 'hide score board') def hideBoard(self, task): self.hide() def hide(self): self.scoreboard.hide() self.maximizeB.show() def showBoardFinal(self, task = None): self.exitCourseB.show() self.minimizeB.hide() self.showBoard() def showBoard(self, task = None): scoreDict = self.golfCourse.scores x = 0 currentGolfer = self.golfCourse.getCurGolfer() for playaIndex in xrange(self.numPlayas): if self.golfCourse.isGameDone(): self.playaTags[playaIndex].setColor(0, 0, 0, 1) elif currentGolfer == self.golfCourse.avIdList[playaIndex]: self.highlightCur.setColor(*GolfGlobals.PlayerColors[playaIndex]) self.highlightCur.setAlphaScale(0.4) self.highlightCur.setPos(-0.003, 0, 0.038 - playaIndex * (self.lineVertOffset + 0.005)) self.highlightCur.show() else: self.playaTags[playaIndex].setColor(0, 0, 0, 1) for avId in self.avIdList: holeIndex = 0 totScore = 0 playerExited = False for y in xrange(len(self.golfCourse.exitedAvIdList)): if self.golfCourse.exitedAvIdList[y] == avId: self.playaTags[x].setColor(0.7, 0.7, 0.7, 1) holeIndex = 0 for holeIndex in xrange(self.golfCourse.numHoles): self.getScoreLabel(self.avIdList[x], holeIndex).setColor(0.7, 0.7, 0.7, 1) self.totalTags[x].setColor(0.7, 0.7, 0.7, 1) playerExited = True if playerExited == False: for holeIndex in xrange(self.golfCourse.numHoles): if holeIndex <= self.golfCourse.curHoleIndex: self.getScoreLabel(avId, holeIndex)['text'] = '%s' % scoreDict[avId][holeIndex] totScore = totScore + scoreDict[avId][holeIndex] if self.golfCourse.isGameDone() == False: if holeIndex == self.golfCourse.curHoleIndex: self.getScoreLabel(avId, holeIndex).setColor(1, 0, 0, 1) self.holeLabels[holeIndex].setColor(1, 0, 0, 1) self.parLabels[holeIndex].setColor(1, 0, 0, 1) title = GolfGlobals.getCourseName(self.golfCourse.courseId) + ' - ' + GolfGlobals.getHoleName(self.golfCourse.holeIds[self.golfCourse.curHoleIndex]) self.titleLabel['text'] = title else: self.getScoreLabel(avId, holeIndex).setColor(0, 0, 0, 1) self.holeLabels[holeIndex].setColor(0, 0, 0, 1) self.parLabels[holeIndex].setColor(0, 0, 0, 1) self.totalTags[x]['text'] = '%s' % totScore if self.golfCourse.isGameDone(): self.getScoreLabel(avId, self.golfCourse.numHoles - 1).setColor(0, 0, 0, 1) self.totalTags[x].setColor(1, 0, 0, 1) x = x + 1 y = 0 if self.golfCourse.isGameDone(): self.parLabels[self.golfCourse.numHoles - 1].setColor(0, 0, 0, 1) self.holeLabels[self.golfCourse.numHoles - 1].setColor(0, 0, 0, 1) self.parLabels[self.golfCourse.numHoles].setColor(1, 0, 0, 1) self.totalLabel.setColor(1, 0, 0, 1) self.scoreboard.show() self.maximizeB.hide() def exitCourse(self): course = self.golfCourse self.delete() course.exitEarly() def delete(self): if self.maximizeB: self.maximizeB.destroy() self.maximizeB = None if self.scoreboard: self.scoreboard.destroy() self.scoreboard = None self.golfCourse = None taskMgr.remove('hide score board') return
def draw(self): # Setup curr mouse pos in 3d space posXY = self.getMouseXY() x = posXY.getX() y = posXY.getY() z = 0 # Draw movement radius moveRadLine = LineSegs() moveRadLine.setThickness(1) moveRadLine.setColor(self._color) moveRadLine.moveTo(self.moveRad, 0, 0) for i in range(self._EDGES + 1): newX = (self.moveRad * math.cos((2*math.pi/self._EDGES)*i)) newY = (self.moveRad * math.sin((2*math.pi/self._EDGES)*i)) moveRadLine.drawTo(newX, newY, 0) moveRadGeom = moveRadLine.create() self._moveRadCircleNP = NodePath(moveRadGeom) self._moveRadCircleNP.reparentTo(self._np) # Draw movement foot circle self._moveFootCircle.setThickness(1) self._moveFootCircle.setColor(self._color) self._moveFootCircle.moveTo(self.footRad, 0, 0) for i in range(self._EDGES): newX = (self.footRad * math.cos((2*math.pi/self._EDGES)*i)) newY = (self.footRad * math.sin((2*math.pi/self._EDGES)*i)) self._moveFootCircle.drawTo(newX, newY, 0) self._moveFootCircle.drawTo(self.footRad, 0, 0) moveFootCircleGeom = self._moveFootCircle.create() self._moveFootCircleNP = NodePath(moveFootCircleGeom) self._moveFootCircleNP.reparentTo(self._np) # Draw movement direction line self._moveLine.setThickness(1) self._moveLine.setColor(self._color) self._moveLine.moveTo(0, 0, 0) self._moveLine.drawTo(x, y, z) moveLine = self._moveLine.create() self._moveLineNP = NodePath(moveLine) self._moveLineNP.reparentTo(self._np) # Draw Z line self._moveZLine.setThickness(1) self._moveZLine.setColor(self._color) self._moveZLine.moveTo(self.start) self._moveZLine.drawTo(x, y, z) moveZLine = self._moveZLine.create() self._moveZLineNP = NodePath(moveZLine) self._moveZLineNP.reparentTo(self._np) # Draw Attack Radius self._attackRadCircle.setThickness(1) self._attackRadCircle.setColor(0.8, 0.0, 0.0, 1) self._attackRadCircle.moveTo(self.attackRad, 0, 0) for i in range(self._EDGES + 1): newX = (self.attackRad * math.cos((2*math.pi/self._EDGES)*i)) newY = (self.attackRad * math.sin((2*math.pi/self._EDGES)*i)) self._attackRadCircle.drawTo(newX, newY, 0) attackRadCircleGeom = self._attackRadCircle.create() self._attackRadCircleNP = NodePath(attackRadCircleGeom) self._attackRadCircleNP.reparentTo(self._np)
class RepairSawingLine: def __init__(self, parent, thickness, color, lineSpawnDist = 0.01): self.points = [] self.parent = parent self.thickness = thickness self.color = color self.lineNode = None self.lineDrawer = LineSegs() self.lineDrawer.setThickness(thickness) self.lineSpawnDist = lineSpawnDist self.currentPoint = None self.startPoint = None self.redraw() def redraw(self): self.clearLine() self.lineDrawer.reset() self.lineDrawer.setThickness(self.thickness) self.lineDrawer.setColor(self.color) if len(self.points) > 0: self.lineDrawer.moveTo(self.points[0]) for i in range(1, len(self.points)): p = self.points[i] self.lineDrawer.drawTo(p) self.currentPoint = p self.lineNode = NodePath(self.lineDrawer.create()) self.lineNode.reparentTo(self.parent) self.lineNode.setBin('fixed', 37) self.lineNode.setTransparency(True) def update(self, point): if self.currentPoint == None or (point - self.currentPoint).length() >= self.lineSpawnDist: self.addPoint(point) self.redraw() def addPoint(self, p): if len(self.points) == 0: self.startPoint = p self.points.append(p) def clearLine(self): if self.lineNode != None: self.lineNode.removeNode() def reset(self): self.clearLine() self.points = [] self.redraw() self.currentPoint = None self.startPoint = None def show(self): self.lineNode.unstash() def hide(self): self.lineNode.stash()
class MoveCursor(object): _EDGES = 40 _zPos = 0 _movingUp = False _movingDown = False _color = Vec4(0.3, 0.3, 0.8, 1) _currentPos = Vec3(0, 0, 0) def __init__(self, parent, entity, foot=1): self.entity = entity self._moveRadCircleNP = NodePath("Movement Radius Node") self._moveLine = LineSegs() self._moveLineNP = NodePath("Movement Direction Line Node") self._moveZLine = LineSegs() self._moveZLineNP = NodePath("Movement Z Line Node") self._moveZFootNP = NodePath("Movement Z Foot Node") self._moveFootCircle = LineSegs() self._moveFootCircleNP = NodePath("Movement Foot Circle Node") self._attackRadCircle = LineSegs() self._attackRadCircleNP = NodePath("Attack Radius Node") self._np = NodePath("Movement Node") self.attackables = [] Event.Dispatcher().register(self, 'E_Key_ZUp', self.onZChange) Event.Dispatcher().register(self, 'E_Key_ZDown', self.onZChange) Event.Dispatcher().register(self, 'E_Key_ZUp-up', self.onZChange) Event.Dispatcher().register(self, 'E_Key_ZDown-up', self.onZChange) self.aaLevel = int(GameSettings().getSetting('ANTIALIAS')) self.parent = parent self.start = Vec3(0, 0, 0) self.moveRad = entity.moveRad self.footRad = foot self.attackRad = entity.attackRad self.plane = Plane(Vec3(0, 0, 1), Point3(0, 0, 0)) self.draw() self._np.reparentTo(self.parent) if self.aaLevel > 0: self._np.setAntialias(AntialiasAttrib.MLine, self.aaLevel) taskMgr.add(self.updateMovePos, 'Movement Indicator Update Task') def draw(self): # Setup curr mouse pos in 3d space posXY = self.getMouseXY() x = posXY.getX() y = posXY.getY() z = 0 # Draw movement radius moveRadLine = LineSegs() moveRadLine.setThickness(1) moveRadLine.setColor(self._color) moveRadLine.moveTo(self.moveRad, 0, 0) for i in range(self._EDGES + 1): newX = (self.moveRad * math.cos((2 * math.pi / self._EDGES) * i)) newY = (self.moveRad * math.sin((2 * math.pi / self._EDGES) * i)) moveRadLine.drawTo(newX, newY, 0) moveRadGeom = moveRadLine.create() self._moveRadCircleNP = NodePath(moveRadGeom) self._moveRadCircleNP.reparentTo(self._np) # Draw movement foot circle self._moveFootCircle.setThickness(1) self._moveFootCircle.setColor(self._color) self._moveFootCircle.moveTo(self.footRad, 0, 0) for i in range(self._EDGES): newX = (self.footRad * math.cos((2 * math.pi / self._EDGES) * i)) newY = (self.footRad * math.sin((2 * math.pi / self._EDGES) * i)) self._moveFootCircle.drawTo(newX, newY, 0) self._moveFootCircle.drawTo(self.footRad, 0, 0) moveFootCircleGeom = self._moveFootCircle.create() self._moveFootCircleNP = NodePath(moveFootCircleGeom) self._moveFootCircleNP.reparentTo(self._np) # Draw movement direction line self._moveLine.setThickness(1) self._moveLine.setColor(self._color) self._moveLine.moveTo(0, 0, 0) self._moveLine.drawTo(x, y, z) moveLine = self._moveLine.create() self._moveLineNP = NodePath(moveLine) self._moveLineNP.reparentTo(self._np) # Draw Z line self._moveZLine.setThickness(1) self._moveZLine.setColor(self._color) self._moveZLine.moveTo(self.start) self._moveZLine.drawTo(x, y, z) moveZLine = self._moveZLine.create() self._moveZLineNP = NodePath(moveZLine) self._moveZLineNP.reparentTo(self._np) # Draw Attack Radius self._attackRadCircle.setThickness(1) self._attackRadCircle.setColor(0.8, 0.0, 0.0, 1) self._attackRadCircle.moveTo(self.attackRad, 0, 0) for i in range(self._EDGES + 1): newX = (self.attackRad * math.cos((2 * math.pi / self._EDGES) * i)) newY = (self.attackRad * math.sin((2 * math.pi / self._EDGES) * i)) self._attackRadCircle.drawTo(newX, newY, 0) attackRadCircleGeom = self._attackRadCircle.create() self._attackRadCircleNP = NodePath(attackRadCircleGeom) self._attackRadCircleNP.reparentTo(self._np) def updateMovePos(self, Task): # endPos must be transformed in the the coord sys of the model m_pos = self.getMouseXY() if m_pos is not None: # Transform current mouse pos endPos = self.parent.getRelativePoint(render, m_pos) # Adjust Z coord if needed if self._movingUp: self._zPos += 0.1 elif self._movingDown: self._zPos -= 0.1 endPos.setZ(self._zPos) # Check if we're trying to move too far, if not update pos dist = math.sqrt(endPos.getX()**2 + endPos.getY()**2 + 2 * (endPos.getZ()**2)) if dist <= self.moveRad: self._moveLine.setVertex(1, endPos) self._moveFootCircleNP.setPos(endPos) self._moveZLine.setVertex( 0, Point3(endPos.getX(), endPos.getY(), 0)) self._moveZLine.setVertex(1, endPos) self._attackRadCircleNP.setPos(endPos) self._currentPos = render.getRelativePoint(self._np, endPos) # Check for attackable ships in range of current pos attackables = Entity.EntityManager().getEntitiesWithin( self._currentPos, self.attackRad) # Unhighlight ships no longer in range for e in self.attackables: if e not in attackables and isinstance( e, Entity.EntityShip): e.representation.unsetAttackable() # Highlight ships in range for e in attackables: if isinstance( e, Entity.EntityShip ) and e != self.entity and e.owner != self.entity.owner: e.representation.setAttackable() self.attackables = attackables return Task.cont def onZChange(self, event): if event.type == 'E_Key_ZUp': self._movingDown = False self._movingUp = True if event.type == 'E_Key_ZDown': self._movingUp = False self._movingDown = True if event.type == 'E_Key_ZUp-up': self._movingUp = False self._movingDown = False if event.type == 'E_Key_ZDown-up': self._movingUp = False self._movingDown = False def getMouseXY(self): # NOTE - this returns the mouse pos in the ships coord sys if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() pos3d = Point3() nearPoint = Point3() farPoint = Point3() base.camLens.extrude(mpos, nearPoint, farPoint) if self.plane.intersectsLine( pos3d, render.getRelativePoint(camera, nearPoint), render.getRelativePoint(camera, farPoint)): #print("Mouse ray intersects ground plane at " + str(pos3d)) return pos3d def getPosition(self): return self._currentPos def removeNode(self): taskMgr.remove('Movement Indicator Update Task') for e in self.attackables: if isinstance(e, Entity.EntityShip): e.representation.unsetAttackable() self._moveRadCircleNP.removeNode() self._moveLineNP.removeNode() self._moveZLineNP.removeNode() self._moveZFootNP.removeNode() self._moveFootCircleNP.removeNode() self._attackRadCircleNP.removeNode() self._np.removeNode() def __del__(self): # TODO - This isn't calling self.removeNode() correctly self._np.removeNode()
def draw(self): # Setup curr mouse pos in 3d space posXY = self.getMouseXY() x = posXY.getX() y = posXY.getY() z = 0 # Draw movement radius moveRadLine = LineSegs() moveRadLine.setThickness(1) moveRadLine.setColor(self._color) moveRadLine.moveTo(self.moveRad, 0, 0) for i in range(self._EDGES + 1): newX = (self.moveRad * math.cos((2 * math.pi / self._EDGES) * i)) newY = (self.moveRad * math.sin((2 * math.pi / self._EDGES) * i)) moveRadLine.drawTo(newX, newY, 0) moveRadGeom = moveRadLine.create() self._moveRadCircleNP = NodePath(moveRadGeom) self._moveRadCircleNP.reparentTo(self._np) # Draw movement foot circle self._moveFootCircle.setThickness(1) self._moveFootCircle.setColor(self._color) self._moveFootCircle.moveTo(self.footRad, 0, 0) for i in range(self._EDGES): newX = (self.footRad * math.cos((2 * math.pi / self._EDGES) * i)) newY = (self.footRad * math.sin((2 * math.pi / self._EDGES) * i)) self._moveFootCircle.drawTo(newX, newY, 0) self._moveFootCircle.drawTo(self.footRad, 0, 0) moveFootCircleGeom = self._moveFootCircle.create() self._moveFootCircleNP = NodePath(moveFootCircleGeom) self._moveFootCircleNP.reparentTo(self._np) # Draw movement direction line self._moveLine.setThickness(1) self._moveLine.setColor(self._color) self._moveLine.moveTo(0, 0, 0) self._moveLine.drawTo(x, y, z) moveLine = self._moveLine.create() self._moveLineNP = NodePath(moveLine) self._moveLineNP.reparentTo(self._np) # Draw Z line self._moveZLine.setThickness(1) self._moveZLine.setColor(self._color) self._moveZLine.moveTo(self.start) self._moveZLine.drawTo(x, y, z) moveZLine = self._moveZLine.create() self._moveZLineNP = NodePath(moveZLine) self._moveZLineNP.reparentTo(self._np) # Draw Attack Radius self._attackRadCircle.setThickness(1) self._attackRadCircle.setColor(0.8, 0.0, 0.0, 1) self._attackRadCircle.moveTo(self.attackRad, 0, 0) for i in range(self._EDGES + 1): newX = (self.attackRad * math.cos((2 * math.pi / self._EDGES) * i)) newY = (self.attackRad * math.sin((2 * math.pi / self._EDGES) * i)) self._attackRadCircle.drawTo(newX, newY, 0) attackRadCircleGeom = self._attackRadCircle.create() self._attackRadCircleNP = NodePath(attackRadCircleGeom) self._attackRadCircleNP.reparentTo(self._np)
class DirectionExperiment(ViewTowers): def __init__(self, *args, **kwargs): ViewTowers.__init__(self, *args, **kwargs) # ignore keys set by viewer for key in self.getAllAccepting(): if key in ("s", "escape"): continue self.ignore(key) self.permanent_events = self.getAllAccepting() # global variables self.text_bg = (1, 1, 1, 0.7) self.font = self.loader.loadFont('cmr12.egg') self.question = ( "Use the mouse to indicate the direction that " "the tower will fall.") self.feedback_time = 3.0 self.buffer_time = 0.75 # create text self.create_all_text() # create direction line self.line = LineSegs() self.line_node = None self.angle = None alight = AmbientLight('alight3') alight.setColor((0.8, 0.8, 0.8, 1)) self.line_light = self.lights.attachNewNode(alight) def place_camera(self): self.cameras.setPos(0, -12, 2.5) self.look_at.setPos(0, 0, 1.5) self.cameras.lookAt(self.look_at) def run(self): # Show the start screen self.toggle_task("show_start_screen") # Call parent's run(). ShowBase.run(self) def create_all_text(self): self.continue_text = OnscreenText(**{ "text": ( "In a moment, you will be asked the question displayed on " "the left. When you are ready, press the spacebar to begin."), "style": 1, "fg": (.75, 0, 0, 1), "bg": self.text_bg, "pos": (.4, .4), "align": TextNode.ACenter, "scale": .08, "font": self.font, "wordwrap": 20 }) self.text_parent = self.continue_text.getParent() self.continue_text.detachNode() xpos = -1.25 self.question_text = OnscreenText(**{ "text": self.question, "style": 1, "fg": (0, 0, .8, 1), "bg": self.text_bg, "pos": ((xpos + .05), .8), "align": TextNode.ALeft, "scale": .075, "font": self.font, "wordwrap": 35}) self.trials_remaining_text = OnscreenText(**{ "text": "", "style": 1, "fg": (0, 0, 0, 1), "bg": self.text_bg, "pos": (-xpos, -.95), "align": TextNode.ARight, "scale": .05, "font": self.font}) def show_start_screen(self, task): self.continue_text.reparentTo(self.text_parent) self.accept("space", self.toggle_task, ["show_trial"]) def show_trial(self, task): if self.line_node is not None: self.line_node.removeNode() self.line_node = None if self.sso is None: self.goto_sso(0) elif self.ssos.index(self.sso) == (self.n_ssos - 1): self.exit() else: self.next() n = self.n_ssos - self.ssos.index(self.sso) self.trials_remaining_text.setText("Trials remaining: %d" % n) self.continue_text.detachNode() self.camera_rot.setH(np.random.randint(0, 360)) self.cam_spin = 270 self.taskMgr.doMethodLater(self.buffer_time, self.rotate, "rotate") def rotate(self, task): """ Task: rotate camera.""" H = (self.camera_rot.getH() + 1) % 360 self.camera_rot.setH(H) self.cam_spin -= 1 if self.cam_spin == 0: self.toggle_task("show_question") return task.done else: return task.cont def show_question(self, task): self.toggle_task("draw_direction") self.accept("mouse1", self.record_response) def record_response(self): self.ignore("mouse1") self.taskMgr.remove("draw_direction") self.toggle_task("physics") def physics(self, task): """ Task: simulate physics.""" # Elapsed time. dt = self._get_elapsed() - self.old_elapsed # Update amount of time simulated so far. self.old_elapsed += dt # Step the physics dt time. size_sub = self.bbase.sim_par["size_sub"] n_subs = int(dt / size_sub) self.bbase.step(dt, n_subs, size_sub) if self.old_elapsed >= self.feedback_time: self.toggle_task("show_trial") return task.done else: return task.cont def draw_direction(self, task): if self.mouseWatcherNode.hasMouse(): cv = self._get_collision(self.floor) cv = cv / np.linalg.norm(cv) self.angle = np.arctan2(cv[1], cv[0]) sx, sy, sz = self.floor.getScale() / 2.0 gx, gy, gz = self.floor.getPos() gz += sz + 0.01 if self.line_node is not None: self.line_node.removeNode() self.line_node = None self.line.reset() self.line.setColor(1, 1, 1, 1) self.line.setThickness(5) self.line.moveTo(gx, gy, gz) self.line.drawTo(cv[0] * sx, cv[1] * sy, gz) self.line_node = self.render.attachNewNode(self.line.create()) self.line_node.setLight(self.line_light) return task.cont def _get_collision(self, node, debug=False): mx = self.mouseWatcherNode.getMouseX() my = self.mouseWatcherNode.getMouseY() if debug: print "mouse:", (mx, my) # get the origin and direction of the ray extending from the # camera to the mouse pointer cm = np.array(self.cam.getNetTransform().getMat()) cr = CollisionRay() cr.setFromLens(self.cam.node(), (mx, my)) cp = np.hstack([cr.getOrigin(), 1]) cd = np.hstack([cr.getDirection(), 0]) cp = np.dot(cm.T, cp)[:3] cd = np.dot(cm.T, cd)[:3] if cd[2] > -1: cd[2] = -1 if debug: print "direction:", cd print "origin:", cp # point on the plane, z-axis pz = node.getPos(self.render)[2] sz = node.getScale(self.render)[2] / 2.0 p0 = np.array([0, 0, pz + sz]) if debug: print "p0:", p0 # this is the intersection equation that we want to solve, # where s is the point on the line that intersects # e_z(cp + s*cd - p0) = 0 s = (p0[2] - cp[2]) / cd[2] if debug: print "s:", s # transform the collision point from line coordinates to world # coordinates cv = cp + s * cd if debug: print "collision:", cv return cv
class MoveCursor(object): _EDGES = 40 _zPos = 0 _movingUp = False _movingDown = False _color = Vec4(0.3, 0.3, 0.8, 1) _currentPos = Vec3(0, 0, 0) def __init__(self, parent, entity, foot=1): # We keep a reference to the entity self.entity = entity # Setup the components of the cursor self._moveRadCircleNP = NodePath("Movement Radius Node") self._moveLine = LineSegs() self._moveLineNP = NodePath("Movement Direction Line Node") self._moveZLine = LineSegs() self._moveZLineNP = NodePath("Movement Z Line Node") self._moveZFootNP = NodePath("Movement Z Foot Node") self._moveFootCircle = LineSegs() self._moveFootCircleNP = NodePath("Movement Foot Circle Node") self._np = NodePath("Movement Node") self.aaLevel = 16 self.parent = parent self.start = Vec3(0, 0, 0) self.moveRad = entity.moveRadius self.footRad = foot self.plane = Plane(Vec3(0, 0, 1), Point3(0, 0, 0)) if self.aaLevel > 0: self._np.setAntialias(AntialiasAttrib.MLine, self.aaLevel) x = 0 y = 0 z = 0 # Draw movement radius moveRadLine = LineSegs() moveRadLine.setThickness(1) moveRadLine.setColor(self._color) moveRadLine.moveTo(self.moveRad, 0, 0) for i in range(self._EDGES + 1): newX = (self.moveRad * math.cos((2*math.pi/self._EDGES)*i)) newY = (self.moveRad * math.sin((2*math.pi/self._EDGES)*i)) moveRadLine.drawTo(newX, newY, 0) moveRadGeom = moveRadLine.create() self._moveRadCircleNP = NodePath(moveRadGeom) self._moveRadCircleNP.reparentTo(self._np) # Draw movement foot circle self._moveFootCircle.setThickness(1) self._moveFootCircle.setColor(self._color) self._moveFootCircle.moveTo(self.footRad, 0, 0) for i in range(self._EDGES): newX = (self.footRad * math.cos((2*math.pi/self._EDGES)*i)) newY = (self.footRad * math.sin((2*math.pi/self._EDGES)*i)) self._moveFootCircle.drawTo(newX, newY, 0) self._moveFootCircle.drawTo(self.footRad, 0, 0) moveFootCircleGeom = self._moveFootCircle.create() self._moveFootCircleNP = NodePath(moveFootCircleGeom) self._moveFootCircleNP.reparentTo(self._np) # Draw movement direction line self._moveLine.setThickness(1) self._moveLine.setColor(self._color) self._moveLine.moveTo(0, 0, 0) self._moveLine.drawTo(x, y, z) self.moveLineGO = self._moveLine.create(True) self._moveLineNP = NodePath(self.moveLineGO) self._moveLineNP.reparentTo(self._np) def updateMovePos(self, Task): # endPos must be transformed in the the coord sys of the model m_pos = self.getMouseXY() if m_pos is not None: # Transform current mouse pos endPos = self.parent.getRelativePoint(render, m_pos) # Adjust Z coord if needed if self._movingUp: self._zPos += 0.1 elif self._movingDown: self._zPos -= 0.1 endPos.setZ(self._zPos) # Check if we're trying to move too far, if not update pos dist = math.sqrt(endPos.getX()**2 + endPos.getY()**2 + 2*(endPos.getZ()**2)) if dist <= self.moveRad: self._moveLine.setVertex(1, endPos) self._moveFootCircleNP.setPos(endPos) #self._currentPos = self.parent.getRelativePoint(self.parent, endPos) #print("endPos=%s"%endPos) #print("myRelPos=%s"%self._currentPos) self._currentPos = endPos return Task.cont def getMouseXY(self): # NOTE - this returns the mouse pos in the ships coord sys if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() pos3d = Point3() nearPoint = Point3() farPoint = Point3() base.camLens.extrude(mpos, nearPoint, farPoint) if self.plane.intersectsLine(pos3d, render.getRelativePoint(camera, nearPoint), render.getRelativePoint(camera, farPoint)): return pos3d return None def getPosition(self): return self._currentPos def startDrawing(self): self._np.reparentTo(self.parent) taskMgr.add(self.updateMovePos, 'Movement Indicator Update Task') def stopDrawing(self): taskMgr.remove('Movement Indicator Update Task') self._np.detachNode()
class MoveCursor(object): _EDGES = 40 _zPos = 0 _movingUp = False _movingDown = False _color = Vec4(0.3, 0.3, 0.8, 1) _currentPos = Vec3(0, 0, 0) def __init__(self, parent, entity, foot=1): self.entity = entity self._moveRadCircleNP = NodePath("Movement Radius Node") self._moveLine = LineSegs() self._moveLineNP = NodePath("Movement Direction Line Node") self._moveZLine = LineSegs() self._moveZLineNP = NodePath("Movement Z Line Node") self._moveZFootNP = NodePath("Movement Z Foot Node") self._moveFootCircle = LineSegs() self._moveFootCircleNP = NodePath("Movement Foot Circle Node") self._attackRadCircle = LineSegs() self._attackRadCircleNP= NodePath("Attack Radius Node") self._np = NodePath("Movement Node") self.attackables = [] Event.Dispatcher().register(self, 'E_Key_ZUp', self.onZChange) Event.Dispatcher().register(self, 'E_Key_ZDown', self.onZChange) Event.Dispatcher().register(self, 'E_Key_ZUp-up', self.onZChange) Event.Dispatcher().register(self, 'E_Key_ZDown-up', self.onZChange) self.aaLevel= int(GameSettings().getSetting('ANTIALIAS')) self.parent = parent self.start = Vec3(0, 0, 0) self.moveRad = entity.moveRad self.footRad = foot self.attackRad = entity.attackRad self.plane = Plane(Vec3(0, 0, 1), Point3(0, 0, 0)) self.draw() self._np.reparentTo(self.parent) if self.aaLevel > 0: self._np.setAntialias(AntialiasAttrib.MLine, self.aaLevel) taskMgr.add(self.updateMovePos, 'Movement Indicator Update Task') def draw(self): # Setup curr mouse pos in 3d space posXY = self.getMouseXY() x = posXY.getX() y = posXY.getY() z = 0 # Draw movement radius moveRadLine = LineSegs() moveRadLine.setThickness(1) moveRadLine.setColor(self._color) moveRadLine.moveTo(self.moveRad, 0, 0) for i in range(self._EDGES + 1): newX = (self.moveRad * math.cos((2*math.pi/self._EDGES)*i)) newY = (self.moveRad * math.sin((2*math.pi/self._EDGES)*i)) moveRadLine.drawTo(newX, newY, 0) moveRadGeom = moveRadLine.create() self._moveRadCircleNP = NodePath(moveRadGeom) self._moveRadCircleNP.reparentTo(self._np) # Draw movement foot circle self._moveFootCircle.setThickness(1) self._moveFootCircle.setColor(self._color) self._moveFootCircle.moveTo(self.footRad, 0, 0) for i in range(self._EDGES): newX = (self.footRad * math.cos((2*math.pi/self._EDGES)*i)) newY = (self.footRad * math.sin((2*math.pi/self._EDGES)*i)) self._moveFootCircle.drawTo(newX, newY, 0) self._moveFootCircle.drawTo(self.footRad, 0, 0) moveFootCircleGeom = self._moveFootCircle.create() self._moveFootCircleNP = NodePath(moveFootCircleGeom) self._moveFootCircleNP.reparentTo(self._np) # Draw movement direction line self._moveLine.setThickness(1) self._moveLine.setColor(self._color) self._moveLine.moveTo(0, 0, 0) self._moveLine.drawTo(x, y, z) moveLine = self._moveLine.create() self._moveLineNP = NodePath(moveLine) self._moveLineNP.reparentTo(self._np) # Draw Z line self._moveZLine.setThickness(1) self._moveZLine.setColor(self._color) self._moveZLine.moveTo(self.start) self._moveZLine.drawTo(x, y, z) moveZLine = self._moveZLine.create() self._moveZLineNP = NodePath(moveZLine) self._moveZLineNP.reparentTo(self._np) # Draw Attack Radius self._attackRadCircle.setThickness(1) self._attackRadCircle.setColor(0.8, 0.0, 0.0, 1) self._attackRadCircle.moveTo(self.attackRad, 0, 0) for i in range(self._EDGES + 1): newX = (self.attackRad * math.cos((2*math.pi/self._EDGES)*i)) newY = (self.attackRad * math.sin((2*math.pi/self._EDGES)*i)) self._attackRadCircle.drawTo(newX, newY, 0) attackRadCircleGeom = self._attackRadCircle.create() self._attackRadCircleNP = NodePath(attackRadCircleGeom) self._attackRadCircleNP.reparentTo(self._np) def updateMovePos(self, Task): # endPos must be transformed in the the coord sys of the model m_pos = self.getMouseXY() if m_pos is not None: # Transform current mouse pos endPos = self.parent.getRelativePoint(render, m_pos) # Adjust Z coord if needed if self._movingUp: self._zPos += 0.1 elif self._movingDown: self._zPos -= 0.1 endPos.setZ(self._zPos) # Check if we're trying to move too far, if not update pos dist = math.sqrt(endPos.getX()**2 + endPos.getY()**2 + 2*(endPos.getZ()**2)) if dist <= self.moveRad: self._moveLine.setVertex(1, endPos) self._moveFootCircleNP.setPos(endPos) self._moveZLine.setVertex(0, Point3(endPos.getX(), endPos.getY(), 0)) self._moveZLine.setVertex(1, endPos) self._attackRadCircleNP.setPos(endPos) self._currentPos = render.getRelativePoint(self._np, endPos) # Check for attackable ships in range of current pos attackables = Entity.EntityManager().getEntitiesWithin(self._currentPos, self.attackRad) # Unhighlight ships no longer in range for e in self.attackables: if e not in attackables and isinstance(e, Entity.EntityShip): e.representation.unsetAttackable() # Highlight ships in range for e in attackables: if isinstance(e, Entity.EntityShip) and e != self.entity and e.owner != self.entity.owner: e.representation.setAttackable() self.attackables = attackables return Task.cont def onZChange(self, event): if event.type == 'E_Key_ZUp': self._movingDown = False self._movingUp = True if event.type == 'E_Key_ZDown': self._movingUp = False self._movingDown = True if event.type == 'E_Key_ZUp-up': self._movingUp = False self._movingDown = False if event.type == 'E_Key_ZDown-up': self._movingUp = False self._movingDown = False def getMouseXY(self): # NOTE - this returns the mouse pos in the ships coord sys if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() pos3d = Point3() nearPoint = Point3() farPoint = Point3() base.camLens.extrude(mpos, nearPoint, farPoint) if self.plane.intersectsLine(pos3d, render.getRelativePoint(camera, nearPoint), render.getRelativePoint(camera, farPoint)): #print("Mouse ray intersects ground plane at " + str(pos3d)) return pos3d def getPosition(self): return self._currentPos def removeNode(self): taskMgr.remove('Movement Indicator Update Task') for e in self.attackables: if isinstance(e, Entity.EntityShip): e.representation.unsetAttackable() self._moveRadCircleNP.removeNode() self._moveLineNP.removeNode() self._moveZLineNP.removeNode() self._moveZFootNP.removeNode() self._moveFootCircleNP.removeNode() self._attackRadCircleNP.removeNode() self._np.removeNode() def __del__(self): # TODO - This isn't calling self.removeNode() correctly self._np.removeNode()
def initRaceMode(self): self.mapScene = self.raceModeRoot.attachNewNode('MapScene') self.mapScene.setPos(1.1, 0, 0.75) self.mapScene.setScale(0.25, 0.001, 0.25) maxT = self.race.curve.getMaxT() pt = Vec3(0, 0, 0) ls = LineSegs('MapLines') ls.setColor(1, 1, 1, 1) ls.setThickness(2) for x in range(101): self.race.curve.getPoint(x / 100.0 * maxT, pt) if x == 0: ls.moveTo(pt[0], pt[1], pt[2]) else: ls.drawTo(pt[0], pt[1], pt[2]) self.mapLines = self.mapScene.attachNewNode(ls.create()) self.mapLines.setScale(0.00025 * RaceGlobals.TrackDict[self.race.trackId][6]) self.mapLines.setP(90) self.faceStartPos = Vec3(-0.8, 0, 0.93) self.faceEndPos = Vec3(0.8, 0, 0.93) self.placeLabelNum = DirectLabel( relief=None, pos=TTLocalizer.RGUIplaceLabelNumPos, text='1', text_scale=0.35, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.placeLabelNum.reparentTo(self.raceModeRoot) self.directObjList.append(self.placeLabelNum) self.placeLabelStr = DirectLabel( relief=None, pos=TTLocalizer.RGUIplaceLabelStrPos, text=TTLocalizer.KartRace_FirstSuffix, text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.placeLabelStr.reparentTo(self.raceModeRoot) self.directObjList.append(self.placeLabelStr) self.lapLabel = DirectLabel(relief=None, pos=(1.1, 0, 0.45), text='1/' + str(self.race.lapCount), text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.lapLabel.reparentTo(self.raceModeRoot) self.directObjList.append(self.lapLabel) self.photoFinishLabel = DirectLabel( relief=None, pos=(0, 0, -0.1), text=TTLocalizer.KartRace_PhotoFinish, text_scale=TTLocalizer.RGUIphotoFinish, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.photoFinishLabel.hide() self.directObjList.append(self.photoFinishLabel) self.wrongWayLabel = DirectLabel( relief=None, pos=(1.1, 0, 0.85), text=TTLocalizer.KartRace_WrongWay, text_scale=0.1, text_fg=(0.95, 0, 0, 1), text_font=ToontownGlobals.getSignFont()) self.wrongWayLabel.reparentTo(self.raceModeRoot) self.directObjList.append(self.wrongWayLabel) self.wrongWayLabel.setColorScale(Vec4(1, 1, 1, 0)) self.wrongWaySeq = Sequence( self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 1), startColorScale=Vec4( 1, 1, 1, 0)), self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 0), startColorScale=Vec4( 1, 1, 1, 1))) interpolateFacePos = lambda x: self.faceStartPos * ( 1.0 - x) + self.faceEndPos * x self.timeLabels = [] for x in range(self.race.lapCount): minLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] - 0.06, 0, 0.84), text="0'", text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) minLabel.reparentTo(self.raceModeRoot) self.directObjList.append(minLabel) secLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.06, 0, 0.84), text="00''", text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) secLabel.reparentTo(self.raceModeRoot) self.directObjList.append(secLabel) fractionLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.14, 0, 0.84), text='00', text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) fractionLabel.reparentTo(self.raceModeRoot) self.directObjList.append(fractionLabel) self.timeLabels.append((minLabel, secLabel, fractionLabel)) self.cardMaker.reset() self.cardMaker.setName('GagIndicator') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) self.cardMaker.setColor(1, 1, 1, 1) self.gagPanel = DirectFrame( parent=self.raceModeRoot, relief=None, image=loader.loadModel('phase_6/models/karting/gag_panel'), image_scale=0.25, pos=(-1.13, 0, -0.5)) self.directObjList.append(self.gagPanel) self.gag = self.gagPanel.attachNewNode('gag') self.gag.setScale(0.2) for gag in self.gagTextures: gag.reparentTo(self.gag) gag.hide() self.cardMaker.reset() self.cardMaker.setName('RaceProgressLine') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) line = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) line.setScale(self.faceEndPos[0] - self.faceStartPos[0], 1, 0.01) line.setPos(0, 0, self.faceStartPos[2]) self.cardMaker.setName('RaceProgressLineHash') for n in range(self.race.lapCount + 1): hash = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) hash.setScale(line.getScale()[2], 1, line.getScale()[2] * 5) t = float(n) / self.race.lapCount hash.setPos( self.faceStartPos[0] * (1 - t) + self.faceEndPos[0] * t, self.faceStartPos[1], self.faceStartPos[2]) self.raceModeReady = True self.disable() return
def initRaceMode(self): ## #setup the 'map' display region ## self.mapScene = NodePath('MapScene') ## self.mapScene.setTransparency(1) ## self.mapSize = 0.15 ## self.mapX = 0.84 ## self.mapY = 0.84 ## self.mapCam = None ## if (base.win.getNumDisplayRegions()>4): ## for x in range(base.win.getNumDisplayRegions()-4): ## dr = base.win.getDisplayRegion(x+4) ## if (dr.getCamera().getName() == 'MapCam'): ## self.mapCam = dr.getCamera() ## break ## if(self.mapCam == None): ## self.mapCam = base.makeCamera(base.win,sort=30,displayRegion = (self.mapX,self.mapX+self.mapSize,self.mapY,self.mapY+self.mapSize),camName = 'MapCam') ## self.mapCam.setY(-10) ## self.mapCam.node().setLens(OrthographicLens()) ## self.mapCam.node().getLens().setFilmSize(2) ## self.mapCam.node().getLens().setAspectRatio(4.0/3.0) ## self.mapCam.reparentTo(self.mapScene) ## self.cardMaker.reset() ## self.cardMaker.setName('MapBackground') ## self.cardMaker.setFrame(-1,1,-1,1) ## self.cardMaker.setColor(1,1,1,0.25) ## card = self.mapScene.attachNewNode(self.cardMaker.generate()) #setup the 'map' display region self.mapScene = self.raceModeRoot.attachNewNode('MapScene') self.mapScene.setPos(1.1, 0, 0.75) self.mapScene.setScale(0.25, 0.001, 0.25) maxT = self.race.curve.getMaxT() pt = Vec3(0, 0, 0) ls = LineSegs('MapLines') ls.setColor(1, 1, 1, 1) ls.setThickness(2) for x in range(101): self.race.curve.getPoint(x / 100.0 * maxT, pt) if (x == 0): ls.moveTo(pt[0], pt[1], pt[2]) else: ls.drawTo(pt[0], pt[1], pt[2]) self.mapLines = self.mapScene.attachNewNode(ls.create()) self.mapLines.setScale(0.00025 * RaceGlobals.TrackDict[self.race.trackId][6]) self.mapLines.setP(90) #setup face info self.faceStartPos = Vec3(-0.80, 0, 0.93) self.faceEndPos = Vec3(0.80, 0, 0.93) #setup place(1st,2nd,...) reporting self.placeLabelNum = DirectLabel( relief=None, pos=TTLocalizer.RGUIplaceLabelNumPos, text='1', text_scale=0.35, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), ) self.placeLabelNum.reparentTo(self.raceModeRoot) self.directObjList.append(self.placeLabelNum) self.placeLabelStr = DirectLabel( relief=None, pos=TTLocalizer.RGUIplaceLabelStrPos, text=TTLocalizer.KartRace_FirstSuffix, text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), ) self.placeLabelStr.reparentTo(self.raceModeRoot) self.directObjList.append(self.placeLabelStr) #setup lap reporting self.lapLabel = DirectLabel( relief=None, pos=(1.1, 0, 0.45), text='1/' + str(self.race.lapCount), text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), ) self.lapLabel.reparentTo(self.raceModeRoot) self.directObjList.append(self.lapLabel) #setup photo finish label self.photoFinishLabel = DirectLabel( relief=None, pos=(0, 0, -0.1), text=TTLocalizer.KartRace_PhotoFinish, text_scale=TTLocalizer.RGUIphotoFinish, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), ) self.photoFinishLabel.hide() self.directObjList.append(self.photoFinishLabel) #setup wrong way reporting self.wrongWayLabel = DirectLabel( relief=None, pos=(1.1, 0, 0.85), text=TTLocalizer.KartRace_WrongWay, text_scale=0.1, text_fg=(0.95, 0, 0, 1), text_font=ToontownGlobals.getSignFont(), ) self.wrongWayLabel.reparentTo(self.raceModeRoot) self.directObjList.append(self.wrongWayLabel) self.wrongWayLabel.setColorScale(Vec4(1, 1, 1, 0)) self.wrongWaySeq = Sequence( self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 1), startColorScale=Vec4( 1, 1, 1, 0)), self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 0), startColorScale=Vec4( 1, 1, 1, 1)), ) #setup time reporting interpolateFacePos = lambda x: self.faceStartPos * ( 1.0 - x) + self.faceEndPos * (x) self.timeLabels = [] for x in range(self.race.lapCount): minLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] - 0.06, 0, 0.84), text='0\'', text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight, ) minLabel.reparentTo(self.raceModeRoot) self.directObjList.append(minLabel) secLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.06, 0, 0.84), text='00\'\'', text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight, ) secLabel.reparentTo(self.raceModeRoot) self.directObjList.append(secLabel) fractionLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.14, 0, 0.84), text='00', text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight, ) fractionLabel.reparentTo(self.raceModeRoot) self.directObjList.append(fractionLabel) self.timeLabels.append((minLabel, secLabel, fractionLabel)) #setup gag indicator self.cardMaker.reset() self.cardMaker.setName('GagIndicator') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) self.cardMaker.setColor(1, 1, 1, 1) self.gagPanel = DirectFrame( parent=self.raceModeRoot, relief=None, image=loader.loadModel('phase_6/models/karting/gag_panel'), image_scale=0.25, pos=(-1.13, 0, -0.5), ) self.directObjList.append(self.gagPanel) self.gag = self.gagPanel.attachNewNode('gag') self.gag.setScale(0.2) for gag in self.gagTextures: gag.reparentTo(self.gag) gag.hide() #setup face line self.cardMaker.reset() self.cardMaker.setName('RaceProgressLine') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) line = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) line.setScale(self.faceEndPos[0] - self.faceStartPos[0], 1, 0.01) line.setPos(0, 0, self.faceStartPos[2]) self.cardMaker.setName('RaceProgressLineHash') for n in range(self.race.lapCount + 1): hash = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) hash.setScale(line.getScale()[2], 1, line.getScale()[2] * 5) t = float(n) / self.race.lapCount hash.setPos( self.faceStartPos[0] * (1 - t) + self.faceEndPos[0] * t, self.faceStartPos[1], self.faceStartPos[2]) self.raceModeReady = True self.disable()
class DirectionExperiment(ViewTowers): def __init__(self, *args, **kwargs): ViewTowers.__init__(self, *args, **kwargs) # ignore keys set by viewer for key in self.getAllAccepting(): if key in ("s", "escape"): continue self.ignore(key) self.permanent_events = self.getAllAccepting() # global variables self.text_bg = (1, 1, 1, 0.7) self.font = self.loader.loadFont("cmr12.egg") self.question = "Use the mouse to indicate the direction that " "the tower will fall." self.feedback_time = 3.0 self.buffer_time = 0.75 # create text self.create_all_text() # create direction line self.line = LineSegs() self.line_node = None self.angle = None alight = AmbientLight("alight3") alight.setColor((0.8, 0.8, 0.8, 1)) self.line_light = self.lights.attachNewNode(alight) def place_camera(self): self.cameras.setPos(0, -12, 2.5) self.look_at.setPos(0, 0, 1.5) self.cameras.lookAt(self.look_at) def run(self): # Show the start screen self.toggle_task("show_start_screen") # Call parent's run(). ShowBase.run(self) def create_all_text(self): self.continue_text = OnscreenText( **{ "text": ( "In a moment, you will be asked the question displayed on " "the left. When you are ready, press the spacebar to begin." ), "style": 1, "fg": (0.75, 0, 0, 1), "bg": self.text_bg, "pos": (0.4, 0.4), "align": TextNode.ACenter, "scale": 0.08, "font": self.font, "wordwrap": 20, } ) self.text_parent = self.continue_text.getParent() self.continue_text.detachNode() xpos = -1.25 self.question_text = OnscreenText( **{ "text": self.question, "style": 1, "fg": (0, 0, 0.8, 1), "bg": self.text_bg, "pos": ((xpos + 0.05), 0.8), "align": TextNode.ALeft, "scale": 0.075, "font": self.font, "wordwrap": 35, } ) self.trials_remaining_text = OnscreenText( **{ "text": "", "style": 1, "fg": (0, 0, 0, 1), "bg": self.text_bg, "pos": (-xpos, -0.95), "align": TextNode.ARight, "scale": 0.05, "font": self.font, } ) def show_start_screen(self, task): self.continue_text.reparentTo(self.text_parent) self.accept("space", self.toggle_task, ["show_trial"]) def show_trial(self, task): if self.line_node is not None: self.line_node.removeNode() self.line_node = None if self.sso is None: self.goto_sso(0) elif self.ssos.index(self.sso) == (self.n_ssos - 1): self.exit() else: self.next() n = self.n_ssos - self.ssos.index(self.sso) self.trials_remaining_text.setText("Trials remaining: %d" % n) self.continue_text.detachNode() self.camera_rot.setH(np.random.randint(0, 360)) self.cam_spin = 270 self.taskMgr.doMethodLater(self.buffer_time, self.rotate, "rotate") def rotate(self, task): """ Task: rotate camera.""" H = (self.camera_rot.getH() + 1) % 360 self.camera_rot.setH(H) self.cam_spin -= 1 if self.cam_spin == 0: self.toggle_task("show_question") return task.done else: return task.cont def show_question(self, task): self.toggle_task("draw_direction") self.accept("mouse1", self.record_response) def record_response(self): self.ignore("mouse1") self.taskMgr.remove("draw_direction") self.toggle_task("physics") def physics(self, task): """ Task: simulate physics.""" # Elapsed time. dt = self._get_elapsed() - self.old_elapsed # Update amount of time simulated so far. self.old_elapsed += dt # Step the physics dt time. size_sub = self.bbase.sim_par["size_sub"] n_subs = int(dt / size_sub) self.bbase.step(dt, n_subs, size_sub) if self.old_elapsed >= self.feedback_time: self.toggle_task("show_trial") return task.done else: return task.cont def draw_direction(self, task): if self.mouseWatcherNode.hasMouse(): cv = self._get_collision(self.floor) cv = cv / np.linalg.norm(cv) self.angle = np.arctan2(cv[1], cv[0]) sx, sy, sz = self.floor.getScale() / 2.0 gx, gy, gz = self.floor.getPos() gz += sz + 0.01 if self.line_node is not None: self.line_node.removeNode() self.line_node = None self.line.reset() self.line.setColor(1, 1, 1, 1) self.line.setThickness(5) self.line.moveTo(gx, gy, gz) self.line.drawTo(cv[0] * sx, cv[1] * sy, gz) self.line_node = self.render.attachNewNode(self.line.create()) self.line_node.setLight(self.line_light) return task.cont def _get_collision(self, node, debug=False): mx = self.mouseWatcherNode.getMouseX() my = self.mouseWatcherNode.getMouseY() if debug: print "mouse:", (mx, my) # get the origin and direction of the ray extending from the # camera to the mouse pointer cm = np.array(self.cam.getNetTransform().getMat()) cr = CollisionRay() cr.setFromLens(self.cam.node(), (mx, my)) cp = np.hstack([cr.getOrigin(), 1]) cd = np.hstack([cr.getDirection(), 0]) cp = np.dot(cm.T, cp)[:3] cd = np.dot(cm.T, cd)[:3] if cd[2] > -1: cd[2] = -1 if debug: print "direction:", cd print "origin:", cp # point on the plane, z-axis pz = node.getPos(self.render)[2] sz = node.getScale(self.render)[2] / 2.0 p0 = np.array([0, 0, pz + sz]) if debug: print "p0:", p0 # this is the intersection equation that we want to solve, # where s is the point on the line that intersects # e_z(cp + s*cd - p0) = 0 s = (p0[2] - cp[2]) / cd[2] if debug: print "s:", s # transform the collision point from line coordinates to world # coordinates cv = cp + s * cd if debug: print "collision:", cv return cv
class GreatArcs(OnSpherePrimitive): '''this class can draw a collection of great arcs on the given sphere (that is a part of the biggest possible circle on a sphere, which has origin at the origin of a sphere)''' def __init__(self, origin, radius, thickness=1.0, color=(0.0, 1.0, 0.0, 1.0)): super(GreatArcs, self).__init__(origin, radius) self.thickness = thickness self.color = color self.vertex_count = 0 self.vertices = [] self.line_seqs = LineSegs() self.line_seqs.setThickness(self.thickness) (r, g, b, a) = self.color self.line_seqs.setColor(Vec4(r, g, b, a)) def _generate_points_on_arc(self, from_v, to_v, depth=0): '''from_v and to_v are vectors, i need to generate approximate middle points on surface of the sphare and add them to line_seqs we assume that from_v, to_v are on the sphere... at the end we return the list without FIRST_VERTEX (from_v), it is convenient in _make_arc, as we neet do do one move, and then we can lineTo to all elements in this list ''' #there is a problem when from_v and to_v are antipodal... TODO: poprawic? dist_sq = sum((from_v[i] - to_v[i])**2 for i in xrange(3)) # distance between points if (dist_sq < (self.radius / 5.0)**2 or depth > 10): # its quesss... # simply connects return [to_v] else: # generate middle point and call recursively new_v = self.cast_to_sphere([(from_v[i] + to_v[i]) / 2.0 for i in xrange(3)]) a = self._generate_points_on_arc(from_v, new_v, depth + 1) b = self._generate_points_on_arc(new_v, to_v, depth + 1) return a + b # concat lists... def _make_arc(self, from_v, to_v): list = self._generate_points_on_arc(from_v, to_v) (x, y, z) = from_v self.line_seqs.moveTo(Point3(x, y, z)) for p in list: (x, y, z) = p self.line_seqs.drawTo(Point3(x, y, z)) def _make_arcs(self, vertices): '''TODO: przetestowac, bo narazie napisalem...''' first = vertices[0] current = first list = [] for next in vertices[1:]: list += self._generate_points_on_arc(current, next) current = next (x, y, z) = first self.line_seqs.moveTo(Point3(x, y, z)) for p in list: (x, y, z) = p self.line_seqs.drawTo(Point3(x, y, z)) def add_vertex(self, vertex, cast_to_sphere=False): '''adds a single point to this object you can connect them wit connect() function ''' self.vertex_count += 1 if (cast_to_sphere): self.vertices.append(self.cast_to_sphere(vertex)) else: self.vertices.append(vertex) return self def add_vertices(self, vertices, cast_to_sphere=False): '''adds a list of vertices you can connect them wit connect() function ''' for p in vertices: self.add_vertex(p, cast_to_sphere) return self def connect(self, indices_list, closed=True): '''connects given list of indices by set of fragments of great arcs the default behaviour is that it creates a closed curve ''' current = indices[0] for next in indices_list[1:]: self._make_arc(self.vertices[current], self.vertices[next]) current = next if closed: self._make_arc(self.vertices[current], self.vertices[indices[0]]) return self def add_arcs(self, vertices, closed=True, cast_to_sphere=False): '''adds a collection of fragments of great arcs between given points points should be on the surface of the ball the default behaviour is that it creates a closed curve ''' first = self.vertex_count current = first self.add_vertex(vertices[0], cast_to_sphere) for p in vertices[1:]: next = self.vertex_count self.add_vertex(p, cast_to_sphere) self._make_arc(self.vertices[current], self.vertices[next]) current = next if closed: self._make_arc(self.vertices[current], self.vertices[first]) return self def attach_to(self, render): '''creates Panda3D representation that can be attached to render this function is mainly used inside Render class and its derivatives and user not need to worry to call it''' lines = NodePath(self.line_seqs.create()) lines.reparentTo(render.render) return lines
def __init__(self, parent, entity, foot=1): # We keep a reference to the entity self.entity = entity # Setup the components of the cursor self._moveRadCircleNP = NodePath("Movement Radius Node") self._moveLine = LineSegs() self._moveLineNP = NodePath("Movement Direction Line Node") self._moveZLine = LineSegs() self._moveZLineNP = NodePath("Movement Z Line Node") self._moveZFootNP = NodePath("Movement Z Foot Node") self._moveFootCircle = LineSegs() self._moveFootCircleNP = NodePath("Movement Foot Circle Node") self._np = NodePath("Movement Node") self.aaLevel = 16 self.parent = parent self.start = Vec3(0, 0, 0) self.moveRad = entity.moveRadius self.footRad = foot self.plane = Plane(Vec3(0, 0, 1), Point3(0, 0, 0)) if self.aaLevel > 0: self._np.setAntialias(AntialiasAttrib.MLine, self.aaLevel) x = 0 y = 0 z = 0 # Draw movement radius moveRadLine = LineSegs() moveRadLine.setThickness(1) moveRadLine.setColor(self._color) moveRadLine.moveTo(self.moveRad, 0, 0) for i in range(self._EDGES + 1): newX = (self.moveRad * math.cos((2*math.pi/self._EDGES)*i)) newY = (self.moveRad * math.sin((2*math.pi/self._EDGES)*i)) moveRadLine.drawTo(newX, newY, 0) moveRadGeom = moveRadLine.create() self._moveRadCircleNP = NodePath(moveRadGeom) self._moveRadCircleNP.reparentTo(self._np) # Draw movement foot circle self._moveFootCircle.setThickness(1) self._moveFootCircle.setColor(self._color) self._moveFootCircle.moveTo(self.footRad, 0, 0) for i in range(self._EDGES): newX = (self.footRad * math.cos((2*math.pi/self._EDGES)*i)) newY = (self.footRad * math.sin((2*math.pi/self._EDGES)*i)) self._moveFootCircle.drawTo(newX, newY, 0) self._moveFootCircle.drawTo(self.footRad, 0, 0) moveFootCircleGeom = self._moveFootCircle.create() self._moveFootCircleNP = NodePath(moveFootCircleGeom) self._moveFootCircleNP.reparentTo(self._np) # Draw movement direction line self._moveLine.setThickness(1) self._moveLine.setColor(self._color) self._moveLine.moveTo(0, 0, 0) self._moveLine.drawTo(x, y, z) self.moveLineGO = self._moveLine.create(True) self._moveLineNP = NodePath(self.moveLineGO) self._moveLineNP.reparentTo(self._np)
def initRaceMode(self): self.mapScene = base.a2dTopRight.attachNewNode('MapScene') self.mapScene.setPos(-0.2, 0, -0.2) self.mapScene.setScale(0.25, 0.001, 0.25) maxT = self.race.curve.getMaxT() pt = Vec3(0, 0, 0) ls = LineSegs('MapLines') ls.setColor(1, 1, 1, 1) ls.setThickness(2) for x in xrange(101): self.race.curve.getPoint(x / 100.0 * maxT, pt) if x == 0: ls.moveTo(pt[0], pt[1], pt[2]) else: ls.drawTo(pt[0], pt[1], pt[2]) self.mapLines = self.mapScene.attachNewNode(ls.create()) self.mapLines.setScale(0.00025 * RaceGlobals.TrackDict[self.race.trackId][6]) self.mapLines.setP(90) self.faceStartPos = Vec3(-0.8, 0, 0.93) self.faceEndPos = Vec3(0.8, 0, 0.93) self.placeLabelNum = DirectLabel(relief=None, pos=TTLocalizer.RGUIplaceLabelNumPos, text='1', text_scale=0.35, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.placeLabelNum.reparentTo(base.a2dBottomLeft) self.directObjList.append(self.placeLabelNum) self.placeLabelStr = DirectLabel(relief=None, pos=TTLocalizer.RGUIplaceLabelStrPos, text=TTLocalizer.KartRace_FirstSuffix, text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.placeLabelStr.reparentTo(base.a2dBottomLeft) self.directObjList.append(self.placeLabelStr) self.lapLabel = DirectLabel(relief=None, pos=(-0.22, 0, -0.5), text='1/' + str(self.race.lapCount), text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.lapLabel.reparentTo(base.a2dTopRight) self.directObjList.append(self.lapLabel) self.photoFinishLabel = DirectLabel(relief=None, pos=(0, 0, -0.1), text=TTLocalizer.KartRace_PhotoFinish, text_scale=TTLocalizer.RGUIphotoFinish, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.photoFinishLabel.hide() self.directObjList.append(self.photoFinishLabel) self.wrongWayLabel = DirectLabel(relief=None, pos=(-0.22, 0, -0.2), text=TTLocalizer.KartRace_WrongWay, text_scale=0.1, text_fg=(0.95, 0, 0, 1), text_font=ToontownGlobals.getSignFont()) self.wrongWayLabel.reparentTo(base.a2dTopRight) self.directObjList.append(self.wrongWayLabel) self.wrongWayLabel.setColorScale(Vec4(1, 1, 1, 0)) self.wrongWaySeq = Sequence(self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 1), startColorScale=Vec4(1, 1, 1, 0)), self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 0), startColorScale=Vec4(1, 1, 1, 1))) interpolateFacePos = lambda x: self.faceStartPos * (1.0 - x) + self.faceEndPos * x self.timeLabels = [] for x in xrange(self.race.lapCount): minLabel = DirectLabel(relief=None, pos=(interpolateFacePos((2.0 * x + 1) / (self.race.lapCount * 2))[0] - 0.06, 0, 0.84), text="0'", text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) minLabel.reparentTo(self.raceModeRoot) self.directObjList.append(minLabel) secLabel = DirectLabel(relief=None, pos=(interpolateFacePos((2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.06, 0, 0.84), text="00''", text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) secLabel.reparentTo(self.raceModeRoot) self.directObjList.append(secLabel) fractionLabel = DirectLabel(relief=None, pos=(interpolateFacePos((2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.14, 0, 0.84), text='00', text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) fractionLabel.reparentTo(self.raceModeRoot) self.directObjList.append(fractionLabel) self.timeLabels.append((minLabel, secLabel, fractionLabel)) self.cardMaker.reset() self.cardMaker.setName('GagIndicator') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) self.cardMaker.setColor(1, 1, 1, 1) self.gagPanel = DirectFrame(parent=base.a2dBottomLeft, relief=None, image=loader.loadModel('phase_6/models/karting/gag_panel'), image_scale=0.25, pos=(0.2, 0, 0.55)) self.directObjList.append(self.gagPanel) self.gag = self.gagPanel.attachNewNode('gag') self.gag.setScale(0.2) for gag in self.gagTextures: gag.reparentTo(self.gag) gag.hide() self.cardMaker.reset() self.cardMaker.setName('RaceProgressLine') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) line = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) line.setScale(self.faceEndPos[0] - self.faceStartPos[0], 1, 0.01) line.setPos(0, 0, self.faceStartPos[2]) self.cardMaker.setName('RaceProgressLineHash') for n in xrange(self.race.lapCount + 1): hash = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) hash.setScale(line.getScale()[2], 1, line.getScale()[2] * 5) t = float(n) / self.race.lapCount hash.setPos(self.faceStartPos[0] * (1 - t) + self.faceEndPos[0] * t, self.faceStartPos[1], self.faceStartPos[2]) self.raceModeReady = True self.disable() return
class GolfScoreBoard: notify = directNotify.newCategory('GolfScoreBoard') def __init__(self, golfCourse): self.golfCourse = golfCourse self.numPlayas = len(golfCourse.avIdList) self.avIdList = golfCourse.avIdList self.playaTags = [] self.scoreTags = [] self.totalTags = [] self.scoreLabels = [] self.holeLabels = [] self.parLabels = [] self.numExited = 0 self.setup() def setup(self): self.scoreboard = DirectFrame( parent=aspect2d, relief=None, geom=DGG.getDefaultDialogGeom(), geom_color=ToontownGlobals.GlobalDialogColor, geom_scale=(1.9, 1, 1.05), pos=(0, 0, 0.375)) self.lines = LineSegs() self.lines.setColor(0, 0, 0, 1) self.lines.setThickness(2) guiModel = loader.loadModel('phase_6/models/golf/golf_gui') highlight = loader.loadModel('phase_6/models/golf/headPanel') self.maximizeB = DirectButton( parent=base.a2dBottomRight, pos=(-0.15, 0, 0.15), relief=None, state=DGG.NORMAL, image=(guiModel.find('**/score_card_icon'), guiModel.find('**/score_card_icon_rollover'), guiModel.find('**/score_card_icon_rollover')), image_scale=(0.2, 1, 0.2), command=self.showBoard) self.vertOffset = 0.13 self.playaTop = 0.12 horzOffset = 0.12 holeTop = 0.3 self.vCenter = 0.025 totScore = 0 totPar = 0 self.lineVStart = -0.465 self.lineHStart = 0.17 self.lineHorOffset = 0.13 self.lineVertOffset = 0.125 self.lineVCenter = 0.025 buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui') self.minimizeB = DirectButton( parent=self.scoreboard, pos=(0, 0, self.lineHStart - 0.59), relief=None, state=DGG.NORMAL, image=(buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr')), image_scale=(1, 1, 1), command=self.hideBoard, extraArgs=[None]) self.exitCourseB = DirectButton( parent=self.scoreboard, pos=(0, 0, self.lineHStart - 0.59), relief=None, state=DGG.NORMAL, image=(buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr')), image_scale=(1, 1, 1), text=TTLocalizer.GolfExitCourse, text_scale=0.04, text_pos=TTLocalizer.GSBexitCourseBPos, command=self.exitCourse) self.exitCourseB.hide() self.highlightCur = DirectLabel(parent=self.scoreboard, relief=None, pos=(-0.003, 0, 0.038), image=highlight, image_scale=(1.82, 1, 0.135)) self.titleBar = DirectLabel(parent=self.scoreboard, relief=None, pos=(-0.003, 0, 0.166), color=(0.7, 0.7, 0.7, 0.3), image=highlight, image_scale=(1.82, 1, 0.195)) self.titleBar.show() self.highlightCur.show() buttons.removeNode() guiModel.removeNode() title = GolfGlobals.getCourseName( self.golfCourse.courseId) + ' - ' + GolfGlobals.getHoleName( self.golfCourse.holeIds[self.golfCourse.curHoleIndex]) self.titleLabel = DirectLabel(parent=self.scoreboard, relief=None, pos=(0, 0, holeTop + 0.1), text_align=TextNode.ACenter, text=title, text_scale=TTLocalizer.GSBtitleLabel, text_font=ToontownGlobals.getSignFont(), text_fg=(0, 0.5, 0.125, 1)) self.playaLabel = DirectLabel( parent=self.scoreboard, relief=None, pos=(self.lineVStart - 0.23, 0, holeTop), text_align=TextNode.ACenter, text=TTLocalizer.GolfHole, text_font=ToontownGlobals.getMinnieFont(), text_scale=0.05) for holeLIndex in xrange(self.golfCourse.numHoles): holeLabel = DirectLabel(parent=self.scoreboard, relief=None, pos=(self.lineVStart + 0.055 + horzOffset * holeLIndex, 0, holeTop), text_align=TextNode.ACenter, text='%s' % (holeLIndex + 1), text_scale=0.05) self.holeLabels.append(holeLabel) self.totalLabel = DirectLabel( parent=self.scoreboard, relief=None, pos=(self.lineVStart + 0.1 + horzOffset * 9.5, 0, holeTop), text_align=TextNode.ACenter, text=TTLocalizer.GolfTotal, text_font=ToontownGlobals.getMinnieFont(), text_scale=0.05) self.parTitleLabel = DirectLabel( parent=self.scoreboard, relief=None, pos=(self.lineVStart - 0.23, 0, holeTop - 0.1), text_align=TextNode.ACenter, text=TTLocalizer.GolfPar, text_font=ToontownGlobals.getMinnieFont(), text_scale=0.05) for parHoleIndex in xrange(self.golfCourse.numHoles): parLabel = DirectLabel( parent=self.scoreboard, relief=None, pos=(self.lineVStart + 0.055 + horzOffset * parHoleIndex, 0, holeTop - 0.1), text_align=TextNode.ACenter, text='%s' % GolfGlobals.HoleInfo[ self.golfCourse.holeIds[parHoleIndex]]['par'], text_scale=0.05, text_wordwrap=10) totPar = totPar + GolfGlobals.HoleInfo[ self.golfCourse.holeIds[parHoleIndex]]['par'] self.parLabels.append(parLabel) parLabel = DirectLabel(parent=self.scoreboard, relief=None, pos=(self.lineVStart + 0.1 + horzOffset * 9.5, 0, holeTop - 0.1), text_align=TextNode.ACenter, text='%s' % totPar, text_scale=0.05, text_wordwrap=10) self.parLabels.append(parLabel) vert = 0.0 self.numPlayas = len(self.golfCourse.avIdList) for playaIndex in xrange(self.numPlayas): name = TTLocalizer.GolfUnknownPlayer av = base.cr.doId2do.get(self.golfCourse.avIdList[playaIndex]) if av: name = av.getName() playaLabel = DirectLabel(parent=self.scoreboard, relief=None, text_align=TextNode.ACenter, text=name, text_scale=0.05, text_wordwrap=9) self.playaTags.append(playaLabel) textN = playaLabel.component(playaLabel.components()[0]) if type(textN) == OnscreenText: try: if textN.textNode.getWordwrappedWtext() != name: vert = self.playaTop - self.vertOffset * playaIndex else: vert = self.playaTop - self.vertOffset * playaIndex - self.vCenter except: vert = self.playaTop - self.vertOffset * playaIndex self.playaTags[playaIndex].setPos(self.lineVStart - 0.23, 0, vert) self.notify.debug('self.text height = %f' % self.playaTags[playaIndex].getHeight()) holeIndex = 0 for holeIndex in xrange(self.golfCourse.numHoles): holeLabel = DirectLabel( parent=self.scoreboard, relief=None, pos=(self.lineVStart + 0.055 + horzOffset * holeIndex, 0, self.playaTop - self.vertOffset * playaIndex - self.vCenter), text_align=TextNode.ACenter, text='-', text_scale=0.05, text_wordwrap=10) self.scoreTags.append(holeLabel) holeLabel = DirectLabel( parent=self.scoreboard, relief=None, pos=(self.lineVStart + 0.1 + horzOffset * 9.5, 0, self.playaTop - self.vertOffset * playaIndex - self.vCenter), text_align=TextNode.ACenter, text='-', text_scale=0.05, text_wordwrap=10) self.totalTags.append(holeLabel) self.lines.moveTo(self.lineVStart - 0.45, 0, self.lineHStart + 0.19) self.lines.drawTo(self.lineVStart + 11 * self.lineVertOffset, 0, self.lineHStart + 0.19) self.lines.moveTo(self.lineVStart - 0.45, 0, self.lineHStart + 0.09) self.lines.drawTo(self.lineVStart + 11 * self.lineVertOffset, 0, self.lineHStart + 0.09) self.lines.moveTo(self.lineVStart - 0.45, 0, self.lineHStart) self.lines.drawTo(self.lineVStart + 11 * self.lineVertOffset, 0, self.lineHStart) self.lines.moveTo(self.lineVStart - 0.45, 0, self.lineHStart + 0.19) self.lines.drawTo(self.lineVStart - 0.45, 0, self.lineHStart - 4 * 0.13) self.lines.moveTo(self.lineVStart, 0, self.lineHStart + 0.19) self.lines.drawTo(self.lineVStart, 0, self.lineHStart - 4 * 0.13) for x in xrange(4): self.lines.moveTo(self.lineVStart - 0.45, 0, self.lineHStart - (x + 1) * self.lineHorOffset) self.lines.drawTo( self.lineVStart + 11 * self.lineVertOffset + 0.005, 0, self.lineHStart - (x + 1) * self.lineHorOffset) for y in xrange(10): self.lines.moveTo(self.lineVStart + y * self.lineVertOffset, 0, self.lineHStart + 0.19) self.lines.drawTo(self.lineVStart + y * self.lineVertOffset, 0, self.lineHStart - 4 * 0.13) self.lines.moveTo(self.lineVStart + 11 * self.lineVertOffset, 0, self.lineHStart + 0.19) self.lines.drawTo(self.lineVStart + 11 * self.lineVertOffset, 0, self.lineHStart - 4 * 0.13) self.scoreboard.attachNewNode(self.lines.create()) self.hide() return def getScoreLabel(self, avIdorIndex, holeNum): index = None if avIdorIndex < 100: index = avIdorIndex else: for playaIndex in xrange(self.numPlayas): if self.golfCourse.avIdList[playaIndex] == avIdorIndex: index = playaIndex return self.scoreTags[index * self.golfCourse.numHoles + holeNum] def update(self): self.showBoard() taskMgr.doMethodLater(AUTO_HIDE_TIMEOUT, self.hideBoard, 'hide score board') def hideBoard(self, task): self.hide() def hide(self): self.scoreboard.hide() self.maximizeB.show() def showBoardFinal(self, task=None): self.exitCourseB.show() self.minimizeB.hide() self.showBoard() def showBoard(self, task=None): scoreDict = self.golfCourse.scores x = 0 currentGolfer = self.golfCourse.getCurGolfer() for playaIndex in xrange(self.numPlayas): if self.golfCourse.isGameDone(): self.playaTags[playaIndex].setColor(0, 0, 0, 1) elif currentGolfer == self.golfCourse.avIdList[playaIndex]: self.highlightCur.setColor( *GolfGlobals.PlayerColors[playaIndex]) self.highlightCur.setAlphaScale(0.4) self.highlightCur.setPos( -0.003, 0, 0.038 - playaIndex * (self.lineVertOffset + 0.005)) self.highlightCur.show() else: self.playaTags[playaIndex].setColor(0, 0, 0, 1) for avId in self.avIdList: holeIndex = 0 totScore = 0 playerExited = False for y in xrange(len(self.golfCourse.exitedAvIdList)): if self.golfCourse.exitedAvIdList[y] == avId: self.playaTags[x].setColor(0.7, 0.7, 0.7, 1) holeIndex = 0 for holeIndex in xrange(self.golfCourse.numHoles): self.getScoreLabel(self.avIdList[x], holeIndex).setColor( 0.7, 0.7, 0.7, 1) self.totalTags[x].setColor(0.7, 0.7, 0.7, 1) playerExited = True if playerExited == False: for holeIndex in xrange(self.golfCourse.numHoles): if holeIndex <= self.golfCourse.curHoleIndex: self.getScoreLabel( avId, holeIndex )['text'] = '%s' % scoreDict[avId][holeIndex] totScore = totScore + scoreDict[avId][holeIndex] if self.golfCourse.isGameDone() == False: if holeIndex == self.golfCourse.curHoleIndex: self.getScoreLabel(avId, holeIndex).setColor( 1, 0, 0, 1) self.holeLabels[holeIndex].setColor(1, 0, 0, 1) self.parLabels[holeIndex].setColor(1, 0, 0, 1) title = GolfGlobals.getCourseName( self.golfCourse.courseId ) + ' - ' + GolfGlobals.getHoleName( self.golfCourse.holeIds[ self.golfCourse.curHoleIndex]) self.titleLabel['text'] = title else: self.getScoreLabel(avId, holeIndex).setColor( 0, 0, 0, 1) self.holeLabels[holeIndex].setColor(0, 0, 0, 1) self.parLabels[holeIndex].setColor(0, 0, 0, 1) self.totalTags[x]['text'] = '%s' % totScore if self.golfCourse.isGameDone(): self.getScoreLabel(avId, self.golfCourse.numHoles - 1).setColor( 0, 0, 0, 1) self.totalTags[x].setColor(1, 0, 0, 1) x = x + 1 y = 0 if self.golfCourse.isGameDone(): self.parLabels[self.golfCourse.numHoles - 1].setColor(0, 0, 0, 1) self.holeLabels[self.golfCourse.numHoles - 1].setColor(0, 0, 0, 1) self.parLabels[self.golfCourse.numHoles].setColor(1, 0, 0, 1) self.totalLabel.setColor(1, 0, 0, 1) self.scoreboard.show() self.maximizeB.hide() def exitCourse(self): course = self.golfCourse self.delete() course.exitEarly() def delete(self): if self.maximizeB: self.maximizeB.destroy() self.maximizeB = None if self.scoreboard: self.scoreboard.destroy() self.scoreboard = None self.golfCourse = None taskMgr.remove('hide score board') return
class SphereArcs(OnSpherePrimitive): '''this allow to draw part of circles that are the result of intersection of two spheres to define this you need to give three points that lie on the plane defined by two intersecting balls ''' def __init__(self, origin, radius, thickness=1.0, color=(0.0, 1.0, 0.0, 1.0)): super(SphereArcs, self).__init__(origin, radius) self.thickness = thickness self.color = color self.vertex_count = 0 self.vertices = [] self.line_seqs = LineSegs() self.line_seqs.setThickness(self.thickness) (r, g, b, a) = self.color self.line_seqs.setColor(Vec4(r, g, b, a)) def _generate_points_on_arc(self, center, from_v, to_v, circle_r=None): '''we assume that the arc is centered at center, and is going from from_v to to_v in a given direction (for example counterclockwise - to set)''' dist_sq = sum((from_v[i] - to_v[i])**2 for i in xrange(3)) # distance between points if circle_r is None: circle_r = sqrt(sum((from_v[i] - center[i])**2 for i in range(3))) if (dist_sq < (self.radius / 10.0)**2): return [to_v] else: new_v = [((from_v[i] + to_v[i]) / 2.0 - center[i]) for i in xrange(3)] d = sqrt(sum(new_v[i]**2 for i in range(3))) new_v = [center[i] + (new_v[i] / d * circle_r) for i in range(3)] a = self._generate_points_on_arc(center, from_v, new_v, circle_r) b = self._generate_points_on_arc(center, new_v, to_v, circle_r) return a + b def _is_greater_arc(self, center, from_v, to_v): return False #TODO: stub!!!!!! def _make_arc(self, center, from_v, to_v): ''' if self._is_greater_arc(center, from_v, to_v): v_prim = self.cast_to_sphere([3.0 * self.origin[i] - from_v[i] + to_v[i] for i in range(3)]) #some point on the greater arc between from and to (it is computed using: cat_to_sphere(origin + 2 * (origin - mid_point(from, to)) (origin - mid_point(from, to)) is a vector from midpoint to origin list = self._generate_points_on_arc(center, from_v, v_prim) list += self._generate_points_on_arc(center, v_prim, to_v) else: list = self._generate_points_on_arc(center, from_v, to_v) (x,y,z) = from_v self.line_seqs.moveTo(Point3(x, y, z)) for p in list: (x,y,z) = p self.line_seqs.drawTo(Point3(x, y, z)) ''' r = self.distance(center, from_v) a = self.normalize(from_v, center) b = self.normalize(to_v, center) divisions = max(int(self.radius * 10), 6) base_theta = (pi / (2.0 * divisions)) c = center (x, y, z) = from_v self.line_seqs.moveTo(Point3(x, y, z)) for i in xrange(1, divisions + 1): theta = base_theta * float(i) (x, y, z) = [ c[i] + r * cos(theta) * a[i] + r * sin(theta) * b[i] for i in range(3) ] self.line_seqs.drawTo(Point3(x, y, z)) def add_arc(self, center, from_v, to_v): '''center = of the circle, the cutting plane from_v = first vertex on arc, should lie on the cutting plane and on the sphere to_t - last vertex on arc, should lie on the cutting plane and on the sphere moreover we require that dist(center, from_v) == dist(center, to_v) ''' #self._make_arc(center, from_v, to_v) #normal = (center[0]-self.origin[0], center[1]-self.origin[1], center[2]-self.origin[2]) normal = self.normalize(center, self.origin) dist = self.distance(center, self.origin) self.add_cutting_plane_arc(normal, dist, from_v, to_v) return self def add_cutting_plane_arc(self, normal, distance, from_v, to_v): '''giving other center and distance gives us chance to handle degenerate case when center = origin of sphere ''' n = self.normalize(normal) # assure normal is normal c = [self.origin[i] + n[i] * distance for i in range(3)] # the center of the arc #TODO: rzutowac from_v i to_v na okrag przeciecia plaszczyzna - ale to skomplikowane divisions = 32 # max(int(self.radius * 10), 16) base_theta = 2.0 * pi / divisions r = self.distance(c, from_v) u = self.normalize(from_v, c) v = self.normalize(to_v, c) uxv = self.cross(u, v) sin_theta = self.distance(uxv) cos_theta = self.dot(u, v) sin_sign = self.dot( n, uxv ) # this should be 1, 0 or -1, 0 not matter (then sin = 0, parallel things, a = u b = self.cross(n, u) self.normalize(a) self.normalize(b) b = [-b[i] for i in range(3)] if (from_v == to_v): final_theta = 2.0 * pi else: if (cos_theta * sin_sign > 0): final_theta = asin(1.0 - sin_theta) else: final_theta = asin(sin_theta) print "add_cutting_plane_arc", final_theta, ",", sin_theta if ( sin_sign < 0 ): #this means that we are on the other side of the line and the angle is 180 deegres plus angle complementar to asin(theta) #final_theta = asin(1.0 - sin_theta) final_theta += pi if (sin_sign == 0 and cos_theta > 0): final_theta += pi if (cos_theta * sin_sign > 0): final_theta += (pi / 2.0) (x, y, z) = from_v self.line_seqs.moveTo(Point3(x, y, z)) theta = base_theta print "add_cutting_plane_arc", "\n\tu:", u, "\n\tv:", v, "\n\tuxv:", uxv, "\n\tsin_theta:", sin_theta, "\n\tcos_theta:", cos_theta, "\n\tsign_theta:", sin_sign, "\n\ta:", a, "\n\tb:", b, "\n\tfinal_theta:", final_theta while theta < final_theta: (x, y, z) = [ c[i] + r * cos(theta) * a[i] + r * sin(theta) * b[i] for i in range(3) ] self.line_seqs.drawTo(Point3(x, y, z)) theta += base_theta (x, y, z) = to_v self.line_seqs.drawTo(Point3(x, y, z)) # self.line_seqs.moveTo(Point3(from_v[0], from_v[1], from_v[2])) # self.line_seqs.drawTo(Point3(c[0], c[1], c[2])) # self.line_seqs.drawTo(Point3(to_v[0], to_v[1], to_v[2])) # if (sin_theta == 0): # if (from_v != to_v): # while theta <= pi: # (x,y,z) = [c[i] + r * cos(theta) * a[i] + r * sin(theta) * b[i] for i in range(3)] # self.line_seqs.drawTo(Point3(x, y, z)) # theta += base_theta # (x,y,z) = to_v # self.line_seqs.drawTo(Point3(x, y, z)) # elif (sin_theta < 0): # #do half an arc # while theta <= pi: # (x,y,z) = [c[i] + r * cos(theta) * a[i] + r * sin(theta) * b[i] for i in range(3)] # self.line_seqs.drawTo(Point3(x, y, z)) # theta += base_theta # #do the rest # count = 0 # #while sin(theta) > sin_theta and count < 40: # while sin(theta) > sin_theta: # (x,y,z) = [c[i] + r * cos(theta) * a[i] + r * sin(theta) * b[i] for i in range(3)] # self.line_seqs.drawTo(Point3(x, y, z)) # theta += base_theta # count += 1 # (x,y,z) = to_v # self.line_seqs.drawTo(Point3(x, y, z)) # else: # count = 0 # #while sin(theta) < sin_theta and count < 40: # while sin(theta) < sin_theta: # (x,y,z) = [c[i] + r * cos(theta) * a[i] + r * sin(theta) * b[i] for i in range(3)] # self.line_seqs.drawTo(Point3(x, y, z)) # theta += base_theta # count+=1 # (x,y,z) = to_v # self.line_seqs.drawTo(Point3(x, y, z)) return self def attach_to(self, render): '''creates Panda3D representation that can be attached to render this function is mainly used inside Render class and its derivatives and user not need to worry to call it''' lines = NodePath(self.line_seqs.create()) lines.reparentTo(render.render) return lines