@Override
 public void getRandomPoint(Vector3f store) {
   do {
     store.x = (FastMath.nextRandomFloat() * 2f - 1f) * radius;
     store.y = (FastMath.nextRandomFloat() * 2f - 1f) * radius;
     store.z = (FastMath.nextRandomFloat() * 2f - 1f) * radius;
   } while (store.distance(center) > radius);
 }
Пример #2
0
  public Vector3f calculateForce(
      Vector3f location,
      Vector3f velocity,
      float collisionRadius,
      float speed,
      float turnSpeed,
      float tpf,
      List<Obstacle> obstacles) {
    float cautionRange = speed * 1.5f / turnSpeed;
    Line line = new Line(location, velocity.normalize());
    Plane plane = new Plane(velocity, 1);
    Vector3f closest = Vector3f.ZERO;
    float shortestDistance = -1;

    for (Obstacle obs : obstacles) {

      Vector3f target = obs.getLocation();

      Vector3f loc = target.subtract(location);

      // If the obstacle isn't ahead of him, just ignore it
      if (plane.whichSide(loc) != Side.Positive) {
        continue;
      }

      // Check if the target is inside the check range
      if (location.distance(target) <= collisionRadius + cautionRange + obs.getRadius()) {

        // Check if the target will collide with the source
        if (obs.distance(line) < collisionRadius) {

          float newDistance = obs.distance(location);
          // Store the closest target
          if (shortestDistance == -1 || newDistance < shortestDistance)
            shortestDistance = newDistance;
          closest = target;
        }
      }
    }

    // If any target was found
    if (shortestDistance != -1) {

      // Find in wich side the target is
      // To do that, we do a signed distance by
      // subtracing the location from the target
      // and the dot product between the line's normal
      float dot = closest.subtract(location).dot(line.getDirection().cross(Vector3f.UNIT_Y));

      if (dot <= 0) return velocity.cross(Vector3f.UNIT_Y);
      else return velocity.cross(Vector3f.UNIT_Y).negate();
    }

    // No target found, just return a zero value
    return Vector3f.ZERO;
  }
Пример #3
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;
  }
Пример #4
0
 private void computeLength() {
   int M = 16;
   Vector3f old = null;
   float length = 0;
   for (int i = 0; i <= M; ++i) {
     Vector3f v = interpolate(i / (float) M).position;
     if (old != null) {
       length += old.distance(v);
     }
     old = v;
   }
   stepLength = length;
 }
  public boolean calculateLod(
      TerrainPatch patch, List<Vector3f> locations, HashMap<String, UpdatedTerrainPatch> updates) {
    if (turnOffLod) {
      // set to full detail
      int prevLOD = patch.getLod();
      UpdatedTerrainPatch utp = updates.get(patch.getName());
      if (utp == null) {
        utp = new UpdatedTerrainPatch(patch);
        updates.put(utp.getName(), utp);
      }
      utp.setNewLod(0);
      utp.setPreviousLod(prevLOD);
      // utp.setReIndexNeeded(true);
      return true;
    }

    float[] lodEntropies = patch.getLodEntropies();
    float cameraConstant = getCameraConstant(cam, pixelError);

    Vector3f patchPos = getCenterLocation(patch);

    // vector from camera to patch
    // Vector3f toPatchDir = locations.get(0).subtract(patchPos).normalizeLocal();
    // float facing = cam.getDirection().dot(toPatchDir);
    float distance = patchPos.distance(locations.get(0));

    // go through each lod level to find the one we are in
    for (int i = 0; i <= patch.getMaxLod(); i++) {
      if (distance < lodEntropies[i] * cameraConstant || i == patch.getMaxLod()) {
        boolean reIndexNeeded = false;
        if (i != patch.getLod()) {
          reIndexNeeded = true;
          //                    System.out.println("lod change: "+lod+" > "+i+"    dist:
          // "+distance);
        }
        int prevLOD = patch.getLod();

        UpdatedTerrainPatch utp = updates.get(patch.getName());
        if (utp == null) {
          utp = new UpdatedTerrainPatch(patch); // save in here, do not update actual variables
          updates.put(utp.getName(), utp);
        }
        utp.setNewLod(i);
        utp.setPreviousLod(prevLOD);
        // utp.setReIndexNeeded(reIndexNeeded);
        return reIndexNeeded;
      }
    }

    return false;
  }
Пример #6
0
  private boolean maxDistanceExceeded(Vector3f vehiclePos) {
    // get box's position on xz-plane (ignore y component)
    Vector3f followBoxPosition = getPosition();
    followBoxPosition.setY(0);

    // get vehicle's position on xz-plane (ignore y component)
    Vector3f vehiclePosition = vehiclePos;
    vehiclePosition.setY(0);

    // distance between box and vehicle
    float currentDistance = followBoxPosition.distance(vehiclePosition);

    // report whether maximum distance is exceeded
    return currentDistance > maxDistance;
  }
Пример #7
0
 public void locationChecker(Monster monster) {
   Vector3f playerLocation = player.Model.getLocalTranslation();
   Vector3f monsterLocation = monster.Model.getLocalTranslation();
   float distance = playerLocation.distance(monsterLocation);
   Vector3f playerDirection = playerLocation.subtract(monsterLocation);
   monsterRotater(monster, playerDirection);
   if (distance < 3) {
     if (monster.attackDelay == 10) {
       monster.attackDelay = 0;
       monster.attack(monster.Model, player);
     } else {
       monster.attackDelay++;
     }
   } else {
     monster.anim.animChange("UnarmedRun", "RunAction", monster.Model);
   }
 }
Пример #8
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);
    }
Пример #9
0
  public final int intersectWhere(
      Ray r,
      Matrix4f worldMatrix,
      BIHTree tree,
      float sceneMin,
      float sceneMax,
      CollisionResults results) {

    TempVars vars = TempVars.get();
    ArrayList<BIHStackData> stack = vars.bihStack;
    stack.clear();

    //        float tHit = Float.POSITIVE_INFINITY;

    Vector3f o = vars.vect1.set(r.getOrigin());
    Vector3f d = vars.vect2.set(r.getDirection());

    Matrix4f inv = vars.tempMat4.set(worldMatrix).invertLocal();

    inv.mult(r.getOrigin(), r.getOrigin());

    // Fixes rotation collision bug
    inv.multNormal(r.getDirection(), r.getDirection());
    //        inv.multNormalAcross(r.getDirection(), r.getDirection());

    // this is a no-no: allocating float arrays for immediate use? blarny!
    /*float[] origins = {r.getOrigin().x,
        r.getOrigin().y,
        r.getOrigin().z};

    float[] invDirections = {1f / r.getDirection().x,
        1f / r.getDirection().y,
        1f / r.getDirection().z};*/

    r.getDirection().normalizeLocal();

    Vector3f v1 = vars.vect3, v2 = vars.vect4, v3 = vars.vect5;
    int cols = 0;

    // stack.add(new BIHStackData(this, sceneMin, sceneMax));
    vars.addStackData(this, sceneMin, sceneMax);
    stackloop:
    while (stack.size() > 0) {

      BIHStackData data = stack.remove(stack.size() - 1);
      BIHNode node = data.node;
      float tMin = data.min, tMax = data.max;

      if (tMax < tMin) {
        continue;
      }

      leafloop:
      while (node.axis != 3) { // while node is not a leaf
        int a = node.axis;

        // find the origin and direction value for the given axis
        float origin, invDirection;
        switch (a) {
          default:
          case 0: // x
            origin = r.getOrigin().x;
            invDirection = 1f / r.getDirection().x;
            break;
          case 1: // y
            origin = r.getOrigin().y;
            invDirection = 1f / r.getDirection().y;
            break;
          case 2: // z
            origin = r.getOrigin().z;
            invDirection = 1f / r.getDirection().z;
            break;
        }
        // float origin = origins[a];
        // float invDirection = invDirections[a];

        float tNearSplit, tFarSplit;
        BIHNode nearNode, farNode;

        tNearSplit = (node.leftPlane - origin) * invDirection;
        tFarSplit = (node.rightPlane - origin) * invDirection;
        nearNode = node.left;
        farNode = node.right;

        if (invDirection < 0) {
          float tmpSplit = tNearSplit;
          tNearSplit = tFarSplit;
          tFarSplit = tmpSplit;

          BIHNode tmpNode = nearNode;
          nearNode = farNode;
          farNode = tmpNode;
        }

        if (tMin > tNearSplit && tMax < tFarSplit) {
          continue stackloop;
        }

        if (tMin > tNearSplit) {
          tMin = max(tMin, tFarSplit);
          node = farNode;
        } else if (tMax < tFarSplit) {
          tMax = min(tMax, tNearSplit);
          node = nearNode;
        } else {
          // stack.add(new BIHStackData(farNode, max(tMin, tFarSplit), tMax));
          vars.addStackData(farNode, max(tMin, tFarSplit), tMax);
          tMax = min(tMax, tNearSplit);
          node = nearNode;
        }
      }

      //            if ( (node.rightIndex - node.leftIndex) > minTrisPerNode){
      //                // on demand subdivision
      //                node.subdivide();
      //                stack.add(new BIHStackData(node, tMin, tMax));
      //                continue stackloop;
      //            }

      // a leaf
      for (int i = node.leftIndex; i <= node.rightIndex; i++) {
        tree.getTriangle(i, v1, v2, v3);

        float t = r.intersects(v1, v2, v3);
        if (!Float.isInfinite(t)) {
          if (worldMatrix != null) {
            worldMatrix.mult(v1, v1);
            worldMatrix.mult(v2, v2);
            worldMatrix.mult(v3, v3);
            vars.ray.setOrigin(o);
            vars.ray.setDirection(d);
            float t_world = vars.ray.intersects(v1, v2, v3);
            t = t_world;
          }

          Vector3f contactPoint = vars.vect4.set(d).multLocal(t).addLocal(o);
          float worldSpaceDist = o.distance(contactPoint);

          // don't add the collision if it is longer than the ray length
          if (worldSpaceDist <= r.limit) {
            CollisionResult cr =
                results.addReusedCollision(
                    contactPoint.x, contactPoint.y, contactPoint.z, worldSpaceDist);
            if (cr.getContactNormal() == null) {
              cr.setContactNormal(Triangle.computeTriangleNormal(v1, v2, v3, null));
            } else {
              Triangle.computeTriangleNormal(v1, v2, v3, cr.getContactNormal());
            }
            cr.setTriangleIndex(tree.getTriangleIndex(i));
            cols++;
          }
        }
      }
    }
    vars.release();
    r.setOrigin(o);
    r.setDirection(d);

    return cols;
  }
Пример #10
0
  public float getReducedSpeed() {
    // return a temporarily reduced speed for the traffic car
    // in order to reach next (lower) speed limit in time
    float reducedSpeedInKmh = Float.POSITIVE_INFINITY;

    // if next way point with lower speed comes closer --> reduce speed
    int currentIndex = motionControl.getCurrentWayPoint();
    Waypoint nextWP = getNextWayPoint(currentIndex);
    if (nextWP != null) {
      // current way point (already passed)
      Waypoint curentWP = waypointList.get(currentIndex);

      // speed at current way point
      float currentSpeedInKmh = curentWP.getSpeed();
      float currentSpeed = currentSpeedInKmh / 3.6f;

      // speed at next way point
      float targetSpeedInKmh = nextWP.getSpeed();
      float targetSpeed = targetSpeedInKmh / 3.6f;

      // if speed at the next WP is lower than at the current WP --> brake vehicle
      if (targetSpeed < currentSpeed) {
        // % of traveled distance between current and next way point
        float wayPercentage = motionControl.getCurrentValue();

        // distance between current and next way point
        Vector3f currentPos = curentWP.getPosition().clone();
        currentPos.setY(0);
        Vector3f nextPos = nextWP.getPosition().clone();
        nextPos.setY(0);
        float distance = currentPos.distance(nextPos);

        // distance (in meters) between follow box and next way point
        float distanceToNextWP = (1 - wayPercentage) * distance;

        // speed difference in m/s between current WP's speed and next WP's speed
        float speedDifference = currentSpeed - targetSpeed;

        // compute the distance in front of the next WP at what the vehicle has to start
        // braking with 50% brake force in order to reach the next WP's (lower) speed in time.
        float deceleration50Percent = 50f * vehicle.getMaxBrakeForce() / vehicle.getMass();

        // time in seconds needed for braking process
        float time = speedDifference / deceleration50Percent;

        // distance covered during braking process
        float coveredDistance = 0.5f * -deceleration50Percent * time * time + currentSpeed * time;

        // start braking in x meters
        float distanceToBrakingPoint = distanceToNextWP - coveredDistance;

        if (distanceToBrakingPoint < 0) {
          // reduce speed linearly beginning from braking point

          // % of traveled distance between braking point and next way point
          float speedPercentage = -distanceToBrakingPoint / coveredDistance;

          //   0% traveled: reduced speed = currentSpeed
          //  50% traveled: reduced speed = (currentSpeed+targetSpeed)/2
          // 100% traveled: reduced speed = targetSpeed
          float reducedSpeed = currentSpeed - (speedPercentage * speedDifference);
          reducedSpeedInKmh = reducedSpeed * 3.6f;

          /*
          if(vehicle.getName().equals("car1"))
          {
          	float vehicleSpeedInKmh = vehicle.getLinearSpeedInKmh();
          	System.out.println(curentWP.getName() + " : " + speedPercentage + " : " +
          			reducedSpeedInKmh + " : " + vehicleSpeedInKmh + " : " + targetSpeedInKmh);
          }
          */
        }
      }
    }
    return reducedSpeedInKmh;
  }
 public float getDistanceToWaypoint() {
   return currentPos3d.distance(nextWaypoint.getPosition());
 }
Пример #12
0
 /**
  * Find the distance from the center of this Bounding Volume to the given point.
  *
  * @param point The point to get the distance to
  * @return distance
  */
 public final float distanceTo(Vector3f point) {
   return center.distance(point);
 }