Update to Worldwind release 0.4.1
[worldwind-tracker.git] / gov / nasa / worldwind / render / PipeRenderer.java
blobad03901b4ff1de42cd0af572d92496965cb3299d
1 /*
2 Copyright (C) 2001, 2006 United States Government
3 as represented by the Administrator of the
4 National Aeronautics and Space Administration.
5 All Rights Reserved.
6 */
7 package gov.nasa.worldwind.render;
9 import gov.nasa.worldwind.geom.Vec4;
10 import gov.nasa.worldwind.globes.SectorGeometryList;
11 import gov.nasa.worldwind.tracks.TrackPoint;
12 import gov.nasa.worldwind.util.Logging;
14 import javax.media.opengl.GL;
15 import java.util.*;
17 /**
18 * @author tag
19 * @version $Id: PipeRenderer.java 2984 2007-09-22 02:20:10Z tgaskins $
21 public class PipeRenderer extends LocationRenderer
23 private Material junctionMaterial = Material.RED;
24 private Material pipeMaterial = Material.WHITE;
25 private double pipeRadius = 1000;
26 private double junctionShapeRadius = 1.8 * this.pipeRadius;
27 private LocationRenderer.Shape junctionShape = SPHERE;
28 private PipeRenderer.Pipe pipeShape = new PipeRenderer.Pipe();
30 public PipeRenderer()
34 public Material getPipeMaterial()
36 return pipeMaterial;
39 public void setPipeMaterial(Material material)
41 if (material == null)
43 String msg = Logging.getMessage("nullValue.MaterialIsNull");
44 Logging.logger().severe(msg);
45 throw new IllegalArgumentException(msg);
48 // don't validate material's colors - material does that.
50 this.pipeMaterial = material;
53 public Material getJunctionMaterial()
55 return junctionMaterial;
58 public void setJunctionMaterial(Material material)
60 if (material == null)
62 String msg = Logging.getMessage("nullValue.MaterialIsNull");
63 Logging.logger().severe(msg);
64 throw new IllegalArgumentException(msg);
67 // don't validate material's colors - material does that.
69 this.junctionMaterial = material;
72 public void setJunctionShape(String shapeName)
74 if (shapeName.equalsIgnoreCase("Cone"))
75 this.junctionShape = CONE;
76 else if (shapeName.equalsIgnoreCase("Cylinder"))
77 this.junctionShape = CYLINDER;
78 else
79 this.junctionShape = SPHERE;
82 public String getJunctionShape()
84 return this.junctionShape.name;
87 protected Vec4 draw(DrawContext dc, Iterator<TrackPoint> trackPositions)
89 if (dc.getVisibleSector() == null)
90 return null;
92 SectorGeometryList geos = dc.getSurfaceGeometry();
93 if (geos == null)
94 return null;
96 if (!this.pipeShape.isInitialized)
98 this.pipeShape.initialize(dc);
101 if (!this.junctionShape.isInitialized)
102 this.junctionShape.initialize(dc);
104 int index = 0;
105 List<Vec4> points = new ArrayList<Vec4>();
106 while (trackPositions.hasNext())
108 TrackPoint tp = trackPositions.next();
109 if (index >= this.lowerLimit && index <= this.upperLimit)
111 Vec4 point = this.computeSurfacePoint(dc, tp);
112 if (point != null)
114 points.add(point);
117 if (++index >= this.upperLimit)
118 break;
121 if (points.size() < 1)
122 return null;
124 this.begin(dc);
126 this.pipeMaterial.apply(dc.getGL(), GL.GL_FRONT);
127 Vec4 p1 = points.get(0);
128 for (int i = 1; i < points.size(); i++)
130 Vec4 p2 = points.get(i);
131 this.pipeShape.render(dc, p1, p2, this.pipeRadius);
132 p1 = p2;
135 this.junctionMaterial.apply(dc.getGL(), GL.GL_FRONT);
136 for (Vec4 point : points)
138 this.junctionShape.render(dc, point, this.junctionShapeRadius);
141 this.end(dc);
143 return null; // TODO: return the last-drawn location
146 private static class Pipe extends Cylinder
148 protected void initialize(DrawContext dc)
150 super.initialize(dc);
151 this.name = "Pipe";
154 private static final double TO_DEGREES = 180d / Math.PI;
156 protected void render(DrawContext dc, Vec4 p1, Vec4 p2, double radius)
158 // To compute the rotation of the cylinder axis to the orientation of the vector between the two points,
159 // this method performs the same operation as Vec4.axisAngle() but with a "v2" of <0, 0, 1>.
161 // Compute rotation angle
162 double length = p1.distanceTo3(p2);
163 Vec4 u1 = new Vec4((p2.x - p1.x) / length, (p2.y - p1.y) / length, (p2.z - p1.z) / length);
164 double angle = Math.acos(u1.z);
166 // Compute the direction cosine factors that define the rotation axis
167 double A = -u1.y;
168 double B = u1.x;
169 double L = Math.sqrt(A * A + B * B);
171 GL gl = dc.getGL();
173 // pushReferenceCenter performs the translation of the pipe's origin to point p1 and the necessary
174 // push/pop of the modelview stack. Otherwise we'd need to include a glPushMatrix and
175 // gl.glTranslated(p1.x, p1.y, p1.z) above the rotation, and a corresponding glPopMatrix after the
176 // call to glCallIst.
177 dc.getView().pushReferenceCenter(dc, p1);
178 gl.glRotated(angle * TO_DEGREES, A / L, B / L, 0);
179 gl.glScaled(radius, radius, length / 2); // length / 2 because cylinder is created with length 2
180 dc.getGL().glCallList(this.glListId);
181 dc.getView().popReferenceCenter(dc);