Files
odin-road-pathfinding/src/draw.odin

124 lines
3.4 KiB
Odin

package main
import "core:math"
import "core:fmt"
import sc "core:strconv"
import rl "vendor:raylib"
import "common"
// Main drawing function
draw :: proc(self: ^Simulator, pos: rl.Vector2) {
rl.ClearBackground(rl.LIGHTGRAY)
draw_roads(self)
draw_nodes(self)
draw_cars(self)
draw_temp_road(self, pos)
if self.display_entity_data do draw_entity_data(self)
draw_ui(self)
}
@(private="file")
draw_roads :: proc(self: ^Simulator) {
for road, index in self.roads {
start := road.nodes[0]
end := road.nodes[1]
road_colour: rl.Color
if road, ok := self.highlighted_road.?; ok && road == uint(index) && self.delete_mode {
road_colour = common.ROAD_HIGHLIGHT_COLOUR
} else do road_colour = common.ROAD_COLOUR
rl.DrawLineEx(self.nodes[start].pos, self.nodes[end].pos, common.ROAD_SIZE, road_colour)
}
}
@(private="file")
draw_nodes :: proc(self: ^Simulator) {
for node in self.nodes {
// draws the snapping radius if key is held down
if self.show_details do rl.DrawCircleV(node.pos, common.NODE_SNAP_RADIUS, common.NODE_SNAP_COLOUR)
// draws the node
rl.DrawCircleV(node.pos, common.NODE_RADIUS, common.NODE_DONE_COLOUR)
}
}
@(private="file")
draw_cars :: proc(self: ^Simulator) {
for car in self.cars {
ref := car.pos.ref
// TODO fix in the future
// let's fix it by tracking length of the road and
pos := car.pos.type == .Node ? self.nodes[ref].pos : self.nodes[self.roads[ref].nodes[0]].pos
rect := rl.Rectangle {
x = pos.x,
y = pos.y,
width = common.CAR_WIDTH,
height = common.CAR_HEIGHT
}
rl.DrawRectangleRec(rect, common.CAR_COLOUR)
}
}
@(private="file")
draw_temp_road :: proc(self: ^Simulator, pos: rl.Vector2) {
// draw temp road if exists
val, ok := self.temp_node.?
if !ok do return
rl.DrawLineEx(self.nodes[val].pos, pos, common.ROAD_SIZE, common.ROAD_COLOUR)
rl.DrawCircleV(self.nodes[val].pos, common.NODE_RADIUS, common.NODE_BUILD_COLOUR)
rl.DrawCircleV(pos, common.NODE_RADIUS, common.NODE_CURSOR_COLOUR)
}
// Drawing UI text, mostly for debugging purposes
@(private="file")
draw_ui :: proc(self: ^Simulator) {
entity_count := fmt.ctprintf("Nodes: %d, Roads: %d, Cars: %d", len(self.nodes), len(self.roads), len(self.cars))
rl.DrawText(entity_count, i32(len(entity_count)), common.HEIGHT - common.TEXT_SIZE, common.TEXT_SIZE, common.TEXT_COLOUR)
}
// Draws ID's on top of all entities (roads, nodes, cars, etc.)
@(private="file")
draw_entity_data :: proc(self: ^Simulator) {
colour := rl.ORANGE
for node, index in self.nodes {
radius_diff := f32(common.NODE_RADIUS / 2)
actual_pos: rl.Vector2 = {
node.pos.x - radius_diff,
node.pos.y - radius_diff,
}
id := fmt.caprintf("%d", index)
rl.DrawText(id, i32(actual_pos.x), i32(actual_pos.y), common.TEXT_SIZE, colour)
}
// todo fix in the future
for road, index in self.roads {
id := fmt.caprintf("%d", index)
start := self.nodes[road.nodes[0]]
end := self.nodes[road.nodes[1]]
// calculate the appropriate coordiante
// first get the leftmost node
leftmost := start.pos.x <= end.pos.x ? start : end
rl.DrawText(id, i32(leftmost.pos.x + road.length / 2), i32((start.pos.y + end.pos.y) / 2), common.TEXT_SIZE, colour)
}
// todo for cars
for car, index in self.cars {
id := fmt.caprintf("%d", index)
offset := math.sqrt(f32(common.CAR_HEIGHT * len(id)))
rl.DrawText(id, i32(car.absolute_pos.x + common.CAR_WIDTH / 2 - offset), i32(car.absolute_pos.y), common.CAR_HEIGHT, colour)
}
}