]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/threedee/ThreeDModel.java
Version 16, February 2014
[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 Track _terrainTrack = null;
16         private PointScaler _scaler = null;
17         private double _scaleFactor = 1.0;
18         private double _altFactor = 1.0;
19         private double _externalScaleFactor = 1.0;
20         // MAYBE: How to store rods (lifts) in data?
21         private byte[] _pointTypes = null;
22         private byte[] _pointHeights = null;
23
24         // Constants for point types
25         public static final byte POINT_TYPE_WAYPOINT      = 1;
26         public static final byte POINT_TYPE_NORMAL_POINT  = 2;
27         public static final byte POINT_TYPE_SEGMENT_START = 3;
28
29
30         /**
31          * Constructor
32          * @param inTrack Track object
33          */
34         public ThreeDModel(Track inTrack)
35         {
36                 _track = inTrack;
37         }
38
39
40         /**
41          * @param inTrack terrain track to set
42          */
43         public void setTerrain(Track inTrack)
44         {
45                 _terrainTrack = inTrack;
46         }
47
48         /**
49          * @return the number of points in the model
50          */
51         public int getNumPoints()
52         {
53                 if (_track == null) return 0;
54                 return _track.getNumPoints();
55         }
56
57         /**
58          * @param inFactor altitude exaggeration factor (default 1.0)
59          */
60         public void setAltitudeFactor(double inFactor)
61         {
62                 _altFactor = inFactor;
63         }
64
65         /**
66          * @param inSize size of model
67          */
68         public void setModelSize(double inSize)
69         {
70                 _externalScaleFactor = inSize;
71         }
72
73         /**
74          * Scale all points and calculate factors
75          */
76         public void scale()
77         {
78                 // Use PointScaler to sort out x and y values
79                 _scaler = new PointScaler(_track);
80                 _scaler.addTerrain(_terrainTrack);
81                 _scaler.scale(); // Add 10% border
82
83                 // cap altitude scale factor if it's too big
84                 double maxAlt = _scaler.getAltitudeRange() * _altFactor;
85                 if (maxAlt > 0.5)
86                 {
87                         // capped
88                         // System.out.println("Capped alt factor from " + _altFactor + " to " + (_altFactor * 0.5 / maxAlt));
89                         _altFactor = _altFactor * 0.5 / maxAlt;
90                 }
91
92                 // calculate point types and height codes
93                 calculatePointTypes();
94         }
95
96
97         /**
98          * Calculate the point types and height codes
99          */
100         private void calculatePointTypes()
101         {
102                 int numPoints = getNumPoints();
103                 _pointTypes = new byte[numPoints];
104                 _pointHeights = new byte[numPoints];
105                 // Loop over points in track
106                 for (int i=0; i<numPoints; i++)
107                 {
108                         DataPoint point = _track.getPoint(i);
109                         _pointTypes[i] = (point.isWaypoint()?POINT_TYPE_WAYPOINT:
110                                 (point.getSegmentStart()?POINT_TYPE_SEGMENT_START:POINT_TYPE_NORMAL_POINT));
111                         _pointHeights[i] = (byte) (point.getAltitude().getMetricValue() / 500);
112                 }
113         }
114
115
116         /**
117          * Get the scaled horizontal value for the specified point
118          * @param inIndex index of point
119          * @return scaled horizontal value
120          */
121         public double getScaledHorizValue(int inIndex)
122         {
123                 return _scaler.getHorizValue(inIndex) * _scaleFactor * _externalScaleFactor;
124         }
125
126         /**
127          * Get the scaled vertical value for the specified point
128          * @param inIndex index of point
129          * @return scaled vertical value
130          */
131         public double getScaledVertValue(int inIndex)
132         {
133                 return _scaler.getVertValue(inIndex) * _scaleFactor * _externalScaleFactor;
134         }
135
136         /**
137          * Get the scaled altitude value for the specified point
138          * @param inIndex index of point
139          * @return scaled altitude value
140          */
141         public double getScaledAltValue(int inIndex)
142         {
143                 // if no altitude, just return 0
144                 double altVal = _scaler.getAltValue(inIndex);
145                 if (altVal <= 0.0) return 0.0;
146                 // scale according to exaggeration factor
147                 return altVal * _altFactor * _externalScaleFactor;
148         }
149
150
151         /**
152          * Get the scaled horizontal value for the specified terrain point
153          * @param inIndex index of point
154          * @return scaled horizontal value
155          */
156         public double getScaledTerrainHorizValue(int inIndex)
157         {
158                 return _scaler.getTerrainHorizValue(inIndex) * _scaleFactor * _externalScaleFactor;
159         }
160
161         /**
162          * Get the scaled vertical value for the specified terrain point
163          * @param inIndex index of point
164          * @return scaled vertical value
165          */
166         public double getScaledTerrainVertValue(int inIndex)
167         {
168                 return _scaler.getTerrainVertValue(inIndex) * _scaleFactor * _externalScaleFactor;
169         }
170
171         /**
172          * Get the scaled altitude value for the specified terrain point
173          * @param inIndex index of point
174          * @return scaled altitude value
175          */
176         public double getScaledTerrainValue(int inIndex)
177         {
178                 // if no altitude, just return 0
179                 double altVal = _scaler.getTerrainAltValue(inIndex);
180                 if (altVal <= 0.0) return 0.0;
181                 // don't scale by scale factor, needs to be unscaled
182                 return altVal * _altFactor;
183         }
184
185
186         /**
187          * @param inIndex index of point, starting at 0
188          * @return point type, either POINT_TYPE_WAYPOINT or POINT_TYPE_NORMAL_POINT
189          */
190         public byte getPointType(int inIndex)
191         {
192                 return _pointTypes[inIndex];
193         }
194
195         /**
196          * @param inIndex index of point, starting at 0
197          * @return point height code
198          */
199         public byte getPointHeightCode(int inIndex)
200         {
201                 return _pointHeights[inIndex];
202         }
203 }