예제 #1
0
파일: test.py 프로젝트: fredyk/F3Visor
class Control(BaseControl):

    gui = None
    NAME = "Control"
    stopped = False
    objs = {}
    # delay = 22.3 / (30.0**2)
    # delay = 0.034
    # delay = 0.067
    delay = 1 / 30.0
    scale = 10
    visor = [5, -10, 5]
    visor_rot = [0, 0, 0]
    visor_disp = [0, 0, 0]
    visorchanged = True
    rots = [0.032, {0: 0, 1: 0, 2: 0}]
    movs = [16, {0: 0, 1: 0, 2: 0}]
    cur_ob = 0  # current object
    available_time = 0

    def __init__(self, Main):
        # threading.Thread.__init__(self)
        BaseControl.__init__(self, Main)
        # self.gui = Main
        self.tkthread = TkThread(self)
        self.tkthread.noVerbose()
        self.tkthread.start()

    def delete(self, code):
        if code >= 0:
            self.gui.mc.delete(code)
        else:
            print "OMIT"

    def update(self, none=None):
        # self.gui.after_idle(self.gui.update)
        # self.gui.mc.update()
        pass

    def ObjFromFile(self, path, color="blue", rotate=True, name="", scale=1.0):
        ob0file = open(path, "rb")
        ob0 = Volume([], [], name=name or ("ob" + str(self.cur_ob)), color=color)
        self.objs[ob0.name] = ob0
        self.cur_ob += 1
        # scale = 1.0
        verts = []
        for l in ob0file:
            dt = l.strip().split(" ")
            if dt[0] == "v":
                verts.append([float(d) for d in dt[1:] if d])

            elif dt[0] == "f":
                vs = [d.split("/")[0] for d in dt[1:]]
                ob0.addFace(tuple([int(float(s)) for s in vs]))
        min_z = 0
        max_z = 0
        min_y = 0
        max_y = 0

        for v in verts:
            if v[2] < min_z:
                min_z = v[2]
            elif v[2] > max_z:
                max_z = v[2]
            if v[1] < min_y:
                min_y = v[1]
            elif v[1] > max_y:
                max_y = v[1]

        scale = ((max_z - min_z) if ((max_z - min_z) > (max_y - min_y)) else (max_y - min_y)) / 5.0 * 1 / float(scale)
        print ob0.name, scale, min_y, max_y, min_z, max_z
        for v in verts:
            ob0.addVert(tuple(float(d) / scale + (5.0 if i < 2 else 0.0) for i, d in enumerate(v)))
        ob0file.close()
        if rotate:
            ob0.rotate([((5, 5, 0), (math.pi / 2.0, 0, 0))])

    def main(self):
        print 1
        # sys.stdout = open("stdout","wb")
        # sys.stderr = open("stderr","wb")
        self.scale = self.gui.w / 10.0
        self.visor = [s for s in self.scaled(self.visor)]
        center = (5, 1, 5)
        print "scale:", self.scale

        sys.stdout.flush()

        cube = Volume(
            [(1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2), (2, 1, 1), (2, 1, 2), (2, 2, 1), (2, 2, 2)],
            [(1, 3, 4, 2), (5, 7, 8, 6), (1, 5, 6, 2), (3, 7, 8, 4), (2, 6, 8, 4), (1, 5, 7, 3)],
            name="cube0",
            color="blue",
        )

        pyramid = Volume(
            [(3, 1, 1), (3.5, 1.5, 3), (3.5, 2, 1), (4, 1, 1)],
            [(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)],
            name="pyr0",
            color="red",
        )

        grid = Volume([], [], name="grid0", color="gray")
        for x in xrange(10):
            for y in xrange(10):
                grid.addVert((x, y, 1))

        for x in xrange(9):
            for y in xrange(9):
                grid.addFace((2 + x * 10 + y, 1 + x * 10 + y, 1 + (x + 1) * 10 + y, 2 + (x + 1) * 10 + y))

        # self.ObjFromFile("./MinoanColumnA_OBJ/MinoanColumnA_Low.obj", color="yellow", name="column")
        # self.ObjFromFile("./palm/palm1_LOD.obj", "green", rotate = True, name="palm")
        self.ObjFromFile("./Gta-spano-2010 obj/Gta-spano-2010 obj.obj", "blue", rotate=True, name="car", scale=2.0)
        # self.ObjFromFile("./L200-OBJ/L200-OBJ/L200-OBJ.obj", "blue", rotate = True, name="car",scale=1.0)
        self.objs["cube0"] = cube
        self.objs["pyr0"] = pyramid
        # self.objs["grid0"] = grid

        sys.stdout.flush()

        self.objs["cube0"].rotate([((5.0, 5.0, 0), (0, 0, 1.0))])
        # -math.pi / 2.0 * 1.5

        self.rePaint()
        cnt = 0
        cnt2 = 0
        init = now()
        step = 1.0 / self.delay

        while not (self.stopped):

            t0 = now()
            if not (self.stopped):

                for r in self.rots[1]:
                    if self.rots[1][r]:
                        self.visor_rot[r] += self.rots[0] * self.rots[1][r]

                for m in self.movs[1]:
                    if self.movs[1][m]:
                        if m == 0:
                            self.visor_disp[m] += self.movs[0] * self.movs[1][m] * math.cos(self.visor_rot[2])
                        elif m == 1:
                            self.visor_disp[m] += self.movs[0] * self.movs[1][m] * math.cos(self.visor_rot[2])
                        else:
                            self.visor_disp[m] += self.movs[0] * self.movs[1][m]

                # self.objs["car"].rotate(
                #     [

                #         (center, (
                #                     0,
                #                     0,
                #                     0
                #                     )

                #             ),
                #         (center, (
                #                     0,
                #                     0,
                #                     2.0*math.pi / 300.0
                #                     )
                #             )
                #         ]
                #     )

                # self.objs["car"].rotate(
                self.tkthread.after_idle(
                    self.objs["car"].rotate, [((5.0, 5.0, 0), (0, 0, 2.0 * math.pi / step / 10.0))]
                )
                # 2.0*math.pi / 300.0
                self.available_time = self.delay - now() + t0
                if self.available_time > 0:
                    self.rePaint()
                else:
                    print "OMIT BY TIME"

            try:
                self.gui.sl.config(text="fps: " + str(round(cnt2 / (max((now() - init), 1)), 1)))
            except TclError:
                print "error 0x04", sys.exc_info()
                pass
            cnt += 1
            cnt2 += 1
            if not (cnt % 600):
                cnt2 = 0
                init = now()

            delay = self.delay - now() + t0

            sys.stdout.flush()
            sleep(max(0.0, delay))

    def rePaint(self):

        _waserror = False
        for obname in self.objs:
            if not (self.stopped):
                obj = self.objs[obname]
                if self.visorchanged or obj.changed:
                    try:
                        # self.gui.mc.delete(*self.gui.mc.find_withtag(obj.name))
                        pass
                    except (ValueError, TclError) as e:
                        _waserror = True
                        print "error 0x03", sys.exc_info()  # , [dir(e) for e in sys.exc_info()], dir(sys.exc_info()[2].tb_frame), sys.exc_info()[2].tb_lasti, sys.exc_info()[2].tb_next
                    else:
                        paintObj(obj, self)
                        obj.noChanges()
        if not (_waserror):
            self.visorchanged = False

    def scaled(self, v):
        if (type(v) == list) and (type(v[0]) == tuple):
            return [tuple([c * self.scale for c in ve]) for ve in v]
        else:
            return tuple([c * self.scale for c in v])

    def unScaled(self, v):
        if type(v) == list:
            return [tuple([c / float(self.scale) for c in ve]) for ve in v]
        else:
            return tuple([c / float(self.scale) for c in v])

    def keyStart(self, e):

        if e.keysym == "Left":  # left

            self.rots[1][2] = -1

        elif e.keysym == "Up":  # up

            self.rots[1][0] = 1

        elif e.keysym == "Right":  # right

            self.rots[1][2] = 1

        elif e.keysym == "Down":  # down

            self.rots[1][0] = -1
        elif e.char.lower() == "a":

            self.movs[1][0] = 1
        elif e.char.lower() == "w":

            self.movs[1][1] = -1
        elif e.char.lower() == "d":

            self.movs[1][0] = -1
        elif e.char.lower() == "s":

            self.movs[1][1] = 1
        elif e.char.lower() == "e":

            self.movs[1][2] = -1
        elif e.char.lower() == "c":

            self.movs[1][2] = 1

        self.visorchanged = True

    def keyEnd(self, e):

        if e.keysym == "Left":  # left

            self.rots[1][2] = 0

        elif e.keysym == "Up":  # up

            self.rots[1][0] = 0

        elif e.keysym == "Right":  # right

            self.rots[1][2] = 0

        elif e.keysym == "Down":  # down

            self.rots[1][0] = 0
        elif e.char.lower() == "a":

            self.movs[1][0] = 0
        elif e.char.lower() == "w":

            self.movs[1][1] = 0
        elif e.char.lower() == "d":

            self.movs[1][0] = 0
        elif e.char.lower() == "s":

            self.movs[1][1] = 0
        elif e.char.lower() == "e":

            self.movs[1][2] = 0
        elif e.char.lower() == "c":

            self.movs[1][2] = 0

    def mouseCamera(self, e):

        midx = self.gui.w / 2.0
        midz = self.gui.h / 2.0
        rotz = math.pi / 2.0 * ((e.x - midx) / float(midx))
        rotx = math.pi / 2.0 * ((e.y - midz) / float(midz)) * (1 - abs(rotz / math.pi * 2.0))
        roty = (rotx + rotz) / 2.0

        self.visor_rot[0] = rotx
        self.visor_rot[1] = roty * 0.16
        self.visor_rot[2] = rotz
        self.visorchanged = True
예제 #2
0
class App(threading.Thread):
    # x = 0
    stopped = False
    objs = dict()
    cur_ob = 0
    delay = 1 / 60.0
    available_time = delay
    scale = 10
    visor =  [5, -10, 5]
    # visor_rot = [0, 0, -math.pi / 4.0]
    visor_rot = [0, 0, 0.0875]
    visor_disp = [0, 0, 0]
    rots = [0.032, {0:0, 1:0, 2:0}]
    movs = [64, {0:0,1:0,2:0}]
    painted = None
    width = 1920.0
    height = 1080.0
    points = []
    last_paint = 0
    cords = None

    def __init__(self):
        threading.Thread.__init__(self)
        self.tkthread = TkThread(self)
        self.tkthread.noVerbose()
        self.tkthread.start()

        print 1
        # sys.stdout = open("stdout","wb")
        # sys.stderr = open("stderr","wb")
        self.scale = self.width / 10.0
        self.visor = [s for s in self.scaled(self.visor)]
        center = ( 5, 1, 5 )
        print "scale:", self.scale

        sys.stdout.flush()

    def scaled(self, v):
        if(type(v) == list)and(type(v[0])==tuple):
            return [
                tuple( [ c * self.scale for c in ve] )
                for ve in v
            ]
        else:
            return tuple( [c * self.scale for c in v] )

    def ObjFromFile(self, path, color = "blue", rotate = True, name = "", scale=1.0):
        ob0file = open(path,"rb")
        ob0 = Volume([], [], name=name or ("ob"+str(self.cur_ob)), color=color)
        self.objs[ob0.name] = ob0
        self.cur_ob+=1
        # scale = 1.0
        verts = []
        for l in ob0file:
            dt = l.strip().split(" ")
            if dt[0] == "v":
                verts.append( [ float(d)  for d in dt[1:] if d ] )

            elif dt[0] == "f":
                vs = [
                    d.split("/")[0]
                    for d in dt[1:]
                ]
                ob0.addFace( tuple( [ int(float(s)) for s in vs ] ) )
        min_z = 0
        max_z = 0
        min_y = 0
        max_y = 0

        for v in verts:
            if(v[2] < min_z ):
                min_z = v[2]
            elif(v[2] > max_z ):
                max_z = v[2]
            if(v[1] < min_y ):
                min_y = v[1]
            elif(v[1] > max_y ):
                max_y = v[1]

        scale = ( (max_z - min_z) if \
                ( (max_z - min_z ) > (max_y - min_y) ) else \
                  (max_y - min_y) ) / 5.0 * 1 / float(scale)
        print ob0.name, scale, min_y, max_y, min_z, max_z
        for v in verts:
            ob0.addVert( tuple( float(d) / scale + ( 5.0 if i < 2 else 0.0 )
                         for i, d in enumerate(v) ) )
        ob0file.close()
        if(rotate):
            ob0.rotate( [ ( (5, 5, 0), (math.pi / 2.0, 0, 1.0) ), ] )

    # def cube(self, width, position, rotation, color, name):
    #     cube = Volume([], [], name=name or ("cube"+str(self.cur_ob)), color=color)
    #     for x in xrange(2):
    #         for y in xrange(2):
                
    #     self.cur_ob += 1


    def calculatePoints(self, loop = False):
        app = self
        self.painted = set()
        init = now()
        for r in self.rots[1]:
            if(self.rots[1][r]):
                self.visor_rot[r] += self.rots[0]*self.rots[1][r]

        for m in self.movs[1]:
            if(self.movs[1][m]):
                if(m == 0):
                    self.visor_disp[m] += self.movs[0]*self.movs[1][m]*math.cos(self.visor_rot[2])
                elif(m == 1):
                    self.visor_disp[m] += self.movs[0]*self.movs[1][m]*math.cos(self.visor_rot[2])
                else:
                    self.visor_disp[m] += self.movs[0]*self.movs[1][m]

        for name, obj in app.objs.iteritems():
            # this method uses app gui main canvas and app cords
            init = now()
            # try: ch = canvas_height = app.gui.mc.winfo_height()
            # try: ch = size[1]
            try: ch = self.height
            except ValueError as e: print "error 0x01", sys.exc_info()#, [dir(e) for e in sys.exc_info()]
            else:
                # self.points = []
                # painted = []
                # painted = dict()
                # vertex = obj.getVertex()
                t0 = now()
                # if self.cords[name] is None:
                    # self.cords[name] = obj.getCords(app.visor, app.visor_rot, app.visor_disp, app.scale)
                cords = obj.getCords(app.visor, app.visor_rot, app.visor_disp, app.scale)
                # else:

                # print "mc:", app.gui.mc.winfo_height()
                # for face in obj.getFaces():
                # polygons = obj.getPolygons()
                # if ( now() - init ) >= self.available_time/2.0: break
                # cnt = self.last_paint
                cnt = 0
                while len(self.points) < cnt:
                    # self.points.append([(0, 0), (0, 0), (0, 0)])
                    self.points.append(None)
                # for pol in polygons[cnt:]:
                for pol in obj.getPolygons(cnt):
                    # if ( now() - init ) >= self.available_time/2.0: break
                    # face = [app.cords[n-1] for n in face]
                    if(not(app.stopped) ):#and (len(face)==4)):
                        # try: app.gui.mc.create_polygon([ cords[f-1] for f in face ], fill=obj.color, width=2, tags=obj.name) # paints in app gui main canvas
                        # except (ValueError, TclError) as e: print "error 0x02", sys.exc_info()#, [dir(e) for e in sys.exc_info()]
                        face = pol.getFace()
                        ps = []
                        for i, n in enumerate(face):
                            if(not(app.stopped)):
                                # if i == 0:
                                #     prev = -1
                                # else:
                                #     prev = i - 1
                                # # px, py = app.cords[face[prev]-1][0], app.gui.mc.winfo_height()-app.cords[face[prev]-1][1]
                                # px, py = cords[face[prev]-1][0], \
                                #          ch-cords[face[prev]-1][1]
                                # cx, cy = cords[n-1][0], \
                                #          ch-cords[n-1][1]
                                # paint = sorted([(px, py,), (cx, cy,)])
                                # if i == 0:
                                #     prev = -1
                                # else:
                                #     prev = i - 1
                                # px, py = app.cords[face[prev]-1][0], app.gui.mc.winfo_height()-app.cords[face[prev]-1][1]
                                # if(i < len(face) - 1):
                                px, py = cords[n-1][0], \
                                         ch-cords[n-1][1]
                                # cx, cy = cords[n-1][0], \
                                #          ch-cords[n-1][1]
                                # paint = sorted([(px, py,), (cx, cy,)])
                                paint = (px, py,)
                                # points.append(paint)
                                ps.append(paint)
                            else: break
                        # points.append(ps)
                        pol.setPaint(ps)
                        if([True for i, p in enumerate(ps[1:]) if p[0] != ps[i][0]]) and \
                          ([True for i, p in enumerate(ps[1:]) if p[1] != ps[i][1]]):
                            if(cnt >= len(self.points)):
                                self.points.append(pol)
                            elif(self.points[cnt] is None):
                                print "was None"
                                self.points[cnt] = pol
                        cnt += 1
                    else: break
                t1 = now()
                print len(cords) / float( (t1 - t0) or 1e-6 ), "cords/s"

                # for paint in points:
                # for pol in points[:16]:
        print "calc time:",now()-init
        if(loop):
            while not self.stopped:
                self.calculatePoints()