瀏覽代碼

Small fixes and support for closed NURBS surfaces.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7098 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
Kae..pl 14 年之前
父節點
當前提交
46785739a4
共有 2 個文件被更改,包括 37 次插入24 次删除
  1. 21 14
      engine/src/core/com/jme3/math/CurveAndSurfaceMath.java
  2. 16 10
      engine/src/core/com/jme3/scene/shape/Surface.java

+ 21 - 14
engine/src/core/com/jme3/math/CurveAndSurfaceMath.java

@@ -47,6 +47,7 @@ public class CurveAndSurfaceMath {
 
 	/**
 	 * This method interpolates tha data for the nurbs surface.
+	 * 
 	 * @param u
 	 *            the u value
 	 * @param v
@@ -54,20 +55,23 @@ public class CurveAndSurfaceMath {
 	 * @param controlPoints
 	 *            the nurbs' control points
 	 * @param knots
-	 * 			  the nurbs' knots
+	 *            the nurbs' knots
+	 * @param basisUFunctionDegree
+	 *            the degree of basis U function
+	 * @param basisVFunctionDegree
+	 *            the degree of basis V function
 	 * @param store
 	 *            the resulting point in 3D space
 	 */
-	public static void interpolate(float u, float v, List<List<Vector4f>> controlPoints, List<Float>[] knots, Vector3f store) {
+	public static void interpolate(float u, float v, List<List<Vector4f>> controlPoints, List<Float>[] knots, 
+			int basisUFunctionDegree, int basisVFunctionDegree, Vector3f store) {
 		store.set(Vector3f.ZERO);
 		float delimeter = 0;
 		int vControlPointsAmount = controlPoints.size();
 		int uControlPointsAmount = controlPoints.get(0).size();
-		int basisUFunctionDegree = knots[0].size() - controlPoints.get(0).size();
-		int basisVFunctionDegree = knots[1]==null ? 0 : knots[1].size() - controlPoints.size();
 		for (int i = 0; i < vControlPointsAmount; ++i) {
 			for (int j = 0; j < uControlPointsAmount; ++j) {
-				Vector4f controlPoint = controlPoints.get(j).get(i);
+				Vector4f controlPoint = controlPoints.get(i).get(j);
 				float val = controlPoint.w
 								* CurveAndSurfaceMath.computeBaseFunctionValue(i, basisVFunctionDegree, v, knots[1])
 								* CurveAndSurfaceMath.computeBaseFunctionValue(j, basisUFunctionDegree, u, knots[0]);
@@ -90,15 +94,18 @@ public class CurveAndSurfaceMath {
 	// point and the following one is lower than it
 	public static void prepareNurbsKnots(List<Float> knots, int basisFunctionDegree) {
 		float delta = KNOTS_MINIMUM_DELTA;
-		for (int i = 1; i < basisFunctionDegree && knots.get(i).equals(knots.get(0)); ++i) {
-			knots.set(i, Float.valueOf(knots.get(i).floatValue() + delta));
-			delta += KNOTS_MINIMUM_DELTA;
-		}
-		float lastKnot = knots.get(knots.size() - 1);
-		delta = KNOTS_MINIMUM_DELTA;
-		for (int i = knots.size() - basisFunctionDegree + 1; i < knots.size() && knots.get(i).equals(lastKnot); ++i) {
-			knots.set(i, Float.valueOf(knots.get(i).floatValue() + delta));
-			delta += KNOTS_MINIMUM_DELTA;
+		float prevValue = knots.get(0).floatValue();
+		for(int i=1;i<knots.size();++i) {
+			float value = knots.get(i).floatValue();
+			if(value<=prevValue) {
+				value += delta;
+				knots.set(i, Float.valueOf(value));
+				delta += KNOTS_MINIMUM_DELTA;
+			} else {
+				delta = KNOTS_MINIMUM_DELTA;//reset the delta's value
+			}
+			
+			prevValue = value;
 		}
 	}
 

+ 16 - 10
engine/src/core/com/jme3/scene/shape/Surface.java

@@ -23,8 +23,8 @@ public class Surface extends Mesh {
 	private SplineType type;						//the type of the surface
 	private List<List<Vector4f>> controlPoints;		//space control points and their weights
 	private List<Float>[] knots;					//knots of the surface
-	private int basisUFunctionDegree;				//the degree of basis U function (computed automatically)
-	private int basisVFunctionDegree;				//the degree of basis V function (computed automatically)
+	private int basisUFunctionDegree;				//the degree of basis U function
+	private int basisVFunctionDegree;				//the degree of basis V function
 	private int uSegments;							//the amount of U segments
 	private int vSegments;							//the amount of V segments
 
@@ -34,18 +34,21 @@ public class Surface extends Mesh {
 	 * @param nurbKnots knots of the surface
 	 * @param uSegments the amount of U segments
 	 * @param vSegments the amount of V segments
+	 * @param basisUFunctionDegree the degree of basis U function
+	 * @param basisVFunctionDegree the degree of basis V function
 	 */
-	private Surface(List<List<Vector4f>> controlPoints, List<Float>[] nurbKnots, int uSegments, int vSegments) {
+	private Surface(List<List<Vector4f>> controlPoints, List<Float>[] nurbKnots, 
+					int uSegments, int vSegments, int basisUFunctionDegree, int basisVFunctionDegree) {
 		this.validateInputData(controlPoints, nurbKnots, uSegments, vSegments);
 		this.type = SplineType.Nurb;
 		this.uSegments = uSegments;
 		this.vSegments = vSegments;
 		this.controlPoints = controlPoints;
 		this.knots = nurbKnots;
-		this.basisUFunctionDegree = nurbKnots[0].size() - controlPoints.get(0).size();
+		this.basisUFunctionDegree = basisUFunctionDegree;
 		CurveAndSurfaceMath.prepareNurbsKnots(nurbKnots[0], basisUFunctionDegree);
 		if(nurbKnots[1]!=null) {
-			this.basisVFunctionDegree = nurbKnots[1].size() - controlPoints.size();
+			this.basisVFunctionDegree = basisVFunctionDegree;
 			CurveAndSurfaceMath.prepareNurbsKnots(nurbKnots[1], basisVFunctionDegree);
 		}
 		
@@ -58,10 +61,13 @@ public class Surface extends Mesh {
 	 * @param nurbKnots knots of the surface
 	 * @param uSegments the amount of U segments
 	 * @param vSegments the amount of V segments
+	 * @param basisUFunctionDegree the degree of basis U function
+	 * @param basisVFunctionDegree the degree of basis V function
 	 * @return an instance of NURBS surface
 	 */
-	public static final Surface createNurbsSurface(List<List<Vector4f>> controlPoints, List<Float>[] nurbKnots, int uSegments, int vSegments) {
-		Surface result = new Surface(controlPoints, nurbKnots, uSegments, vSegments);
+	public static final Surface createNurbsSurface(List<List<Vector4f>> controlPoints, List<Float>[] nurbKnots, 
+			int uSegments, int vSegments, int basisUFunctionDegree, int basisVFunctionDegree) {
+		Surface result = new Surface(controlPoints, nurbKnots, uSegments, vSegments, basisUFunctionDegree, basisVFunctionDegree);
 		result.type = SplineType.Nurb;
 		return result;
 	}
@@ -87,7 +93,7 @@ public class Surface extends Mesh {
 		for(int i=0;i<=vSegments; ++i) {
 			for(int j=0;j<=uSegments; ++j) {
 				Vector3f interpolationResult = new Vector3f();
-				CurveAndSurfaceMath.interpolate(u, v, controlPoints, knots, interpolationResult);
+				CurveAndSurfaceMath.interpolate(u, v, controlPoints, knots, basisUFunctionDegree, basisVFunctionDegree, interpolationResult);
 				vertices[arrayIndex++] = interpolationResult;
 				u += deltaU;
 			}
@@ -200,7 +206,7 @@ public class Surface extends Mesh {
 	 * @return the maximum nurb curve knot value
 	 */
     private float getMaxUNurbKnot() {
-    	return knots[0].get(controlPoints.get(0).size());
+    	return knots[0].get(knots[0].size() - basisUFunctionDegree);
     }
     
     /**
@@ -216,7 +222,7 @@ public class Surface extends Mesh {
 	 * @return the maximum nurb curve knot value
 	 */
     private float getMaxVNurbKnot() {
-    	return knots[1].get(controlPoints.size());
+    	return knots[1].get(knots[1].size() - basisVFunctionDegree);
     }
     
     /**