/**
  * This method applies the variation to the particle with already set velocity.
  *
  * @param particle the particle to be affected
  */
 protected void applyVelocityVariation(Particle particle) {
   particle.velocity.set(initialVelocity);
   temp.set(FastMath.nextRandomFloat(), FastMath.nextRandomFloat(), FastMath.nextRandomFloat());
   temp.multLocal(2f);
   temp.subtractLocal(1f, 1f, 1f);
   temp.multLocal(initialVelocity.length());
   particle.velocity.interpolate(temp, velocityVariation);
 }
Пример #2
0
  @Override
  public void update(float tpf) {
    super.update(tpf);

    // If the mouse is being dragged, update the locations of any dragged
    // temporary geometries. To determine if the locations need to be
    // updated, the mouse button must be down AND the mouse must have moved
    // since the last update.
    if (!click.get() && newTemporaryPosition.getAndSet(false)) {
      // Add the temporary spatials node if the drag has just started.
      if (!showTemporarySpatials.getAndSet(true)) {
        appState.getRootNode().attachChild(tempSpatials);
      }
      // Get the cursor's current location on the grid.
      CollisionResults results = getCollision(grid, appState.getCursorRay());
      if (results.size() > 0) {
        // Determine the vector between the start point for the mouse
        // drag and the current location of the mouse drag.
        Vector3f dragLoc =
            appState.getClosestGridPoint(results.getClosestCollision().getContactPoint());
        dragLoc.subtractLocal(dragStart);

        // We need to modify the controllers for all the
        // currently-selected vertices. It's possible that
        // selectionChanged() is executing at the same time, so we need
        // to temporarily "lock" the selected vertex data structures.
        selectionLock.lock();
        try {
          // Add the vector to all temporary vertices.
          for (Entry<Integer, Vertex> e : selectedVertices.entrySet()) {
            float[] array = e.getValue().getLocation();
            Vector3f location = dragLoc.add(array[0], array[1], array[2]);
            vertexControllers.get(e.getKey()).setLocation(location);
          }
        } finally {
          selectionLock.unlock();
        }
      }
    }
    // If the dragging has stopped and we are still showing temporary
    // spatials in the scene, stop showing them.
    else if (!drag.get() && showTemporarySpatials.getAndSet(false)) {
      appState.getRootNode().detachChild(tempSpatials);
    }

    return;
  }
Пример #3
0
  private Vector3f getWorldIntersection() {
    Vector3f origin =
        cam.getWorldCoordinates(
            new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.0f);
    Vector3f direction =
        cam.getWorldCoordinates(
            new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.3f);
    direction.subtractLocal(origin).normalizeLocal();

    Ray ray = new Ray(origin, direction);
    CollisionResults results = new CollisionResults();
    int numCollisions = terrain.collideWith(ray, results);
    if (numCollisions > 0) {
      CollisionResult hit = results.getClosestCollision();
      return hit.getContactPoint();
    }
    return null;
  }
Пример #4
0
  public MouseStatus getMouseCollision() {
    if (gui.isMouseOver()) {
      return null;
    }

    Vector3f origin = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.0f);
    Vector3f direction = cam.getWorldCoordinates(inputManager.getCursorPosition(), 0.3f);
    direction.subtractLocal(origin).normalizeLocal();

    Ray ray = new Ray(origin, direction);
    CollisionResults results = new CollisionResults();
    clickableNode.collideWith(ray, results);

    Vector3f v3f = null;
    Model m = null;

    if (results.size() > 0) {

      CollisionResult closest = results.getClosestCollision();
      Geometry g = closest.getGeometry();

      v3f = closest.getContactPoint();
      m = Model.Geometry2Model(g);

      // return new
      // MouseStatus(m,closest.getContactPoint().getX(),closest.getContactPoint().getZ());
    }

    if (water != null) {
      Vector3f waterv = water.collision(ray);
      if (waterv != null && (v3f == null || waterv.distance(origin) < v3f.distance(origin))) {
        v3f = waterv;
      }
    }

    if (v3f != null) return new MouseStatus(m, v3f.getX(), v3f.getZ());

    return null;
  }
 private void doPicking() {
   Point mouse = canvas.getMousePosition();
   if (mouse == null) {
     clearLabel();
   } else {
     vec2.x = mouse.x;
     vec2.y = canvas.getHeight() - mouse.y;
     // create ray
     Vector3f end = scene.getCamera().getWorldCoordinates(vec2, 0.2f);
     Vector3f start = scene.getCamera().getLocation();
     Ray ray = new Ray(start, end.subtractLocal(start).normalizeLocal());
     // do collision checking
     CollisionResults results = new CollisionResults();
     scene.getRootNode().collideWith(ray, results);
     CollisionResult result = results.getClosestCollision();
     if (result != null) {
       Vector3f contactPoint = result.getContactPoint();
       setLabel(contactPoint);
     } else {
       clearLabel();
     }
   }
 }
  @Override
  public void updateParticleData(ParticleData[] particles, Camera cam, Matrix3f inverseRotation) {

    for (int i = 0; i < particles.length; i++) {
      ParticleData p = particles[i];
      int offset = templateVerts.capacity() * i;
      int colorOffset = templateColors.capacity() * i;
      if (p.life == 0 || !p.active) {
        for (int x = 0; x < templateVerts.capacity(); x += 3) {
          finVerts.put(offset + x, 0);
          finVerts.put(offset + x + 1, 0);
          finVerts.put(offset + x + 2, 0);
        }
        continue;
      }

      for (int x = 0; x < templateVerts.capacity(); x += 3) {
        switch (emitter.getBillboardMode()) {
          case Velocity:
            if (p.velocity.x != Vector3f.UNIT_Y.x
                && p.velocity.y != Vector3f.UNIT_Y.y
                && p.velocity.z != Vector3f.UNIT_Y.z)
              up.set(p.velocity).crossLocal(Vector3f.UNIT_Y).normalizeLocal();
            else up.set(p.velocity).crossLocal(lock).normalizeLocal();
            left.set(p.velocity).crossLocal(up).normalizeLocal();
            dir.set(p.velocity);
            break;
          case Velocity_Z_Up:
            if (p.velocity.x != Vector3f.UNIT_Y.x
                && p.velocity.y != Vector3f.UNIT_Y.y
                && p.velocity.z != Vector3f.UNIT_Y.z)
              up.set(p.velocity).crossLocal(Vector3f.UNIT_Y).normalizeLocal();
            else up.set(p.velocity).crossLocal(lock).normalizeLocal();
            left.set(p.velocity).crossLocal(up).normalizeLocal();
            dir.set(p.velocity);
            rotStore = tempQ.fromAngleAxis(-90 * FastMath.DEG_TO_RAD, left);
            left = rotStore.mult(left);
            up = rotStore.mult(up);
            break;
          case Velocity_Z_Up_Y_Left:
            up.set(p.velocity).crossLocal(Vector3f.UNIT_Y).normalizeLocal();
            left.set(p.velocity).crossLocal(up).normalizeLocal();
            dir.set(p.velocity);
            tempV3.set(left).crossLocal(up).normalizeLocal();
            rotStore = tempQ.fromAngleAxis(90 * FastMath.DEG_TO_RAD, p.velocity);
            left = rotStore.mult(left);
            up = rotStore.mult(up);
            rotStore = tempQ.fromAngleAxis(-90 * FastMath.DEG_TO_RAD, left);
            up = rotStore.mult(up);
            break;
          case Normal:
            emitter.getShape().setNext(p.triangleIndex);
            tempV3.set(emitter.getShape().getNormal());
            if (tempV3 == Vector3f.UNIT_Y) tempV3.set(p.velocity);

            up.set(tempV3).crossLocal(Vector3f.UNIT_Y).normalizeLocal();
            left.set(tempV3).crossLocal(up).normalizeLocal();
            dir.set(tempV3);
            break;
          case Normal_Y_Up:
            emitter.getShape().setNext(p.triangleIndex);
            tempV3.set(p.velocity);
            if (tempV3 == Vector3f.UNIT_Y) tempV3.set(Vector3f.UNIT_X);

            up.set(Vector3f.UNIT_Y);
            left.set(tempV3).crossLocal(up).normalizeLocal();
            dir.set(tempV3);
            break;
          case Camera:
            up.set(cam.getUp());
            left.set(cam.getLeft());
            dir.set(cam.getDirection());
            break;
          case UNIT_X:
            up.set(Vector3f.UNIT_Y);
            left.set(Vector3f.UNIT_Z);
            dir.set(Vector3f.UNIT_X);
            break;
          case UNIT_Y:
            up.set(Vector3f.UNIT_Z);
            left.set(Vector3f.UNIT_X);
            dir.set(Vector3f.UNIT_Y);
            break;
          case UNIT_Z:
            up.set(Vector3f.UNIT_X);
            left.set(Vector3f.UNIT_Y);
            dir.set(Vector3f.UNIT_Z);
            break;
        }

        tempV3.set(templateVerts.get(x), templateVerts.get(x + 1), templateVerts.get(x + 2));
        tempV3 = rotStore.mult(tempV3);
        tempV3.multLocal(p.size);

        rotStore.fromAngles(p.angles.x, p.angles.y, p.angles.z);
        tempV3 = rotStore.mult(tempV3);

        tempV3.addLocal(p.position);
        if (!emitter.getParticlesFollowEmitter()) {
          tempV3.subtractLocal(
              emitter
                  .getEmitterNode()
                  .getWorldTranslation()
                  .subtract(p.initialPosition)); // .divide(8f));
        }

        finVerts.put(offset + x, tempV3.getX());
        finVerts.put(offset + x + 1, tempV3.getY());
        finVerts.put(offset + x + 2, tempV3.getZ());
      }
      if (p.emitter.getApplyLightingTransform()) {
        for (int v = 0; v < templateNormals.capacity(); v += 3) {
          tempV3.set(
              templateNormals.get(v), templateNormals.get(v + 1), templateNormals.get(v + 2));

          rotStore.fromAngles(p.angles.x, p.angles.y, p.angles.z);
          mat3.set(rotStore.toRotationMatrix());
          float vx = tempV3.x, vy = tempV3.y, vz = tempV3.z;
          tempV3.x = mat3.get(0, 0) * vx + mat3.get(0, 1) * vy + mat3.get(0, 2) * vz;
          tempV3.y = mat3.get(1, 0) * vx + mat3.get(1, 1) * vy + mat3.get(1, 2) * vz;
          tempV3.z = mat3.get(2, 0) * vx + mat3.get(2, 1) * vy + mat3.get(2, 2) * vz;

          finNormals.put(offset + v, tempV3.getX());
          finNormals.put(offset + v + 1, tempV3.getY());
          finNormals.put(offset + v + 2, tempV3.getZ());
        }
      }
      for (int v = 0; v < templateColors.capacity(); v += 4) {
        finColors
            .put(colorOffset + v, p.color.r)
            .put(colorOffset + v + 1, p.color.g)
            .put(colorOffset + v + 2, p.color.b)
            .put(colorOffset + v + 3, p.color.a * p.alpha);
      }
    }

    this.setBuffer(VertexBuffer.Type.Position, 3, finVerts);
    if (particles[0].emitter.getApplyLightingTransform())
      this.setBuffer(VertexBuffer.Type.Normal, 3, finNormals);
    this.setBuffer(VertexBuffer.Type.Color, 4, finColors);

    updateBound();
  }
Пример #7
0
  private static BoneWorldGrid makeBoneWorldGrid(
      ByteArray3d boneMeshGrid, float worldScale, MyBone bone) {
    Transform transform = BoneTransformUtils.boneTransform2(bone);
    // bounding box needed for boneMeshGrid in world grid:
    float bs = 1.0f;
    Vector3f c1 =
        transform.transformVector(new Vector3f(-bs, -bs, -bs), null).multLocal(worldScale);
    Vector3f c2 =
        transform.transformVector(new Vector3f(+bs, -bs, -bs), null).multLocal(worldScale);
    Vector3f c3 =
        transform.transformVector(new Vector3f(-bs, +bs, -bs), null).multLocal(worldScale);
    Vector3f c4 =
        transform.transformVector(new Vector3f(-bs, -bs, +bs), null).multLocal(worldScale);
    Vector3f c5 =
        transform.transformVector(new Vector3f(+bs, +bs, -bs), null).multLocal(worldScale);
    Vector3f c6 =
        transform.transformVector(new Vector3f(-bs, +bs, +bs), null).multLocal(worldScale);
    Vector3f c7 =
        transform.transformVector(new Vector3f(+bs, -bs, +bs), null).multLocal(worldScale);
    Vector3f c8 =
        transform.transformVector(new Vector3f(+bs, +bs, +bs), null).multLocal(worldScale);

    Vector3f cmin = c1.clone();
    cmin.minLocal(c2);
    cmin.minLocal(c3);
    cmin.minLocal(c4);
    cmin.minLocal(c5);
    cmin.minLocal(c6);
    cmin.minLocal(c7);
    cmin.minLocal(c8);
    Vector3f cmax = c1.clone();
    cmax.maxLocal(c2);
    cmax.maxLocal(c3);
    cmax.maxLocal(c4);
    cmax.maxLocal(c5);
    cmax.maxLocal(c6);
    cmax.maxLocal(c7);
    cmax.maxLocal(c8);

    int xsize = (int) FastMath.ceil(cmax.x - cmin.x);
    int ysize = (int) FastMath.ceil(cmax.y - cmin.y);
    int zsize = (int) FastMath.ceil(cmax.z - cmin.z);

    ByteArray3d grid = new ByteArray3d(xsize, ysize, zsize);
    int w = grid.getWidth();
    int h = grid.getHeight();
    int d = grid.getDepth();
    Vector3f v = new Vector3f();
    Vector3f inv = new Vector3f();
    Vector3f inv2 = new Vector3f();

    // we want to calculate transform: (inv - (-bs)) * (sz / (bs - (-bs)))
    // se let's precalculate it to (inv + shift) * scale
    Vector3f scale =
        new Vector3f(boneMeshGrid.getWidth(), boneMeshGrid.getHeight(), boneMeshGrid.getDepth())
            .divideLocal(bs * 2);
    Vector3f shift = Vector3f.UNIT_XYZ.mult(bs);

    for (int x = 0; x < w; x++) {
      for (int y = 0; y < h; y++) {
        // calculate inverse transform at (x,y,0) and (x,y,1), the rest of the transforms in inner
        // loop
        // can be calculated by adding (inv2-inv1) because the transforms are linear
        v.set(x, y, 0).addLocal(cmin).divideLocal(worldScale);
        transform.transformInverseVector(v, inv);
        inv.addLocal(shift).multLocal(scale);

        v.set(x, y, 1).addLocal(cmin).divideLocal(worldScale);
        transform.transformInverseVector(v, inv2);
        inv2.addLocal(shift).multLocal(scale);

        Vector3f add = inv2.subtractLocal(inv);

        for (int z = 0; z < d; z++) {
          inv.addLocal(add);
          if (inv.x >= 0
              && inv.x < boneMeshGrid.getWidth()
              && inv.y >= 0
              && inv.y < boneMeshGrid.getHeight()
              && inv.z >= 0
              && inv.z < boneMeshGrid.getDepth()) {

            grid.set(x, y, z, boneMeshGrid.get((int) inv.x, (int) inv.y, (int) inv.z));
          }
        }
      }
    }

    // Once the boneMeshGrid has been transformed into world grid, it may suffer from
    // downsampling and upsampling artifacts (because the sampling is very simple nearest-neighbor).
    // Blurring the grid helps with both issues (blur=fake antialias). It has the added benefit
    // that each BoneWorldGrid will have some "smoothing buffer" around the actual shape, so that
    // the shape blends better with other bones' shapes.
    blurGrid(grid);

    BoneWorldGrid bwg2 = new BoneWorldGrid();
    bwg2.grid = grid;
    bwg2.location = new Vector3i(Math.round(cmin.x), Math.round(cmin.y), Math.round(cmin.z));
    return bwg2;
  }