2 Copyright (C) 2001, 2006 United States Government
3 as represented by the Administrator of the
4 National Aeronautics and Space Administration.
7 package gov
.nasa
.worldwind
.render
;
9 import com
.sun
.opengl
.util
.BufferUtil
;
10 import gov
.nasa
.worldwind
.Movable
;
11 import gov
.nasa
.worldwind
.geom
.*;
12 import gov
.nasa
.worldwind
.util
.Logging
;
14 import javax
.media
.opengl
.GL
;
16 import java
.nio
.DoubleBuffer
;
18 import java
.util
.List
;
22 * @version $Id: Polyline.java 2932 2007-09-19 19:41:34Z patrickmurris $
24 public class Polyline
implements Renderable
, Movable
26 private ArrayList
<Position
> positions
;
27 private Vec4 referenceCenter
;
28 private DoubleBuffer vertices
;
29 private int antiAliasHint
= GL
.GL_FASTEST
;
30 private Color color
= Color
.WHITE
;
31 private boolean filled
= false; // makes it a polygon
32 private boolean followGreatCircles
= true;
33 private int numEdgeIntervals
= 10;
34 private Position center
;
36 public Polyline(Iterable
<Position
> positions
)
38 if (positions
== null)
40 String msg
= Logging
.getMessage("nullValue.PositionsListIsNull");
41 Logging
.logger().severe(msg
);
42 throw new IllegalArgumentException(msg
);
45 this.setPositions(positions
);
48 public Polyline(Iterable
<LatLon
> positions
, double elevation
)
50 if (positions
== null)
52 String msg
= Logging
.getMessage("nullValue.PositionsListIsNull");
53 Logging
.logger().severe(msg
);
54 throw new IllegalArgumentException(msg
);
57 this.setPositions(positions
, elevation
);
60 public Color
getColor()
65 public void setColor(Color color
)
69 String msg
= Logging
.getMessage("nullValue.ColorIsNull");
70 Logging
.logger().severe(msg
);
71 throw new IllegalArgumentException(msg
);
77 public int getAntiAliasHint()
82 public void setAntiAliasHint(int hint
)
84 if (!(hint
== GL
.GL_DONT_CARE
|| hint
== GL
.GL_FASTEST
|| hint
== GL
.GL_NICEST
))
86 String msg
= Logging
.getMessage("generic.InvalidHint");
87 Logging
.logger().severe(msg
);
88 throw new IllegalArgumentException(msg
);
91 this.antiAliasHint
= hint
;
94 public boolean isFilled()
99 public void setFilled(boolean filled
)
101 this.filled
= filled
;
104 public boolean isFollowGreatCircles()
106 return followGreatCircles
;
109 public void setFollowGreatCircles(boolean followGreatCircles
)
111 this.followGreatCircles
= followGreatCircles
;
114 public int getNumEdgeIntervals()
116 return numEdgeIntervals
;
119 public void setNumEdgeIntervals(int numEdgeIntervals
)
121 this.numEdgeIntervals
= numEdgeIntervals
;
124 public void setPositions(Iterable
<Position
> inPositions
)
126 if (inPositions
== null)
128 String msg
= Logging
.getMessage("nullValue.PositionsListIsNull");
129 Logging
.logger().severe(msg
);
130 throw new IllegalArgumentException(msg
);
133 this.positions
= new ArrayList
<Position
>();
134 for (Position position
: inPositions
)
136 this.positions
.add(position
);
139 if ((this.filled
&& this.positions
.size() < 3) || (!this.filled
&& this.positions
.size() < 2))
141 String msg
= Logging
.getMessage("generic.InsufficientPositions");
142 Logging
.logger().severe(msg
);
143 throw new IllegalArgumentException(msg
);
146 this.vertices
= null;
149 public void setPositions(Iterable
<LatLon
> inPositions
, double elevation
)
151 if (inPositions
== null)
153 String msg
= Logging
.getMessage("nullValue.PositionsListIsNull");
154 Logging
.logger().severe(msg
);
155 throw new IllegalArgumentException(msg
);
158 this.positions
= new ArrayList
<Position
>();
159 for (LatLon position
: inPositions
)
161 this.positions
.add(new Position(position
, elevation
));
164 if (this.positions
.size() < 2 || (this.filled
&& this.positions
.size() < 3))
166 String msg
= Logging
.getMessage("generic.InsufficientPositions");
167 Logging
.logger().severe(msg
);
168 throw new IllegalArgumentException(msg
);
171 this.vertices
= null;
174 public Iterable
<Position
> getPositions()
176 return this.positions
;
179 private void intializeGeometry(DrawContext dc
)
181 if (this.positions
.size() < 2)
184 double[] refCenter
= new double[3];
185 if (this.followGreatCircles
)
186 this.vertices
= this.makeGreatCircleVertices(dc
, this.positions
, refCenter
);
188 this.vertices
= makeVertices(dc
, this.positions
, refCenter
);
189 this.referenceCenter
= new Vec4(refCenter
[0], refCenter
[1], refCenter
[2]);
191 double avgX
= this.referenceCenter
.x
;
192 double avgY
= this.referenceCenter
.y
;
193 double avgZ
= this.referenceCenter
.z
;
195 this.vertices
.rewind();
196 for (int i
= 0; i
< this.vertices
.limit(); i
+= 3)
198 this.vertices
.put(i
, this.vertices
.get(i
) - avgX
);
199 this.vertices
.put(i
+ 1, this.vertices
.get(i
+ 1) - avgY
);
200 this.vertices
.put(i
+ 2, this.vertices
.get(i
+ 2) - avgZ
);
203 this.center
= dc
.getGlobe().computePositionFromPoint(this.referenceCenter
);
206 protected DoubleBuffer
makeVertices(DrawContext dc
, List
<Position
> posList
, double[] refCenter
)
208 DoubleBuffer verts
= BufferUtil
.newDoubleBuffer(posList
.size() * 3);
215 for (Position p
: posList
)
217 Vec4 pt
= dc
.getGlobe().computePointFromPosition(p
.getLatitude(), p
.getLongitude(), p
.getElevation());
218 verts
.put(pt
.x
).put(pt
.y
).put(pt
.z
);
225 refCenter
[0] = avgX
/ (double) n
;
226 refCenter
[1] = avgY
/ (double) n
;
227 refCenter
[2] = avgZ
/ (double) n
;
232 protected DoubleBuffer
makeGreatCircleVertices(DrawContext dc
, List
<Position
> posList
, double[] refCenter
)
234 if (posList
.size() < 1)
237 int size
= posList
.size() + (this.numEdgeIntervals
- 1) * (posList
.size() - 1);
238 DoubleBuffer verts
= BufferUtil
.newDoubleBuffer(size
* 3);
245 Iterator
<Position
> iter
= posList
.iterator();
246 Position pos
= iter
.next();
247 Vec4 pt
= dc
.getGlobe().computePointFromPosition(pos
.getLatitude(), pos
.getLongitude(), pos
.getElevation());
256 double delta
= 1d
/ this.numEdgeIntervals
;
257 while (iter
.hasNext())
259 Position posNext
= iter
.next();
260 for (int i
= 1; i
< numEdgeIntervals
; i
++)
262 LatLon ll
= LatLon
.interpolate(i
* delta
, new LatLon(pos
.getLatitude(), pos
.getLongitude()),
263 new LatLon(posNext
.getLatitude(), posNext
.getLongitude()));
264 double elevation
= (1d
- i
* delta
) * pos
.getElevation() + (i
* delta
) * posNext
.getElevation();
265 pt
= dc
.getGlobe().computePointFromPosition(ll
.getLatitude(), ll
.getLongitude(), elevation
);
266 verts
.put(pt
.x
).put(pt
.y
).put(pt
.z
);
273 pt
= dc
.getGlobe().computePointFromPosition(posNext
.getLatitude(), posNext
.getLongitude(),
274 posNext
.getElevation());
275 verts
.put(pt
.x
).put(pt
.y
).put(pt
.z
);
284 refCenter
[0] = avgX
/ (double) n
;
285 refCenter
[1] = avgY
/ (double) n
;
286 refCenter
[2] = avgZ
/ (double) n
;
291 public void render(DrawContext dc
)
295 String message
= Logging
.getMessage("nullValue.DrawContextIsNull");
296 Logging
.logger().severe(message
);
297 throw new IllegalStateException(message
);
300 if (this.vertices
== null)
302 this.intializeGeometry(dc
);
304 if (this.vertices
== null)
305 return; // TODO: logger a warning
310 int attrBits
= GL
.GL_HINT_BIT
| GL
.GL_CURRENT_BIT
;
311 if (!dc
.isPickingMode())
313 if (this.color
.getAlpha() != 255)
314 attrBits
|= GL
.GL_COLOR_BUFFER_BIT
;
317 gl
.glPushAttrib(attrBits
);
318 gl
.glPushClientAttrib(GL
.GL_CLIENT_VERTEX_ARRAY_BIT
);
319 dc
.getView().pushReferenceCenter(dc
, this.referenceCenter
);
323 if (!dc
.isPickingMode())
325 if (this.color
.getAlpha() != 255)
327 gl
.glEnable(GL
.GL_BLEND
);
328 gl
.glBlendFunc(GL
.GL_SRC_ALPHA
, GL
.GL_ONE_MINUS_SRC_ALPHA
);
330 dc
.getGL().glColor4ub((byte) this.color
.getRed(), (byte) this.color
.getGreen(),
331 (byte) this.color
.getBlue(), (byte) this.color
.getAlpha());
334 int hintAttr
= GL
.GL_LINE_SMOOTH_HINT
;
336 hintAttr
= GL
.GL_POLYGON_SMOOTH_HINT
;
337 gl
.glHint(hintAttr
, this.antiAliasHint
);
339 gl
.glEnableClientState(GL
.GL_VERTEX_ARRAY
);
340 gl
.glVertexPointer(3, GL
.GL_DOUBLE
, 0, this.vertices
.rewind());
342 int primType
= GL
.GL_LINE_STRIP
;
344 primType
= GL
.GL_POLYGON
;
345 gl
.glDrawArrays(primType
, 0, this.vertices
.capacity() / 3);
349 gl
.glPopClientAttrib();
351 dc
.getView().popReferenceCenter(dc
);
355 public Position
getReferencePosition()
360 public void move(Position position
)
362 if (position
== null)
364 String msg
= Logging
.getMessage("nullValue.PositionIsNull");
365 Logging
.logger().severe(msg
);
366 throw new IllegalArgumentException(msg
);
369 for (int i
= 0; i
< this.positions
.size(); i
++)
371 this.positions
.set(i
, this.positions
.get(i
).add(position
));
374 this.vertices
= null;
377 public void moveTo(Position position
)
379 if (position
== null)
381 String msg
= Logging
.getMessage("nullValue.PositionIsNull");
382 Logging
.logger().severe(msg
);
383 throw new IllegalArgumentException(msg
);
386 Position delta
= position
.subtract(this.getReferencePosition());