Use PhTree

This commit is contained in:
fullwall 2019-05-27 23:19:42 +08:00
parent 0e747889e7
commit 220fc1623d
2 changed files with 35 additions and 32 deletions

View File

@ -3,6 +3,7 @@ package net.citizensnpcs.trait.waypoint;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -15,12 +16,15 @@ import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.Vector;
import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import ch.ethz.globis.phtree.PhDistanceL;
import ch.ethz.globis.phtree.PhFilterDistance;
import ch.ethz.globis.phtree.PhTree;
import ch.ethz.globis.phtree.PhTree.PhKnnQuery;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.ai.Goal;
import net.citizensnpcs.api.ai.GoalSelector;
@ -36,10 +40,6 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.persistence.PersistenceLoader;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.api.util.prtree.DistanceResult;
import net.citizensnpcs.api.util.prtree.PRTree;
import net.citizensnpcs.api.util.prtree.Region3D;
import net.citizensnpcs.api.util.prtree.SimplePointND;
import net.citizensnpcs.trait.waypoint.WaypointProvider.EnumerableWaypointProvider;
import net.citizensnpcs.util.Messages;
import net.citizensnpcs.util.Util;
@ -56,7 +56,7 @@ public class GuidedWaypointProvider implements EnumerableWaypointProvider {
private final List<Waypoint> helpers = Lists.newArrayList();
private NPC npc;
private boolean paused;
private PRTree<Region3D<Waypoint>> tree = PRTree.create(new Region3D.Converter<Waypoint>(), 30);
private PhTree<Waypoint> tree = PhTree.create(3);
public void addHelperWaypoint(Waypoint helper) {
helpers.add(helper);
@ -229,16 +229,11 @@ public class GuidedWaypointProvider implements EnumerableWaypointProvider {
}
private void rebuildTree() {
tree = PRTree.create(new Region3D.Converter<Waypoint>(), 30);
tree.load(Lists.newArrayList(Iterables.transform(Iterables.<Waypoint> concat(available, helpers),
new Function<Waypoint, Region3D<Waypoint>>() {
@Override
public Region3D<Waypoint> apply(Waypoint arg0) {
Location loc = arg0.getLocation();
Vector root = new Vector(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
return new Region3D<Waypoint>(root, root, arg0);
}
})));
tree = PhTree.create(3);
for (Waypoint waypoint : waypoints()) {
tree.put(new long[] { waypoint.getLocation().getBlockX(), waypoint.getLocation().getBlockY(),
waypoint.getLocation().getBlockZ() }, waypoint);
}
}
@Override
@ -374,16 +369,19 @@ public class GuidedWaypointProvider implements EnumerableWaypointProvider {
@Override
public Iterable<AStarNode> getNeighbours() {
List<DistanceResult<Region3D<Waypoint>>> res = tree.nearestNeighbour(
Region3D.<Waypoint> distanceCalculator(), Region3D.<Waypoint> alwaysAcceptNodeFilter(), 15,
new SimplePointND(waypoint.getLocation().getBlockX(), waypoint.getLocation().getBlockY(),
waypoint.getLocation().getBlockZ()));
return Iterables.transform(res, new Function<DistanceResult<Region3D<Waypoint>>, AStarNode>() {
PhFilterDistance filter = new PhFilterDistance();
filter.set(new long[] { waypoint.getLocation().getBlockX(), waypoint.getLocation().getBlockY(),
waypoint.getLocation().getBlockZ() }, new PhDistanceL(), 15);
PhKnnQuery<Waypoint> res = tree.nearestNeighbour(0, null, filter, waypoint.getLocation().getBlockX(),
waypoint.getLocation().getBlockY(), waypoint.getLocation().getBlockZ());
List<AStarNode> resList = Lists.newArrayList();
res.forEachRemaining(new Consumer<Waypoint>() {
@Override
public AStarNode apply(DistanceResult<Region3D<Waypoint>> arg0) {
return new GuidedNode(GuidedNode.this, arg0.get().getData());
public void accept(Waypoint t) {
resList.add(new GuidedNode(null, t));
}
});
return resList;
}
@Override

View File

@ -19,6 +19,7 @@ import com.google.common.base.Supplier;
import com.google.common.collect.ForwardingList;
import com.google.common.collect.Lists;
import ch.ethz.globis.phtree.PhTreeSolid;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.ai.goals.WanderGoal;
import net.citizensnpcs.api.astar.pathfinder.MinecraftBlockExaminer;
@ -27,8 +28,6 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.api.util.cuboid.QuadCuboid;
import net.citizensnpcs.api.util.cuboid.QuadTree;
import net.citizensnpcs.util.Messages;
import net.citizensnpcs.util.Util;
@ -36,7 +35,8 @@ import net.citizensnpcs.util.Util;
* A wandering waypoint provider that wanders between either a box centered at the current location or inside a region
* defined by a list of boxes.
*/
public class WanderWaypointProvider implements WaypointProvider, Supplier<QuadTree>, Function<NPC, Location> {
public class WanderWaypointProvider
implements WaypointProvider, Supplier<PhTreeSolid<Boolean>>, Function<NPC, Location> {
private WanderGoal currentGoal;
@Persist
public int delay = -1;
@ -44,7 +44,7 @@ public class WanderWaypointProvider implements WaypointProvider, Supplier<QuadTr
private volatile boolean paused;
@Persist
private final List<Location> regionCentres = Lists.newArrayList();
private QuadTree tree = new QuadTree();
private PhTreeSolid<Boolean> tree = PhTreeSolid.create(3);
@Persist
public int xrange = DEFAULT_XRANGE;
@Persist
@ -162,12 +162,15 @@ public class WanderWaypointProvider implements WaypointProvider, Supplier<QuadTr
currentGoal.setDelay(delay);
}
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
@Override
public void run() {
Messaging.sendTr(sender, Messages.WANDER_WAYPOINTS_DELAY_SET, delay);
}
});
} catch (Exception e) {
} catch (
Exception e) {
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() {
@Override
public void run() {
@ -211,11 +214,12 @@ public class WanderWaypointProvider implements WaypointProvider, Supplier<QuadTr
regionCentres.size());
recalculateTree();
}
};
}
@Override
public QuadTree get() {
public PhTreeSolid<Boolean> get() {
return regionCentres.isEmpty() ? null : tree;
}
@ -250,10 +254,11 @@ public class WanderWaypointProvider implements WaypointProvider, Supplier<QuadTr
}
private void recalculateTree() {
tree = new QuadTree();
tree = PhTreeSolid.create(3);
for (Location loc : regionCentres) {
tree.insert(new QuadCuboid(loc.getBlockX() - xrange, loc.getBlockY() - yrange, loc.getBlockZ() - xrange,
loc.getBlockX() + xrange, loc.getBlockY() + yrange, loc.getBlockZ() + xrange));
long[] lower = { loc.getBlockX() - xrange, loc.getBlockY() - yrange, loc.getBlockZ() - xrange };
long[] upper = { loc.getBlockX() + xrange, loc.getBlockY() + yrange, loc.getBlockZ() + xrange };
tree.put(lower, upper, true);
}
}