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
|
|
|
|