1 package nl.tudelft.goal.ut2004.visualizer.timeline.map;
2
3 import cz.cuni.amis.pogamut.base3d.worldview.object.Location;
4 import cz.cuni.amis.pogamut.unreal.communication.worldview.map.Box;
5 import java.util.HashSet;
6 import java.util.Set;
7 import javax.vecmath.Matrix4d;
8 import javax.vecmath.Vector3d;
9
10
11
12
13
14
15
16 public class MapViewpoint {
17
18 private Location center;
19 private Location eye;
20 private Vector3d up;
21
22 public MapViewpoint() {
23 this(0, 0, 0);
24
25 }
26
27 public MapViewpoint(double x, double y, double z) {
28 center = new Location(x, y, z);
29 eye = Location.ZERO;
30 up = new Vector3d(1, 0, 0);
31 }
32
33 public void moveEye(Location delta) {
34 eye = eye.add(delta);
35 emitChangedViewport();
36 }
37
38 public Location getLocation() {
39 return center;
40 }
41
42 public Location getEye() {
43 return eye;
44 }
45
46 public Vector3d getUp() {
47 return new Vector3d(up);
48 }
49
50 public Location getEye2Center() {
51 return Location.sub(center, eye);
52 }
53
54
55
56
57
58
59 public double getCenter2EyeDistance() {
60 return Location.getDistance(eye, center);
61 }
62
63 public Location getRightVector() {
64 Location moveUpVec = new Location(up.x, up.y, up.z);
65 Location center2eye = Location.sub(getEye(), getLocation());
66 Location moveRightVec = center2eye.cross(moveUpVec).getNormalized();
67
68 return moveRightVec;
69 }
70
71 public void setLocation(Location location) {
72 this.center = location;
73
74 emitChangedViewport();
75 }
76
77 public void setFromViewedBox(Box box) {
78 center = new Location(box.getCenterX(), box.getCenterY(), box.getCenterZ());
79
80 double max = Math.max(box.getDeltaX(), box.getDeltaY());
81
82 eye = new Location(box.getCenterX(), box.getCenterY(), box.getCenterZ() - max);
83
84 this.up.x = 0;
85 this.up.y = 1;
86 this.up.z = 0;
87 }
88
89
90
91
92
93
94
95
96
97
98 public void rotateEye(Location axis, double angle) {
99
100 Location eyeVector = Location.sub(eye, center);
101
102 Location newEyeVector = rotateVectorAroundAxis(eyeVector, axis, angle);
103 Location newUpVector = rotateVectorAroundAxis(new Location(up.x, up.y, up.z), axis, angle);
104
105 eye = Location.add(center, newEyeVector);
106 up = new Vector3d(newUpVector.x, newUpVector.y, newUpVector.z);
107
108 emitChangedViewport();
109 }
110
111 public void rotateCenter(Location axis, double angle) {
112
113 Location eyeVector = Location.sub(center, eye);
114
115 Location newEye2Center = rotateVectorAroundAxis(eyeVector, axis, angle);
116 Location newUpVector = rotateVectorAroundAxis(new Location(up.x, up.y, up.z), axis, angle);
117
118 center = Location.add(eye, newEye2Center);
119 up = new Vector3d(newUpVector.x, newUpVector.y, newUpVector.z);
120
121
122
123
124 emitChangedViewport();
125
126 }
127
128
129
130
131
132
133
134
135
136
137 public static Location rotateVectorAroundAxis(Location vector, Location axis, double angle) {
138
139 double x = axis.x;
140 double y = axis.y;
141 double z = axis.z;
142
143 double radianAngle = angle * Math.PI / 180;
144 double c = Math.cos(radianAngle);
145 double s = Math.sin(radianAngle);
146
147
148
149
150
151
152 Matrix4d rotateMatrix = new Matrix4d(x * x * (1 - c) + c, x * y * (1 - c) - z * s, x * z * (1 - c) + y * s, 0,
153 y * x * (1 - c) + z * s, y * y * (1 - c) + c, y * z * (1 - c) - x * s, 0, x * z * (1 - c) - y * s, y
154 * z * (1 - c) + x * s, z * z * (1 - c) + c, 0, 0, 0, 0, 1);
155
156 Vector3d vec = new Vector3d(vector.x, vector.y, vector.z);
157
158 rotateMatrix.transform(vec);
159
160 return new Location(vec.x, vec.y, vec.z);
161 }
162
163 private Set<ViewpointListener> listeners = new HashSet<ViewpointListener>();
164
165
166 public void setFrontView(Box box) {
167 center = new Location(box.getCenterX(), box.getCenterY(), box.getCenterZ());
168
169 double maxDelta = Math.max(box.getDeltaX(), box.getDeltaZ());
170
171 double halfAngleRad = Math.PI * ((getViewAngle() / 2) / 180);
172 double distance = (maxDelta / 2) / (Math.tan(halfAngleRad));
173
174 eye = new Location(box.getCenterX(), (box.getCenterY() - (box.getDeltaY() / 2)) - distance, box.getCenterZ());
175
176 this.up.x = 0;
177 this.up.y = 0;
178 this.up.z = 1;
179
180 emitChangedViewport();
181 }
182
183 public void setSideView(Box box) {
184 center = new Location(box.getCenterX(), box.getCenterY(), box.getCenterZ());
185
186 double maxDelta = Math.max(box.getDeltaZ(), box.getDeltaY());
187
188 double halfAngleRad = Math.PI * ((getViewAngle() / 2) / 180);
189 double distance = (maxDelta / 2) / (Math.tan(halfAngleRad));
190
191 eye = new Location(box.getCenterX() + box.getDeltaX() / 2 + distance, box.getCenterY(), box.getCenterZ());
192
193 this.up.x = 0;
194 this.up.y = 0;
195 this.up.z = 1;
196
197 emitChangedViewport();
198 }
199
200 public void setTopView(Box box) {
201 center = new Location(box.getCenterX(),box.getCenterY(),box.getCenterZ());
202
203 double maxDelta = Math.max(box.getDeltaX(), box.getDeltaY());
204
205 double halfAngleRad = Math.PI * ((getViewAngle() / 2) / 180);
206 double distance = (maxDelta / 2) / (Math.tan(halfAngleRad));
207
208 eye = new Location(box.getCenterX(), box.getCenterY(), box.getCenterZ() + box.getDeltaZ() / 2 + distance);
209
210 this.up.x = 0;
211 this.up.y = 1;
212 this.up.z = 0;
213
214 emitChangedViewport();
215 }
216
217 public double getViewAngle() {
218 return 45.0;
219 }
220
221
222
223
224
225
226
227 public void move(Location moveVec) {
228 center = this.center.add(moveVec);
229 eye = this.eye.add(moveVec);
230
231 emitChangedViewport();
232 }
233
234
235
236
237
238
239
240
241
242
243
244 public void move(double deltaX, double deltaY, double deltaZ) {
245 move(new Location(deltaX, deltaY, deltaZ));
246 }
247
248
249
250
251
252
253
254
255
256 void zoom(double factor, double minDist) {
257 Location center2eye = Location.sub(eye, center);
258
259 eye = Location.add(center, center2eye.scale(factor));
260
261 emitChangedViewport();
262 }
263
264 private void emitChangedViewport() {
265 ViewpointListener[] listenersArray = listeners.toArray(new ViewpointListener[] {});
266
267 for (ViewpointListener listener : listenersArray) {
268 listener.onChangedViewpoint(this);
269 }
270 }
271
272 public void addViewpointListener(ViewpointListener listener) {
273 listeners.add(listener);
274 }
275
276 public boolean isViewpointListener(ViewpointListener listener) {
277 return listeners.contains(listener);
278 }
279
280 public void removeViewpointListener(ViewpointListener listener) {
281 listeners.remove(listener);
282 }
283
284
285
286
287
288
289
290
291
292
293
294
295
296 public void lookAt(Location location, int axis, boolean upFlag) {
297 System.out.println("Look at target: " + location);
298
299 Vector3d newEye2Center = new Vector3d();
300 newEye2Center.x = location.x - eye.x;
301 newEye2Center.y = location.y - eye.y;
302 newEye2Center.z = location.z - eye.z;
303
304 Vector3d currentEye2Center = new Vector3d(getEye2Center().x, getEye2Center().y, getEye2Center().z);
305
306 double angle = currentEye2Center.angle(newEye2Center);
307 System.out.println("Angle " + angle + " " + angle * 180 / Math.PI);
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330 }
331
332 public interface ViewpointListener {
333
334 public void onChangedViewpoint(MapViewpoint viewpoint);
335 }
336 }