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()
示例#2
0
文件: Grid.py 项目: crempp/psg
	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)
示例#3
0
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 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 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()