예제 #1
0
  /**
   * Gets the point of collision between a BoundingSphere and a Ray.
   *
   * @param a
   * @param b
   * @return
   */
  public static Vector3 getCollision(BoundingSphere a, Ray b) {
    Vector3 m = b.origin.subtract(a.center);
    float e = m.dot(b.direction);
    float f = (float) (m.dot(m) - a.radius * a.radius);

    // Exit if r’s origin outside s (c > 0) and r pointing away from s (b > 0)
    if (f > 0.0f && e > 0.0f) {
      return null;
    }
    float discr = e * e - f;

    // A negative discriminant corresponds to ray missing sphere
    if (discr < 0.0f) {
      return null;
    }

    // Ray now found to intersect sphere, compute smallest t value of intersection
    float t = (float) (-e - MathHelper.sqrt(discr));

    // If t is negative, ray started inside sphere so clamp t to zero
    if (t < 0.0f) {
      t = 0.0f;
    }
    return b.origin.add(b.direction.multiply(t));
  }
예제 #2
0
 public void setBlockMaterial(int xx, int yy, int zz, BlockMaterial material, short data) {
   final Vector3 transformed = transform(xx, yy, zz);
   position
       .getWorld()
       .setBlockMaterial(
           transformed.getFloorX(),
           transformed.getFloorY(),
           transformed.getFloorZ(),
           material,
           data,
           null);
   if (material instanceof Directional) {
     final Directional directional = (Directional) material;
     final Block block = position.getWorld().getBlock(transformed);
     final BlockFace face = directional.getFacing(block);
     if (face != BlockFace.BOTTOM && face != BlockFace.TOP) {
       directional.setFacing(
           block, BlockFace.fromYaw(face.getDirection().getYaw() + rotation.getYaw()));
     }
   } else if (material instanceof Attachable) {
     final Attachable attachable = (Attachable) material;
     final Block block = position.getWorld().getBlock(transformed);
     final BlockFace face = attachable.getAttachedFace(block);
     if (face != BlockFace.BOTTOM && face != BlockFace.TOP) {
       attachable.setAttachedFace(
           block, BlockFace.fromYaw(face.getDirection().getYaw() + rotation.getYaw()), null);
     }
   }
 }
예제 #3
0
 public BlockMaterial getBlockMaterial(int xx, int yy, int zz) {
   final Vector3 transformed = transform(xx, yy, zz);
   return position
       .getWorld()
       .getBlockMaterial(
           transformed.getFloorX(), transformed.getFloorY(), transformed.getFloorZ());
 }
예제 #4
0
 @Override
 public int hashCode() {
   int hash = 5;
   hash = 89 * hash + (min != null ? min.hashCode() : 0);
   hash = 89 * hash + (max != null ? max.hashCode() : 0);
   return hash;
 }
예제 #5
0
 @Override
 public BoundingBox getBoundingBox() {
   final Vector3 rotatedMin = transform(0, 0, 0);
   final Vector3 rotatedMax = transform(4, 4, 4);
   return new BoundingBox(
       Vector3.min(rotatedMin, rotatedMax), Vector3.max(rotatedMin, rotatedMax));
 }
예제 #6
0
 /**
  * Gets the collision point between two BoundingBoxes.
  *
  * @param a
  * @param b
  * @return
  */
 public static Vector3 getCollision(BoundingBox a, BoundingBox b) {
   BoundingBox intersection = getIntersection(a, b);
   if (intersection == null) {
     return null;
   }
   Vector3 ret = new Vector3(intersection.min);
   ret.add(intersection.max);
   ret.multiply(0.5f);
   return ret;
 }
예제 #7
0
  @Override
  public boolean commitCuboid(CuboidBlockMaterialBuffer buffer, Cause<?> cause) {
    Vector3 base = buffer.getBase();
    int x = base.getFloorX();
    int y = base.getFloorY();
    int z = base.getFloorZ();
    SpoutChunk[][][] chunks = getChunks(x, y, z, buffer);

    return commitCuboid(chunks, buffer, cause);
  }
예제 #8
0
 public BlockFaces(BlockFace... blockfaces) {
   this.faces = blockfaces;
   byte mask = 0;
   Vector3 offsetc = new Vector3();
   for (BlockFace face : this.faces) {
     offsetc = offsetc.add(face.getOffset());
     mask |= face.getMask();
   }
   offset = offsetc;
   this.mask = mask;
 }
예제 #9
0
 private static byte getOffsetHash(Vector3 offset) {
   offset = offset.normalize();
   offset = offset.round();
   int x = offset.getFloorX();
   int y = offset.getFloorY();
   int z = offset.getFloorZ();
   x += 1;
   y += 1;
   z += 1;
   return (byte) (x | y << 2 | z << 4);
 }
예제 #10
0
  /**
   * Checks collision between a BoundingSphere and a Ray.
   *
   * @param a
   * @param b
   * @return
   */
  public static boolean checkCollision(BoundingSphere a, Ray b) {
    Vector3 m = b.origin.subtract(a.center);
    float e = m.dot(b.direction);
    float f = (float) (m.dot(m) - a.radius * a.radius);

    // Exit if r’s origin outside s (c > 0) and r pointing away from s (b > 0)
    if (f > 0.0f && e > 0.0f) {
      return false;
    }
    float discr = e * e - f;

    // A negative discriminant corresponds to ray missing sphere
    if (discr < 0.0f) {
      return false;
    }

    // Ray now found to intersect sphere
    return true;
  }
예제 #11
0
 @Override
 public void setAttachedFace(Block block, BlockFace attachedFace) {
   if (attachedFace == BlockFace.BOTTOM) {
     Source source = block.getSource();
     short data = 0;
     if (source instanceof Entity) {
       Vector3 direction =
           block.getPosition().subtract(((Entity) source).getTransform().getPosition());
       float rotation = direction.rotationTo(Vector3.RIGHT).getYaw();
       rotation = rotation / 360f * 16f;
       data = (short) rotation;
     }
     block.setMaterial(VanillaMaterials.SIGN_POST, data).queueUpdate(EffectRange.THIS);
   } else {
     // get the data for this face
     short data = (short) (BlockFaces.NSWE.indexOf(attachedFace, 0) + 2);
     block.setMaterial(VanillaMaterials.WALL_SIGN, data).queueUpdate(EffectRange.THIS);
   }
 }
예제 #12
0
 @Override
 public void queueChunkForGeneration(final Vector3 chunk) {
   final int rx = (chunk.getFloorX() >> Region.CHUNKS.BITS);
   final int ry = (chunk.getFloorY() >> Region.CHUNKS.BITS);
   final int rz = (chunk.getFloorZ() >> Region.CHUNKS.BITS);
   SpoutRegion region = getRegion(rx, ry, rz, LoadOption.NO_LOAD);
   if (region != null) {
     region.queueChunkForGeneration(chunk);
   } else {
     Spout.getScheduler()
         .scheduleSyncDelayedTask(
             this,
             new Runnable() {
               @Override
               public void run() {
                 SpoutRegion region = getRegion(rx, ry, rz, LoadOption.LOAD_GEN);
                 region.queueChunkForGeneration(chunk);
               }
             });
   }
 }
예제 #13
0
  private SpoutChunk[][][] getChunks(int x, int y, int z, CuboidBlockMaterialBuffer buffer) {
    Vector3 size = buffer.getSize();

    int startX = x;
    int startY = y;
    int startZ = z;

    int endX = x + size.getFloorX();
    int endY = y + size.getFloorY();
    int endZ = z + size.getFloorZ();

    Chunk start = getChunkFromBlock(startX, startY, startZ);
    Chunk end = getChunkFromBlock(endX - 1, endY - 1, endZ - 1);

    int chunkStartX = start.getX();
    int chunkStartY = start.getY();
    int chunkStartZ = start.getZ();

    int chunkEndX = end.getX();
    int chunkEndY = end.getY();
    int chunkEndZ = end.getZ();

    int chunkSizeX = chunkEndX - chunkStartX + 1;
    int chunkSizeY = chunkEndY - chunkStartY + 1;
    int chunkSizeZ = chunkEndZ - chunkStartZ + 1;

    SpoutChunk[][][] chunks = new SpoutChunk[chunkSizeX][chunkSizeY][chunkSizeZ];
    for (int dx = chunkStartX; dx <= chunkEndX; dx++) {
      for (int dy = chunkStartY; dy <= chunkEndY; dy++) {
        for (int dz = chunkStartZ; dz <= chunkEndZ; dz++) {
          SpoutChunk chunk = getChunk(dx, dy, dz, LoadOption.LOAD_GEN);
          if (chunk == null) {
            throw new IllegalStateException("Null chunk loaded with LoadOption.LOAD_GEN");
          }
          chunks[dx - chunkStartX][dy - chunkStartY][dz - chunkStartZ] = chunk;
        }
      }
    }
    return chunks;
  }
예제 #14
0
  protected boolean commitCuboid(
      SpoutChunk[][][] chunks, CuboidBlockMaterialBuffer buffer, Cause<?> cause) {

    Vector3 base = buffer.getBase();
    int x = base.getFloorX();
    int y = base.getFloorY();
    int z = base.getFloorZ();

    lockChunks(chunks);

    try {
      for (int dx = 0; dx < chunks.length; dx++) {
        SpoutChunk[][] subArray1 = chunks[dx];
        for (int dy = 0; dy < subArray1.length; dy++) {
          SpoutChunk[] subArray2 = subArray1[dy];
          for (int dz = 0; dz < subArray2.length; dz++) {
            if (!subArray2[dz].testCuboid(x, y, z, buffer)) {
              return false;
            }
          }
        }
      }

      // set
      for (int dx = 0; dx < chunks.length; dx++) {
        SpoutChunk[][] subArray1 = chunks[dx];
        for (int dy = 0; dy < subArray1.length; dy++) {
          SpoutChunk[] subArray2 = subArray1[dy];
          for (int dz = 0; dz < subArray2.length; dz++) {
            subArray2[dz].setCuboid(x, y, z, buffer, cause);
          }
        }
      }

      return true;
    } finally {
      unlockChunks(chunks);
    }
  }
예제 #15
0
  @Override
  public Point[] generatePoints(Point center, int number) {

    float angle = 0;
    float distance = 1;

    Point[] points = new Point[number];

    points[0] = center;

    for (int i = 1; i < number; i++) {
      distance = (float) Math.sqrt(i);

      Vector3 offset = Point.FORWARD.transform(MathHelper.rotateY(angle));
      offset = offset.multiply(distance).multiply(scaleRadius);

      points[i] = center.add(offset);

      angle += scaleCircumference * 360.0 / (Math.PI * distance);
    }

    return points;
  }
예제 #16
0
 public void placeObject(int xx, int yy, int zz, WorldGeneratorObject object) {
   final Vector3 transformed = transform(xx, yy, zz);
   if (object.canPlaceObject(
       position.getWorld(),
       transformed.getFloorX(),
       transformed.getFloorY(),
       transformed.getFloorZ())) {
     object.placeObject(
         position.getWorld(),
         transformed.getFloorX(),
         transformed.getFloorY(),
         transformed.getFloorZ());
   }
 }
예제 #17
0
  /**
   * Checks the collision between a BoundingSphere and a Segment.
   *
   * @param a
   * @param b
   * @return
   */
  public static boolean checkCollision(BoundingSphere a, Segment b) {
    Vector3 m = b.origin.subtract(a.center);
    Vector3 l = b.endpoint.subtract(b.origin);
    float lnorm = l.fastLength();
    Vector3 d = l.multiply(1f / lnorm);

    float e = m.dot(d);
    float f = (float) (m.dot(m) - a.radius * a.radius);

    // Exit if r’s origin outside s (c > 0) and r pointing away from s (b > 0)
    if (f > 0.0f && e > 0.0f) {
      return false;
    }
    float discr = e * e - f;

    // A negative discriminant corresponds to ray missing sphere
    if (discr < 0.0f) {
      return false;
    }

    // Check that the intersection is not past the segment
    return -e - MathHelper.sqrt(discr) <= lnorm;
  }
예제 #18
0
 public EntityVelocityMessage(int id, Vector3 velocity) {
   this(id, (int) velocity.getX(), (int) velocity.getY(), (int) velocity.getZ());
 }
예제 #19
0
파일: Plane.java 프로젝트: nallar/SpoutAPI
 public float distance(Vector3 b) {
   return b.subtract(point).dot(normal);
 }
예제 #20
0
파일: Plane.java 프로젝트: nallar/SpoutAPI
 public static Plane fromTwoVectors(Vector3 a, Vector3 b) {
   return new Plane(a, a.cross(b));
 }
예제 #21
0
  /**
   * Updates the list of chunks around the player.
   *
   * @param force Forces the update
   * @return True if the list was changed
   */
  public boolean updateNearbyChunkMeshes(boolean force) {
    if (world == null) {
      world = client.getDefaultWorld();
      if (world != null)
        System.out.println("World updated to " + world.getName() + "-" + world.getUID());
    }

    if (world == null) {
      try {
        Thread.sleep(5);
      } catch (InterruptedException e) {
      }
      return false;
    }

    int chunkViewDistance = client.getActivePlayer().getViewDistance() / 16;

    Point currentPos = client.getActivePlayer().getTransform().getPosition();

    int currentChunkX = currentPos.getChunkX();
    int currentChunkY = currentPos.getChunkY();
    int currentChunkZ = currentPos.getChunkZ();

    if (currentChunkX == lastChunkX
        && currentChunkY == lastChunkY
        && currentChunkZ == lastChunkZ
        && !force
        && !firstUpdate) {
      return false;
    }
    // just add all visible chunks

    if (chunkRenderers.size() == 0 || force) {
      chunkRenderers.clear();

      int cubeMinX = currentChunkX - chunkViewDistance;
      int cubeMinY = currentChunkY - chunkViewDistance;
      int cubeMinZ = currentChunkZ - chunkViewDistance;

      int cubeMaxX = currentChunkX + chunkViewDistance;
      int cubeMaxY = currentChunkY + chunkViewDistance;
      int cubeMaxZ = currentChunkZ + chunkViewDistance;

      Vector3 batchMin =
          ChunkMeshBatch.getBatchCoordinates(new Vector3(cubeMinX, cubeMinY, cubeMinZ));
      Vector3 batchMax =
          ChunkMeshBatch.getBatchCoordinates(new Vector3(cubeMaxX, cubeMaxY, cubeMaxZ));

      for (int x = batchMin.getFloorX(); x <= batchMax.getFloorX(); x++) {
        for (int y = batchMin.getFloorY(); y <= batchMax.getFloorY(); y++) {
          for (int z = batchMin.getFloorZ(); z <= batchMax.getFloorZ(); z++) {
            Vector3 chunkCoords = ChunkMeshBatch.getChunkCoordinates(new Vector3(x, y, z));
            ChunkMeshBatch batch =
                new ChunkMeshBatch(
                    material,
                    world,
                    chunkCoords.getFloorX(),
                    chunkCoords.getFloorY(),
                    chunkCoords.getFloorZ());
            addChunkMeshBatch(batch);
            batch.update();

            System.out.println(batch);
          }
        }
      }
    } else {
      Cube oldView =
          new Cube(
              new Point(
                  world,
                  lastChunkX - chunkViewDistance,
                  lastChunkY - chunkViewDistance,
                  lastChunkZ - chunkViewDistance),
              chunkViewDistance * 2);
      Cube newView =
          new Cube(
              new Point(
                  world,
                  currentChunkX - chunkViewDistance,
                  currentChunkY - chunkViewDistance,
                  currentChunkZ - chunkViewDistance),
              chunkViewDistance * 2);

      Vector3 min = oldView.getBase().min(newView.getBase());
      Vector3 max =
          oldView.getBase().add(oldView.getSize()).max(newView.getBase().add(newView.getSize()));

      // Shared area
      Vector3 ignoreMin = oldView.getBase().max(newView.getBase());
      Vector3 ignoreMax =
          oldView.getBase().add(oldView.getSize()).min(newView.getBase().add(newView.getSize()));
      Cuboid ignore = new Cuboid(new Point(ignoreMin, world), ignoreMax.subtract(ignoreMin));

      for (int x = min.getFloorX(); x < max.getFloorX(); x++) {
        for (int y = min.getFloorY(); y < max.getFloorY(); y++) {
          for (int z = min.getFloorZ(); z < max.getFloorZ(); z++) {
            Vector3 vec = new Vector3(x, y, z);
            if (ignore.contains(vec)) {
              continue;
            }

            Vector3 pos = ChunkMeshBatch.getChunkCoordinates(vec);

            if (oldView.contains(vec)) {
              ChunkMeshBatch c =
                  chunkRenderersByPosition.get(pos.getFloorX(), pos.getFloorY(), pos.getFloorZ());
              removeChunkMeshBatch(c);
              continue;
            }

            if (newView.contains(vec)) {
              ChunkMeshBatch c =
                  new ChunkMeshBatch(
                      material, world, pos.getFloorX(), pos.getFloorY(), pos.getFloorZ());
              addChunkMeshBatch(c);
              c.update();
            }
          }
        }
      }
    }

    firstUpdate = false;
    lastChunkX = currentChunkX;
    lastChunkY = currentChunkY;
    lastChunkZ = currentChunkZ;

    return true;
  }
예제 #22
0
 @Override
 public SpoutChunk getChunkFromBlock(Vector3 position, LoadOption loadopt) {
   return this.getChunkFromBlock(
       position.getFloorX(), position.getFloorY(), position.getFloorZ(), loadopt);
 }
예제 #23
0
 @Override
 public SpoutBlock getBlock(Vector3 position) {
   return this.getBlock(position.getX(), position.getY(), position.getZ());
 }
예제 #24
0
  /** Called when the tick is finished and collisions need to be resolved and move events fired */
  public void resolve() {
    if (Spout.debugMode()) {
      //	System.out.println("COLLISION DEBUGGING");
      //	System.out.println("Current Collision: " + this.collision.toString());
    }

    List<CollisionVolume> colliding =
        ((SpoutWorld) collisionPoint.getWorld()).getCollidingObject(this.collision);

    Vector3 offset = this.lastTransform.getPosition().subtract(collisionPoint);
    for (CollisionVolume box : colliding) {
      if (Spout.debugMode()) {
        //	System.out.println("Colliding box: " + box.toString());
      }
      Vector3 collision = this.collision.resolve(box);
      if (Spout.debugMode()) {
        //	System.out.println("Collision vector: " + collision.toString());
      }
      if (collision != null) {
        collision = collision.subtract(collisionPoint);
        if (Spout.debugMode()) {
          //	System.out.println("Collision point: " + collision.toString() + " Collision vector: " +
          // collision);
        }

        if (collision.getX() != 0F) {
          offset = new Vector3(collision.getX(), offset.getY(), offset.getZ());
        }
        if (collision.getY() != 0F) {
          offset = new Vector3(offset.getX(), collision.getY(), offset.getZ());
        }
        if (collision.getZ() != 0F) {
          offset = new Vector3(offset.getX(), offset.getY(), collision.getZ());
        }

        if (Spout.debugMode()) {
          //	System.out.println("Collision offset: " + offset.toString());
        }
        if (this.getCollision().getStrategy() == CollisionStrategy.SOLID
            && box.getStrategy() == CollisionStrategy.SOLID) {
          this.setPosition(collisionPoint.add(offset));
          if (Spout.debugMode()) {
            //	System.out.println("New Position: " + this.getPosition());
          }
        }

        controllerLive.get().onCollide(getWorld().getBlock(box.getPosition()));
      }
    }

    // Check to see if we should fire off a Move event
  }
예제 #25
0
 @Override
 public void getCuboid(CuboidBlockMaterialBuffer buffer) {
   Vector3 base = buffer.getBase();
   getCuboid(base.getFloorX(), base.getFloorY(), base.getFloorZ(), buffer);
 }
예제 #26
0
  /**
   * Checks if a bounding box and a line segment collide. Based off of
   * people.csail.mit.edu/amy/papers/box-jgt.ps
   *
   * <p>There must be a better way to do this.
   *
   * @param a
   * @param b
   * @return
   */
  public static boolean checkCollision(BoundingBox a, Segment b) {
    Vector3 box = a.max.subtract(a.min);
    Vector3 seg = b.endpoint.subtract(b.origin);
    Vector3 m = b.origin.add(b.endpoint).subtract(a.max).subtract(a.min);

    // Try world coordinate axes as separating axes
    float adx = Math.abs(seg.getX());
    if (Math.abs(m.getX()) > box.getX() + adx) {
      return false;
    }
    float ady = Math.abs(seg.getY());
    if (Math.abs(m.getY()) > box.getY() + ady) {
      return false;
    }
    float adz = Math.abs(seg.getZ());
    if (Math.abs(m.getZ()) > box.getZ() + adz) {
      return false;
    }

    // Add in an epsilon term to counteract arithmetic errors when segment is
    // (near) parallel to a coordinate axis (see text for detail)
    adx += MathHelper.FLT_EPSILON;
    ady += MathHelper.FLT_EPSILON;
    adz += MathHelper.FLT_EPSILON;

    // Try cross products of segment direction vector with coordinate axes
    if (Math.abs(m.getY() * seg.getZ() - m.getZ() * seg.getY())
        > box.getY() * adz + box.getZ() * ady) {
      return false;
    }
    if (Math.abs(m.getZ() * seg.getX() - m.getX() * seg.getZ())
        > box.getX() * adz + box.getZ() * adx) {
      return false;
    }

    if (Math.abs(m.getX() * seg.getY() - m.getY() * seg.getX())
        > box.getX() * ady + box.getY() * adx) {
      return false;
    }

    // No separating axis found; segment must be overlapping AABB
    return true;
  }
예제 #27
0
 public ExplosionMessage(Vector3 position, float radius, byte[] coordinates) {
   this(position.getX(), position.getY(), position.getZ(), radius, coordinates);
 }
예제 #28
0
 @Override
 public Block translate(Vector3 offset) {
   return this.translate((int) offset.getX(), (int) offset.getY(), (int) offset.getZ());
 }
예제 #29
0
 public static Vector3 getProtocolVelocity(Vector3 velocity) {
   final float x = velocity.getX() * 32000;
   final float y = velocity.getY() * 32000;
   final float z = velocity.getZ() * 32000;
   return new Vector3(x, y, z);
 }
예제 #30
0
 @Override
 public void setCuboid(CuboidBlockMaterialBuffer buffer, Cause<?> cause) {
   Vector3 base = buffer.getBase();
   setCuboid(base.getFloorX(), base.getFloorY(), base.getFloorZ(), buffer, cause);
 }