-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodels.py
143 lines (110 loc) · 4.77 KB
/
models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
from rendering import draw_line
import mathutils
import math
import bpy
class Road():
__incrementing_road_id = 0
def __init__(self, road_size=0, points=[]):
self.road_size = road_size
self.points = points
self.id = self.__incrementing_road_id
self.__class__.__incrementing_road_id += 1
def draw(self):
draw_line("road" + str(self.id), "curve" + str(self.id), self.points)
class Wanderer():
def __init__(self):
self.circle_radius = .5
self.max_angle_change_per_delta = 5
self.move_change_per_delta = 1
self.rotation_angle_change_per_delta = 360
self.offset_from_center = 1
self.cur_angle = mathutils.noise.random() * 360 # random in degrees
self.position = mathutils.Vector((0, 0, 0))
self.forward = mathutils.Vector((1, 0, 0))
def update(self, delta):
point_on_circle = self._find_point_on_circle()
turn_to = (point_on_circle - self.position).normalized()
angle_between = math.degrees(self.forward.angle(turn_to))
to_rotate_amount = angle_between # max(min(1.0, self.rotation_angle_change_per_delta/angle_between), 0.0)
self.forward = self.forward.slerp(turn_to, to_rotate_amount * delta) # in this setup, the circle will turn independently of the person and they will just approach a single facing direction
self.forward.normalize()
self.position += self.forward * self.move_change_per_delta * delta
self._update_circle_point(delta)
def _find_point_on_circle(self):
circle_center = self.position + self.forward * self.offset_from_center
circle_point = mathutils.Vector((math.cos(self.cur_angle), math.sin(self.cur_angle), 0)) * self.circle_radius
return circle_center + circle_point
def _update_circle_point(self, delta):
randomness = mathutils.noise.random() * 2 - 1
self.cur_angle += randomness * self.max_angle_change_per_delta * delta
class Grid():
def __init__(self, center, width, height):
self.center = center
self.width = width
self.height = height
def is_point_inside(self, point):
to_position = point - self.center
return (math.fabs(to_position.x) <= self.width and math.fabs(to_position.y) <= self.height)
def draw(self):
grid_points = [
self.center + mathutils.Vector((-self.width, -self.height, 0)),
self.center + mathutils.Vector((-self.width, self.height, 0)),
self.center + mathutils.Vector((self.width, self.height, 0)),
self.center + mathutils.Vector((self.width, -self.height, 0)),
self.center + mathutils.Vector((-self.width, -self.height, 0))
]
draw_line('grid', 'square', grid_points)
class HeatmapSquare():
def __init__(self, center=None, value=None):
self.center = center
self.value = value
class Building():
__incrementing_building_id = 0
def __init__(self, position=mathutils.Vector((0, 0, 0)), width=1, height=1, depth=1):
self.center = position
self.width = width
self.height = height
self.depth = depth
self.top_points = []
self.bottom_points = []
self.id = self.__incrementing_building_id
self.__class__.__incrementing_building_id += 1
def generate_points(self):
x_vec = mathutils.Vector((self.width, 0, 0))
y_vec = mathutils.Vector((0, self.height, 0))
self.bottom_points = [
x_vec + y_vec,
x_vec - y_vec,
-x_vec - y_vec,
-x_vec + y_vec
]
self.top_points = [bot + mathutils.Vector((0, 0, self.depth)) for bot in self.bottom_points]
def draw(self):
vertices = self.bottom_points + self.top_points
indices = [
(0, 1, 2, 3), # bottom
(4, 5, 6, 7), # top (maybe wound wrong way)
(0, 1, 5, 4),
(1, 2, 6, 5),
(2, 3, 7, 6),
(3, 0, 4, 7)
]
mesh = bpy.data.meshes.new('Building Mesh ' + str(self.id))
obj = bpy.data.objects.new("Building Object " + str(self.id), mesh)
obj.location = self.center
bpy.context.scene.objects.link(obj)
mesh.from_pydata(vertices, [], indices)
mesh.update(calc_edges=True)
class BuildingLot():
__incrementing_lot_id = 0
def __init__(self, center, base_size, to_road):
self.center = center
self.base_size = base_size
self.to_road = to_road
self.id = self.__incrementing_lot_id
self.__class__.__incrementing_lot_id += 1
def draw(self):
draw_line("lot" + str(self.id), "curve" + str(self.id), self._points)
@property
def _points(self):
return [self.center, self.center + self.to_road * self.base_size / 2]