-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRaycast.pde
147 lines (114 loc) · 5.16 KB
/
Raycast.pde
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
class Raycast implements IGraphic{
PVector origin;
PVector direction;
boolean isCulled;
Map<Camera, Integer> cameras = new HashMap();//Camera, Layer
public Raycast(PVector _origin, PVector _direction){
origin = _origin;
direction = _direction;
}
///IDEALLY, A FLAG SHOULD BE SET TO TELL RAYCAST ALREADY HAS BEEN CALCULATED FOR THIS FRAME, GAMEENGINE SHOULD THEN MANAGE IT.
///WITH THE CURRENT CONFIG, I COULD CHECK THE SAME RAYCAST N TIMES BY FRAME WHICH IS AWFUL.
String raycastHit(){
String againstTag = "";
int len = GameEngine.colliderObjects.size();
boolean result = false;
PVector lineEnd = origin.get();
lineEnd.add(direction);
for (int i = 0; i < len; i++){
againstTag = "";
ICollidable against = GameEngine.colliderObjects.get(i);
PVector againstPos = against.getPosition();
PVector againstSize = against.getSize();
boolean xEndInside = false;
boolean xOriginInside = (origin.x >= againstPos.x && origin.x < againstPos.x + againstSize.x);
xEndInside = (lineEnd.x >= againstPos.x && lineEnd.x < againstPos.x + againstSize.x);
boolean yEndInside = false;
boolean yOriginInside = (origin.y >= againstPos.y && origin.y < againstPos.y + againstSize.y);
yEndInside = (lineEnd.y >= againstPos.y && lineEnd.y < againstPos.y + againstSize.y);
boolean xThrough = (origin.x <= againstPos.x && lineEnd.x >= againstPos.x + againstSize.x);
boolean yThrough = (origin.y <= againstPos.y && lineEnd.y >= againstPos.y + againstSize.y);
boolean couldHit =
((xOriginInside && (yOriginInside || yEndInside || yThrough)) || (xEndInside && (yOriginInside || yEndInside || yThrough)) ||
(yOriginInside && (xOriginInside || xEndInside || xThrough)) || (yEndInside && (xOriginInside || xEndInside || xThrough))
|| (xThrough && yThrough) || (xOriginInside && xEndInside) || (yOriginInside && yEndInside));
if (couldHit){
againstTag = against.getTag();
if (against.getColliderType() == ColliderType.SQUARE){
PVector[] vertex = { againstPos, new PVector(againstPos.x, againstPos.y + againstSize.y),
new PVector(againstPos.x + againstSize.x, againstPos.y + againstSize.y),
new PVector(againstPos.x + againstSize.x, againstPos.y) };
result = CollisionHelper.pointRect(origin, againstPos, againstSize);
if (!result)
result = CollisionHelper.pointRect(lineEnd, againstPos, againstSize);
if (!result)
result = CollisionHelper.linePolyCollision(origin, lineEnd, vertex);
} else if (against.getColliderType() == ColliderType.CIRCLE){
PVector againstCenter = against.getPosition();
float againstRadius = against.getSize().x / 2f;
againstCenter.add(new PVector(againstRadius, againstRadius));
result = CollisionHelper.lineCircle(origin.x, origin.y, lineEnd.x, lineEnd.y, againstCenter.x, againstCenter.y , againstRadius);
}
else if (against.getColliderType() == ColliderType.TRIANGLE){
result = CollisionHelper.linePolyCollision(origin, lineEnd, against.getVertices());
}
if (result)
return againstTag;
}
}
return null;
}
public void removeFromGraphicsList(Camera camera, int layer){
camera.removeFromGraphicsList(this, cameras.get(camera));
}
public void addToGraphicsList(Camera camera, int layer){
attachCamera(camera, layer);
setLayer(camera, layer);
camera.addToGraphicsList(this, layer);
}
void display(Camera camera){
PVector viewStart = origin.get();
PVector viewEnd = PVector.add(viewStart, direction);
line(viewStart.x - camera.getPosition().x, viewStart.y - camera.getPosition().y, viewEnd.x - camera.getPosition().x, viewEnd.y - camera.getPosition().y);
}
public boolean isCulled(){
return isCulled;
}
public void manageCulling(Camera camera){
//if (gameObject.transform.getPosition() != gameObject.transform.getPreviousPosition())
checkCulling(camera);
}
public void checkCulling(Camera camera){
PVector startPos;
PVector endPos;
PVector lineEnd = origin.get();
lineEnd.add(direction);
if (origin.x > lineEnd.x){
startPos = lineEnd.get();
endPos = origin.get();
}
else{
startPos = origin.get();
endPos = lineEnd.get();
}
startPos.add(camera.getPosition());
PVector currentSize = endPos;
currentSize.sub(startPos);
isCulled = camera.isInFrame(startPos, currentSize, camera.getPosition());
}
public void attachCamera(Camera camera, int layer){
cameras.put(camera, layer);
}
public void setLayer(Camera camera, int _layer){
camera.removeFromGraphicsList(this, cameras.get(camera));
Integer layer = cameras.get(camera);
layer = _layer;
camera.addToGraphicsList(this, cameras.get(camera));
}
public void toggleRaycastDisplay(Camera camera, int layer, boolean toggleOn){
if (toggleOn)
addToGraphicsList(camera, layer);
else
removeFromGraphicsList(camera, layer);
}
}