Commit f00a1d52 authored by Ahmad Reza Cheraghi's avatar Ahmad Reza Cheraghi
Browse files

Delete vis.py

parent ff627bb6
import datetime, math, os, time
from pyglet.gl import *
from pyglet.window import mouse
import pyglet.window.key as key
import importlib
import copy
black = 1
gray = 2
red = 3
green = 4
blue = 5
# screenshot manager parameters
screenshot_directory = 'screenshots/'
screenshot_file_type = '.png'
# control parameters
zoom_enabled = True
zoom_min = 4
zoom_max = 128
zoom_init = 16
zoom_speed = 1 / 50
translation_enabled = True
translation_init = (0, 0)
# presentation parameters
window_width = 800
window_height = 600
window_resizable = True # set to False to force resolution even if window does not fit on screen
show_grid = True
rotate_thirty_degree = False # the grid is not drawn correctly if the view is rotated!
# rendering parameters
target_frame_rate = 60
busy_waiting_time = 0.0015
print_frame_stats = False
# simulation parameters
rounds_per_second = 10
# tile_alpha = 0.6
particle_alpha = 1
color_map = {black: [0, 0, 0], gray: [0.4, 0.4, 0.4], red: [0.8, 0, 0], green: [0, 0.8, 0], blue: [0, 0, 0.8]}
def coords_to_world(coords):
return coords[0], coords[1] * math.sqrt(3/4)
def world_to_coords(x, y):
return int(x), int(round(y / math.sqrt(3/4), 0))
def window_to_world(x, y, view):
x_coord = view.left + (view.right - view.left) * (x / view.width) # correct
y_coord = view.bottom + (view.top - view.bottom) * (y / view.height) # not correct
return x_coord, y_coord
class ScreenshotManager:
dt = datetime.datetime.now()
prefix = dt.isoformat(sep = '_', timespec = 'seconds').replace(':', '') + '_'
def takeScreenshot():
if not os.path.exists(screenshot_directory):
os.makedirs(screenshot_directory)
index = math.floor(time.monotonic() * 10**3)
file_name = screenshot_directory + ScreenshotManager.prefix + str(index) + screenshot_file_type
pyglet.image.get_buffer_manager().get_color_buffer().save(file_name)
class View:
def __init__(self):
self.focusPos = translation_init
self.zoom = zoom_init
def setDimensions(self, width, height):
self.width = width
self.height = height
self.update()
def drag(self, dx, dy):
if not translation_enabled:
return
self.focusPos = (self.focusPos[0] - dx / self.zoom, self.focusPos[1] - dy / self.zoom)
self.update()
def scroll(self, x, y, scroll_x, scroll_y):
if not zoom_enabled:
return
oldPos = (self.left + x / self.zoom, self.bottom + y / self.zoom)
self.zoom = self.zoom * math.exp(-scroll_y * zoom_speed)
self.zoom = max(self.zoom, zoom_min)
self.zoom = min(self.zoom, zoom_max)
self.update()
newPos = (self.left + x / self.zoom, self.bottom + y / self.zoom)
self.focusPos = (self.focusPos[0] + oldPos[0] - newPos[0], self.focusPos[1] + oldPos[1] - newPos[1])
self.update()
def update(self):
halfZoomRec = 0.5 / self.zoom
self.left = self.focusPos[0] - halfZoomRec * self.width;
self.right = self.focusPos[0] + halfZoomRec * self.width;
self.bottom = self.focusPos[1] - halfZoomRec * self.height;
self.top = self.focusPos[1] + halfZoomRec * self.height;
class VisWindow(pyglet.window.Window):
def __init__(self, world, sim):
#super().__init__(world.get_world_x_size(), world.get_world_y_size(), resizable=window_resizable, vsync=False, caption="Simulator")
super().__init__(world.get_world_x_size(), world.get_world_y_size(), resizable=window_resizable, vsync=False, caption="Simulator")
self.window_active = True
glClearColor(0.0, 0.0, 0.0, 0.0)
glClearDepth(1.0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
self.world = world
self.sim = sim
self.init_tile_vertex_list()
self.init_particle_vertex_list()
self.view = View()
self.particleTexture = pyglet.image.load('robotsOnTiles/images/particle.png').get_mipmapped_texture()
self.gridTexture = pyglet.image.load('robotsOnTiles/images/grid.png').get_mipmapped_texture()
glDisable(GL_DEPTH_TEST)
glDisable(GL_CULL_FACE)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glEnable(self.gridTexture.target)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
if rotate_thirty_degree:
glRotatef(30, 0, 0, 1)
glMatrixMode(GL_PROJECTION)
self.simulation_running = False
self.video_mode = False
def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
if buttons & mouse.LEFT:
self.view.drag(dx, dy)
def exit_callback(self):
self.close()
def on_mouse_scroll(self, x, y, scroll_x, scroll_y):
self.view.scroll(x, y, scroll_x, scroll_y)
def on_mouse_press(self, x, y, button, modifiers):
if modifiers & key.MOD_CTRL:
# get correct coordinates
world_coords = window_to_world(x, y, self.view)
coords_coords = world_to_coords(world_coords[0], world_coords[1])
if coords_coords not in self.world.tile_map:
# add tile and vertices
#tile = Tile(coords_coords[0], coords_coords[1])
if self.world.add_tile(coords_coords[0], coords_coords[1]):
tile = self.world.tile_map[coords_coords[0], coords_coords[1]]
self.tile_vertex_list.resize(4 * len(self.world.tiles), 4 * len(self.world.tiles))
#self.tile_vertex_list.resize(4 * len(self.world.tiles), 8 * len(self.world.tiles))
self.tile_vertex_list.indices[4 * (len(self.world.tiles) - 1) : 4 * (len(self.world.tiles) - 1) + 4] = range(4 * (len(self.world.tiles) - 1), 4 * (len(self.world.tiles) - 1) + 4)
# self.tile_vertex_list.indices = list(range(0, 8 * len(self.world.tiles)))
self.update_tile(len(self.world.tiles) - 1, tile)
else:
# delete tile
self.world.remove_tile(coords_coords)
self.tile_vertex_list.resize(4 * len(self.world.tiles), 4 * len(self.world.tiles))
self.update_tiles(True)
def on_resize(self, width, height):
glViewport(0, 0, width, height)
self.view.setDimensions(width, height)
return pyglet.event.EVENT_HANDLED
def on_close(self):
self.window_active = False
return pyglet.event.EVENT_HANDLED
def on_key_press(self, symbol, modifiers):
if symbol == key.Q and modifiers & key.MOD_COMMAND: # cmd+q: quit application
self.window_active = False
elif symbol == key.SPACE: # space: pause / unpause simulation
self.pause()
elif symbol == key.S and modifiers & key.MOD_COMMAND: # cmd+s: save screenshot
ScreenshotManager.takeScreenshot()
elif symbol == key.V and modifiers & key.MOD_COMMAND: # cmd+v: toggle video mode
if not self.video_mode:
self.video_mode = True
self.simulation_running = True
self.elapsed_frame_time = 0 # make videos completely reproducible
else:
self.video_mode = False
self.simulation_running = False
return pyglet.event.EVENT_HANDLED
def draw(self):
pyglet.gl.glClearColor(0, 0, 0, 0)
self.clear()
self.update_tiles()
self.update_particles()
self.update_locations()
glLoadIdentity()
glOrtho(self.view.left, self.view.right, self.view.bottom, self.view.top, 1, -1)
glClearColor(1, 1, 1, 1)
glClear(GL_COLOR_BUFFER_BIT)
if show_grid:
self.drawGrid()
else:
glClearColor(1, 1, 1, 1)
glClear(GL_COLOR_BUFFER_BIT)
glBindTexture(self.particleTexture.target, self.particleTexture.id)
if len(self.world.tiles) != 0:
self.tile_vertex_list.draw(GL_QUADS)
self.particle_vertex_list.draw(GL_QUADS)
self.flip()
if self.video_mode:
ScreenshotManager.takeScreenshot()
def drawGrid(self):
texLeft = math.fmod(self.view.left, 1)
texRight = texLeft + self.view.right - self.view.left
texHeight = 2 * math.sqrt(3/4)
texBottom = math.fmod(self.view.bottom, texHeight)
texTop = texBottom + self.view.top - self.view.bottom
texBottom = texBottom / texHeight
texTop = texTop / texHeight
glColor4f(1, 1, 1, 1)
glBindTexture(self.gridTexture.target, self.gridTexture.id)
glBegin(GL_QUADS)
glTexCoord2f(texLeft, texBottom)
glVertex2f(self.view.left, self.view.bottom)
glTexCoord2f(texRight, texBottom)
glVertex2f(self.view.right, self.view.bottom)
glTexCoord2f(texRight, texTop)
glVertex2f(self.view.right, self.view.top)
glTexCoord2f(texLeft, texTop)
glVertex2f(self.view.left, self.view.top)
glEnd()
def pause(self):
self.simulation_running = not self.simulation_running
def round(self):
if self.world.run_world():
return True
def init_tile_vertex_list(self):
self.tile_vertex_list = pyglet.graphics.vertex_list_indexed(4 * len(self.world.tiles),
list(range(0, 4 * len(self.world.tiles))),
#list(range(0,8 * len(self.world.tiles))),
'v2f', 't2f', 'c4f')
self.update_tiles(True)
def init_particle_vertex_list(self):
self.particle_vertex_list = pyglet.graphics.vertex_list_indexed(4 * len(self.world.particles),
[x for x in range(4 * len(self.world.particles))],
'v2f', 't2f', 'c4f')
self.update_particles(True)
def update_tiles(self, update_all=False):
foreground = []
background = []
for i, tile in enumerate(self.world.tiles):
if update_all or tile.modified:
self.update_tile(i, tile)
tile.modified = False
indices = list(range(4 * i, 4 * i + 4))
if tile.get_tile_status():
foreground += indices
else:
background += indices
self.tile_vertex_list.indices = background + foreground
def update_tile(self, i, tile):
weird = 256 / 220
pos = coords_to_world(tile.coords)
x = pos[0]
y = pos[1]
self.tile_vertex_list.vertices[8 * i: 8 * i + 8] = [x - weird, y - weird, x + weird, y - weird, x + weird,
y + weird, x - weird, y + weird]
if tile.get_tile_status():
texLeft = 0 / 8
texRight = 1 / 8
texBottom = 5 / 8
texTop = 6 / 8
tile_alpha = 1
else:
texLeft = 7 / 8
texRight = 8 / 8
texBottom = 4 / 8
texTop = 5 / 8
tile_alpha = 0.5
self.tile_vertex_list.tex_coords[8 * i: 8 * i + 8] = [texLeft, texBottom, texRight, texBottom, texRight, texTop,
texLeft, texTop]
self.tile_vertex_list.colors[16 * i: 16 * i + 16] = (color_map[tile.color] + [tile_alpha]) * 4
def update_particles(self, update_all = False):
for i, particle in enumerate(self.world.particles):
if update_all or particle.modified:
self.update_particle(i, particle)
particle.modified = False
def update_particle(self, i, particle):
weird = 256 / 220
pos = coords_to_world(particle.coords)
x = pos[0]
y = pos[1]
self.particle_vertex_list.vertices[8 * i: 8 * i + 8] = [x - weird, y - weird, x + weird, y - weird, x + weird,
y + weird, x - weird, y + weird]
texLeft = 0/8
texRight = 1/8
texBottom = 0/8
texTop = 1/8
self.particle_vertex_list.tex_coords[8 * i: 8 * i + 8] = [texLeft, texBottom, texRight, texBottom,
texRight, texTop, texLeft, texTop]
self.particle_vertex_list.colors[16 * i: 16 * i + 16] = (color_map[particle.color] + [particle_alpha]) * 4
def update_locations(self, update_all=True):
for i, location in enumerate(self.world.locations):
if update_all or location.modified:
self.update_location(i, location)
def update_location(self, i, location):
weird = 256 / 220
pos = coords_to_world(location.coords)
x = pos[0]
y = pos[1]
def run(self):
target_frame_time = 1 / target_frame_rate
round_time = 1 / rounds_per_second
self.elapsed_frame_time = 0
mod = importlib.import_module('robotsOnTiles.scenarios.' + self.sim.get_scenario())
while self.sim.get_actual_round() <= self.sim.get_max_round(): #while actual simulation round is below max round
while self.window_active:
last_time = time.perf_counter()
while self.elapsed_frame_time >= round_time:
mod.scenario(self.sim, self.world)
self.elapsed_frame_time -= round_time
if self.elapsed_frame_time <= round_time:
self.world.csv_round_writer.next_line(self.sim.get_actual_round())
self.sim.inc_round_cnter() # increase simulation round counter by one.
self.dispatch_events()
self.draw()
while time.perf_counter() - last_time < target_frame_time:
sleep_time = max(target_frame_time - (time.perf_counter() - last_time), 0)
if sleep_time >= busy_waiting_time:
time.sleep(sleep_time - busy_waiting_time)
else:
pass
if self.simulation_running:
self.elapsed_frame_time += target_frame_time
if print_frame_stats:
frame_time_delta = time.perf_counter() - last_time - target_frame_time
frame_time_ok = abs(frame_time_delta) <= 0.0001
print('frame time:', format(time.perf_counter() - last_time, '.6f'), '\tdelta:', format(frame_time_delta, '0.6f'), '\tok:', frame_time_ok)
self.world.csv_round_writer.aggregate_metrics () #After simulation is finished, aggregate everything
for particle in self.world.particles:
particle.csv_particle_writer.close_particle()
return
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment