Esempio n. 1
0
 public void set(final double radius, final double start, final double end) {
   final FloatBuffer buf = getMeshData().getVertexBuffer();
   buf.limit(buf.capacity());
   this.getMeshData().updateVertexCount();
   buf.rewind();
   double arc = end - start;
   final int n = buf.limit() / 3;
   for (int i = 0; i < n; i++) {
     double theta = start + arc / (n - 1) * i;
     float x = (float) (MathUtils.cos(theta) * radius);
     float y = (float) (MathUtils.sin(theta) * radius);
     buf.put(x).put(y).put(0);
   }
   getMeshData().updateVertexCount();
 }
Esempio n. 2
0
  /**
   * Update the vertices for this particle, taking size, spin and viewer into consideration. In the
   * case of particle type ParticleType.GeomMesh, the original triangle normal is maintained rather
   * than rotating it to face the camera or parent vectors.
   *
   * @param cam Camera to use in determining viewer aspect. If null, or if parent is not set to
   *     camera facing, parent's left and up vectors are used.
   */
  public void updateVerts(final Camera cam) {
    final double orient = parent.getParticleOrientation() + values[VAL_CURRENT_SPIN];
    final double currSize = values[VAL_CURRENT_SIZE];

    if (type == ParticleSystem.ParticleType.GeomMesh
        || type == ParticleSystem.ParticleType.Point) {; // nothing to do
    } else if (cam != null && parent.isCameraFacing()) {
      final ReadOnlyVector3 camUp = cam.getUp();
      final ReadOnlyVector3 camLeft = cam.getLeft();
      final ReadOnlyVector3 camDir = cam.getDirection();
      if (parent.isVelocityAligned()) {
        bbX.set(_velocity).normalizeLocal().multiplyLocal(currSize);
        camDir.cross(bbX, bbY).normalizeLocal().multiplyLocal(currSize);
      } else if (orient == 0) {
        bbX.set(camLeft).multiplyLocal(currSize);
        bbY.set(camUp).multiplyLocal(currSize);
      } else {
        final double cA = MathUtils.cos(orient) * currSize;
        final double sA = MathUtils.sin(orient) * currSize;
        bbX.set(camLeft)
            .multiplyLocal(cA)
            .addLocal(camUp.getX() * sA, camUp.getY() * sA, camUp.getZ() * sA);
        bbY.set(camLeft)
            .multiplyLocal(-sA)
            .addLocal(camUp.getX() * cA, camUp.getY() * cA, camUp.getZ() * cA);
      }
    } else {
      bbX.set(parent.getLeftVector()).multiplyLocal(0);
      bbY.set(parent.getUpVector()).multiplyLocal(0);
    }

    final Vector3 tempVec3 = Vector3.fetchTempInstance();
    final FloatBuffer vertexBuffer = parent.getParticleGeometry().getMeshData().getVertexBuffer();
    switch (type) {
      case Quad:
        {
          _position.subtract(bbX, tempVec3).subtractLocal(bbY);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 0);

          _position.subtract(bbX, tempVec3).addLocal(bbY);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 1);

          _position.add(bbX, tempVec3).addLocal(bbY);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 2);

          _position.add(bbX, tempVec3).subtractLocal(bbY);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 3);
          break;
        }
      case GeomMesh:
        {
          final Quaternion tempQuat = Quaternion.fetchTempInstance();
          final ReadOnlyVector3 norm = triModel.getNormal();
          if (orient != 0) {
            tempQuat.fromAngleNormalAxis(orient, norm);
          }

          for (int x = 0; x < 3; x++) {
            if (orient != 0) {
              tempQuat.apply(triModel.get(x), tempVec3);
            } else {
              tempVec3.set(triModel.get(x));
            }
            tempVec3.multiplyLocal(currSize).addLocal(_position);
            BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + x);
          }
          Quaternion.releaseTempInstance(tempQuat);
          break;
        }
      case Triangle:
        {
          _position
              .subtract(3 * bbX.getX(), 3 * bbX.getY(), 3 * bbX.getZ(), tempVec3)
              .subtractLocal(bbY);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 0);

          _position.add(bbX, tempVec3).addLocal(3 * bbY.getX(), 3 * bbY.getY(), 3 * bbY.getZ());
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 1);

          _position.add(bbX, tempVec3).subtractLocal(bbY);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 2);
          break;
        }
      case Line:
        {
          _position.subtract(bbX, tempVec3);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex);

          _position.add(bbX, tempVec3);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 1);
          break;
        }
      case Point:
        {
          BufferUtils.setInBuffer(_position, vertexBuffer, startIndex);
          break;
        }
    }
    Vector3.releaseTempInstance(tempVec3);
  }
Esempio n. 3
0
  private void setGeometryData() {
    // generate geometry
    final double inverseRadial = 1.0 / _radialSamples;
    final double inverseAxisLess = 1.0 / (_closed ? _axisSamples - 3 : _axisSamples - 1);
    final double inverseAxisLessTexture = 1.0 / (_axisSamples - 1);
    final double halfHeight = 0.5 * _height;

    // Generate points on the unit circle to be used in computing the mesh
    // points on a cylinder slice.
    final double[] sin = new double[_radialSamples + 1];
    final double[] cos = new double[_radialSamples + 1];

    for (int radialCount = 0; radialCount < _radialSamples; radialCount++) {
      final double angle = MathUtils.TWO_PI * inverseRadial * radialCount;
      cos[radialCount] = MathUtils.cos(angle);
      sin[radialCount] = MathUtils.sin(angle);
    }
    sin[_radialSamples] = sin[0];
    cos[_radialSamples] = cos[0];

    // generate the cylinder itself
    final Vector3 tempNormal = new Vector3();
    for (int axisCount = 0, i = 0; axisCount < _axisSamples; axisCount++) {
      double axisFraction;
      double axisFractionTexture;
      int topBottom = 0;
      if (!_closed) {
        axisFraction = axisCount * inverseAxisLess; // in [0,1]
        axisFractionTexture = axisFraction;
      } else {
        if (axisCount == 0) {
          topBottom = -1; // bottom
          axisFraction = 0;
          axisFractionTexture = inverseAxisLessTexture;
        } else if (axisCount == _axisSamples - 1) {
          topBottom = 1; // top
          axisFraction = 1;
          axisFractionTexture = 1 - inverseAxisLessTexture;
        } else {
          axisFraction = (axisCount - 1) * inverseAxisLess;
          axisFractionTexture = axisCount * inverseAxisLessTexture;
        }
      }
      final double z = -halfHeight + _height * axisFraction;

      // compute center of slice
      final Vector3 sliceCenter = new Vector3(0, 0, z);

      // compute slice vertices with duplication at end point
      final int save = i;
      for (int radialCount = 0; radialCount < _radialSamples; radialCount++) {
        final double radialFraction = radialCount * inverseRadial; // in [0,1)
        tempNormal.set(cos[radialCount], sin[radialCount], 0);
        if (topBottom == 0) {
          if (!_inverted) {
            _meshData
                .getNormalBuffer()
                .put(tempNormal.getXf())
                .put(tempNormal.getYf())
                .put(tempNormal.getZf());
          } else {
            _meshData
                .getNormalBuffer()
                .put(-tempNormal.getXf())
                .put(-tempNormal.getYf())
                .put(-tempNormal.getZf());
          }
        } else {
          _meshData.getNormalBuffer().put(0).put(0).put(topBottom * (_inverted ? -1 : 1));
        }

        tempNormal
            .multiplyLocal((_radius - _radius2) * axisFraction + _radius2)
            .addLocal(sliceCenter);
        _meshData
            .getVertexBuffer()
            .put(tempNormal.getXf())
            .put(tempNormal.getYf())
            .put(tempNormal.getZf());

        _meshData
            .getTextureCoords(0)
            .getBuffer()
            .put((float) (_inverted ? 1 - radialFraction : radialFraction))
            .put((float) axisFractionTexture);
        i++;
      }

      BufferUtils.copyInternalVector3(_meshData.getVertexBuffer(), save, i);
      BufferUtils.copyInternalVector3(_meshData.getNormalBuffer(), save, i);

      _meshData
          .getTextureCoords(0)
          .getBuffer()
          .put((_inverted ? 0.0f : 1.0f))
          .put((float) axisFractionTexture);

      i++;
    }

    if (_closed) {
      _meshData.getVertexBuffer().put(0).put(0).put((float) -halfHeight); // bottom center
      _meshData.getNormalBuffer().put(0).put(0).put(-1 * (_inverted ? -1 : 1));
      _meshData.getTextureCoords(0).getBuffer().put(0.5f).put(0);
      _meshData.getVertexBuffer().put(0).put(0).put((float) halfHeight); // top center
      _meshData.getNormalBuffer().put(0).put(0).put(1 * (_inverted ? -1 : 1));
      _meshData.getTextureCoords(0).getBuffer().put(0.5f).put(1);
    }
  }
Esempio n. 4
0
  private void setGeometryData() {
    final FloatBuffer verts = _meshData.getVertexBuffer();
    final FloatBuffer norms = _meshData.getNormalBuffer();
    final FloatBuffer texs = _meshData.getTextureBuffer(0);
    verts.rewind();
    norms.rewind();
    texs.rewind();

    // generate geometry
    final double inverseRadial = 1.0 / radialSamples;
    final double inverseSphere = 1.0 / sphereSamples;
    final double halfHeight = 0.5 * height;

    // Generate points on the unit circle to be used in computing the mesh
    // points on a cylinder slice.
    final double[] sin = new double[radialSamples + 1];
    final double[] cos = new double[radialSamples + 1];

    for (int radialCount = 0; radialCount < radialSamples; radialCount++) {
      final double angle = MathUtils.TWO_PI * inverseRadial * radialCount;
      cos[radialCount] = MathUtils.cos(angle);
      sin[radialCount] = MathUtils.sin(angle);
    }
    sin[radialSamples] = sin[0];
    cos[radialSamples] = cos[0];

    final Vector3 tempA = new Vector3();

    // top point.
    verts.put(0).put((float) (radius + halfHeight)).put(0);
    norms.put(0).put(1).put(0);
    texs.put(1).put(1);

    // generating the top dome.
    for (int i = 0; i < sphereSamples; i++) {
      final double center = radius * (1 - (i + 1) * (inverseSphere));
      final double lengthFraction = (center + height + radius) / (height + 2 * radius);

      // compute radius of slice
      final double fSliceRadius = Math.sqrt(Math.abs(radius * radius - center * center));

      for (int j = 0; j <= radialSamples; j++) {
        final Vector3 kRadial = tempA.set(cos[j], 0, sin[j]);
        kRadial.multiplyLocal(fSliceRadius);
        verts.put(kRadial.getXf()).put((float) (center + halfHeight)).put(kRadial.getZf());
        kRadial.setY(center);
        kRadial.normalizeLocal();
        norms.put(kRadial.getXf()).put(kRadial.getYf()).put(kRadial.getZf());
        final double radialFraction = 1 - (j * inverseRadial); // in [0,1)
        texs.put((float) radialFraction).put((float) lengthFraction);
      }
    }

    // generate cylinder... but no need to add points for first and last
    // samples as they are already part of domes.
    for (int i = 1; i < axisSamples; i++) {
      final double center = halfHeight - (i * height / axisSamples);
      final double lengthFraction = (center + halfHeight + radius) / (height + 2 * radius);

      for (int j = 0; j <= radialSamples; j++) {
        final Vector3 kRadial = tempA.set(cos[j], 0, sin[j]);
        kRadial.multiplyLocal(radius);
        verts.put(kRadial.getXf()).put((float) center).put(kRadial.getZf());
        kRadial.normalizeLocal();
        norms.put(kRadial.getXf()).put(kRadial.getYf()).put(kRadial.getZf());
        final double radialFraction = 1 - (j * inverseRadial); // in [0,1)
        texs.put((float) radialFraction).put((float) lengthFraction);
      }
    }

    // generating the bottom dome.
    for (int i = 0; i < sphereSamples; i++) {
      final double center = i * (radius / sphereSamples);
      final double lengthFraction = (radius - center) / (height + 2 * radius);

      // compute radius of slice
      final double fSliceRadius = Math.sqrt(Math.abs(radius * radius - center * center));

      for (int j = 0; j <= radialSamples; j++) {
        final Vector3 kRadial = tempA.set(cos[j], 0, sin[j]);
        kRadial.multiplyLocal(fSliceRadius);
        verts.put(kRadial.getXf()).put((float) (-center - halfHeight)).put(kRadial.getZf());
        kRadial.setY(-center);
        kRadial.normalizeLocal();
        norms.put(kRadial.getXf()).put(kRadial.getYf()).put(kRadial.getZf());
        final double radialFraction = 1 - (j * inverseRadial); // in [0,1)
        texs.put((float) radialFraction).put((float) lengthFraction);
      }
    }

    // bottom point.
    verts.put(0).put((float) (-radius - halfHeight)).put(0);
    norms.put(0).put(-1).put(0);
    texs.put(0).put(0);
  }