|
1
|
|
|
from gem import vector |
|
2
|
|
|
from gem import matrix |
|
3
|
|
|
from ed2d.physics import aabb |
|
4
|
|
|
|
|
5
|
|
|
class Rectangle(object): |
|
6
|
|
|
def __init__(self, x, y, width=None, height=None, flag=None, data=None): |
|
7
|
|
|
# Object information |
|
8
|
|
|
self.width = width |
|
9
|
|
|
self.height = height |
|
10
|
|
|
|
|
11
|
|
|
# Scale data |
|
12
|
|
|
self.scaleDeltaX = 0 |
|
13
|
|
|
self.scaleDeltaY = 0 |
|
14
|
|
|
self._scaleX = 1 |
|
15
|
|
|
self._scaleY = 1 |
|
16
|
|
|
|
|
17
|
|
|
# Positon data |
|
18
|
|
|
self.xPosDelta = 0 |
|
19
|
|
|
self.yPosDelta = 0 |
|
20
|
|
|
self.xPos = 0 |
|
21
|
|
|
self.yPos = 0 |
|
22
|
|
|
|
|
23
|
|
|
# Containers |
|
24
|
|
|
self.data = [None, None, None, None] |
|
25
|
|
|
self.collisionData = [] |
|
26
|
|
|
|
|
27
|
|
|
# Type of collision model, used by the physics engine |
|
28
|
|
|
self.type = "AABB" |
|
29
|
|
|
|
|
30
|
|
|
self.modelMatrix = matrix.Matrix(4) |
|
31
|
|
|
|
|
32
|
|
|
# Params processing |
|
33
|
|
|
if width is None and height is None: |
|
34
|
|
|
self.findDim() |
|
35
|
|
|
|
|
36
|
|
|
if flag is None and data is None: |
|
37
|
|
|
self.generateVertices() |
|
38
|
|
|
elif flag == 'QT' and data is None: |
|
39
|
|
|
self.fgenerateVertices() |
|
40
|
|
|
else: |
|
41
|
|
|
self.data = data |
|
42
|
|
|
self.__findDim() |
|
43
|
|
|
|
|
44
|
|
|
self.translate(x, y) |
|
45
|
|
|
self.scale(self.width, self.height) |
|
46
|
|
|
self.update() |
|
47
|
|
|
|
|
48
|
|
|
|
|
49
|
|
|
def make_aabb(self): |
|
50
|
|
|
'''Generate an AABB for this object''' |
|
51
|
|
|
# The collision data should be used by the collider to run an intersection test |
|
52
|
|
|
aabbData10 = (self.modelMatrix.transpose() * vector.Vector(4, data=[self.data[0][0], self.data[0][1], 0.0, 1.0])).xy() |
|
53
|
|
|
aabbData11 = (self.modelMatrix.transpose() * vector.Vector(4, data=[self.data[1][0], self.data[1][1], 0.0, 1.0])).xy() |
|
54
|
|
|
aabbData12 = (self.modelMatrix.transpose() * vector.Vector(4, data=[self.data[2][0], self.data[2][1], 0.0, 1.0])).xy() |
|
55
|
|
|
aabbData13 = (self.modelMatrix.transpose() * vector.Vector(4, data=[self.data[3][0], self.data[3][1], 0.0, 1.0])).xy() |
|
56
|
|
|
|
|
57
|
|
|
box11 = aabb.AABB(vector.Vector(2, aabbData10), vector.Vector(2, aabbData11)) |
|
58
|
|
|
box12 = aabb.AABB(vector.Vector(2, aabbData11), vector.Vector(2, aabbData12)) |
|
59
|
|
|
box13 = aabb.AABB(vector.Vector(2, aabbData12), vector.Vector(2, aabbData13)) |
|
60
|
|
|
box14 = aabb.AABB(vector.Vector(2, aabbData13), vector.Vector(2, aabbData11)) |
|
61
|
|
|
|
|
62
|
|
|
self.collisionData = [box11, box12, box13, box14] |
|
63
|
|
|
|
|
64
|
|
|
def fgenerateVertices(self): |
|
65
|
|
|
'''Generate a box based on width and height''' |
|
66
|
|
|
# This is here to be used with the quadtree |
|
67
|
|
|
# Is definetly temporary, it might be better to init a unit sized rectangle and then scale it |
|
68
|
|
|
self.data = [[0.0, self.height], |
|
69
|
|
|
[self.width, self.height], |
|
70
|
|
|
[0.0, 0.0], |
|
71
|
|
|
[self.width, 0.0]] |
|
72
|
|
|
|
|
73
|
|
|
def generateVertices(self): |
|
74
|
|
|
'''Generate a unit box.''' |
|
75
|
|
|
self.data = [[0.0, 1.0], |
|
76
|
|
|
[1.0, 1.0], |
|
77
|
|
|
[0.0, 0.0], |
|
78
|
|
|
[1.0, 0.0]] |
|
79
|
|
|
|
|
80
|
|
|
def scale(self, valueX, valueY): |
|
81
|
|
|
'''Scale the object by X and Y''' |
|
82
|
|
|
self.scaleDeltaX = valueX / self._scaleX |
|
83
|
|
|
self.scaleDeltaY = valueY / self._scaleY |
|
84
|
|
|
self._scaleX = valueX |
|
85
|
|
|
self._scaleY = valueY |
|
86
|
|
|
self.width = valueX |
|
87
|
|
|
self.height = valueY |
|
88
|
|
|
|
|
89
|
|
|
def translate(self, x, y): |
|
90
|
|
|
'''Translate the object by X and Y''' |
|
91
|
|
|
self.xPosDelta += x - self.xPos |
|
92
|
|
|
self.yPosDelta += y - self.yPos |
|
93
|
|
|
self.xPos = x |
|
94
|
|
|
self.yPos = y |
|
95
|
|
|
|
|
96
|
|
|
def update(self): |
|
97
|
|
|
'''Update all the vertices''' |
|
98
|
|
|
if self.scaleDeltaX or self.scaleDeltaY: |
|
99
|
|
|
vecScale = vector.Vector(3, data=[self.scaleDeltaX, self.scaleDeltaY, 0.0]) |
|
100
|
|
|
self.modelMatrix.i_scale(vecScale) |
|
101
|
|
|
self.scaleDeltaX = 0 |
|
102
|
|
|
self.scaleDeltaY = 0 |
|
103
|
|
|
if self.xPosDelta or self.yPosDelta: |
|
104
|
|
|
vecTrans = vector.Vector(3, data=[self.xPosDelta, self.yPosDelta, 0.0]) |
|
105
|
|
|
self.modelMatrix.i_translate(vecTrans) |
|
106
|
|
|
self.xPosDelta = 0 |
|
107
|
|
|
self.yPosDelta = 0 |
|
108
|
|
|
self.make_aabb() |
|
109
|
|
|
|
|
110
|
|
|
def __findDim(self): |
|
111
|
|
|
'''Calculate the width and height based on the inputed data''' |
|
112
|
|
|
self.width = vector.Vector(2, [self.data[0] - self.data[2], self.data[1] - self.data[3]]).magnitude() |
|
113
|
|
|
self.height = vector.Vector(2, [self.data[2] - self.data[4], self.data[3] - self.data[5]]).magnitude() |
|
114
|
|
|
|
|
115
|
|
|
|
|
116
|
|
|
# Getters |
|
117
|
|
|
def getVertices(self): |
|
118
|
|
|
return self.data |
|
119
|
|
|
|
|
120
|
|
|
def getType(self): |
|
121
|
|
|
return self.type |
|
122
|
|
|
|
|
123
|
|
|
def getCollisionData(self): |
|
124
|
|
|
return self.collisionData |
|
125
|
|
|
|
|
126
|
|
|
def getModelMatrix(self): |
|
127
|
|
|
return self.modelMatrix |
|
128
|
|
|
|
|
129
|
|
|
def getX(self): |
|
130
|
|
|
return self.xPos |
|
131
|
|
|
|
|
132
|
|
|
def getY(self): |
|
133
|
|
|
return self.yPos |
|
134
|
|
|
|
|
135
|
|
|
def getWidth(self): |
|
136
|
|
|
return self.width |
|
137
|
|
|
|
|
138
|
|
|
def getHeight(self): |
|
139
|
|
|
return self.height |
|
140
|
|
|
|
|
141
|
|
|
def getCenter(self): |
|
142
|
|
|
return [self.xPos + self.width / 2.0, self.yPos + self.height / 2.0, 1.0] |
|
143
|
|
|
|