-
Notifications
You must be signed in to change notification settings - Fork 2
/
pointstream.py
167 lines (139 loc) · 4.11 KB
/
pointstream.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
"""
PointStream -- The main galvo multiple object drawing algorithm.
This code is responsible for drawing multiple objects.
It will need to be improved for efficiency.
FIXME/NOTE: The documentation / variable names are a bit out of date.
"Ball", where it occurs, means "entity object".
"""
import math
import random
import itertools
import sys
import thread
import time
import pygame
# GLOBALS
from globalvals import *
from entities import *
class PointStream(object):
def __init__(self):
self.called = False
self.stream = self.produce()
# A list of all the objects to draw
# XXX: For now, add and remove manually.
self.objects = []
def produce(self):
"""
This infinite loop functions as an infinite point generator.
It generates points for both balls as well as the "blanking"
that must occur between them.
"""
while True:
#print "POINT STREAM LOOP BEGIN"
curObj = None # XXX SCOPE HERE FOR DEBUG ONLY
nextObj = None # XXX SCOPE HERE FOR DEBUG ONLY
try:
# Generate and cache the first points of the objects.
# Necessary in order to slow down galvo tracking as we
# move to the next object.
for b in self.objects:
b.cacheFirstPt()
# Objects to destroy at end of loop
destroy = []
"""
# TOPOLOGICAL SORT OF OBJECTS TO MAKE DRAWING W/
# GALVOS EFFICIENT!
sortedObjects = []
presort = self.objects[:]
sortedObjects.append(presort.pop(0))
while len(presort):
#lowx = presort[0].x
lastObj = sortedObjects[-1]
lowdist = 10000000
li = 0
for i in range(len(presort)):
obj = presort[i]
a = obj.x - lastObj.x
b = obj.y - lastObj.y
c = math.sqrt(a**2 + b**2)
if c < lowdist:
lowdist = c
li = i
sortedObjects.append(presort.pop(li))
#sortedObjects = self.objects[:]
self.objects = sortedObjects # XXX XXX XXX XXX TURN OFF HERE
"""
# Draw all the objects...
for i in range(len(self.objects)):
curObj = self.objects[i]
nextObj = self.objects[(i+1)%len(self.objects)]
# Skip draw?
if curObj.skipDraw:
continue
# Prepare to cull object if it is marked destroy
if curObj.destroy:
destroy.append(i)
# Blanking (on the way in), if set
if curObj.doBlanking:
p = curObj.firstPt
p = (p[0], p[1], 0, 0, 0)
for x in range(BLANK_SAMPLE_PTS):
yield p
# Draw the object
if not curObj.drawn:
yield curObj.firstPt # This was cached upfront
for x in curObj.produce():
yield x
"""
# XXX: BULLET SPECIFIC -- Remove?
if type(curObj) == Bullet:
# Paint last pt for smoothness
# XXX: Remove?
for x in xrange(BLANK_SAMPLE_PTS):
yield curObj.firstPt
# Paint empty for smoothness
# XXX: Remove?
for x in xrange(BLANK_SAMPLE_PTS):
yield (curObj.lastPt[0], curObj.lastPt[1],
0, 0, 0)
"""
# Blanking (on the way out), if set
if curObj.doBlanking:
p = curObj.lastPt
p = (p[0], p[1], 0, 0, 0)
for x in range(BLANK_SAMPLE_PTS):
yield p
# Now, track to the next object.
lastX = curObj.lastPt[0]
lastY = curObj.lastPt[1]
xDiff = curObj.lastPt[0] - nextObj.firstPt[0]
yDiff = curObj.lastPt[1] - nextObj.firstPt[1]
mv = TRACKING_SAMPLE_PTS
for i in xrange(mv):
percent = i/float(mv)
xb = int(lastX - xDiff*percent)
yb = int(lastY - yDiff*percent)
# If we want to 'see' the tracking path (debug)
if SHOW_TRACKING_PATH:
yield (xb, yb, 0, CMAX, 0)
else:
yield (xb, yb, 0, 0, 0)
# Reset object state (nasty hack for point caching)
for b in self.objects:
b.drawn = False
# Items to destroy
#print destroy
destroy.sort()
destroy.reverse()
for i in destroy:
self.objects.pop(i)
except Exception as e:
import sys, traceback
while True:
print '\n---------------------'
print 'PointStream Exception: %s' % e
traceback.print_tb(sys.exc_info()[2])
print "---------------------\n"
def read(self, n):
d = [self.stream.next() for i in xrange(n)]
return d