]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/threedee/ThreeDModel.java
ddf91623b717309daf1bb3bfcd82dadefe850097
[GpsPrune.git] / tim / prune / threedee / ThreeDModel.java
1 package tim.prune.threedee;
2
3 import tim.prune.data.DataPoint;
4 import tim.prune.data.PointScaler;
5 import tim.prune.data.Track;
6
7 /**
8  * Class to hold a 3d model of the track data,
9  * including all points and scaling operations.
10  * Used by java3d and also Pov export functions
11  */
12 public class ThreeDModel
13 {
14         private Track _track = null;
15         private PointScaler _scaler = null;
16         private double _scaleFactor = 1.0;
17         private double _altFactor = 1.0;
18         private double _externalScaleFactor = 1.0;
19         // MAYBE: How to store rods (lifts) in data?
20         private byte[] _pointTypes = null;
21         private byte[] _pointHeights = null;
22
23         // Constants for point types
24         public static final byte POINT_TYPE_WAYPOINT      = 1;
25         public static final byte POINT_TYPE_NORMAL_POINT  = 2;
26         public static final byte POINT_TYPE_SEGMENT_START = 3;
27
28
29         /**
30          * Constructor
31          * @param inTrack Track object
32          */
33         public ThreeDModel(Track inTrack)
34         {
35                 _track = inTrack;
36         }
37
38
39         /**
40          * @return the number of points in the model
41          */
42         public int getNumPoints()
43         {
44                 if (_track == null) return 0;
45                 return _track.getNumPoints();
46         }
47
48         /**
49          * @param inFactor altitude exaggeration factor (default 1.0)
50          */
51         public void setAltitudeFactor(double inFactor)
52         {
53                 if (inFactor >= 1.0) {
54                         _altFactor = inFactor;
55                 }
56         }
57
58         /**
59          * @param inSize size of model
60          */
61         public void setModelSize(double inSize)
62         {
63                 _externalScaleFactor = inSize;
64         }
65
66         /**
67          * Scale all points and calculate factors
68          */
69         public void scale()
70         {
71                 // Use PointScaler to sort out x and y values
72                 _scaler = new PointScaler(_track);
73                 _scaler.scale(); // Add 10% border
74
75                 // cap altitude scale factor if it's too big
76                 double maxAlt = _scaler.getAltitudeRange() * _altFactor;
77                 if (maxAlt > 0.5)
78                 {
79                         // capped
80                         //System.out.println("Capped alt factor from " + _altFactor + " to " + (_altFactor * 0.5 / maxAlt));
81                         _altFactor = _altFactor * 0.5 / maxAlt;
82                 }
83
84                 // calculate point types and height codes
85                 calculatePointTypes();
86         }
87
88
89         /**
90          * Calculate the point types and height codes
91          */
92         private void calculatePointTypes()
93         {
94                 int numPoints = getNumPoints();
95                 _pointTypes = new byte[numPoints];
96                 _pointHeights = new byte[numPoints];
97                 // Loop over points in track
98                 for (int i=0; i<numPoints; i++)
99                 {
100                         DataPoint point = _track.getPoint(i);
101                         _pointTypes[i] = (point.isWaypoint()?POINT_TYPE_WAYPOINT:
102                                 (point.getSegmentStart()?POINT_TYPE_SEGMENT_START:POINT_TYPE_NORMAL_POINT));
103                         _pointHeights[i] = (byte) (point.getAltitude().getMetricValue() / 500);
104                 }
105         }
106
107
108         /**
109          * Get the scaled horizontal value for the specified point
110          * @param inIndex index of point
111          * @return scaled horizontal value
112          */
113         public double getScaledHorizValue(int inIndex)
114         {
115                 return _scaler.getHorizValue(inIndex) * _scaleFactor * _externalScaleFactor;
116         }
117
118         /**
119          * Get the scaled vertical value for the specified point
120          * @param inIndex index of point
121          * @return scaled vertical value
122          */
123         public double getScaledVertValue(int inIndex)
124         {
125                 return _scaler.getVertValue(inIndex) * _scaleFactor * _externalScaleFactor;
126         }
127
128         /**
129          * Get the scaled altitude value for the specified point
130          * @param inIndex index of point
131          * @return scaled altitude value
132          */
133         public double getScaledAltValue(int inIndex)
134         {
135                 // if no altitude, just return 0
136                 double altVal = _scaler.getAltValue(inIndex);
137                 if (altVal < 0) return 0;
138                 // scale according to exaggeration factor
139                 return altVal * _altFactor * _externalScaleFactor;
140         }
141
142
143         /**
144          * @param inIndex index of point, starting at 0
145          * @return point type, either POINT_TYPE_WAYPOINT or POINT_TYPE_NORMAL_POINT
146          */
147         public byte getPointType(int inIndex)
148         {
149                 return _pointTypes[inIndex];
150         }
151
152         /**
153          * @param inIndex index of point, starting at 0
154          * @return point height code
155          */
156         public byte getPointHeightCode(int inIndex)
157         {
158                 return _pointHeights[inIndex];
159         }
160 }