Пример #1
0
 @Override
 public void simpleUpdate(float tpf) {
   Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);
   Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
   walkDirection.set(0, 0, 0);
   if (left) walkDirection.addLocal(camLeft);
   if (right) walkDirection.addLocal(camLeft.negate());
   if (up) walkDirection.addLocal(camDir);
   if (down) walkDirection.addLocal(camDir.negate());
   player.setWalkDirection(walkDirection);
   cam.setLocation(player.getPhysicsLocation());
 }
Пример #2
0
  @Override
  protected void initialize(Application app) {

    ed = getState(EntityDataState.class).getEntityData();
    entities = ed.getEntities(Position.class, ModelType.class);

    // Calculate how big min/max needs to be to incorporate
    // the full view + margin at z = 0
    Camera cam = app.getCamera();
    float z = cam.getViewToProjectionZ(cam.getLocation().z);
    Vector3f worldMin = cam.getWorldCoordinates(new Vector2f(0, 0), z);
    Vector3f worldMax = cam.getWorldCoordinates(new Vector2f(cam.getWidth(), cam.getHeight()), z);
    min = worldMin.addLocal(-margin, -margin, 0);
    max = worldMax.addLocal(margin, margin, 0);
  }
Пример #3
0
  private void refreshFont() {
    Camera cam = IsoCamera.getInstance().getCam();

    Vector3f start = from.getPlanet().getPosition();
    Vector3f end = to.getPlanet().getPosition();

    float width = label.getLineWidth();
    Random r = new Random();
    //        float height = r.nextFloat() * end.subtract(start).z;

    Vector3f position = new Vector3f(width / 2, .15f, 0);
    Vector3f fontPos = start.add(end.subtract(start).mult(0.4f + 0.75f * r.nextFloat()));
    position.addLocal(fontPos);

    Vector3f up = cam.getUp().clone();
    Vector3f dir = cam.getDirection().clone().negateLocal().normalizeLocal();
    Vector3f left = cam.getLeft().clone().normalizeLocal().negateLocal();

    Quaternion look = new Quaternion();
    look.fromAxes(left, up, dir);

    label.setLocalTransform(new Transform(position, look));

    //        Vector3f camPos = IsoCamera.getInstance().getCam().getLocation();
    //        Vector3f fontPos = to.getPlanet().getPosition().
    //                subtract(from.getPlanet().getPosition());
    //        Vector3f up = IsoCamera.getInstance().getCam().getUp().clone();
    //        Vector3f dir = camPos.subtract(fontPos);
    ////        Vector3f dir = Vector3f.UNIT_Y.clone().subtract(fontPos);
    //
    //        Vector3f left = IsoCamera.getInstance().getCam().getLeft().clone();
    //        dir.normalizeLocal();
    //        left.negateLocal();
    //        left.normalizeLocal();
    //        up.normalizeLocal();
    ////        dir.negateLocal();
    //
    //        Quaternion look = new Quaternion();
    //        look.fromAxes(left, up, dir);
    //
    //        Vector3f newPos = to.getPlanet().getPosition().
    //                subtract(from.getPlanet().getPosition());
    //
    //        newPos.x -= label.getLineWidth() / 2;
    //
    //        Transform t = new Transform(newPos, look);
    //
    //        label.setLocalTransform(t);
  }
Пример #4
0
 @Override
 public void simpleUpdate(float lastTimePerFrame) {
   float playerMoveSpeed = ((cubesSettings.getBlockSize() * 6.5f) * lastTimePerFrame);
   Vector3f camDir = cam.getDirection().mult(playerMoveSpeed);
   Vector3f camLeft = cam.getLeft().mult(playerMoveSpeed);
   walkDirection.set(0, 0, 0);
   if (arrowKeys[0]) {
     walkDirection.addLocal(camDir);
   }
   if (arrowKeys[1]) {
     walkDirection.addLocal(camLeft.negate());
   }
   if (arrowKeys[2]) {
     walkDirection.addLocal(camDir.negate());
   }
   if (arrowKeys[3]) {
     walkDirection.addLocal(camLeft);
   }
   walkDirection.setY(0);
   walkDirection.normalize();
   walkDirection.multLocal(lastTimePerFrame * 10);
   playerControl.setWalkDirection(walkDirection);
   cam.setLocation(playerControl.getPhysicsLocation());
 }
Пример #5
0
  public void postQueue(RenderQueue rq) {
    GeometryList occluders = rq.getShadowQueueContent(ShadowMode.Cast);
    if (occluders.size() == 0) {
      noOccluders = true;
      return;
    } else {
      noOccluders = false;
    }

    GeometryList receivers = rq.getShadowQueueContent(ShadowMode.Receive);

    // update frustum points based on current camera
    Camera viewCam = viewPort.getCamera();
    ShadowUtil.updateFrustumPoints(
        viewCam, viewCam.getFrustumNear(), viewCam.getFrustumFar(), 1.0f, points);

    Vector3f frustaCenter = new Vector3f();
    for (Vector3f point : points) {
      frustaCenter.addLocal(point);
    }
    frustaCenter.multLocal(1f / 8f);

    // update light direction
    shadowCam.setProjectionMatrix(null);
    shadowCam.setParallelProjection(true);
    //        shadowCam.setFrustumPerspective(45, 1, 1, 20);

    shadowCam.lookAtDirection(direction, Vector3f.UNIT_Y);
    shadowCam.update();
    shadowCam.setLocation(frustaCenter);
    shadowCam.update();
    shadowCam.updateViewProjection();

    // render shadow casters to shadow map
    ShadowUtil.updateShadowCamera(occluders, receivers, shadowCam, points);

    Renderer r = renderManager.getRenderer();
    renderManager.setCamera(shadowCam, false);
    renderManager.setForcedMaterial(preshadowMat);

    r.setFrameBuffer(shadowFB);
    r.clearBuffers(false, true, false);
    viewPort.getQueue().renderShadowQueue(ShadowMode.Cast, renderManager, shadowCam, true);
    r.setFrameBuffer(viewPort.getOutputFrameBuffer());

    renderManager.setForcedMaterial(null);
    renderManager.setCamera(viewCam, false);
  }
  public Vector3f onMove(Vector3f moveVec) {
    if (moveVec.equals(Vector3f.ZERO)) {
      return currentPos3d;
    }

    Vector3f newPos2d = new Vector3f(currentPos3d);
    newPos2d.addLocal(moveVec);
    newPos2d.setY(0);

    Vector3f currentPos2d = new Vector3f(currentPos3d);
    currentPos2d.setY(0);

    // Cell nextCell = navMesh.resolveMotionOnMesh(currentPos2d, currentCell, newPos2d, newPos2d);
    // currentCell = nextCell;
    newPos2d.setY(currentPos3d.getY());
    return newPos2d;
  }
  public static Mesh genNormalLines(Mesh mesh, float scale) {
    FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
    FloatBuffer normalBuffer = (FloatBuffer) mesh.getBuffer(Type.Normal).getData();

    ColorRGBA originColor = ColorRGBA.White;
    ColorRGBA normalColor = ColorRGBA.Blue;

    Mesh lineMesh = new Mesh();
    lineMesh.setMode(Mesh.Mode.Lines);

    Vector3f origin = new Vector3f();
    Vector3f point = new Vector3f();

    FloatBuffer lineVertex = BufferUtils.createFloatBuffer(vertexBuffer.limit() * 2);
    FloatBuffer lineColor = BufferUtils.createFloatBuffer(vertexBuffer.limit() / 3 * 4 * 2);

    for (int i = 0; i < vertexBuffer.limit() / 3; i++) {
      populateFromBuffer(origin, vertexBuffer, i);
      populateFromBuffer(point, normalBuffer, i);

      int index = i * 2;

      setInBuffer(origin, lineVertex, index);
      setInBuffer(originColor, lineColor, index);

      point.multLocal(scale);
      point.addLocal(origin);
      setInBuffer(point, lineVertex, index + 1);
      setInBuffer(normalColor, lineColor, index + 1);
    }

    lineMesh.setBuffer(Type.Position, 3, lineVertex);
    lineMesh.setBuffer(Type.Color, 4, lineColor);

    lineMesh.setStatic();
    // lineMesh.setInterleaved();
    return lineMesh;
  }
Пример #8
0
  private static Transform convertPositions(FloatBuffer input, BoundingBox bbox, Buffer output) {
    if (output.capacity() < input.capacity())
      throw new RuntimeException("Output must be at least as large as input!");

    Vector3f offset = bbox.getCenter().negate();
    Vector3f size = new Vector3f(bbox.getXExtent(), bbox.getYExtent(), bbox.getZExtent());
    size.multLocal(2);

    ShortBuffer sb = null;
    ByteBuffer bb = null;
    float dataTypeSize;
    float dataTypeOffset;
    if (output instanceof ShortBuffer) {
      sb = (ShortBuffer) output;
      dataTypeOffset = shortOff;
      dataTypeSize = shortSize;
    } else {
      bb = (ByteBuffer) output;
      dataTypeOffset = byteOff;
      dataTypeSize = byteSize;
    }
    Vector3f scale = new Vector3f();
    scale.set(dataTypeSize, dataTypeSize, dataTypeSize).divideLocal(size);

    Vector3f invScale = new Vector3f();
    invScale.set(size).divideLocal(dataTypeSize);

    offset.multLocal(scale);
    offset.addLocal(dataTypeOffset, dataTypeOffset, dataTypeOffset);

    // offset = (-modelOffset * shortSize)/modelSize + shortOff
    // scale = shortSize / modelSize

    input.clear();
    output.clear();
    Vector3f temp = new Vector3f();
    int vertexCount = input.capacity() / 3;
    for (int i = 0; i < vertexCount; i++) {
      BufferUtils.populateFromBuffer(temp, input, i);

      // offset and scale vector into -32768 ... 32767
      // or into -128 ... 127 if using bytes
      temp.multLocal(scale);
      temp.addLocal(offset);

      // quantize and store
      if (sb != null) {
        short v1 = (short) temp.getX();
        short v2 = (short) temp.getY();
        short v3 = (short) temp.getZ();
        sb.put(v1).put(v2).put(v3);
      } else {
        byte v1 = (byte) temp.getX();
        byte v2 = (byte) temp.getY();
        byte v3 = (byte) temp.getZ();
        bb.put(v1).put(v2).put(v3);
      }
    }

    Transform transform = new Transform();
    transform.setTranslation(offset.negate().multLocal(invScale));
    transform.setScale(invScale);
    return transform;
  }
  @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();
  }
Пример #10
0
    public Hallway(Vector3f start, float xi, float zi) {
      float x = start.getX() + xi;
      float z = start.getZ() + zi;
      float rng, dist;
      int len = 0;
      int spread = 0;
      int lenMax = FastMath.nextRandomInt(HALL_LENGTH_MIN, HALL_LENGTH_MAX);
      boolean b = false;
      // Make sure both xi and zi have an absolute value of 1:
      xi = A.sign(xi);
      zi = A.sign(zi);
      // Assign the first 2 corners:
      corners[0] =
          new Vector3f(
              (zi * (HALL_WIDTH - 1)) + x,
              start.getY(),
              (xi * (HALL_WIDTH - 1)) + z); // Bottom Left
      corners[1] =
          new Vector3f(
              (-zi * (HALL_WIDTH - 1)) + x,
              start.getY(),
              (-xi * (HALL_WIDTH - 1)) + z); // Bottom Right
      Vector3f left = corners[0].clone();
      Vector3f right = corners[1].clone();
      ArrayList<HallData> newHalls = new ArrayList(1);
      while (len <= lenMax) {
        if (world.get(left) != null && world.get(left).contains("h")) {
          b = true;
        }
        if (world.get(right) != null && world.get(right).contains("h")) {
          b = true;
        }
        // Check each of the spaces in this step for hallway:
        if (b) {
          right.addLocal(-xi, 0, -zi);
          left.addLocal(-xi, 0, -zi);
          break;
        }
        world.put(left.clone(), "h");
        world.put(right.add(zi, 0, xi), "h");
        world.put(right.clone(), "h");
        // Check distance & random to see if more hallways should be created:
        dist = left.distance(Vector3f.ZERO);
        rng = FastMath.nextRandomFloat();
        if (dist < HALL_MAX_RADIUS && spread > HALL_SPREAD && len < lenMax) {
          if (rng < 0.13f) {
            newHalls.add(new HallData(left.clone(), zi, xi));
            spread = 0;
          } else if (rng < 0.26f) {
            newHalls.add(new HallData(right.clone(), -zi, -xi));
            spread = 0;
          } else if (rng < 0.33f) {
            newHalls.add(new HallData(left.clone(), zi, xi));
            newHalls.add(new HallData(right.clone(), -zi, -xi));
            spread = 0;
          }
        }
        x += xi;
        z += zi;
        spread++;
        len++;
        left.addLocal(xi, 0, zi);
        right.addLocal(xi, 0, zi);
      }
      corners[2] = right.clone(); // Top Right
      corners[3] = left.clone(); // Top Left

      // Generate hallways:
      int j = 0;
      while (j < newHalls.size()) {
        hallways.add(new Hallway(newHalls.get(j).start, newHalls.get(j).xi, newHalls.get(j).zi));
        j++;
      }

      // Return if there's no hallway to generate (0 in size):
      float xs = FastMath.abs(corners[1].getX() - corners[3].getX()) + 1;
      float zs = FastMath.abs(corners[1].getZ() - corners[3].getZ()) + 1;
      if (Math.min(FastMath.abs(xs), FastMath.abs(zs)) < 1) {
        return;
      }

      // Generate the front wall:
      walls.add(new Wall(left.add(xi, 0, zi), -zi, -xi, HALL_WIDTH * 2 - 1));
      walls.add(new Wall(left.add(zi, 0, xi), -xi, -zi, len + 1));
      walls.add(new Wall(right.add(-zi, 0, -xi), -xi, -zi, len + 1));

      // Generate the actual floor:
      float xloc = (corners[3].getX() + corners[1].getX()) * 0.5f;
      float zloc = (corners[3].getZ() + corners[1].getZ()) * 0.5f;
      NPCManager.addNew("grunt", new Vector3f(xloc, start.getY(), zloc).mult(ZS).add(0, 5, 0));
      center = new Vector3f(xloc, start.getY() - 0.5f, zloc);
      floor = geoFloor(center, xs, zs, T.getMaterialPath("BC_Tex"), new Vector2f(zs, xs), true);
      map.add(floor);
    }
Пример #11
0
  /**
   * Updates the points array to contain the frustum corners of the given camera. The nearOverride
   * and farOverride variables can be used to override the camera's near/far values with own values.
   *
   * <p>TODO: Reduce creation of new vectors
   *
   * @param viewCam
   * @param nearOverride
   * @param farOverride
   */
  public static void updateFrustumPoints(
      Camera viewCam, float nearOverride, float farOverride, float scale, Vector3f[] points) {

    Vector3f pos = viewCam.getLocation();
    Vector3f dir = viewCam.getDirection();
    Vector3f up = viewCam.getUp();

    float depthHeightRatio = viewCam.getFrustumTop() / viewCam.getFrustumNear();
    float near = nearOverride;
    float far = farOverride;
    float ftop = viewCam.getFrustumTop();
    float fright = viewCam.getFrustumRight();
    float ratio = fright / ftop;

    float near_height;
    float near_width;
    float far_height;
    float far_width;

    if (viewCam.isParallelProjection()) {
      near_height = ftop;
      near_width = near_height * ratio;
      far_height = ftop;
      far_width = far_height * ratio;
    } else {
      near_height = depthHeightRatio * near;
      near_width = near_height * ratio;
      far_height = depthHeightRatio * far;
      far_width = far_height * ratio;
    }

    Vector3f right = dir.cross(up).normalizeLocal();

    Vector3f temp = new Vector3f();
    temp.set(dir).multLocal(far).addLocal(pos);
    Vector3f farCenter = temp.clone();
    temp.set(dir).multLocal(near).addLocal(pos);
    Vector3f nearCenter = temp.clone();

    Vector3f nearUp = temp.set(up).multLocal(near_height).clone();
    Vector3f farUp = temp.set(up).multLocal(far_height).clone();
    Vector3f nearRight = temp.set(right).multLocal(near_width).clone();
    Vector3f farRight = temp.set(right).multLocal(far_width).clone();

    points[0].set(nearCenter).subtractLocal(nearUp).subtractLocal(nearRight);
    points[1].set(nearCenter).addLocal(nearUp).subtractLocal(nearRight);
    points[2].set(nearCenter).addLocal(nearUp).addLocal(nearRight);
    points[3].set(nearCenter).subtractLocal(nearUp).addLocal(nearRight);

    points[4].set(farCenter).subtractLocal(farUp).subtractLocal(farRight);
    points[5].set(farCenter).addLocal(farUp).subtractLocal(farRight);
    points[6].set(farCenter).addLocal(farUp).addLocal(farRight);
    points[7].set(farCenter).subtractLocal(farUp).addLocal(farRight);

    if (scale != 1.0f) {
      // find center of frustum
      Vector3f center = new Vector3f();
      for (int i = 0; i < 8; i++) {
        center.addLocal(points[i]);
      }
      center.divideLocal(8f);

      Vector3f cDir = new Vector3f();
      for (int i = 0; i < 8; i++) {
        cDir.set(points[i]).subtractLocal(center);
        cDir.multLocal(scale - 1.0f);
        points[i].addLocal(cDir);
      }
    }
  }
Пример #12
0
  @Override
  public void simpleUpdate(float tpf) {
    for (Planet planet : planets) {
      planet.getGeom().rotate(0, 0, planet.getRotationSpeed() * tpf);
      planet.getPivot().rotate(0, planet.getTranslationSpeed() * tpf, 0);
    }

    for (Spatial spatial : explosions.getChildren()) {
      ParticleEmitter explosion = (ParticleEmitter) spatial;
      if (explosion.getNumVisibleParticles() < 1) {
        explosion.removeFromParent();
      }
    }

    Vector3f rotation = new Vector3f(0, 0, 0);
    if (left) {
      rotation.addLocal(0, 1, 0);
    }
    if (right) {
      rotation.addLocal(0, -1, 0);
    }
    if (up) {
      rotation.addLocal(1, 0, 0);
    }
    if (down) {
      rotation.addLocal(-1, 0, 0);
    }
    if (leftSide) {
      rotation.addLocal(0, 0, 1);
    }
    if (rightSide) {
      rotation.addLocal(0, 0, -1);
    }

    Vector3f transformed = new Vector3f(0, 0, 0);
    spaceship.getLocalRotation().mult(rotation, transformed);
    spaceship.getControl().setAngularVelocity(transformed);

    Vector3f movement = new Vector3f(0, 0, 0);
    if (moving) {
      spaceship.getWorldRotation().mult(new Vector3f(0, 0, -6), movement);
    }
    spaceship.getControl().setLinearVelocity(movement);

    bloom.setBloomIntensity(bloom.getBloomIntensity() + (bloomDirection * tpf / 8));
    if (bloom.getBloomIntensity() > 4) {
      bloomDirection = -1;
    }
    if (bloom.getBloomIntensity() < 2) {
      bloomDirection = 1;
    }

    Vector3f direction = spaceship.getRear().getWorldTranslation().subtract(cam.getLocation());
    float magnitude = direction.length();
    if (magnitude > 0) {
      cam.setLocation(
          cam.getLocation().add(direction.normalize().mult(tpf * magnitude * magnitude / 2)));
    }
    cam.lookAt(spaceship.getFront().getWorldTranslation(), Vector3f.UNIT_Y);

    for (Spatial spatial : asteroids.getChildren()) {
      if (spatial.getWorldTranslation().subtract(Vector3f.ZERO).length() > 200) {
        spatial.removeFromParent();
      }
    }

    if (Math.random() < 0.01 && asteroids.getChildren().size() < MAX_ASTEROIDS) {
      generateRandomAsteroid();
    }

    for (Spatial spatial : lasers.getChildren()) {
      Laser laser = (Laser) spatial;
      if (laser.getWorldTranslation().subtract(Vector3f.ZERO).length() > 200) {
        bap.getPhysicsSpace().remove(laser.getControl());
        laser.removeFromParent();
        continue;
      }
      laser.move(laser.getDirection().mult(laser.getSpeed()));
    }

    scoreText.setText("Score: " + score);
  }
Пример #13
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;
  }
  private static Mesh genTangentLines(Mesh mesh, float scale) {
    FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
    FloatBuffer normalBuffer = (FloatBuffer) mesh.getBuffer(Type.Normal).getData();
    FloatBuffer tangentBuffer = (FloatBuffer) mesh.getBuffer(Type.Tangent).getData();

    FloatBuffer binormalBuffer = null;
    if (mesh.getBuffer(Type.Binormal) != null) {
      binormalBuffer = (FloatBuffer) mesh.getBuffer(Type.Binormal).getData();
    }

    ColorRGBA originColor = ColorRGBA.White;
    ColorRGBA tangentColor = ColorRGBA.Red;
    ColorRGBA binormalColor = ColorRGBA.Green;
    ColorRGBA normalColor = ColorRGBA.Blue;

    Mesh lineMesh = new Mesh();
    lineMesh.setMode(Mesh.Mode.Lines);

    Vector3f origin = new Vector3f();
    Vector3f point = new Vector3f();
    Vector3f tangent = new Vector3f();
    Vector3f normal = new Vector3f();

    IntBuffer lineIndex = BufferUtils.createIntBuffer(vertexBuffer.limit() / 3 * 6);
    FloatBuffer lineVertex = BufferUtils.createFloatBuffer(vertexBuffer.limit() * 4);
    FloatBuffer lineColor = BufferUtils.createFloatBuffer(vertexBuffer.limit() / 3 * 4 * 4);

    boolean hasParity = mesh.getBuffer(Type.Tangent).getNumComponents() == 4;
    float tangentW = 1;

    for (int i = 0; i < vertexBuffer.limit() / 3; i++) {
      populateFromBuffer(origin, vertexBuffer, i);
      populateFromBuffer(normal, normalBuffer, i);

      if (hasParity) {
        tangent.x = tangentBuffer.get(i * 4);
        tangent.y = tangentBuffer.get(i * 4 + 1);
        tangent.z = tangentBuffer.get(i * 4 + 2);
        tangentW = tangentBuffer.get(i * 4 + 3);
      } else {
        populateFromBuffer(tangent, tangentBuffer, i);
      }

      int index = i * 4;

      int id = i * 6;
      lineIndex.put(id, index);
      lineIndex.put(id + 1, index + 1);
      lineIndex.put(id + 2, index);
      lineIndex.put(id + 3, index + 2);
      lineIndex.put(id + 4, index);
      lineIndex.put(id + 5, index + 3);

      setInBuffer(origin, lineVertex, index);
      setInBuffer(originColor, lineColor, index);

      point.set(tangent);
      point.multLocal(scale);
      point.addLocal(origin);
      setInBuffer(point, lineVertex, index + 1);
      setInBuffer(tangentColor, lineColor, index + 1);

      // wvBinormal = cross(wvNormal, wvTangent) * -inTangent.w

      if (binormalBuffer == null) {
        normal.cross(tangent, point);
        point.multLocal(-tangentW);
        point.normalizeLocal();
      } else {
        populateFromBuffer(point, binormalBuffer, i);
      }

      point.multLocal(scale);
      point.addLocal(origin);
      setInBuffer(point, lineVertex, index + 2);
      setInBuffer(binormalColor, lineColor, index + 2);

      point.set(normal);
      point.multLocal(scale);
      point.addLocal(origin);
      setInBuffer(point, lineVertex, index + 3);
      setInBuffer(normalColor, lineColor, index + 3);
    }

    lineMesh.setBuffer(Type.Index, 1, lineIndex);
    lineMesh.setBuffer(Type.Position, 3, lineVertex);
    lineMesh.setBuffer(Type.Color, 4, lineColor);

    lineMesh.setStatic();
    // lineMesh.setInterleaved();
    return lineMesh;
  }
  private static void processTriangleData(
      Mesh mesh, List<VertexData> vertices, boolean approxTangent, boolean splitMirrored) {
    ArrayList<VertexInfo> vertexMap = linkVertices(mesh, splitMirrored);

    FloatBuffer tangents = BufferUtils.createFloatBuffer(vertices.size() * 4);

    ColorRGBA[] cols = null;
    if (debug) {
      cols = new ColorRGBA[vertices.size()];
    }

    Vector3f tangent = new Vector3f();
    Vector3f binormal = new Vector3f();
    // Vector3f normal = new Vector3f();
    Vector3f givenNormal = new Vector3f();

    Vector3f tangentUnit = new Vector3f();
    Vector3f binormalUnit = new Vector3f();

    for (int k = 0; k < vertexMap.size(); k++) {
      float wCoord = -1;

      VertexInfo vertexInfo = vertexMap.get(k);

      givenNormal.set(vertexInfo.normal);
      givenNormal.normalizeLocal();

      TriangleData firstTriangle = vertices.get(vertexInfo.indices.get(0)).triangles.get(0);

      // check tangent and binormal consistency
      tangent.set(firstTriangle.tangent);
      tangent.normalizeLocal();
      binormal.set(firstTriangle.binormal);
      binormal.normalizeLocal();

      for (int i : vertexInfo.indices) {
        ArrayList<TriangleData> triangles = vertices.get(i).triangles;

        for (int j = 0; j < triangles.size(); j++) {
          TriangleData triangleData = triangles.get(j);

          tangentUnit.set(triangleData.tangent);
          tangentUnit.normalizeLocal();
          if (tangent.dot(tangentUnit) < toleranceDot) {
            // log.log(Level.WARNING,
            // "Angle between tangents exceeds tolerance "
            // + "for vertex {0}.", i);
            break;
          }

          if (!approxTangent) {
            binormalUnit.set(triangleData.binormal);
            binormalUnit.normalizeLocal();
            if (binormal.dot(binormalUnit) < toleranceDot) {
              // log.log(Level.WARNING,
              // "Angle between binormals exceeds tolerance "
              // + "for vertex {0}.", i);
              break;
            }
          }
        }
      }

      // find average tangent
      tangent.set(0, 0, 0);
      binormal.set(0, 0, 0);

      int triangleCount = 0;
      for (int i : vertexInfo.indices) {
        ArrayList<TriangleData> triangles = vertices.get(i).triangles;
        triangleCount += triangles.size();
        if (debug) {
          cols[i] = ColorRGBA.White;
        }

        for (int j = 0; j < triangles.size(); j++) {
          TriangleData triangleData = triangles.get(j);
          tangent.addLocal(triangleData.tangent);
          binormal.addLocal(triangleData.binormal);
        }
      }

      int blameVertex = vertexInfo.indices.get(0);

      if (tangent.length() < ZERO_TOLERANCE) {
        log.log(Level.WARNING, "Shared tangent is zero for vertex {0}.", blameVertex);
        // attempt to fix from binormal
        if (binormal.length() >= ZERO_TOLERANCE) {
          binormal.cross(givenNormal, tangent);
          tangent.normalizeLocal();
        } // if all fails use the tangent from the first triangle
        else {
          tangent.set(firstTriangle.tangent);
        }
      } else {
        tangent.divideLocal(triangleCount);
      }

      tangentUnit.set(tangent);
      tangentUnit.normalizeLocal();
      if (Math.abs(Math.abs(tangentUnit.dot(givenNormal)) - 1) < ZERO_TOLERANCE) {
        log.log(Level.WARNING, "Normal and tangent are parallel for vertex {0}.", blameVertex);
      }

      if (!approxTangent) {
        if (binormal.length() < ZERO_TOLERANCE) {
          log.log(Level.WARNING, "Shared binormal is zero for vertex {0}.", blameVertex);
          // attempt to fix from tangent
          if (tangent.length() >= ZERO_TOLERANCE) {
            givenNormal.cross(tangent, binormal);
            binormal.normalizeLocal();
          } // if all fails use the binormal from the first triangle
          else {
            binormal.set(firstTriangle.binormal);
          }
        } else {
          binormal.divideLocal(triangleCount);
        }

        binormalUnit.set(binormal);
        binormalUnit.normalizeLocal();
        if (Math.abs(Math.abs(binormalUnit.dot(givenNormal)) - 1) < ZERO_TOLERANCE) {
          log.log(Level.WARNING, "Normal and binormal are parallel for vertex {0}.", blameVertex);
        }

        if (Math.abs(Math.abs(binormalUnit.dot(tangentUnit)) - 1) < ZERO_TOLERANCE) {
          log.log(Level.WARNING, "Tangent and binormal are parallel for vertex {0}.", blameVertex);
        }
      }

      Vector3f finalTangent = new Vector3f();
      Vector3f tmp = new Vector3f();
      for (int i : vertexInfo.indices) {
        if (approxTangent) {
          // Gram-Schmidt orthogonalize
          finalTangent
              .set(tangent)
              .subtractLocal(tmp.set(givenNormal).multLocal(givenNormal.dot(tangent)));
          finalTangent.normalizeLocal();

          wCoord = tmp.set(givenNormal).crossLocal(tangent).dot(binormal) < 0f ? -1f : 1f;

          tangents.put((i * 4), finalTangent.x);
          tangents.put((i * 4) + 1, finalTangent.y);
          tangents.put((i * 4) + 2, finalTangent.z);
          tangents.put((i * 4) + 3, wCoord);
        } else {
          tangents.put((i * 4), tangent.x);
          tangents.put((i * 4) + 1, tangent.y);
          tangents.put((i * 4) + 2, tangent.z);
          tangents.put((i * 4) + 3, wCoord);

          // setInBuffer(binormal, binormals, i);
        }
      }
    }
    tangents.limit(tangents.capacity());
    // If the model already had a tangent buffer, replace it with the regenerated one
    mesh.clearBuffer(Type.Tangent);
    mesh.setBuffer(Type.Tangent, 4, tangents);

    if (mesh.isAnimated()) {
      mesh.clearBuffer(Type.BindPoseNormal);
      mesh.clearBuffer(Type.BindPosePosition);
      mesh.clearBuffer(Type.BindPoseTangent);
      mesh.generateBindPose(true);
    }

    if (debug) {
      writeColorBuffer(vertices, cols, mesh);
    }
    mesh.updateBound();
    mesh.updateCounts();
  }