示例#1
0
文件: Line.java 项目: jmecn/learnJME3
  public void orthogonalLineFit(FloatBuffer points) {
    if (points == null) {
      return;
    }

    points.rewind();

    // compute average of points
    int length = points.remaining() / 3;

    BufferUtils.populateFromBuffer(origin, points, 0);
    for (int i = 1; i < length; i++) {
      BufferUtils.populateFromBuffer(compVec1, points, i);
      origin.addLocal(compVec1);
    }

    origin.multLocal(1f / (float) length);

    // compute sums of products
    float sumXX = 0.0f, sumXY = 0.0f, sumXZ = 0.0f;
    float sumYY = 0.0f, sumYZ = 0.0f, sumZZ = 0.0f;

    points.rewind();
    for (int i = 0; i < length; i++) {
      BufferUtils.populateFromBuffer(compVec1, points, i);
      compVec1.subtract(origin, compVec2);
      sumXX += compVec2.x * compVec2.x;
      sumXY += compVec2.x * compVec2.y;
      sumXZ += compVec2.x * compVec2.z;
      sumYY += compVec2.y * compVec2.y;
      sumYZ += compVec2.y * compVec2.z;
      sumZZ += compVec2.z * compVec2.z;
    }

    // find the smallest eigen vector for the direction vector
    compMat1.m00 = sumYY + sumZZ;
    compMat1.m01 = -sumXY;
    compMat1.m02 = -sumXZ;
    compMat1.m10 = -sumXY;
    compMat1.m11 = sumXX + sumZZ;
    compMat1.m12 = -sumYZ;
    compMat1.m20 = -sumXZ;
    compMat1.m21 = -sumYZ;
    compMat1.m22 = sumXX + sumYY;

    compEigen1.calculateEigen(compMat1);
    direction = compEigen1.getEigenVector(0);
  }
  /**
   * <code>tessellate</code> generates the <code>BezierMesh</code> vertices from the supplied patch
   * and detail level. This method is called when patch is set, and therefore, should normally have
   * to be called. However, if patch is changed externally, and you wish to update the mesh, a call
   * to <code>tessellate</code> is appropriate.
   */
  public void tessellate() {
    if (patch == null) {
      return;
    }
    int u = 0, v;
    float py, px, pyold;
    int detailLevel = patch.getDetailLevel();

    Vector3f[] temp = new Vector3f[4];
    Vector3f[] last = new Vector3f[detailLevel + 1];

    temp[0] = patch.getAnchor(0, 3);
    temp[1] = patch.getAnchor(1, 3);
    temp[2] = patch.getAnchor(2, 3);
    temp[3] = patch.getAnchor(3, 3);

    for (v = 0; v <= detailLevel; v++) {
      px = ((float) v) / ((float) detailLevel);
      last[v] = calcBerstein(px, temp);
    }

    u = 1;
    setVertexCount(((detailLevel * 2) + 2) * detailLevel);
    setVertexBuffer(BufferUtils.createVector3Buffer(getVertexCount()));
    setTextureCoords(new TexCoords(BufferUtils.createFloatBuffer(getVertexCount() * 2), 2), 0);
    setNormalBuffer(BufferUtils.createVector3Buffer(getVertexCount()));

    setTriangleQuantity(detailLevel * detailLevel * 6);
    setIndexBuffer(BufferUtils.createIntBuffer(getTriangleCount() * 3));

    getVertexBuffer().clear();
    FloatBuffer src = getTextureCoords().get(0).coords;
    src.clear();
    for (u = 1; u <= detailLevel; u++) {
      py = ((float) u) / ((float) detailLevel);
      pyold = (u - 1.0f) / (detailLevel);
      temp[0] = calcBerstein(py, patch.getAnchors()[0]);
      temp[1] = calcBerstein(py, patch.getAnchors()[1]);
      temp[2] = calcBerstein(py, patch.getAnchors()[2]);
      temp[3] = calcBerstein(py, patch.getAnchors()[3]);

      for (v = 0; v <= detailLevel; v++) {
        px = ((float) v) / ((float) detailLevel);
        src.put(pyold).put(px);
        getVertexBuffer().put(last[v].x).put(last[v].y).put(last[v].z);
        last[v] = calcBerstein(px, temp);
        src.put(py).put(px);
        getVertexBuffer().put(last[v].x).put(last[v].y).put(last[v].z);
      }
    }

    int index = -1;
    for (int i = 0; i < getTriangleCount(); i = i + 6) {

      index++;
      if (i > 0 && i % (detailLevel * 6) == 0) {
        index += 1;
      }

      getIndexBuffer().put(2 * index);
      getIndexBuffer().put((2 * index) + 1);
      getIndexBuffer().put((2 * index) + 2);

      getIndexBuffer().put((2 * index) + 3);
      getIndexBuffer().put((2 * index) + 2);
      getIndexBuffer().put((2 * index) + 1);
    }

    setNormalBuffer(BufferUtils.createVector3Buffer(getVertexCount()));
    Vector3f oppositePoint = new Vector3f();
    Vector3f adjacentPoint = new Vector3f();
    Vector3f rootPoint = new Vector3f();
    Vector3f tempNorm = new Vector3f();
    int adj = 0, opp = 0, normalIndex = 0;
    for (int i = 0; i < detailLevel; i++) {
      for (int j = 0; j < (detailLevel * 2) + 2; j++) {
        BufferUtils.populateFromBuffer(rootPoint, getVertexBuffer(), normalIndex);
        if (j % 2 == 0) {
          if (i == 0) {
            if (j < (detailLevel * 2)) {
              // right cross up
              adj = normalIndex + 1;
              opp = normalIndex + 2;
            } else {
              // down cross right
              adj = normalIndex - 1;
              opp = normalIndex + 1;
            }
          } else {
            int ind = normalIndex - (detailLevel * 2 + 1);
            getNormalBuffer().rewind();
            tempNorm.x = getNormalBuffer().get(ind * 3);
            tempNorm.y = getNormalBuffer().get(ind * 3 + 1);
            tempNorm.z = getNormalBuffer().get(ind * 3 + 2);
            tempNorm.normalizeLocal();
            BufferUtils.setInBuffer(tempNorm, getNormalBuffer(), normalIndex);
            normalIndex++;
            continue;
          }
        } else {
          if (j < (detailLevel * 2) + 1) {
            // up cross left
            adj = normalIndex + 2;
            opp = normalIndex - 1;
          } else {
            // left cross down
            adj = normalIndex - 1;
            opp = normalIndex - 2;
          }
        }
        BufferUtils.populateFromBuffer(adjacentPoint, getVertexBuffer(), adj);
        BufferUtils.populateFromBuffer(oppositePoint, getVertexBuffer(), opp);
        tempNorm
            .set(adjacentPoint)
            .subtractLocal(rootPoint)
            .crossLocal(oppositePoint.subtractLocal(rootPoint))
            .normalizeLocal();
        BufferUtils.setInBuffer(tempNorm, getNormalBuffer(), normalIndex);
        normalIndex++;
      }
    }
  }