/** * Create a curve mesh. Use a CatmullRom spline model that does not cycle. * * @param controlPoints the control points to use to create this curve * @param nbSubSegments the number of subsegments between the control points */ public Curve(Vector3f[] controlPoints, int nbSubSegments) { this(new Spline(Spline.SplineType.CatmullRom, controlPoints, 10, false), nbSubSegments); }
/** * This method computes the total length of the curve. */ private void computeTotalLength() { totalLength = 0; float l = 0; if (segmentsLength == null) { segmentsLength = new ArrayList<Float>(); } else { segmentsLength.clear(); } if (type == SplineType.Linear) { if (controlPoints.size() > 1) { for (int i = 0; i < controlPoints.size() - 1; i++) { l = controlPoints.get(i + 1).subtract(controlPoints.get(i)).length(); segmentsLength.add(l); totalLength += l; } } } else if(type == SplineType.Bezier) { this.computeBezierLength(); } else if(type == SplineType.Nurb) { this.computeNurbLength(); } else { this.initCatmullRomWayPoints(controlPoints); this.computeCatmulLength(); } }
/** * This method interpolates the data for the nurbs curve. * @param u * the u value * @param nurbSpline * the nurbs spline definition * @param store * the resulting point in 3D space */ public static void interpolateNurbs(float u, Spline nurbSpline, Vector3f store) { if (nurbSpline.getType() != SplineType.Nurb) { throw new IllegalArgumentException("Given spline is not of a NURB type!"); } List<Vector3f> controlPoints = nurbSpline.getControlPoints(); float[] weights = nurbSpline.getWeights(); List<Float> knots = nurbSpline.getKnots(); int controlPointAmount = controlPoints.size(); store.set(Vector3f.ZERO); float delimeter = 0; for (int i = 0; i < controlPointAmount; ++i) { float val = weights[i] * CurveAndSurfaceMath.computeBaseFunctionValue(i, nurbSpline.getBasisFunctionDegree(), u, knots); store.addLocal(nurbSpline.getControlPoints().get(i) .mult(val)); delimeter += val; } store.divideLocal(delimeter); }
/** * sets the curve tension * * @param curveTension the tension */ public void setCurveTension(float curveTension) { this.curveTension = curveTension; if(type==SplineType.CatmullRom && !getControlPoints().isEmpty()) { this.computeTotalLength(); } }
/** * compute the index of the waypoint and the interpolation value according to a distance * returns a vector 2 containing the index in the x field and the interpolation value in the y field * @param distance the distance traveled on this path * @return the waypoint index and the interpolation value in a vector2 */ public Vector2f getWayPointIndexForDistance(float distance, Vector2f store) { float sum = 0; if(spline.getTotalLength() == 0){ store.set(0, 0); return store; } distance = distance % spline.getTotalLength(); int i = 0; for (Float len : spline.getSegmentsLength()) { if (sum + len >= distance) { return new Vector2f((float) i, (distance - sum) / len); } sum += len; i++; } store.set((float) spline.getControlPoints().size() - 1, 1.0f); return store; }
if(spline.getControlPoints() != null && spline.getControlPoints().size() > 0) { if(nbSubSegments == 0) { nbSubSegments = spline.getControlPoints().size() + 1; } else { nbSubSegments = spline.getControlPoints().size() * nbSubSegments + 1; float minKnot = spline.getMinNurbKnot(); float maxKnot = spline.getMaxNurbKnot(); float deltaU = (maxKnot - minKnot) / nbSubSegments; Vector3f interpolationResult = new Vector3f(); for (int i = 0; i < array.length; i += 3) { spline.interpolate(u, 0, interpolationResult); array[i] = interpolationResult.x; array[i + 1] = interpolationResult.y;
private void createCatmullRomMesh(int nbSubSegments) { float[] array = new float[((spline.getControlPoints().size() - 1) * nbSubSegments + 1) * 3]; short[] indices = new short[(spline.getControlPoints().size() - 1) * nbSubSegments * 2]; int i = 0; int cptCP = 0; for (Iterator<Vector3f> it = spline.getControlPoints().iterator(); it.hasNext();) { Vector3f vector3f = it.next(); array[i] = vector3f.x; if (it.hasNext()) { for (int j = 1; j < nbSubSegments; j++) { spline.interpolate((float) j / nbSubSegments, cptCP, temp); array[i] = temp.getX(); i++; for (int j = 0; j < (spline.getControlPoints().size() - 1) * nbSubSegments; j++) { k = j; indices[i] = (short) k;
float minKnot = spline.getMinNurbKnot(); float maxKnot = spline.getMaxNurbKnot(); float deltaU = (maxKnot - minKnot)/nbSubSegments; Vector3f interpolationResult = new Vector3f(); for(int i=0;i<array.length;i+=3) { spline.interpolate(u, 0, interpolationResult); array[i] = interpolationResult.x; array[i + 1] = interpolationResult.y;
/** * returns the waypoint at the given index * @param i the index * @return returns the waypoint position */ public Vector3f getWayPoint(int i) { return spline.getControlPoints().get(i); }
private void attachDebugNode(Node root) { if (debugNode == null) { debugNode = new Node(); Material m = assetManager.loadMaterial("Common/Materials/RedColor.j3m"); for (Iterator<Vector3f> it = spline.getControlPoints().iterator(); it.hasNext();) { Vector3f cp = it.next(); Geometry geo = new Geometry("box", new Box(0.3f, 0.3f, 0.3f)); geo.setLocalTranslation(cp); geo.setMaterial(m); debugNode.attachChild(geo); } switch (spline.getType()) { case CatmullRom: debugNode.attachChild(CreateCatmullRomPath()); break; case Linear: debugNode.attachChild(CreateLinearPath()); break; default: debugNode.attachChild(CreateLinearPath()); break; } root.attachChild(debugNode); } }
/** * Return the length of the path in world units * @return the length */ public float getLength() { return spline.getTotalLength(); }
if(spline.getControlPoints() != null && spline.getControlPoints().size() > 0) { if(nbSubSegments == 0) { nbSubSegments = spline.getControlPoints().size() + 1; } else { nbSubSegments = spline.getControlPoints().size() * nbSubSegments + 1; float minKnot = spline.getMinNurbKnot(); float maxKnot = spline.getMaxNurbKnot(); float deltaU = (maxKnot - minKnot) / nbSubSegments; Vector3f interpolationResult = new Vector3f(); for (int i = 0; i < array.length; i += 3) { spline.interpolate(u, 0, interpolationResult); array[i] = interpolationResult.x; array[i + 1] = interpolationResult.y;
nbSubSegments = 1; int centerPointsAmount = (spline.getControlPoints().size() + 2) / 3; List<Vector3f> controlPoints = spline.getControlPoints(); int lineIndex = 0; for (int i = 0; i < centerPointsAmount - 1; ++i) { array[lineIndex++] = vector3f.z; for (int j = 1; j < nbSubSegments; ++j) { spline.interpolate((float) j / nbSubSegments, currentControlPoint, temp); array[lineIndex++] = temp.getX(); array[lineIndex++] = temp.getY();
/** * compute the index of the waypoint and the interpolation value according to a distance * returns a vector 2 containing the index in the x field and the interpolation value in the y field * @param distance the distance traveled on this path * @return the waypoint index and the interpolation value in a vector2 */ public Vector2f getWayPointIndexForDistance(float distance, Vector2f store) { float sum = 0; if(spline.getTotalLength() == 0){ store.set(0, 0); return store; } distance = distance % spline.getTotalLength(); int i = 0; for (Float len : spline.getSegmentsLength()) { if (sum + len >= distance) { return new Vector2f((float) i, (distance - sum) / len); } sum += len; i++; } store.set((float) spline.getControlPoints().size() - 1, 1.0f); return store; }
/** * returns an iterator on the waypoints collection * @return */ public Iterator<Vector3f> iterator() { return spline.getControlPoints().iterator(); }
private void attachDebugNode(Node root) { if (debugNode == null) { debugNode = new Node(); Material m = assetManager.loadMaterial("Common/Materials/RedColor.j3m"); for (Iterator<Vector3f> it = spline.getControlPoints().iterator(); it.hasNext();) { Vector3f cp = it.next(); Geometry geo = new Geometry("box", new Box(0.3f, 0.3f, 0.3f)); geo.setLocalTranslation(cp); geo.setMaterial(m); debugNode.attachChild(geo); } switch (spline.getType()) { case CatmullRom: debugNode.attachChild(CreateCatmullRomPath()); break; case Linear: debugNode.attachChild(CreateLinearPath()); break; default: debugNode.attachChild(CreateLinearPath()); break; } root.attachChild(debugNode); } }
/** * sets the curve tension * * @param curveTension the tension */ public void setCurveTension(float curveTension) { this.curveTension = curveTension; if(type==SplineType.CatmullRom && !getControlPoints().isEmpty()) { this.computeTotalLength(); } }
/** * This method returns the length of the curve. * * @return the length of the curve */ public float getLength() { return spline.getTotalLength(); } }
/** * This method interpolates the data for the nurbs curve. * @param u * the u value * @param nurbSpline * the nurbs spline definition * @param store * the resulting point in 3D space */ public static void interpolateNurbs(float u, Spline nurbSpline, Vector3f store) { if (nurbSpline.getType() != SplineType.Nurb) { throw new IllegalArgumentException("Given spline is not of a NURB type!"); } List<Vector3f> controlPoints = nurbSpline.getControlPoints(); float[] weights = nurbSpline.getWeights(); List<Float> knots = nurbSpline.getKnots(); int controlPointAmount = controlPoints.size(); store.set(Vector3f.ZERO); float delimeter = 0; for (int i = 0; i < controlPointAmount; ++i) { float val = weights[i] * CurveAndSurfaceMath.computeBaseFunctionValue(i, nurbSpline.getBasisFunctionDegree(), u, knots); store.addLocal(nurbSpline.getControlPoints().get(i) .mult(val)); delimeter += val; } store.divideLocal(delimeter); }
/** * This method computes the total length of the curve. */ private void computeTotalLength() { totalLength = 0; float l = 0; if (segmentsLength == null) { segmentsLength = new ArrayList<Float>(); } else { segmentsLength.clear(); } if (type == SplineType.Linear) { if (controlPoints.size() > 1) { for (int i = 0; i < controlPoints.size() - 1; i++) { l = controlPoints.get(i + 1).subtract(controlPoints.get(i)).length(); segmentsLength.add(l); totalLength += l; } } } else if(type == SplineType.Bezier) { this.computeBezierLength(); } else if(type == SplineType.Nurb) { this.computeNurbLength(); } else { this.initCatmullRomWayPoints(controlPoints); this.computeCatmulLength(); } }