Small fixes and support for closed NURBS surfaces.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7098 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
Kae..pl 14 years ago
parent 66f5e2c1b6
commit 46785739a4
  1. 35
      engine/src/core/com/jme3/math/CurveAndSurfaceMath.java
  2. 26
      engine/src/core/com/jme3/scene/shape/Surface.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;
}
}

@ -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);
}
/**

Loading…
Cancel
Save