package tim.prune.threedee;
-import tim.prune.data.Altitude;
import tim.prune.data.DataPoint;
import tim.prune.data.PointScaler;
import tim.prune.data.Track;
public class ThreeDModel
{
private Track _track = null;
+ private Track _terrainTrack = null;
private PointScaler _scaler = null;
- private double _modelSize;
- private int _altitudeCap = -1;
private double _scaleFactor = 1.0;
private double _altFactor = 1.0;
+ private double _externalScaleFactor = 1.0;
// MAYBE: How to store rods (lifts) in data?
private byte[] _pointTypes = null;
private byte[] _pointHeights = null;
- private static final double DEFAULT_MODEL_SIZE = 10.0;
- /** Minimum altitude cap */
- public static final int MINIMUM_ALTITUDE_CAP = 100;
-
// Constants for point types
public static final byte POINT_TYPE_WAYPOINT = 1;
public static final byte POINT_TYPE_NORMAL_POINT = 2;
*/
public ThreeDModel(Track inTrack)
{
- this(inTrack, DEFAULT_MODEL_SIZE);
+ _track = inTrack;
}
/**
- * Constructor
- * @param inTrack Track object
- * @param inSize model size
+ * @param inTrack terrain track to set
*/
- public ThreeDModel(Track inTrack, double inSize)
+ public void setTerrain(Track inTrack)
{
- _track = inTrack;
- _modelSize = inSize;
- if (_modelSize <= 0.0) _modelSize = DEFAULT_MODEL_SIZE;
+ _terrainTrack = inTrack;
}
-
/**
* @return the number of points in the model
*/
return _track.getNumPoints();
}
-
/**
- * Set the altitude cap
- * @param inAltitudeCap altitude range to cap to (ignored if less than data range)
+ * @param inFactor altitude exaggeration factor (default 1.0)
*/
- public void setAltitudeCap(int inAltitudeCap)
+ public void setAltitudeFactor(double inFactor)
{
- _altitudeCap = inAltitudeCap;
- if (_altitudeCap < MINIMUM_ALTITUDE_CAP)
- {
- _altitudeCap = MINIMUM_ALTITUDE_CAP;
- }
+ _altFactor = inFactor;
}
+ /**
+ * @param inSize size of model
+ */
+ public void setModelSize(double inSize)
+ {
+ _externalScaleFactor = inSize;
+ }
/**
* Scale all points and calculate factors
{
// Use PointScaler to sort out x and y values
_scaler = new PointScaler(_track);
- _scaler.scale();
- // Calculate scale factor to fit within box
- _scaleFactor = 1.0;
- if (_scaler.getMaximumHoriz() > 0.0 || _scaler.getMaximumVert() > 0.0)
- {
- if (_scaler.getMaximumHoriz() > _scaler.getMaximumVert())
- {
- // scale limited by longitude
- _scaleFactor = _modelSize / _scaler.getMaximumHoriz();
- }
- else
- {
- // scale limited by latitude
- _scaleFactor = _modelSize / _scaler.getMaximumVert();
- }
- }
- // calculate altitude scale factor
- _altFactor = 1.0;
- if (_scaler.getMaximumAlt() >= 0)
+ _scaler.addTerrain(_terrainTrack);
+ _scaler.scale(); // Add 10% border
+
+ // cap altitude scale factor if it's too big
+ double maxAlt = _scaler.getAltitudeRange() * _altFactor;
+ if (maxAlt > 0.5)
{
- // limit by altitude cap or by data range?
- if (_scaler.getMaximumAlt() > _altitudeCap)
- {
- // data is bigger than cap
- _altFactor = _modelSize / _scaler.getMaximumAlt();
- }
- else
- {
- // capped
- _altFactor = _modelSize / _altitudeCap;
- }
+ // capped
+ // System.out.println("Capped alt factor from " + _altFactor + " to " + (_altFactor * 0.5 / maxAlt));
+ _altFactor = _altFactor * 0.5 / maxAlt;
}
- // calculate lat/long lines
- _scaler.calculateLatLongLines();
// calculate point types and height codes
calculatePointTypes();
for (int i=0; i<numPoints; i++)
{
DataPoint point = _track.getPoint(i);
- _pointTypes[i] = (point.isWaypoint()?POINT_TYPE_WAYPOINT:(point.getSegmentStart()?POINT_TYPE_SEGMENT_START:POINT_TYPE_NORMAL_POINT));
- _pointHeights[i] = (byte) (point.getAltitude().getValue(Altitude.Format.METRES) / 500);
+ _pointTypes[i] = (point.isWaypoint()?POINT_TYPE_WAYPOINT:
+ (point.getSegmentStart()?POINT_TYPE_SEGMENT_START:POINT_TYPE_NORMAL_POINT));
+ _pointHeights[i] = (byte) (point.getAltitude().getMetricValue() / 500);
}
}
*/
public double getScaledHorizValue(int inIndex)
{
- return _scaler.getHorizValue(inIndex) * _scaleFactor;
+ return _scaler.getHorizValue(inIndex) * _scaleFactor * _externalScaleFactor;
}
/**
*/
public double getScaledVertValue(int inIndex)
{
- return _scaler.getVertValue(inIndex) * _scaleFactor;
+ return _scaler.getVertValue(inIndex) * _scaleFactor * _externalScaleFactor;
}
/**
public double getScaledAltValue(int inIndex)
{
// if no altitude, just return 0
- int altVal = _scaler.getAltValue(inIndex);
- if (altVal < 0) return 0;
- // scale according to altitude cap
- return altVal * _altFactor;
+ double altVal = _scaler.getAltValue(inIndex);
+ if (altVal <= 0.0) return 0.0;
+ // scale according to exaggeration factor
+ return altVal * _altFactor * _externalScaleFactor;
}
/**
- * @return latitude lines
+ * Get the scaled horizontal value for the specified terrain point
+ * @param inIndex index of point
+ * @return scaled horizontal value
*/
- public double[] getLatitudeLines()
+ public double getScaledTerrainHorizValue(int inIndex)
{
- return _scaler.getLatitudeLines();
+ return _scaler.getTerrainHorizValue(inIndex) * _scaleFactor * _externalScaleFactor;
}
/**
- * @param inIndex index of line, starting at 0
- * @return scaled position of latitude line
+ * Get the scaled vertical value for the specified terrain point
+ * @param inIndex index of point
+ * @return scaled vertical value
*/
- public double getScaledLatitudeLine(int inIndex)
+ public double getScaledTerrainVertValue(int inIndex)
{
- return _scaler.getScaledLatitudeLines()[inIndex] * _scaleFactor;
+ return _scaler.getTerrainVertValue(inIndex) * _scaleFactor * _externalScaleFactor;
}
/**
- * @return longitude lines
+ * Get the scaled altitude value for the specified terrain point
+ * @param inIndex index of point
+ * @return scaled altitude value
*/
- public double[] getLongitudeLines()
+ public double getScaledTerrainValue(int inIndex)
{
- return _scaler.getLongitudeLines();
+ // if no altitude, just return 0
+ double altVal = _scaler.getTerrainAltValue(inIndex);
+ if (altVal <= 0.0) return 0.0;
+ // don't scale by scale factor, needs to be unscaled
+ return altVal * _altFactor;
}
- /**
- * @param inIndex index of line, starting at 0
- * @return scaled position of longitude line
- */
- public double getScaledLongitudeLine(int inIndex)
- {
- return _scaler.getScaledLongitudeLines()[inIndex] * _scaleFactor;
- }
/**
* @param inIndex index of point, starting at 0
{
return _pointHeights[inIndex];
}
-
- /**
- * @return the current model size
- */
- public double getModelSize()
- {
- return _modelSize;
- }
}