+ /**
+ * Write out all the data points to the file in the tubes-and-walls style
+ * @param inWriter Writer to use for writing file
+ * @param inModel model object for getting data points
+ * @param inLineSeparator line separator to use
+ * @throws IOException on file writing error
+ */
+ private void writeDataPointsTubesAndWalls(FileWriter inWriter, ThreeDModel inModel, String inLineSeparator)
+ throws IOException
+ {
+ inWriter.write("// Data points:");
+ inWriter.write(inLineSeparator);
+ int numPoints = inModel.getNumPoints();
+ int numTrackPoints = 0;
+ // Loop over all points and write out waypoints as balls
+ for (int i=0; i<numPoints; i++)
+ {
+ if (inModel.getPointType(i) == ThreeDModel.POINT_TYPE_WAYPOINT)
+ {
+ // waypoint ball
+ inWriter.write("object { waypoint_sphere translate <" + inModel.getScaledHorizValue(i)
+ + "," + inModel.getScaledAltValue(i) + "," + inModel.getScaledVertValue(i) + "> }");
+ // vertical rod (if altitude positive)
+ if (inModel.getScaledAltValue(i) > 0.0)
+ {
+ inWriter.write(inLineSeparator);
+ inWriter.write("object { point_rod translate <" + inModel.getScaledHorizValue(i) + ",0,"
+ + inModel.getScaledVertValue(i) + "> scale <1," + inModel.getScaledAltValue(i) + ",1> }");
+ }
+ inWriter.write(inLineSeparator);
+ }
+ else {numTrackPoints++;}
+ }
+ inWriter.write(inLineSeparator);
+
+ // Loop over all the track segments
+ ArrayList<ModelSegment> segmentList = getSegmentList(inModel);
+ Iterator<ModelSegment> segmentIterator = segmentList.iterator();
+ while (segmentIterator.hasNext())
+ {
+ ModelSegment segment = segmentIterator.next();
+ int segLength = segment.getNumTrackPoints();
+
+ // if the track segment is long enough, do a cubic spline sphere sweep
+ if (segLength <= 1)
+ {
+ // single point in segment - just draw sphere
+ int index = segment.getStartIndex();
+ inWriter.write("object { track_sphere_t"
+ + " translate <" + inModel.getScaledHorizValue(index) + "," + inModel.getScaledAltValue(index)
+ + "," + inModel.getScaledVertValue(index) + "> }");
+ // maybe draw some kind of polygon too or rod?
+ }
+ else
+ {
+ writeSphereSweep(inWriter, inModel, segment, inLineSeparator);
+ }
+
+ // Write wall underneath segment
+ if (segLength > 1)
+ {
+ writePolygonWall(inWriter, inModel, segment, inLineSeparator);
+ }
+ }
+ }
+
+
+ /**
+ * Write out a single sphere sweep using either cubic spline or linear spline
+ * @param inWriter Writer to use for writing file
+ * @param inModel model object for getting data points
+ * @param inSegment model segment to draw
+ * @param inLineSeparator line separator to use
+ * @throws IOException on file writing error
+ */
+ private static void writeSphereSweep(FileWriter inWriter, ThreeDModel inModel, ModelSegment inSegment, String inLineSeparator)
+ throws IOException
+ {
+ // 3d sphere sweep
+ inWriter.write("// Sphere sweep:");
+ inWriter.write(inLineSeparator);
+ String splineType = inSegment.getNumTrackPoints() < 5?"linear_spline":"cubic_spline";
+ inWriter.write("sphere_sweep { "); inWriter.write(splineType);
+ inWriter.write(" " + inSegment.getNumTrackPoints() + ",");
+ inWriter.write(inLineSeparator);
+ // Loop over all points in this segment and write out sphere sweep
+ for (int i=inSegment.getStartIndex(); i<=inSegment.getEndIndex(); i++)
+ {
+ if (inModel.getPointType(i) != ThreeDModel.POINT_TYPE_WAYPOINT)
+ {
+ inWriter.write(" <" + inModel.getScaledHorizValue(i) + "," + inModel.getScaledAltValue(i)
+ + "," + inModel.getScaledVertValue(i) + ">, 0.25");
+ inWriter.write(inLineSeparator);
+ }
+ }
+ inWriter.write(" tolerance 0.1");
+ inWriter.write(inLineSeparator);
+ inWriter.write(" texture { pigment {color rgb <0.6 1.0 0.2>} finish {phong 1} }");
+ inWriter.write(inLineSeparator);
+ inWriter.write(" no_shadow");
+ inWriter.write(inLineSeparator);
+ inWriter.write("}");
+ inWriter.write(inLineSeparator);
+ }
+
+
+ /**
+ * Write out a single polygon-based wall for the tubes-and-walls style
+ * @param inWriter Writer to use for writing file
+ * @param inModel model object for getting data points
+ * @param inSegment model segment to draw
+ * @param inLineSeparator line separator to use
+ * @throws IOException on file writing error
+ */
+ private static void writePolygonWall(FileWriter inWriter, ThreeDModel inModel, ModelSegment inSegment, String inLineSeparator)
+ throws IOException
+ {
+ // wall
+ inWriter.write(inLineSeparator);
+ inWriter.write("// wall between sweep and floor:");
+ inWriter.write(inLineSeparator);
+ // Loop over all points in this segment again and write out polygons
+ int prevIndex = -1;
+ for (int i=inSegment.getStartIndex(); i<=inSegment.getEndIndex(); i++)
+ {
+ if (inModel.getPointType(i) != ThreeDModel.POINT_TYPE_WAYPOINT)
+ {
+ if (prevIndex >= 0)
+ {
+ double xDiff = inModel.getScaledHorizValue(i) - inModel.getScaledHorizValue(prevIndex);
+ double yDiff = inModel.getScaledVertValue(i) - inModel.getScaledVertValue(prevIndex);
+ double dist = Math.sqrt(xDiff * xDiff + yDiff * yDiff);
+ if (dist > 0)
+ {
+ inWriter.write("polygon {");
+ inWriter.write(" 5, <" + inModel.getScaledHorizValue(prevIndex) + ", 0.0, " + inModel.getScaledVertValue(prevIndex) + ">,");
+ inWriter.write(" <" + inModel.getScaledHorizValue(prevIndex) + ", " + inModel.getScaledAltValue(prevIndex) + ", "
+ + inModel.getScaledVertValue(prevIndex) + ">,");
+ inWriter.write(" <" + inModel.getScaledHorizValue(i) + ", " + inModel.getScaledAltValue(i) + ", "
+ + inModel.getScaledVertValue(i) + ">,");
+ inWriter.write(" <" + inModel.getScaledHorizValue(i) + ", 0.0, " + inModel.getScaledVertValue(i) + ">,");
+ inWriter.write(" <" + inModel.getScaledHorizValue(prevIndex) + ", 0.0, " + inModel.getScaledVertValue(prevIndex) + ">");
+ inWriter.write(" pigment { color wall_colour } no_shadow");
+ inWriter.write("}");
+ inWriter.write(inLineSeparator);
+ }
+ }
+ prevIndex = i;
+ }
+ }
+ }
+
+