/*
* Copyright 2012 Benjamin Glatzel <benjamin.glatzel@me.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.terasology.logic;
import org.terasology.logic.world.WorldProvider;
import org.terasology.model.structures.RayBlockIntersection;
import org.terasology.teraspout.TeraBlock;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author Immortius
*/
public class BlockRaytracer {
public static RayBlockIntersection.Intersection trace(Vector3d from, Vector3d direction, WorldProvider worldProvider) {
List<RayBlockIntersection.Intersection> inters = new ArrayList<RayBlockIntersection.Intersection>();
Vector3f pos = new Vector3f(from);
int blockPosX, blockPosY, blockPosZ;
for (int x = -3; x <= 3; x++) {
for (int y = -3; y <= 3; y++) {
for (int z = -3; z <= 3; z++) {
// Make sure the correct block positions are calculated relatively to the position of the player
blockPosX = (int) (pos.x + (pos.x >= 0 ? 0.5f : -0.5f)) + x;
blockPosY = (int) (pos.y + (pos.y >= 0 ? 0.5f : -0.5f)) + y;
blockPosZ = (int) (pos.z + (pos.z >= 0 ? 0.5f : -0.5f)) + z;
TeraBlock blockType = worldProvider.getBlock(blockPosX, blockPosY, blockPosZ);
// Ignore special blocks
if (blockType.isSelectionRayThrough()) {
continue;
}
// The ray originates from the "player's eye"
List<RayBlockIntersection.Intersection> iss = RayBlockIntersection.executeIntersection(worldProvider, blockPosX, blockPosY, blockPosZ, from, direction);
if (iss != null) {
inters.addAll(iss);
}
}
}
}
/**
* Calculated the closest intersection.
*/
if (inters.size() > 0) {
Collections.sort(inters);
return inters.get(0);
}
return null;
}
}