From 45c65f4f78b4776b286fac08b75793881dc81ffe Mon Sep 17 00:00:00 2001 From: BananaPuncher714 Date: Tue, 17 Mar 2026 00:45:35 -0400 Subject: [PATCH] Refactor and add basic sparse mesh implementation --- .../bananapuncher714/mesh/test/MeshTest.java | 1 - .../mesh/command/CommandBase.java | 4 +- .../mesh/command/CommandOption.java | 4 +- .../mesh/command/CommandParameters.java | 2 +- .../mesh/command/CommandResult.java | 2 +- .../mesh/command/SplitCommand.java | 2 +- .../mesh/command/SubCommand.java | 10 +- .../command/executor/CommandExecutable.java | 4 +- .../executor/CommandExecutableMessage.java | 4 +- .../mesh/command/executor/package-info.java | 2 +- .../mesh/command/package-info.java | 2 +- .../command/validator/InputValidator.java | 2 +- .../validator/InputValidatorArguments.java | 2 +- .../validator/InputValidatorBoolean.java | 2 +- .../validator/InputValidatorChain.java | 2 +- .../validator/InputValidatorDouble.java | 2 +- .../command/validator/InputValidatorInt.java | 2 +- .../validator/InputValidatorPattern.java | 2 +- .../validator/InputValidatorPlayer.java | 2 +- .../validator/InputValidatorString.java | 2 +- .../mesh/command/validator/package-info.java | 2 +- .../validator/sender/SenderValidator.java | 2 +- .../sender/SenderValidatorNotPlayer.java | 2 +- .../sender/SenderValidatorPermission.java | 2 +- .../sender/SenderValidatorPlayer.java | 2 +- .../validator/sender/package-info.java | 2 +- .../mesh/environment/ChunkMeshCache.java | 5 + ...ment.java => McMeshEnvironmentPlugin.java} | 12 +- .../mesh/environment/MeshEnvironment.java | 894 ++++++++++++++++++ .../environment}/MiniePlugin.java | 209 ++-- .../environment}/objects/Aabb.java | 15 +- .../environment/objects/AbstractMesh.java | 62 ++ .../objects/BlockDataInformation.java | 25 + .../environment/objects/BlockDataType.java | 5 + .../objects/BlockDataTypeSet.java | 4 +- .../environment}/objects/ChunkLocation.java | 2 +- .../environment}/objects/ChunkMesh.java | 88 +- .../mesh/environment/objects/IndexedNGon.java | 19 + .../environment/objects/IndexedPolygon.java | 11 + .../environment/objects/IndexedTriangle.java | 44 + .../environment}/objects/MinecraftPlane.java | 6 +- .../mesh/environment/objects/PlaneMesh.java | 10 + .../mesh/environment/objects/SparseMesh.java | 38 + .../environment}/objects/VectorReference.java | 2 +- .../mesh/environment/util/BukkitUtil.java | 8 +- .../mesh/environment/util/ChunkMeshUtil.java | 2 +- .../mesh/environment/util/NmsUtil.java | 59 ++ .../minietest/ChunkMeshCache.java | 51 - .../bananapuncher714/minietest/MinieTest.java | 37 - .../minietest/objects/BlockDataType.java | 5 - .../minietest/objects/IndexedPolygon.java | 8 - .../minietest/objects/PlaneMesh.java | 10 - plugin/pom.xml | 2 +- 53 files changed, 1408 insertions(+), 292 deletions(-) create mode 100644 plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/ChunkMeshCache.java rename plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/{McMeshEnvironment.java => McMeshEnvironmentPlugin.java} (76%) create mode 100644 plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/MeshEnvironment.java rename plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/{minietest => mesh/environment}/MiniePlugin.java (90%) rename plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/{minietest => mesh/environment}/objects/Aabb.java (74%) create mode 100644 plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/AbstractMesh.java create mode 100644 plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/BlockDataInformation.java create mode 100644 plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/BlockDataType.java rename plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/{minietest => mesh/environment}/objects/BlockDataTypeSet.java (92%) rename plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/{minietest => mesh/environment}/objects/ChunkLocation.java (93%) rename plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/{minietest => mesh/environment}/objects/ChunkMesh.java (79%) create mode 100644 plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/IndexedNGon.java create mode 100644 plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/IndexedPolygon.java create mode 100644 plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/IndexedTriangle.java rename plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/{minietest => mesh/environment}/objects/MinecraftPlane.java (93%) create mode 100644 plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/PlaneMesh.java create mode 100644 plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/SparseMesh.java rename plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/{minietest => mesh/environment}/objects/VectorReference.java (92%) create mode 100644 plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/util/NmsUtil.java delete mode 100644 plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/ChunkMeshCache.java delete mode 100644 plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MinieTest.java delete mode 100644 plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/BlockDataType.java delete mode 100644 plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/IndexedPolygon.java delete mode 100644 plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/PlaneMesh.java diff --git a/application/visualizer/Test1/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/test/MeshTest.java b/application/visualizer/Test1/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/test/MeshTest.java index 78b2d46..ed05a7d 100644 --- a/application/visualizer/Test1/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/test/MeshTest.java +++ b/application/visualizer/Test1/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/test/MeshTest.java @@ -65,7 +65,6 @@ public class MeshTest { // Now that we have a bunch of bounding boxes, do whatever MeshBuilder builder = new MeshBuilder(); - int i = 0; for ( AABB box : boxes ) { for ( Facet facet : generateFacetsFor( box ) ) { builder.addFacet( facet ); diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/CommandBase.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/CommandBase.java index fd437ed..4dcf4cc 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/CommandBase.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/CommandBase.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command; import java.util.ArrayList; import java.util.Collection; @@ -8,7 +8,7 @@ import java.util.Set; import org.bukkit.command.PluginCommand; import org.bukkit.permissions.Permission; -import com.aaaaahhhhhhh.bananapuncher714.minietest.util.BukkitUtil; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.util.BukkitUtil; public class CommandBase { protected PluginCommand command; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/CommandOption.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/CommandOption.java index d4002ec..b82493f 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/CommandOption.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/CommandOption.java @@ -1,8 +1,8 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command; import org.bukkit.command.CommandSender; -import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.executor.CommandExecutable; +import com.aaaaahhhhhhh.bananapuncher714.mesh.command.executor.CommandExecutable; public class CommandOption { protected CommandExecutable exe; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/CommandParameters.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/CommandParameters.java index 43f793d..ce3556a 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/CommandParameters.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/CommandParameters.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command; import java.util.ArrayList; import java.util.List; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/CommandResult.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/CommandResult.java index f336253..862bfc7 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/CommandResult.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/CommandResult.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command; import java.util.ArrayList; import java.util.Collection; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/SplitCommand.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/SplitCommand.java index 5de8199..1081cd2 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/SplitCommand.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/SplitCommand.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command; public class SplitCommand { protected String[] input; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/SubCommand.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/SubCommand.java index fc0f7d3..61dfc06 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/SubCommand.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/SubCommand.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command; import java.util.ArrayList; import java.util.Arrays; @@ -13,10 +13,10 @@ import org.bukkit.command.CommandSender; import org.bukkit.command.PluginCommand; import org.bukkit.util.StringUtil; -import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.executor.CommandExecutable; -import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator.InputValidator; -import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator.InputValidatorString; -import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator.sender.SenderValidator; +import com.aaaaahhhhhhh.bananapuncher714.mesh.command.executor.CommandExecutable; +import com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator.InputValidator; +import com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator.InputValidatorString; +import com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator.sender.SenderValidator; /** * A build and run command framework for automatic tab completions and easy branching. diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/executor/CommandExecutable.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/executor/CommandExecutable.java index 3b1fba8..6b06662 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/executor/CommandExecutable.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/executor/CommandExecutable.java @@ -1,8 +1,8 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.executor; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command.executor; import org.bukkit.command.CommandSender; -import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.CommandParameters; +import com.aaaaahhhhhhh.bananapuncher714.mesh.command.CommandParameters; public interface CommandExecutable { void execute( CommandSender sender, String[] args, CommandParameters params ); diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/executor/CommandExecutableMessage.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/executor/CommandExecutableMessage.java index 01beafe..3cf5a9d 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/executor/CommandExecutableMessage.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/executor/CommandExecutableMessage.java @@ -1,8 +1,8 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.executor; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command.executor; import org.bukkit.command.CommandSender; -import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.CommandParameters; +import com.aaaaahhhhhhh.bananapuncher714.mesh.command.CommandParameters; public class CommandExecutableMessage implements CommandExecutable { protected String message; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/executor/package-info.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/executor/package-info.java index b217062..5cb086e 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/executor/package-info.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/executor/package-info.java @@ -5,4 +5,4 @@ * @author BananaPuncher714 * */ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.executor; \ No newline at end of file +package com.aaaaahhhhhhh.bananapuncher714.mesh.command.executor; \ No newline at end of file diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/package-info.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/package-info.java index 54f1b5c..d6ae2db 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/package-info.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/package-info.java @@ -3,4 +3,4 @@ * * @author BananaPuncher714 */ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command; \ No newline at end of file +package com.aaaaahhhhhhh.bananapuncher714.mesh.command; \ No newline at end of file diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidator.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidator.java index e05b583..5fa8aad 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidator.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidator.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator; import java.util.Collection; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorArguments.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorArguments.java index 0bda58e..2319d0c 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorArguments.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorArguments.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator; import java.util.Collection; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorBoolean.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorBoolean.java index 0907529..ee6ba3b 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorBoolean.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorBoolean.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator; import java.util.Collection; import java.util.HashSet; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorChain.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorChain.java index d271bb9..d7d5592 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorChain.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorChain.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator; import java.util.ArrayList; import java.util.Collection; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorDouble.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorDouble.java index e2f29ff..d2579b3 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorDouble.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorDouble.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator; import java.util.Collection; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorInt.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorInt.java index 0d13483..03f1ea1 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorInt.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorInt.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator; import java.util.Collection; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorPattern.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorPattern.java index 103575c..8ac9b0b 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorPattern.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorPattern.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator; import java.util.Collection; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorPlayer.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorPlayer.java index e6a31d7..b6ca3a5 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorPlayer.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorPlayer.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator; import java.util.Collection; import java.util.HashSet; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorString.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorString.java index 6723516..bfa74a6 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorString.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/InputValidatorString.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator; import java.util.Collection; import java.util.HashSet; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/package-info.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/package-info.java index 051b321..b6eda8e 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/package-info.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/package-info.java @@ -5,4 +5,4 @@ * @author BananaPuncher714 * */ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator; \ No newline at end of file +package com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator; \ No newline at end of file diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/SenderValidator.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/SenderValidator.java index 585e568..479b8eb 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/SenderValidator.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/SenderValidator.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator.sender; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator.sender; import org.bukkit.command.CommandSender; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/SenderValidatorNotPlayer.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/SenderValidatorNotPlayer.java index 9b903d3..0080d3f 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/SenderValidatorNotPlayer.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/SenderValidatorNotPlayer.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator.sender; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator.sender; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/SenderValidatorPermission.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/SenderValidatorPermission.java index 6e3fac9..3dc4ec2 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/SenderValidatorPermission.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/SenderValidatorPermission.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator.sender; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator.sender; import java.util.HashSet; import java.util.Set; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/SenderValidatorPlayer.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/SenderValidatorPlayer.java index d731229..71cdf66 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/SenderValidatorPlayer.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/SenderValidatorPlayer.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator.sender; +package com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator.sender; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/package-info.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/package-info.java index fe40a20..d6f1d98 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/package-info.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/command/validator/sender/package-info.java @@ -5,4 +5,4 @@ * @author BananaPuncher714 * */ -package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator.sender; \ No newline at end of file +package com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator.sender; \ No newline at end of file diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/ChunkMeshCache.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/ChunkMeshCache.java new file mode 100644 index 0000000..3dc561d --- /dev/null +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/ChunkMeshCache.java @@ -0,0 +1,5 @@ +package com.aaaaahhhhhhh.bananapuncher714.mesh.environment; + +public class ChunkMeshCache { + +} diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/McMeshEnvironment.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/McMeshEnvironmentPlugin.java similarity index 76% rename from plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/McMeshEnvironment.java rename to plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/McMeshEnvironmentPlugin.java index 97eef30..0d4db5b 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/McMeshEnvironment.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/McMeshEnvironmentPlugin.java @@ -1,12 +1,17 @@ package com.aaaaahhhhhhh.bananapuncher714.mesh.environment; import java.io.File; +import java.util.logging.Level; +import org.apache.commons.lang.SystemUtils; +import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.util.FileUtil; +import com.jme3.bullet.PhysicsSpace; +import com.jme3.bullet.objects.PhysicsRigidBody; -public class McMeshEnvironment extends JavaPlugin { +public class McMeshEnvironmentPlugin extends JavaPlugin { @Override public void onEnable() { FileUtil.saveToFile( getResource( "native/windows/x86_64/bulletjme.dll" ), new File( getDataFolder() + "/lib", "bulletjme.dll" ), false ); @@ -17,6 +22,11 @@ public class McMeshEnvironment extends JavaPlugin { Bukkit.getPluginManager().disablePlugin( this ); return; } + + // Don't log anything + PhysicsSpace.logger.setLevel( Level.WARNING ); + PhysicsSpace.loggerC.setLevel( Level.WARNING ); + PhysicsRigidBody.logger2.setLevel( Level.WARNING ); } private final boolean loadNativeLibraries() { diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/MeshEnvironment.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/MeshEnvironment.java new file mode 100644 index 0000000..8bb0c90 --- /dev/null +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/MeshEnvironment.java @@ -0,0 +1,894 @@ +package com.aaaaahhhhhhh.bananapuncher714.mesh.environment; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.world.ChunkLoadEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitTask; +import org.bukkit.util.BoundingBox; +import org.bukkit.util.Vector; + +import com.aaaaahhhhhhh.bananapuncher714.mesh.algorithm.Mesh; +import com.aaaaahhhhhhh.bananapuncher714.mesh.algorithm.Point; +import com.aaaaahhhhhhh.bananapuncher714.mesh.algorithm.Polygon; +import com.aaaaahhhhhhh.bananapuncher714.mesh.algorithm.region.simple.RegionRuleWinding; +import com.aaaaahhhhhhh.bananapuncher714.mesh.algorithm.region.simple.RegionSimple; +import com.aaaaahhhhhhh.bananapuncher714.mesh.algorithm.region.simple.RegionSimple.GluWindingRule; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.AbstractMesh; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.BlockDataInformation; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.BlockDataType; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.ChunkLocation; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.ChunkMesh; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.IndexedPolygon; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.IndexedTriangle; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.MinecraftPlane; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.MinecraftPlane.PlaneAxis; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.PlaneMesh; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.SparseMesh; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.VectorReference; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.util.ChunkMeshUtil; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.util.NmsUtil; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.util.NmsUtil.BlockShapeType; +import com.jme3.bullet.collision.shapes.MeshCollisionShape; +import com.jme3.bullet.collision.shapes.infos.IndexedMesh; +import com.jme3.bullet.objects.PhysicsBody; +import com.jme3.bullet.objects.PhysicsRigidBody; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; + +public class MeshEnvironment { + private JavaPlugin plugin; + private File cacheDirectory; + + private Map< ChunkLocation, ChunkMesh > chunkMeshes; + + private Listener eventListener = new Listener() { + @EventHandler + private void onChunkLoad( ChunkLoadEvent event ) { + // TODO Queue chunk load + loadOrGenerateMesh( event.getChunk() ); + } + + @EventHandler + private void onChunkUnload( ChunkUnloadEvent event ) { + // TODO Queue chunk unload + if ( event.getWorld().getName().equalsIgnoreCase( "world" ) ) { + final ChunkLocation loc = new ChunkLocation( event.getChunk() ); + if ( chunks.containsKey( loc ) ) { + space.removeCollisionObject( chunks.get( loc ) ); + chunks.remove( loc ); + } + + final ChunkMesh mesh = chunkMeshes.remove( loc ); + if ( mesh != null ) { + saveMesh( loc, mesh ); + } + } + } + + final Map< ChunkLocation, Collection< Location > > updateLocations = new TreeMap< ChunkLocation, Collection< Location > >(); + final BukkitTask task = Bukkit.getScheduler().runTaskTimer( plugin, () -> { + final Collection< ChunkLocation > locations = new ArrayDeque< ChunkLocation >(); + updateLocations.entrySet().stream().forEach( e -> { + final Collection< Location > locs = update( e.getValue() ); + e.getValue().removeAll( locs ); + if ( !locs.isEmpty() ) { + locations.add( e.getKey() ); + } + } ); + + if ( !locations.isEmpty() ) { + space.activateAll( true ); + } + + updateLocations.values().removeIf( c -> c.isEmpty() ); + }, 1, 1 ); + final Function< ChunkLocation, Collection< Location > > getLocationFor = c -> { + Collection< Location > locations = updateLocations.get( c ); + if ( locations == null ) { + locations = new HashSet< Location >(); + updateLocations.put( c, locations ); + } + return locations; + }; + + @EventHandler( priority = EventPriority.MONITOR ) + private void onBlockUpdateEvent( final BlockPhysicsEvent event ) { + final ChunkLocation chunkLocation = new ChunkLocation( event.getBlock().getChunk() ); + getLocationFor.apply( chunkLocation ).add( event.getBlock().getLocation() ); + } + }; + + public MeshEnvironment( JavaPlugin plugin, File cacheDirectory ) { + this.plugin = plugin; + this.cacheDirectory = cacheDirectory; + } + + public void activate() { + Bukkit.getPluginManager().registerEvents( eventListener, plugin ); + } + + public void deactivate() { + HandlerList.unregisterAll( eventListener ); + } + + private void loadOrGenerateMesh( final Chunk chunk ) { + final ChunkLocation location = new ChunkLocation( chunk ); + + final ChunkMesh mesh = loadMesh( location ); + if ( mesh == null ) { + generateMesh( chunk ); + } else { + // Save our chunk mesh + chunkMeshes.put( location, mesh ); + } + } + + private ChunkMesh loadMesh( final ChunkLocation location ) { + final File file = new File( cacheDirectory, "meshes/" + location.getWorldName() + "/" + location.getX() + "/" + location.getZ() + ".cmesh" ); + if ( file.exists() ) { + try { + final byte[] data = Files.readAllBytes( file.toPath() ); + final ChunkMesh mesh = ChunkMeshUtil.deserialize( data ); + + return mesh; + } catch ( IOException e ) { + e.printStackTrace(); + } + } + return null; + } + + private void saveMesh( final ChunkLocation location, final ChunkMesh mesh ) { + final File file = new File( cacheDirectory, "meshes/" + location.getWorldName() + "/" + location.getX() + "/" + location.getZ() + ".cmesh" ); + file.getParentFile().mkdirs(); + + final byte[] data = ChunkMeshUtil.serialize( mesh ); + + try { + Files.write( file.toPath(), data, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE, StandardOpenOption.WRITE ); + } catch ( IOException e ) { + e.printStackTrace(); + } + } + + private SparseMesh generateSpareMesh( World world, Collection< Vector > locations ) { + final long start = System.currentTimeMillis(); + + boolean set = false; + Vector min; + Vector max; + + for ( Vector v : locations ) { + if ( !set ) { + set = true; + + min = v.toBlockVector(); + max = v.toBlockVector(); + } else { + min = Vector.getMinimum( min, v.toBlockVector() ); + max = Vector.getMaximum( max, v.toBlockVector() ); + } + } + + final SparseMesh sparseMesh = new SparseMesh( min, max ); + final Map< MinecraftPlane, Collection< Polygon > > polygons = new TreeMap< MinecraftPlane, Collection< Polygon > >(); + + { + final Function< MinecraftPlane, Collection< Polygon > > getPolygons = p -> { + Collection< Polygon > polygonCollection = polygons.get( p ); + if ( polygonCollection == null ) { + polygonCollection = new ArrayDeque< Polygon >(); + polygons.put( p, polygonCollection ); + } + return polygonCollection; + }; + + for ( final Vector location : locations ) { + final Block block = world.getBlockAt( location.getBlockX(), location.getBlockY(), location.getBlockZ() ); + + if ( !( block.isEmpty() && block.isLiquid() ) ) { + final BlockData data = block.getBlockData(); + final Location loc = block.getLocation(); + + // Start the box at 0, 0, 0 + final BoundingBox[] boundingBoxes = NmsUtil.getShape( data, loc, BlockShapeType.COLLISION_SHAPE ).e().stream().map( aabb -> new BoundingBox( aabb.a, aabb.b, aabb.c, aabb.d, aabb.e, aabb.f ) ).toArray( BoundingBox[]::new ); + + final BlockDataInformation information = new BlockDataInformation( data ); + + if ( boundingBoxes.length == 0 ) { + // No bounding box + information.type = BlockDataType.NONE; + } else if ( boundingBoxes.length == 1 && boundingBoxes[ 0 ].getVolume() == 1 ) { + // Solid + information.type = BlockDataType.SOLID; + } else { + information.type = BlockDataType.COMPLEX; + // Complex bounding shape + + // Add the voxel shape to the chunk mesh + for ( final BoundingBox aabb : boundingBoxes ) { + final double minX = aabb.getMinX() + loc.getBlockX() - min.getBlockX(); + final double minY = aabb.getMinY() + loc.getBlockY() - min.getBlockY(); + final double minZ = aabb.getMinZ() + loc.getBlockZ() - min.getBlockZ(); + final double maxX = aabb.getMaxX() + loc.getBlockX() - min.getBlockX(); + final double maxY = aabb.getMaxY() + loc.getBlockY() - min.getBlockY(); + final double maxZ = aabb.getMaxZ() + loc.getBlockZ() - min.getBlockZ(); + + final Polygon xPoly = new Polygon( Arrays.asList( + new Point( minY, minZ ), + new Point( minY, maxZ ), + new Point( maxY, maxZ ), + new Point( maxY, minZ ) + ) ); + final Polygon yPoly = new Polygon( Arrays.asList( + new Point( minX, minZ ), + new Point( minX, maxZ ), + new Point( maxX, maxZ ), + new Point( maxX, minZ ) + ) ); + final Polygon zPoly = new Polygon( Arrays.asList( + new Point( minX, minY ), + new Point( minX, maxY ), + new Point( maxX, maxY ), + new Point( maxX, minY ) + ) ); + + getPolygons.apply( new MinecraftPlane( PlaneAxis.X, minX ) ).add( xPoly ); + getPolygons.apply( new MinecraftPlane( PlaneAxis.X, maxX ) ).add( xPoly ); + getPolygons.apply( new MinecraftPlane( PlaneAxis.Y, minY ) ).add( yPoly ); + getPolygons.apply( new MinecraftPlane( PlaneAxis.Y, maxY ) ).add( yPoly ); + getPolygons.apply( new MinecraftPlane( PlaneAxis.Z, minZ ) ).add( zPoly ); + getPolygons.apply( new MinecraftPlane( PlaneAxis.Z, maxZ ) ).add( zPoly ); + } + + information.boundingBoxes = boundingBoxes; + sparseMesh.setBlockDataInformationFor( information, loc.toVector().subtract( min ) ); + } + } + } + + // Now generate facets for each solid block based on if the side they are on is visible + for ( final Vector location : locations ) { + final Vector blockVector = location.toBlockVector().subtract( min ); + final BlockDataInformation info = sparseMesh.getBlockDataInformationFor( blockVector ); + if ( info != null ) { + if ( info.type == BlockDataType.SOLID ) { + final Polygon xPoly = new Polygon( Arrays.asList( + new Point( blockVector.getY(), blockVector.getZ() ), + new Point( blockVector.getY(), blockVector.getZ() + 1 ), + new Point( blockVector.getY() + 1, blockVector.getZ() + 1 ), + new Point( blockVector.getY() + 1, blockVector.getZ() ) + ) ); + final Polygon yPoly = new Polygon( Arrays.asList( + new Point( blockVector.getX(), blockVector.getZ() ), + new Point( blockVector.getX(), blockVector.getZ() + 1 ), + new Point( blockVector.getX() + 1, blockVector.getZ() + 1 ), + new Point( blockVector.getX() + 1, blockVector.getZ() ) + ) ); + final Polygon zPoly = new Polygon( Arrays.asList( + new Point( blockVector.getX(), blockVector.getY() ), + new Point( blockVector.getX(), blockVector.getY() + 1 ), + new Point( blockVector.getX() + 1, blockVector.getY() + 1 ), + new Point( blockVector.getX() + 1, blockVector.getY() ) + ) ); + + BlockDataInformation adjacent; + if ( ( adjacent = sparseMesh.getBlockDataInformationFor( blockVector.clone().subtract( new Vector( 0, 1, 0 ) ) ) ) == null || adjacent.type != BlockDataType.SOLID ) { + getPolygons.apply( new MinecraftPlane( PlaneAxis.Y, blockVector.getY() ) ).add( yPoly ); + } + + if ( ( adjacent = sparseMesh.getBlockDataInformationFor( blockVector.clone().add( new Vector( 0, 1, 0 ) ) ) ) == null || adjacent.type != BlockDataType.SOLID ) { + getPolygons.apply( new MinecraftPlane( PlaneAxis.Y, blockVector.getY() + 1 ) ).add( yPoly ); + } + + if ( ( adjacent = sparseMesh.getBlockDataInformationFor( blockVector.clone().subtract( new Vector( 0, 0, 1 ) ) ) ) == null || adjacent.type != BlockDataType.SOLID ) { + getPolygons.apply( new MinecraftPlane( PlaneAxis.Z, blockVector.getZ() ) ).add( zPoly ); + } + + if ( ( adjacent = sparseMesh.getBlockDataInformationFor( blockVector.clone().add( new Vector( 0, 0, 1 ) ) ) ) == null || adjacent.type != BlockDataType.SOLID ) { + getPolygons.apply( new MinecraftPlane( PlaneAxis.Z, blockVector.getZ() + 1 ) ).add( zPoly ); + } + + if ( ( adjacent = sparseMesh.getBlockDataInformationFor( blockVector.clone().subtract( new Vector( 1, 0, 0 ) ) ) ) == null || adjacent.type != BlockDataType.SOLID ) { + getPolygons.apply( new MinecraftPlane( PlaneAxis.X, blockVector.getX() ) ).add( xPoly ); + } + + if ( ( adjacent = sparseMesh.getBlockDataInformationFor( blockVector.clone().add( new Vector( 1, 0, 0 ) ) ) ) == null || adjacent.type != BlockDataType.SOLID ) { + getPolygons.apply( new MinecraftPlane( PlaneAxis.X, blockVector.getX() + 1 ) ).add( xPoly ); + } + } + } else { + // Shouldn't be null btw + } + } + } + + // Mesh the data and get the output + final MeshResult meshResult = generateMeshFrom( polygons ); + + sparseMesh.planes = meshResult.meshes; + sparseMesh.pointReferences = meshResult.points; + + // DONE + + return sparseMesh; + } + + private void generateMesh( final Chunk chunk ) { + final long start = System.currentTimeMillis(); + final World world = chunk.getWorld(); + + final ChunkLocation chunkLocation = new ChunkLocation( chunk ); + final int worldMinHeight = world.getMinHeight(); + final int worldMaxHeight = world.getMaxHeight(); + final int worldHeight = worldMaxHeight - worldMinHeight; + + final ChunkMesh chunkMesh = new ChunkMesh( new BoundingBox( 0, 0, 0, 16, worldHeight, 16 ) ); + final Map< MinecraftPlane, Collection< Polygon > > polygons = new TreeMap< MinecraftPlane, Collection< Polygon > >(); + + { + final Function< MinecraftPlane, Collection< Polygon > > getPolygons = p -> { + Collection< Polygon > polygonCollection = polygons.get( p ); + if ( polygonCollection == null ) { + polygonCollection = new ArrayDeque< Polygon >(); + polygons.put( p, polygonCollection ); + } + return polygonCollection; + }; + + // When we would have inserted each facet, instead, find or create the + // corresponding plane, and add directly. + // Also, create a chunk mesh and populate the structs + for ( int y = worldMinHeight; y < worldMaxHeight; ++y ) { + final int relY = y - worldMinHeight; + final int yIndex = relY << 8; + for ( int z = 0; z < 16; ++z ) { + final int zIndex = yIndex + ( z << 4 ); + for ( int x = 0; x < 16; ++x ) { + final int index = zIndex + x; + final Block block = chunk.getBlock( x, y, z ); + if ( !( block.isEmpty() && block.isLiquid() ) ) { + final BlockData data = block.getBlockData(); + final Location loc = block.getLocation(); + + // Start the box at 0, 0, 0 + final BoundingBox[] boundingBoxes = NmsUtil.getShape( data, loc, BlockShapeType.COLLISION_SHAPE ).e().stream().map( aabb -> new BoundingBox( aabb.a, aabb.b, aabb.c, aabb.d, aabb.e, aabb.f ) ).toArray( BoundingBox[]::new ); + + if ( boundingBoxes.length == 0 ) { + // No bounding box + chunkMesh.setType( index, BlockDataType.NONE ); + } else if ( boundingBoxes.length == 1 && boundingBoxes[ 0 ].getVolume() == 1 ) { + // Solid + chunkMesh.setType( index, BlockDataType.SOLID ); + } else { + chunkMesh.setType( index, BlockDataType.COMPLEX ); + // Complex bounding shape + + // Only store the old block data if we know it is not empty or solid!! + chunkMesh.setData( index, data ); + + // Add the voxel shape to the chunk mesh + for ( final BoundingBox aabb : boundingBoxes ) { + final double minX = aabb.getMinX() + x; + final double minY = aabb.getMinY() + relY; + final double minZ = aabb.getMinZ() + z; + final double maxX = aabb.getMaxX() + x; + final double maxY = aabb.getMaxY() + relY; + final double maxZ = aabb.getMaxZ() + z; + + final Polygon xPoly = new Polygon( Arrays.asList( + new Point( minY, minZ ), + new Point( minY, maxZ ), + new Point( maxY, maxZ ), + new Point( maxY, minZ ) + ) ); + final Polygon yPoly = new Polygon( Arrays.asList( + new Point( minX, minZ ), + new Point( minX, maxZ ), + new Point( maxX, maxZ ), + new Point( maxX, minZ ) + ) ); + final Polygon zPoly = new Polygon( Arrays.asList( + new Point( minX, minY ), + new Point( minX, maxY ), + new Point( maxX, maxY ), + new Point( maxX, minY ) + ) ); + + getPolygons.apply( new MinecraftPlane( PlaneAxis.X, minX ) ).add( xPoly ); + getPolygons.apply( new MinecraftPlane( PlaneAxis.X, maxX ) ).add( xPoly ); + getPolygons.apply( new MinecraftPlane( PlaneAxis.Y, minY ) ).add( yPoly ); + getPolygons.apply( new MinecraftPlane( PlaneAxis.Y, maxY ) ).add( yPoly ); + getPolygons.apply( new MinecraftPlane( PlaneAxis.Z, minZ ) ).add( zPoly ); + getPolygons.apply( new MinecraftPlane( PlaneAxis.Z, maxZ ) ).add( zPoly ); + } + + chunkMesh.setBoxes( index, boundingBoxes ); + } + } else { + chunkMesh.setType( index, BlockDataType.NONE ); + } + } + } + } + + // Now generate facets for each solid block based on if the side they are on is visible + for ( int y = 0; y < worldHeight; ++y ) { + final int yIndex = y << 8; + for ( int z = 0; z < 16; ++z ) { + final int zIndex = z << 4; + for ( int x = 0; x < 16; ++x ) { + final int index = yIndex + zIndex + x; + if ( chunkMesh.getType( index ) == BlockDataType.SOLID ) { + final Polygon xPoly = new Polygon( Arrays.asList( + new Point( y, z ), + new Point( y, z + 1 ), + new Point( y + 1, z + 1 ), + new Point( y + 1, z ) + ) ); + final Polygon yPoly = new Polygon( Arrays.asList( + new Point( x, z ), + new Point( x, z + 1 ), + new Point( x + 1, z + 1 ), + new Point( x + 1, z ) + ) ); + final Polygon zPoly = new Polygon( Arrays.asList( + new Point( x, y ), + new Point( x, y + 1 ), + new Point( x + 1, y + 1 ), + new Point( x + 1, y ) + ) ); + + // Check each face + if ( y == 0 || chunkMesh.getType( index - 256 ) != BlockDataType.SOLID ) { + getPolygons.apply( new MinecraftPlane( PlaneAxis.Y, y ) ).add( yPoly ); + } + + if ( y == worldHeight - 1 || chunkMesh.getType( index + 256 ) != BlockDataType.SOLID ) { + getPolygons.apply( new MinecraftPlane( PlaneAxis.Y, y + 1 ) ).add( yPoly ); + } + + if ( z == 0 || chunkMesh.getType( index - 16 ) != BlockDataType.SOLID ) { + getPolygons.apply( new MinecraftPlane( PlaneAxis.Z, z ) ).add( zPoly ); + } + + if ( z == 15 || chunkMesh.getType( index + 16 ) != BlockDataType.SOLID ) { + getPolygons.apply( new MinecraftPlane( PlaneAxis.Z, z + 1 ) ).add( zPoly ); + } + + if ( x == 0 || chunkMesh.getType( index - 1 ) != BlockDataType.SOLID ) { + getPolygons.apply( new MinecraftPlane( PlaneAxis.X, x ) ).add( xPoly ); + } + + if ( x == 15 || chunkMesh.getType( index + 1 ) != BlockDataType.SOLID ) { + getPolygons.apply( new MinecraftPlane( PlaneAxis.X, x + 1 ) ).add( xPoly ); + } + } + } + } + } + } + + Bukkit.getScheduler().runTaskAsynchronously( plugin, () -> { + // Mesh the data and get the output + final MeshResult meshResult = generateMeshFrom( polygons ); + + chunkMesh.planes = meshResult.meshes; + chunkMesh.pointReferences = meshResult.points; + + // DONE + + // Now, create a physics object from the chunk mesh + final IndexedMesh nativeMesh = chunkMesh.toIndexedMesh(); + // Enable quantized AABB compression... hopefully that doesn't mess with the accuracy or anything... + final MeshCollisionShape mesh = new MeshCollisionShape( true, nativeMesh ); + + // Create a rigid body + PhysicsRigidBody rigid = new PhysicsRigidBody( mesh, PhysicsBody.massForStatic ); + rigid.setPhysicsLocation( new Vector3f( chunk.getX() << 4, world.getMinHeight(), chunk.getZ() << 4 ) ); + rigid.setPhysicsRotation( new Quaternion( 0, 0, 0, 1 ) ); + rigid.setKinematic( false ); + + Bukkit.getScheduler().runTask( plugin, () -> { + // Save our chunk mesh + chunkMeshes.put( chunkLocation, chunkMesh ); + + space.addCollisionObject( rigid ); + + PhysicsRigidBody old = chunks.put( new ChunkLocation( chunk ), rigid ); + if ( old != null ) { + getLogger().warning( "Old rigid body found!" ); + space.remove( old ); + } + + final long time = System.currentTimeMillis() - start; +// getLogger().info( "Took " + time + "ms to mesh chunk " + chunk.getX() + ", " + chunk.getZ() + " into " + mesh.countMeshVertices() + " vertices and " + mesh.countMeshTriangles() + " triangles" ); + } ); + } ); + } + + private Collection< Location > update( final AbstractMesh mesh, final Collection< Location > locations ) { + if ( locations.isEmpty() ) { + return Collections.emptySet(); + } + + final World world = locations.iterator().next().getWorld(); + + final Collection< Location > canRemove = new ArrayDeque< Location >(); + // Check each location + final Map< MinecraftPlane, Collection< Polygon > > polygons = new TreeMap< MinecraftPlane, Collection< Polygon > >(); + final Function< MinecraftPlane, Collection< Polygon > > getPolygons = p -> { + Collection< Polygon > polygonCollection = polygons.get( p ); + if ( polygonCollection == null ) { + polygonCollection = new ArrayDeque< Polygon >(); + polygons.put( p, polygonCollection ); + } + return polygonCollection; + }; + + final BiFunction< List< BoundingBox >, BoundingBox[], Boolean > isEqual = ( a, b ) -> { + if ( a.size() == b.length ) { + for ( int i = 0; i < b.length; ++i ) { + final BoundingBox b1 = a.get( i ); + final BoundingBox b2 = b[ i ]; + + if ( !b1.equals( b2 ) ) { + return false; + } + } + } + + return true; + }; + + for ( final Location location : locations ) { + final BlockData data = location.getBlock().getBlockData(); + + // Defer moving piston updates until another tick when it's done moving + if ( data.getMaterial() == Material.MOVING_PISTON ) { + continue; + } + + final Vector position = location.toVector().subtract( mesh.getMinimumCorner() ); + final BlockDataInformation information = mesh.getBlockDataInformationFor( position ); + if ( information != null ) { + canRemove.add( location ); + if ( information.isBlockData( data ) ) { + // Ignore if the block data has not changed + continue; + } else { + final List< BoundingBox > boxes = NmsUtil.getShape( data, location, BlockShapeType.COLLISION_SHAPE ).e().stream() + .map( aabb -> new BoundingBox( aabb.a, aabb.b, aabb.c, aabb.d, aabb.e, aabb.f ) ).collect( Collectors.toList() ); + final BlockDataType oldType = information.type; + final BoundingBox[] otherBoxes = information.boundingBoxes; + if ( boxes.size() == 0 ) { + if ( oldType == BlockDataType.NONE ) { + continue; + } + + BlockDataInformation newInfo = new BlockDataInformation( data ); + newInfo.type = BlockDataType.NONE; + newInfo.boundingBoxes = null; + + mesh.setBlockDataInformationFor( newInfo, position ); + } else if ( boxes.size() == 1 && boxes.get( 0 ).getVolume() == 1 ) { + if ( oldType == BlockDataType.SOLID ) { + continue; + } + + BlockDataInformation newInfo = new BlockDataInformation( data ); + newInfo.type = BlockDataType.SOLID; + newInfo.boundingBoxes = null; + + mesh.setBlockDataInformationFor( newInfo, position ); + } else { + if ( otherBoxes != null && isEqual.apply( boxes, otherBoxes ) ) { + continue; + } + + BlockDataInformation newInfo = new BlockDataInformation( data ); + newInfo.type = BlockDataType.COMPLEX; + newInfo.boundingBoxes = boxes.toArray( BoundingBox[]::new ); + + mesh.setBlockDataInformationFor( newInfo, position ); + } + + if ( oldType == BlockDataType.SOLID ) { + boxes.add( new BoundingBox( 0, 0, 0, 1, 1, 1 ) ); + } else if ( oldType == BlockDataType.COMPLEX ) { + if ( otherBoxes == null || otherBoxes.length == 0 ) { + throw new IllegalStateException( "Complex shape but no bounding boxes!" ); + } + + for ( final BoundingBox box : otherBoxes ) { + boxes.add( box ); + } + } + + // Add the voxel shape to the chunk mesh + for ( final BoundingBox aabb : boxes ) { + final double minX = aabb.getMinX() + position.getX(); + final double minY = aabb.getMinY() + position.getY(); + final double minZ = aabb.getMinZ() + position.getZ(); + final double maxX = aabb.getMaxX() + position.getX(); + final double maxY = aabb.getMaxY() + position.getY(); + final double maxZ = aabb.getMaxZ() + position.getZ(); + + final Polygon xPoly = new Polygon( Arrays.asList( + new Point( minY, minZ ), + new Point( minY, maxZ ), + new Point( maxY, maxZ ), + new Point( maxY, minZ ) + ) ); + final Polygon yPoly = new Polygon( Arrays.asList( + new Point( minX, minZ ), + new Point( minX, maxZ ), + new Point( maxX, maxZ ), + new Point( maxX, minZ ) + ) ); + final Polygon zPoly = new Polygon( Arrays.asList( + new Point( minX, minY ), + new Point( minX, maxY ), + new Point( maxX, maxY ), + new Point( maxX, minY ) + ) ); + + getPolygons.apply( new MinecraftPlane( PlaneAxis.X, minX ) ).add( xPoly ); + getPolygons.apply( new MinecraftPlane( PlaneAxis.X, maxX ) ).add( xPoly ); + getPolygons.apply( new MinecraftPlane( PlaneAxis.Y, minY ) ).add( yPoly ); + getPolygons.apply( new MinecraftPlane( PlaneAxis.Y, maxY ) ).add( yPoly ); + getPolygons.apply( new MinecraftPlane( PlaneAxis.Z, minZ ) ).add( zPoly ); + getPolygons.apply( new MinecraftPlane( PlaneAxis.Z, maxZ ) ).add( zPoly ); + } + } + } + } + + // No polygons found... which means nothing changed + if ( polygons.isEmpty() ) { + return canRemove; + } + + final Map< MinecraftPlane, Mesh< RegionSimple > > meshMap = new HashMap< MinecraftPlane, Mesh< RegionSimple > >(); + + // Now mesh the blocks asynchronously and combine, then do the bare minimum to regenerate the chunk mesh + for ( final Entry< MinecraftPlane, Collection< Polygon > > entry : polygons.entrySet() ) { + final MinecraftPlane plane = entry.getKey(); + final PlaneMesh planeMesh = mesh.planes.remove( plane ); + final Mesh< RegionSimple > mesher = new Mesh< RegionSimple >( () -> new RegionSimple( GluWindingRule.ODD ) ); + + if ( planeMesh != null ) { + // Reset all indexed polygons(triangles) for this plane + for ( final IndexedTriangle poly : planeMesh.completedPolygons ) { + poly.getPoints().parallelStream().forEach( p -> --p.referenceCount ); + } + + // Add all polygons that were previously generated + for ( final Polygon polygon : planeMesh.generatedRegions ) { + mesher.addPolygon( polygon, RegionRuleWinding.CLOCKWISE ); + } + } + for ( final Polygon polygon : entry.getValue() ) { + mesher.addPolygon( polygon, RegionRuleWinding.CLOCKWISE ); + } + + meshMap.put( plane, mesher ); + } + + // Mesh each plane + final Map< MinecraftPlane, CompleteMesh > triangles = meshMap.entrySet().parallelStream().collect( Collectors.toConcurrentMap( e -> e.getKey(), e -> new CompleteMesh( e.getKey(), e.getValue() ) ) ); + + for ( final Entry< MinecraftPlane, CompleteMesh > entry : triangles.entrySet() ) { + final MinecraftPlane plane = entry.getKey(); + final CompleteMesh completeMesh = entry.getValue(); + final Collection< Polygon > tris = completeMesh.triangles; + final Mesh< RegionSimple > mesher = completeMesh.mesh; + + // Ignore any planes that are empty + if ( !tris.isEmpty() ) { + final PlaneMesh newMesh = new PlaneMesh(); + newMesh.completedPolygons = new ArrayList< IndexedTriangle >(); + for ( final Polygon tri : tris ) { + final IndexedTriangle newPoly = new IndexedTriangle(); + for ( int i = 0; i < tri.getPoints().size() && i < 3; ++i ) { + final Point point = tri.getPoints().get( i ); + final Vector vert = plane.convert( point ); + + // Find an existing vertex reference if one exists + final VectorReference tempRef = new VectorReference( vert ); + + VectorReference ref = null; + final VectorReference upperRef = mesh.pointReferences.ceiling( tempRef ); + if ( upperRef != null && upperRef.vector.distanceSquared( vert ) < 1e-8 ) { + ref = upperRef; + } else { + final VectorReference lowerRef = mesh.pointReferences.floor( tempRef ); + if ( lowerRef != null && lowerRef.vector.distanceSquared( vert ) < 1e-8 ) { + ref = lowerRef; + } + } + + if ( ref == null ) { + ref = tempRef; + ref.referenceCount = 1; + mesh.pointReferences.add( ref ); + } else { + ++ref.referenceCount; + } + + switch ( i ) { + case 0: + newPoly.setPoint1( ref ); + break; + case 1: + newPoly.setPoint2( ref ); + break; + case 2: + newPoly.setPoint3( ref ); + break; + default: + // Should never be here! + } + } + newMesh.completedPolygons.add( newPoly ); + } + + // Save the generated regions as an intermediary step so we can re-use them later + newMesh.generatedRegions = mesher.getPolygons(); + + mesh.planes.put( plane, newMesh ); + } + } + + // Remove all vector references that have a reference count of 0 + mesh.pointReferences.removeIf( v -> v.referenceCount <= 0 ); + + // DONE + + // Now, create a physics object from the chunk mesh + final IndexedMesh nativeMesh = chunkMesh.toIndexedMesh(); + // Enable quantized AABB compression... hopefully that doesn't mess with the accuracy or anything... + final MeshCollisionShape mesh = new MeshCollisionShape( true, nativeMesh ); + + // Create a rigid body + PhysicsRigidBody rigid = new PhysicsRigidBody( mesh, PhysicsBody.massForStatic ); + rigid.setPhysicsLocation( new Vector3f( chunkLocation.getX() << 4, world.getMinHeight(), chunkLocation.getZ() << 4 ) ); + rigid.setPhysicsRotation( new Quaternion( 0, 0, 0, 1 ) ); + rigid.setKinematic( false ); + + return canRemove; + } + + private MeshResult generateMeshFrom( final Map< MinecraftPlane, Collection< Polygon > > polygons ) { + final Map< MinecraftPlane, Mesh< RegionSimple > > meshMap = new HashMap< MinecraftPlane, Mesh< RegionSimple > >(); + for ( final Entry< MinecraftPlane, Collection< Polygon > > entry : polygons.entrySet() ) { + final MinecraftPlane plane = entry.getKey(); + final Mesh< RegionSimple > mesh = new Mesh< RegionSimple >( () -> new RegionSimple( GluWindingRule.ODD ) ); + for ( final Polygon polygon : entry.getValue() ) { + mesh.addPolygon( polygon, RegionRuleWinding.CLOCKWISE ); + } + meshMap.put( plane, mesh ); + } + + // Mesh each plane + final Map< MinecraftPlane, CompleteMesh > triangles = meshMap.entrySet().parallelStream().collect( Collectors.toConcurrentMap( e -> e.getKey(), e -> new CompleteMesh( e.getKey(), e.getValue() ) ) ); + + // Construct a series of indexed polygons + final TreeSet< VectorReference > vertices = new TreeSet< VectorReference >(); + + final MeshResult result = new MeshResult(); + for ( final Entry< MinecraftPlane, CompleteMesh > entry : triangles.entrySet() ) { + final MinecraftPlane plane = entry.getKey(); + final CompleteMesh completeMesh = entry.getValue(); + final Collection< Polygon > tris = completeMesh.triangles; + final Mesh< RegionSimple > mesh = completeMesh.mesh; + + // Ignore any planes that are empty + if ( !tris.isEmpty() ) { + final PlaneMesh newMesh = new PlaneMesh(); + newMesh.completedPolygons = new ArrayList< IndexedTriangle >(); + for ( final Polygon tri : tris ) { + final IndexedTriangle newPoly = new IndexedTriangle(); + for ( int i = 0; i < tri.getPoints().size() && i < 3; ++i ) { + final Point point = tri.getPoints().get( i ); + final Vector vert = plane.convert( point ); + + final VectorReference tempRef = new VectorReference( vert ); + // Find an existing vertex reference if one exists + VectorReference ref = null; + if ( ref == null ) { + final VectorReference upperRef = vertices.ceiling( tempRef ); + if ( upperRef != null && upperRef.vector.distanceSquared( vert ) < 1e-8 ) { + ref = upperRef; + } else { + final VectorReference lowerRef = vertices.floor( tempRef ); + if ( lowerRef != null && lowerRef.vector.distanceSquared( vert ) < 1e-8 ) { + ref = lowerRef; + } + } + } + + if ( ref == null ) { + ref = tempRef; + ref.referenceCount = 1; + vertices.add( ref ); + } else { + ++ref.referenceCount; + } + + switch ( i ) { + case 0: + newPoly.setPoint1( ref ); + break; + case 1: + newPoly.setPoint2( ref ); + break; + case 2: + newPoly.setPoint3( ref ); + break; + default: + // Should never be here! + } + + } + newMesh.completedPolygons.add( newPoly ); + } + + // Save the generated regions as an intermediary step so we can re-use them later + newMesh.generatedRegions = mesh.getPolygons(); + + result.meshes.put( plane, newMesh ); + } + } + + // Add all vector references + result.points = vertices; + } + + private class CompleteMesh { + Mesh< RegionSimple > mesh; + Collection< Polygon > triangles; + + CompleteMesh( final MinecraftPlane plane, final Mesh< RegionSimple > mesh ) { + this.mesh = mesh; + triangles = mesh.meshify(); + } + } + + private class MeshResult { + Map< MinecraftPlane, PlaneMesh > meshes; + TreeSet< VectorReference > points; + } +} diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MiniePlugin.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/MiniePlugin.java similarity index 90% rename from plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MiniePlugin.java rename to plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/MiniePlugin.java index 79fc014..c4a7b38 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MiniePlugin.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/MiniePlugin.java @@ -1,10 +1,9 @@ -package com.aaaaahhhhhhh.bananapuncher714.minietest; +package com.aaaaahhhhhhh.bananapuncher714.mesh.environment; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.nio.file.Files; -import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.util.ArrayDeque; import java.util.ArrayList; @@ -20,7 +19,6 @@ import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; -import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiFunction; import java.util.function.Function; import java.util.logging.Level; @@ -57,30 +55,32 @@ import org.bukkit.util.Vector; import org.joml.Matrix4f; import org.joml.Quaternionf; -import com.aaaaahhhhhhh.bananapuncher714.mesh.Mesh; -import com.aaaaahhhhhhh.bananapuncher714.mesh.Point; -import com.aaaaahhhhhhh.bananapuncher714.mesh.Polygon; -import com.aaaaahhhhhhh.bananapuncher714.mesh.region.simple.RegionRuleWinding; -import com.aaaaahhhhhhh.bananapuncher714.mesh.region.simple.RegionSimple; -import com.aaaaahhhhhhh.bananapuncher714.mesh.region.simple.RegionSimple.GluWindingRule; -import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.CommandParameters; -import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.SubCommand; -import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.executor.CommandExecutableMessage; -import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator.InputValidatorDouble; -import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator.InputValidatorInt; -import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.command.validator.sender.SenderValidatorPlayer; -import com.aaaaahhhhhhh.bananapuncher714.minietest.objects.BlockDataType; -import com.aaaaahhhhhhh.bananapuncher714.minietest.objects.ChunkLocation; -import com.aaaaahhhhhhh.bananapuncher714.minietest.objects.ChunkMesh; -import com.aaaaahhhhhhh.bananapuncher714.minietest.objects.IndexedPolygon; -import com.aaaaahhhhhhh.bananapuncher714.minietest.objects.MinecraftPlane; -import com.aaaaahhhhhhh.bananapuncher714.minietest.objects.MinecraftPlane.PlaneAxis; -import com.aaaaahhhhhhh.bananapuncher714.minietest.objects.PlaneMesh; -import com.aaaaahhhhhhh.bananapuncher714.minietest.objects.VectorReference; -import com.aaaaahhhhhhh.bananapuncher714.minietest.objects.mesh.Facet; -import com.aaaaahhhhhhh.bananapuncher714.minietest.objects.mesh.MeshBuilder; -import com.aaaaahhhhhhh.bananapuncher714.minietest.util.ChunkMeshUtil; -import com.aaaaahhhhhhh.bananapuncher714.minietest.util.FileUtil; +import com.aaaaahhhhhhh.bananapuncher714.mesh.algorithm.Mesh; +import com.aaaaahhhhhhh.bananapuncher714.mesh.algorithm.Point; +import com.aaaaahhhhhhh.bananapuncher714.mesh.algorithm.Polygon; +import com.aaaaahhhhhhh.bananapuncher714.mesh.algorithm.region.simple.RegionRuleWinding; +import com.aaaaahhhhhhh.bananapuncher714.mesh.algorithm.region.simple.RegionSimple; +import com.aaaaahhhhhhh.bananapuncher714.mesh.algorithm.region.simple.RegionSimple.GluWindingRule; +import com.aaaaahhhhhhh.bananapuncher714.mesh.base.Facet; +import com.aaaaahhhhhhh.bananapuncher714.mesh.base.MeshBuilder; +import com.aaaaahhhhhhh.bananapuncher714.mesh.base.Plane; +import com.aaaaahhhhhhh.bananapuncher714.mesh.base.Vector3d; +import com.aaaaahhhhhhh.bananapuncher714.mesh.command.CommandParameters; +import com.aaaaahhhhhhh.bananapuncher714.mesh.command.SubCommand; +import com.aaaaahhhhhhh.bananapuncher714.mesh.command.executor.CommandExecutableMessage; +import com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator.InputValidatorDouble; +import com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator.InputValidatorInt; +import com.aaaaahhhhhhh.bananapuncher714.mesh.command.validator.sender.SenderValidatorPlayer; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.BlockDataType; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.ChunkLocation; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.ChunkMesh; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.IndexedPolygon; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.MinecraftPlane; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.PlaneMesh; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.VectorReference; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.MinecraftPlane.PlaneAxis; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.util.ChunkMeshUtil; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.util.FileUtil; import com.jme3.bullet.PhysicsSpace; import com.jme3.bullet.PhysicsSpace.BroadphaseType; import com.jme3.bullet.RotationOrder; @@ -101,7 +101,6 @@ import com.jme3.bullet.joints.motors.MotorParam; import com.jme3.bullet.objects.PhysicsBody; import com.jme3.bullet.objects.PhysicsRigidBody; import com.jme3.math.Matrix3f; -import com.jme3.math.Plane; import com.jme3.math.Quaternion; import com.jme3.math.Vector3f; @@ -153,7 +152,7 @@ public class MiniePlugin extends JavaPlugin { PhysicsRigidBody.logger2.setLevel( Level.WARNING ); space = new PhysicsSpace( BroadphaseType.DBVT ); - PlaneCollisionShape plane = new PlaneCollisionShape( new Plane( new Vector3f( 0, 1, 0 ), 0 ) ); + PlaneCollisionShape plane = new PlaneCollisionShape( new com.jme3.math.Plane( new Vector3f( 0, 1, 0 ), 0 ) ); planeBody = new PhysicsRigidBody( plane, PhysicsBody.massForStatic ); planeBody.setPhysicsLocation( new Vector3f( 0, 128, 0 ) ); // space.addCollisionObject( planeBody ); @@ -829,61 +828,61 @@ public class MiniePlugin extends JavaPlugin { // Check each face if ( y == 0 || types[ index - 256 ] != BlockVoxelType.SOLID ) { Facet facet = new Facet(); - facet.points.add( new Vector( x, y, z ) ); - facet.points.add( new Vector( x, y, z + 1 ) ); - facet.points.add( new Vector( x + 1, y, z + 1 ) ); - facet.points.add( new Vector( x + 1, y, z ) ); - facet.normal = new Vector( 0, -1, 0 ); + facet.points.add( new Vector3d( x, y, z ) ); + facet.points.add( new Vector3d( x, y, z + 1 ) ); + facet.points.add( new Vector3d( x + 1, y, z + 1 ) ); + facet.points.add( new Vector3d( x + 1, y, z ) ); + facet.normal = new Vector3d( 0, -1, 0 ); facets.add( facet ); } if ( y == worldHeight - 1 || types[ index + 256 ] != BlockVoxelType.SOLID ) { Facet facet = new Facet(); - facet.points.add( new Vector( x, y + 1, z ) ); - facet.points.add( new Vector( x, y + 1, z + 1 ) ); - facet.points.add( new Vector( x + 1, y + 1, z + 1 ) ); - facet.points.add( new Vector( x + 1, y + 1, z ) ); - facet.normal = new Vector( 0, 1, 0 ); + facet.points.add( new Vector3d( x, y + 1, z ) ); + facet.points.add( new Vector3d( x, y + 1, z + 1 ) ); + facet.points.add( new Vector3d( x + 1, y + 1, z + 1 ) ); + facet.points.add( new Vector3d( x + 1, y + 1, z ) ); + facet.normal = new Vector3d( 0, 1, 0 ); facets.add( facet ); } if ( z == 0 || types[ index - 16 ] != BlockVoxelType.SOLID ) { Facet facet = new Facet(); - facet.points.add( new Vector( x, y, z ) ); - facet.points.add( new Vector( x, y + 1, z ) ); - facet.points.add( new Vector( x + 1, y + 1, z ) ); - facet.points.add( new Vector( x + 1, y, z ) ); - facet.normal = new Vector( 0, 0, -1 ); + facet.points.add( new Vector3d( x, y, z ) ); + facet.points.add( new Vector3d( x, y + 1, z ) ); + facet.points.add( new Vector3d( x + 1, y + 1, z ) ); + facet.points.add( new Vector3d( x + 1, y, z ) ); + facet.normal = new Vector3d( 0, 0, -1 ); facets.add( facet ); } if ( z == 15 || types[ index + 16 ] != BlockVoxelType.SOLID ) { Facet facet = new Facet(); - facet.points.add( new Vector( x, y, z + 1 ) ); - facet.points.add( new Vector( x, y + 1, z + 1 ) ); - facet.points.add( new Vector( x + 1, y + 1, z + 1 ) ); - facet.points.add( new Vector( x + 1, y, z + 1 ) ); - facet.normal = new Vector( 0, 0, 1 ); + facet.points.add( new Vector3d( x, y, z + 1 ) ); + facet.points.add( new Vector3d( x, y + 1, z + 1 ) ); + facet.points.add( new Vector3d( x + 1, y + 1, z + 1 ) ); + facet.points.add( new Vector3d( x + 1, y, z + 1 ) ); + facet.normal = new Vector3d( 0, 0, 1 ); facets.add( facet ); } if ( x == 0 || types[ index - 1 ] != BlockVoxelType.SOLID ) { Facet facet = new Facet(); - facet.points.add( new Vector( x, y, z ) ); - facet.points.add( new Vector( x, y, z + 1 ) ); - facet.points.add( new Vector( x, y + 1, z + 1 ) ); - facet.points.add( new Vector( x, y + 1, z ) ); - facet.normal = new Vector( -1, 0, 0 ); + facet.points.add( new Vector3d( x, y, z ) ); + facet.points.add( new Vector3d( x, y, z + 1 ) ); + facet.points.add( new Vector3d( x, y + 1, z + 1 ) ); + facet.points.add( new Vector3d( x, y + 1, z ) ); + facet.normal = new Vector3d( -1, 0, 0 ); facets.add( facet ); } if ( x == 15 || types[ index + 1 ] != BlockVoxelType.SOLID ) { Facet facet = new Facet(); - facet.points.add( new Vector( x + 1, y, z ) ); - facet.points.add( new Vector( x + 1, y, z + 1 ) ); - facet.points.add( new Vector( x + 1, y + 1, z + 1 ) ); - facet.points.add( new Vector( x + 1, y + 1, z ) ); - facet.normal = new Vector( 1, 0, 0 ); + facet.points.add( new Vector3d( x + 1, y, z ) ); + facet.points.add( new Vector3d( x + 1, y, z + 1 ) ); + facet.points.add( new Vector3d( x + 1, y + 1, z + 1 ) ); + facet.points.add( new Vector3d( x + 1, y + 1, z ) ); + facet.normal = new Vector3d( 1, 0, 0 ); facets.add( facet ); } } @@ -945,61 +944,61 @@ public class MiniePlugin extends JavaPlugin { // Check each face if ( y == 0 || types[ index - 256 ] != BlockVoxelType.SOLID ) { Facet facet = new Facet(); - facet.points.add( new Vector( x, y, z ) ); - facet.points.add( new Vector( x, y, z + 1 ) ); - facet.points.add( new Vector( x + 1, y, z + 1 ) ); - facet.points.add( new Vector( x + 1, y, z ) ); - facet.normal = new Vector( 0, -1, 0 ); + facet.points.add( new Vector3d( x, y, z ) ); + facet.points.add( new Vector3d( x, y, z + 1 ) ); + facet.points.add( new Vector3d( x + 1, y, z + 1 ) ); + facet.points.add( new Vector3d( x + 1, y, z ) ); + facet.normal = new Vector3d( 0, -1, 0 ); facets.add( facet ); } if ( y == worldHeight - 1 || types[ index + 256 ] != BlockVoxelType.SOLID ) { Facet facet = new Facet(); - facet.points.add( new Vector( x, y + 1, z ) ); - facet.points.add( new Vector( x, y + 1, z + 1 ) ); - facet.points.add( new Vector( x + 1, y + 1, z + 1 ) ); - facet.points.add( new Vector( x + 1, y + 1, z ) ); - facet.normal = new Vector( 0, 1, 0 ); + facet.points.add( new Vector3d( x, y + 1, z ) ); + facet.points.add( new Vector3d( x, y + 1, z + 1 ) ); + facet.points.add( new Vector3d( x + 1, y + 1, z + 1 ) ); + facet.points.add( new Vector3d( x + 1, y + 1, z ) ); + facet.normal = new Vector3d( 0, 1, 0 ); facets.add( facet ); } if ( z == 0 || types[ index - 16 ] != BlockVoxelType.SOLID ) { Facet facet = new Facet(); - facet.points.add( new Vector( x, y, z ) ); - facet.points.add( new Vector( x, y + 1, z ) ); - facet.points.add( new Vector( x + 1, y + 1, z ) ); - facet.points.add( new Vector( x + 1, y, z ) ); - facet.normal = new Vector( 0, 0, -1 ); + facet.points.add( new Vector3d( x, y, z ) ); + facet.points.add( new Vector3d( x, y + 1, z ) ); + facet.points.add( new Vector3d( x + 1, y + 1, z ) ); + facet.points.add( new Vector3d( x + 1, y, z ) ); + facet.normal = new Vector3d( 0, 0, -1 ); facets.add( facet ); } if ( z == 15 || types[ index + 16 ] != BlockVoxelType.SOLID ) { Facet facet = new Facet(); - facet.points.add( new Vector( x, y, z + 1 ) ); - facet.points.add( new Vector( x, y + 1, z + 1 ) ); - facet.points.add( new Vector( x + 1, y + 1, z + 1 ) ); - facet.points.add( new Vector( x + 1, y, z + 1 ) ); - facet.normal = new Vector( 0, 0, 1 ); + facet.points.add( new Vector3d( x, y, z + 1 ) ); + facet.points.add( new Vector3d( x, y + 1, z + 1 ) ); + facet.points.add( new Vector3d( x + 1, y + 1, z + 1 ) ); + facet.points.add( new Vector3d( x + 1, y, z + 1 ) ); + facet.normal = new Vector3d( 0, 0, 1 ); facets.add( facet ); } if ( x == 0 || types[ index - 1 ] != BlockVoxelType.SOLID ) { Facet facet = new Facet(); - facet.points.add( new Vector( x, y, z ) ); - facet.points.add( new Vector( x, y, z + 1 ) ); - facet.points.add( new Vector( x, y + 1, z + 1 ) ); - facet.points.add( new Vector( x, y + 1, z ) ); - facet.normal = new Vector( -1, 0, 0 ); + facet.points.add( new Vector3d( x, y, z ) ); + facet.points.add( new Vector3d( x, y, z + 1 ) ); + facet.points.add( new Vector3d( x, y + 1, z + 1 ) ); + facet.points.add( new Vector3d( x, y + 1, z ) ); + facet.normal = new Vector3d( -1, 0, 0 ); facets.add( facet ); } if ( x == 15 || types[ index + 1 ] != BlockVoxelType.SOLID ) { Facet facet = new Facet(); - facet.points.add( new Vector( x + 1, y, z ) ); - facet.points.add( new Vector( x + 1, y, z + 1 ) ); - facet.points.add( new Vector( x + 1, y + 1, z + 1 ) ); - facet.points.add( new Vector( x + 1, y + 1, z ) ); - facet.normal = new Vector( 1, 0, 0 ); + facet.points.add( new Vector3d( x + 1, y, z ) ); + facet.points.add( new Vector3d( x + 1, y, z + 1 ) ); + facet.points.add( new Vector3d( x + 1, y + 1, z + 1 ) ); + facet.points.add( new Vector3d( x + 1, y + 1, z ) ); + facet.normal = new Vector3d( 1, 0, 0 ); facets.add( facet ); } } @@ -1046,7 +1045,7 @@ public class MiniePlugin extends JavaPlugin { } final Triangle triangle = new Triangle(); - for ( final Vector vec : facet.points ) { + for ( final Vector3d vec : facet.points ) { VectorRef ref = null; for ( final Entry< Vector, VectorRef > entry : vertices.entrySet() ) { final Vector existingVec = entry.getKey(); @@ -1850,7 +1849,7 @@ public class MiniePlugin extends JavaPlugin { return true; } - private static Collection< Polygon > process( final com.aaaaahhhhhhh.bananapuncher714.minietest.objects.mesh.Plane plane ) { + private static Collection< Polygon > process( final Plane plane ) { final Mesh< RegionSimple > mesh = new Mesh< RegionSimple >( () -> { return new RegionSimple( GluWindingRule.ODD ); } ); for ( Polygon poly : plane.polygons ) { mesh.addPolygon( poly, RegionRuleWinding.CLOCKWISE ); @@ -1914,14 +1913,14 @@ public class MiniePlugin extends JavaPlugin { private static List< Facet > generateFacetsFor( BoundingBox box ) { List< Facet > facets = new ArrayList< Facet >(); - Vector p1 = new Vector( box.getMinX(), box.getMinY(), box.getMinZ() ); - Vector p2 = new Vector( box.getMinX(), box.getMinY(), box.getMaxZ() ); - Vector p3 = new Vector( box.getMinX(), box.getMaxY(), box.getMinZ() ); - Vector p4 = new Vector( box.getMinX(), box.getMaxY(), box.getMaxZ() ); - Vector p5 = new Vector( box.getMaxX(), box.getMinY(), box.getMinZ() ); - Vector p6 = new Vector( box.getMaxX(), box.getMinY(), box.getMaxZ() ); - Vector p7 = new Vector( box.getMaxX(), box.getMaxY(), box.getMinZ() ); - Vector p8 = new Vector( box.getMaxX(), box.getMaxY(), box.getMaxZ() ); + Vector3d p1 = new Vector3d( box.getMinX(), box.getMinY(), box.getMinZ() ); + Vector3d p2 = new Vector3d( box.getMinX(), box.getMinY(), box.getMaxZ() ); + Vector3d p3 = new Vector3d( box.getMinX(), box.getMaxY(), box.getMinZ() ); + Vector3d p4 = new Vector3d( box.getMinX(), box.getMaxY(), box.getMaxZ() ); + Vector3d p5 = new Vector3d( box.getMaxX(), box.getMinY(), box.getMinZ() ); + Vector3d p6 = new Vector3d( box.getMaxX(), box.getMinY(), box.getMaxZ() ); + Vector3d p7 = new Vector3d( box.getMaxX(), box.getMaxY(), box.getMinZ() ); + Vector3d p8 = new Vector3d( box.getMaxX(), box.getMaxY(), box.getMaxZ() ); { Facet facet = new Facet(); @@ -1929,7 +1928,7 @@ public class MiniePlugin extends JavaPlugin { facet.points.add( p2 ); facet.points.add( p4 ); facet.points.add( p3 ); - facet.normal = new Vector( -1, 0, 0 ); + facet.normal = new Vector3d( -1, 0, 0 ); facets.add( facet ); } @@ -1939,7 +1938,7 @@ public class MiniePlugin extends JavaPlugin { facet.points.add( p6 ); facet.points.add( p8 ); facet.points.add( p7 ); - facet.normal = new Vector( 1, 0, 0 ); + facet.normal = new Vector3d( 1, 0, 0 ); facets.add( facet ); } @@ -1949,7 +1948,7 @@ public class MiniePlugin extends JavaPlugin { facet.points.add( p2 ); facet.points.add( p6 ); facet.points.add( p5 ); - facet.normal = new Vector( 0, -1, 0 ); + facet.normal = new Vector3d( 0, -1, 0 ); facets.add( facet ); } @@ -1959,7 +1958,7 @@ public class MiniePlugin extends JavaPlugin { facet.points.add( p4 ); facet.points.add( p8 ); facet.points.add( p7 ); - facet.normal = new Vector( 0, 1, 0 ); + facet.normal = new Vector3d( 0, 1, 0 ); facets.add( facet ); } @@ -1969,7 +1968,7 @@ public class MiniePlugin extends JavaPlugin { facet.points.add( p3 ); facet.points.add( p7 ); facet.points.add( p5 ); - facet.normal = new Vector( 0, 0, -1 ); + facet.normal = new Vector3d( 0, 0, -1 ); facets.add( facet ); } @@ -1979,7 +1978,7 @@ public class MiniePlugin extends JavaPlugin { facet.points.add( p4 ); facet.points.add( p8 ); facet.points.add( p6 ); - facet.normal = new Vector( 0, 0, 1 ); + facet.normal = new Vector3d( 0, 0, 1 ); facets.add( facet ); } diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/Aabb.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/Aabb.java similarity index 74% rename from plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/Aabb.java rename to plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/Aabb.java index 7c666f9..58d0ea2 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/Aabb.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/Aabb.java @@ -1,8 +1,9 @@ -package com.aaaaahhhhhhh.bananapuncher714.minietest.objects; +package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects; import java.io.Serializable; import org.bukkit.util.BoundingBox; +import org.bukkit.util.Vector; public class Aabb implements Serializable { private static final long serialVersionUID = 6518512405568765913L; @@ -18,6 +19,10 @@ public class Aabb implements Serializable { public final int depth; public final int height; + public Aabb( Vector min, Vector max ) { + this( min.getBlockX(), min.getBlockY(), min.getBlockZ(), max.getBlockX(), max.getBlockY(), max.getBlockZ() ); + } + public Aabb( final int minX, final int minY, final int minZ, final int maxX, final int maxY, final int maxZ ) { this.minX = minX; this.minY = minY; @@ -47,4 +52,12 @@ public class Aabb implements Serializable { public int getVolume() { return width * depth * height; } + + public Vector getMinimumCorner() { + return new Vector( minX, minY, minZ ); + } + + public Vector getMaximumCorner() { + return new Vector( maxX, maxY, maxZ ); + } } diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/AbstractMesh.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/AbstractMesh.java new file mode 100644 index 0000000..108d357 --- /dev/null +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/AbstractMesh.java @@ -0,0 +1,62 @@ +package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; +import java.util.TreeSet; + +import org.bukkit.util.Vector; + +import com.jme3.bullet.collision.shapes.infos.IndexedMesh; +import com.jme3.math.Vector3f; + +public abstract class AbstractMesh { + // References to every point used by at least one planemesh + public TreeSet< VectorReference > pointReferences = new TreeSet< VectorReference >(); + // Map of meshes to each plane + // TODO Allow for non axis-aligned planes + public Map< MinecraftPlane, PlaneMesh > planes = new TreeMap< MinecraftPlane, PlaneMesh >(); + + public abstract Vector getMinimumCorner(); + public abstract Vector getMaximumCorner(); + + public abstract BlockDataInformation getBlockDataInformationFor( Vector position ); + public abstract void setBlockDataInformationFor( BlockDataInformation information, Vector position ); + + public IndexedMesh toIndexedMesh() { + final Vector3f[] positionArray = new Vector3f[ pointReferences.size() ]; + int vertexIndex = 0; + for ( final VectorReference ref : pointReferences ) { + final Vector vector = ref.vector; + + positionArray[ vertexIndex ] = new Vector3f( ( float ) vector.getX(), ( float ) vector.getY(), ( float ) vector.getZ() ); + ref.index = vertexIndex; + + ++vertexIndex; + } + + final int totalTriangleCount = planes.values().stream().mapToInt( m -> m.completedPolygons.size() ).sum(); + + int triangleIndex = 0; + final int[] indexArray = new int[ totalTriangleCount * 3 ]; + for ( final PlaneMesh mesh : planes.values() ) { + for ( final IndexedPolygon triangle : mesh.completedPolygons ) { + Collection< VectorReference > refs = triangle.getPoints(); + if ( refs.size() != 3 ) { + throw new IllegalStateException( "Triangle does not have exactly 3 vertices!" ); + } + + final int indexArrayStart = triangleIndex * 3; + Iterator< VectorReference > it = refs.iterator(); + indexArray[ indexArrayStart ] = it.next().index; + indexArray[ indexArrayStart + 1 ] = it.next().index; + indexArray[ indexArrayStart + 2 ] = it.next().index; + + ++triangleIndex; + } + } + + return new IndexedMesh( positionArray, indexArray ); + } +} diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/BlockDataInformation.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/BlockDataInformation.java new file mode 100644 index 0000000..f3b1726 --- /dev/null +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/BlockDataInformation.java @@ -0,0 +1,25 @@ +package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects; + +import org.bukkit.block.data.BlockData; +import org.bukkit.util.BoundingBox; + +public class BlockDataInformation { + // If the block is complex/simple/empty + public BlockDataType type; + // Hashcode of the current block's blockdata so we can check if it changed + public final int blockDataHash; + // The bounding boxes for each complex block, null if air or a cube + public BoundingBox[] boundingBoxes; + + public BlockDataInformation( int hash ) { + blockDataHash = hash; + } + + public BlockDataInformation( BlockData data ) { + blockDataHash = data.hashCode(); + } + + public boolean isBlockData( BlockData data ) { + return blockDataHash == data.hashCode(); + } +} \ No newline at end of file diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/BlockDataType.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/BlockDataType.java new file mode 100644 index 0000000..82d082b --- /dev/null +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/BlockDataType.java @@ -0,0 +1,5 @@ +package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects; + +public enum BlockDataType { + NONE, COMPLEX, SOLID +} diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/BlockDataTypeSet.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/BlockDataTypeSet.java similarity index 92% rename from plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/BlockDataTypeSet.java rename to plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/BlockDataTypeSet.java index 104485b..2957957 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/BlockDataTypeSet.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/BlockDataTypeSet.java @@ -1,9 +1,7 @@ -package com.aaaaahhhhhhh.bananapuncher714.minietest.objects; +package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects; import java.util.BitSet; -import com.aaaaahhhhhhh.bananapuncher714.minietest.util.BinaryWriter; - public class BlockDataTypeSet { private static final int BLOCK_SIZE; private static final BitSet[] SETS; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/ChunkLocation.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/ChunkLocation.java similarity index 93% rename from plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/ChunkLocation.java rename to plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/ChunkLocation.java index ed08df4..75e34db 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/ChunkLocation.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/ChunkLocation.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.minietest.objects; +package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/ChunkMesh.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/ChunkMesh.java similarity index 79% rename from plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/ChunkMesh.java rename to plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/ChunkMesh.java index 1301a65..6ded08a 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/ChunkMesh.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/ChunkMesh.java @@ -1,28 +1,25 @@ -package com.aaaaahhhhhhh.bananapuncher714.minietest.objects; +package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects; import java.nio.ByteBuffer; -import java.nio.IntBuffer; import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.HashSet; +import java.util.Collection; +import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.Map.Entry; -import java.util.TreeMap; -import java.util.TreeSet; import org.bukkit.block.data.BlockData; import org.bukkit.util.BoundingBox; import org.bukkit.util.Vector; -import com.aaaaahhhhhhh.bananapuncher714.mesh.Point; -import com.aaaaahhhhhhh.bananapuncher714.mesh.Polygon; -import com.aaaaahhhhhhh.bananapuncher714.minietest.objects.MinecraftPlane.PlaneAxis; -import com.aaaaahhhhhhh.bananapuncher714.minietest.util.BinaryWriter; +import com.aaaaahhhhhhh.bananapuncher714.mesh.algorithm.Point; +import com.aaaaahhhhhhh.bananapuncher714.mesh.algorithm.Polygon; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.MinecraftPlane.PlaneAxis; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.util.BinaryWriter; import com.jme3.bullet.collision.shapes.infos.IndexedMesh; import com.jme3.math.Vector3f; -public class ChunkMesh { +public class ChunkMesh extends AbstractMesh { // TODO Public for now while I figure out how to organize the stuff properly // Hashcode of the current block's blockdata so we can check if it changed @@ -31,11 +28,6 @@ public class ChunkMesh { private BoundingBox[][] boxes; // Stores which blocks are complex/simple/empty private BlockDataTypeSet blockTypes; - // References to every point used by at least one planemesh - public TreeSet< VectorReference > pointReferences = new TreeSet< VectorReference >(); - // Map of meshes to each plane - // TODO Allow for non axis-aligned planes - public Map< MinecraftPlane, PlaneMesh > planes = new TreeMap< MinecraftPlane, PlaneMesh >(); // Bounding box of this mesh private Aabb box; @@ -89,7 +81,38 @@ public class ChunkMesh { } return results; } + + @Override + public Vector getMinimumCorner() { + return box.getMinimumCorner(); + } + @Override + public Vector getMaximumCorner() { + return box.getMaximumCorner(); + } + + @Override + public BlockDataInformation getBlockDataInformationFor( Vector position ) { + final int index = position.getBlockX() + ( position.getBlockZ() << 4 ) + ( position.getBlockY() << 8 ); + + BlockDataInformation information = new BlockDataInformation( data[ index ] ); + information.type = getType( index ); + information.boundingBoxes = getBoxesAt( index ); + + return information; + } + + @Override + public void setBlockDataInformationFor( BlockDataInformation information, Vector position ) { + final int index = position.getBlockX() + ( position.getBlockZ() << 4 ) + ( position.getBlockY() << 8 ); + + data[ index ] = information.blockDataHash; + setType( index, information.type ); + setBoxes( index, information.boundingBoxes ); + } + + @Override public IndexedMesh toIndexedMesh() { final Vector3f[] positionArray = new Vector3f[ pointReferences.size() ]; int vertexIndex = 0; @@ -108,14 +131,16 @@ public class ChunkMesh { final int[] indexArray = new int[ totalTriangleCount * 3 ]; for ( final PlaneMesh mesh : planes.values() ) { for ( final IndexedPolygon triangle : mesh.completedPolygons ) { - if ( triangle.points.size() != 3 ) { + Collection< VectorReference > refs = triangle.getPoints(); + if ( refs.size() != 3 ) { throw new IllegalStateException( "Triangle does not have exactly 3 vertices!" ); } final int indexArrayStart = triangleIndex * 3; - indexArray[ indexArrayStart ] = triangle.points.get( 0 ).index; - indexArray[ indexArrayStart + 1 ] = triangle.points.get( 1 ).index; - indexArray[ indexArrayStart + 2 ] = triangle.points.get( 2 ).index; + Iterator< VectorReference > it = refs.iterator(); + indexArray[ indexArrayStart ] = it.next().index; + indexArray[ indexArrayStart + 1 ] = it.next().index; + indexArray[ indexArrayStart + 2 ] = it.next().index; ++triangleIndex; } @@ -198,8 +223,8 @@ public class ChunkMesh { // Write each triangle writer.write( mesh.completedPolygons.size() ); for ( final IndexedPolygon poly : mesh.completedPolygons ) { - writer.write( poly.points.size() ); - for ( final VectorReference ref : poly.points ) { + writer.write( poly.getPointCount() ); + for ( final VectorReference ref : poly.getPoints() ) { writer.write( ref.index ); } } @@ -252,7 +277,7 @@ public class ChunkMesh { final PlaneMesh planeMesh = new PlaneMesh(); planeMesh.generatedRegions = new ArrayDeque< Polygon >(); - planeMesh.completedPolygons = new ArrayDeque< IndexedPolygon >(); + planeMesh.completedPolygons = new ArrayDeque< IndexedTriangle >(); final int regionCount = buffer.getInt(); for ( int j = 0; j < regionCount; ++j ) { final int vertexCount = buffer.getInt(); @@ -269,9 +294,22 @@ public class ChunkMesh { for ( int j = 0; j < triangleCount; ++j ) { final int vertexCount = buffer.getInt(); - final IndexedPolygon triangle = new IndexedPolygon(); + final IndexedTriangle triangle = new IndexedTriangle(); for ( int k = 0; k < vertexCount; ++k ) { - triangle.points.add( references[ buffer.getInt() ] ); + switch ( k ) { + case 0: + triangle.setPoint1( references[ buffer.getInt() ] ); + break; + case 1: + triangle.setPoint2( references[ buffer.getInt() ] ); + break; + case 2: + triangle.setPoint3( references[ buffer.getInt() ] ); + break; + default: + // Discard + buffer.getInt(); + } } planeMesh.completedPolygons.add( triangle ); diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/IndexedNGon.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/IndexedNGon.java new file mode 100644 index 0000000..8c9302d --- /dev/null +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/IndexedNGon.java @@ -0,0 +1,19 @@ +package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class IndexedNGon implements IndexedPolygon { + List< VectorReference > points = new ArrayList< VectorReference >(); + + @Override + public Collection< VectorReference > getPoints() { + return points; + } + + @Override + public int getPointCount() { + return points.size(); + } +} diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/IndexedPolygon.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/IndexedPolygon.java new file mode 100644 index 0000000..7fc4f4f --- /dev/null +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/IndexedPolygon.java @@ -0,0 +1,11 @@ +package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects; + +import java.util.Collection; + +/* + * Represents a polygon with associated vector references + */ +public abstract interface IndexedPolygon { + public Collection< VectorReference > getPoints(); + public int getPointCount(); +} diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/IndexedTriangle.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/IndexedTriangle.java new file mode 100644 index 0000000..835c9d4 --- /dev/null +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/IndexedTriangle.java @@ -0,0 +1,44 @@ +package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects; + +import java.util.Collection; +import java.util.List; + +public class IndexedTriangle implements IndexedPolygon { + private VectorReference p1; + private VectorReference p2; + private VectorReference p3; + + public VectorReference getPoint1() { + return p1; + } + + public VectorReference getPoint2() { + return p2; + } + + public VectorReference getPoint3() { + return p3; + } + + public void setPoint1( VectorReference p1 ) { + this.p1 = p1; + } + + public void setPoint2( VectorReference p2 ) { + this.p2 = p2; + } + + public void setPoint3( VectorReference p3 ) { + this.p3 = p3; + } + + @Override + public Collection< VectorReference > getPoints() { + return List.of( p1, p2, p3 ); + } + + @Override + public int getPointCount() { + return 3; + } +} diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/MinecraftPlane.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/MinecraftPlane.java similarity index 93% rename from plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/MinecraftPlane.java rename to plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/MinecraftPlane.java index 26191cc..4189d7c 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/MinecraftPlane.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/MinecraftPlane.java @@ -1,10 +1,8 @@ -package com.aaaaahhhhhhh.bananapuncher714.minietest.objects; - -import java.io.Serializable; +package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects; import org.bukkit.util.Vector; -import com.aaaaahhhhhhh.bananapuncher714.mesh.Point; +import com.aaaaahhhhhhh.bananapuncher714.mesh.algorithm.Point; public class MinecraftPlane implements Comparable< MinecraftPlane > { public final PlaneAxis normal; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/PlaneMesh.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/PlaneMesh.java new file mode 100644 index 0000000..2e260be --- /dev/null +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/PlaneMesh.java @@ -0,0 +1,10 @@ +package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects; + +import java.util.Collection; + +import com.aaaaahhhhhhh.bananapuncher714.mesh.algorithm.Polygon; + +public class PlaneMesh { + public Collection< Polygon > generatedRegions; + public Collection< IndexedTriangle > completedPolygons; +} diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/SparseMesh.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/SparseMesh.java new file mode 100644 index 0000000..49059c2 --- /dev/null +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/SparseMesh.java @@ -0,0 +1,38 @@ +package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.util.Vector; + +public class SparseMesh extends AbstractMesh { + private Map< Vector, BlockDataInformation > data = new HashMap< Vector, BlockDataInformation >(); + + // Bounding box of this mesh + private Vector min, max; + + public SparseMesh( Vector min, Vector max ) { + this.min = min.clone(); + this.max = max.clone(); + } + + @Override + public Vector getMinimumCorner() { + return min; + } + + @Override + public Vector getMaximumCorner() { + return max; + } + + @Override + public BlockDataInformation getBlockDataInformationFor( Vector position ) { + return data.get( position.toBlockVector() ); + } + + @Override + public void setBlockDataInformationFor( BlockDataInformation information, Vector position ) { + data.put( position, information ); + } +} diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/VectorReference.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/VectorReference.java similarity index 92% rename from plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/VectorReference.java rename to plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/VectorReference.java index 0655cc6..b424f7c 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/VectorReference.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/objects/VectorReference.java @@ -1,4 +1,4 @@ -package com.aaaaahhhhhhh.bananapuncher714.minietest.objects; +package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects; import org.bukkit.util.Vector; diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/util/BukkitUtil.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/util/BukkitUtil.java index e6aad94..b352499 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/util/BukkitUtil.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/util/BukkitUtil.java @@ -18,7 +18,7 @@ import org.bukkit.plugin.SimplePluginManager; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPluginLoader; -import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.McMeshEnvironment; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.McMeshEnvironmentPlugin; public class BukkitUtil { private static Constructor< PluginCommand > PLUGINCOMMAND_CONSTRUCTOR; @@ -69,7 +69,7 @@ public class BukkitUtil { public static PluginCommand constructCommand( String id ) { PluginCommand command = null; try { - command = PLUGINCOMMAND_CONSTRUCTOR.newInstance( id, JavaPlugin.getPlugin( McMeshEnvironment.class ) ); + command = PLUGINCOMMAND_CONSTRUCTOR.newInstance( id, JavaPlugin.getPlugin( McMeshEnvironmentPlugin.class ) ); } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); return null; @@ -84,7 +84,7 @@ public class BukkitUtil { if ( Bukkit.getServer().isPrimaryThread() ) { Bukkit.getPluginManager().callEvent( event ); } else { - Bukkit.getScheduler().scheduleSyncDelayedTask( JavaPlugin.getPlugin( McMeshEnvironment.class ), () -> { callEventSync( event ); } ); + Bukkit.getScheduler().scheduleSyncDelayedTask( JavaPlugin.getPlugin( McMeshEnvironmentPlugin.class ), () -> { callEventSync( event ); } ); } } @@ -111,7 +111,7 @@ public class BukkitUtil { if ( JAVAPLUGINLOADER_GETCLASS_1 != null ) { return ( Class< ? > ) JAVAPLUGINLOADER_GETCLASS_1.invoke( loader, name ); } else { - return ( Class< ? > ) JAVAPLUGINLOADER_GETCLASS_2.invoke( loader, name, true, JavaPlugin.getPlugin( MiniePlugin.class ).getDescription() ); + return ( Class< ? > ) JAVAPLUGINLOADER_GETCLASS_2.invoke( loader, name, true, JavaPlugin.getPlugin( McMeshEnvironmentPlugin.class ).getDescription() ); } } } diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/util/ChunkMeshUtil.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/util/ChunkMeshUtil.java index f9e77dd..2409a5c 100644 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/util/ChunkMeshUtil.java +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/util/ChunkMeshUtil.java @@ -2,7 +2,7 @@ package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.util; import java.nio.ByteBuffer; -import com.aaaaahhhhhhh.bananapuncher714.minietest.objects.ChunkMesh; +import com.aaaaahhhhhhh.bananapuncher714.mesh.environment.objects.ChunkMesh; public class ChunkMeshUtil { public static byte[] serialize( final ChunkMesh mesh ) { diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/util/NmsUtil.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/util/NmsUtil.java new file mode 100644 index 0000000..b0bea4b --- /dev/null +++ b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/mesh/environment/util/NmsUtil.java @@ -0,0 +1,59 @@ +package com.aaaaahhhhhhh.bananapuncher714.mesh.environment.util; + +import org.bukkit.Location; +import org.bukkit.block.data.BlockData; +import org.bukkit.craftbukkit.v1_21_R6.CraftWorld; +import org.bukkit.craftbukkit.v1_21_R6.block.data.CraftBlockData; +import org.bukkit.util.BoundingBox; +import org.bukkit.util.Vector; + +import net.minecraft.core.BlockPosition; +import net.minecraft.server.level.WorldServer; +import net.minecraft.world.phys.shapes.VoxelShape; +import net.minecraft.world.phys.shapes.VoxelShapeCollision; + +public class NmsUtil { + // 1.21.5 + public static VoxelShape getShape( BlockData blockData, Location location, BlockShapeType type ) { + final CraftBlockData data = ( CraftBlockData ) blockData; + + WorldServer server = null; + BlockPosition pos = null; + if ( location != null ) { + server = ( ( CraftWorld ) location.getWorld() ).getHandle(); + pos = new BlockPosition( location.getBlockX(), location.getBlockY(), location.getBlockZ() ); + } + + switch ( type ) { + default: + case SHAPE: + return data.getState().f( server, pos ); + case COLLISION_SHAPE: + return data.getState().g( server, pos ); + case VISUAL_SHAPE: + return data.getState().c( server, pos, VoxelShapeCollision.a() ); + case INTERACTION_SHAPE: + return data.getState().i( server, pos ); + case BLOCK_SUPPORT_SHAPE: + return data.getState().h( server, pos ); + } + } + + public static BoundingBox[] convertFrom( final VoxelShape shape ) { + return convertFrom( shape, new Vector() ); + } + + public static BoundingBox[] convertFrom( final VoxelShape shape, final Vector offset ) { + return shape.e().stream() + .map( aabb -> { return new BoundingBox( aabb.a, aabb.b, aabb.c, aabb.d, aabb.e, aabb.f ).shift( offset ); } ) + .toArray( BoundingBox[]::new ); + } + + public enum BlockShapeType { + SHAPE, + COLLISION_SHAPE, + VISUAL_SHAPE, + INTERACTION_SHAPE, + BLOCK_SUPPORT_SHAPE + } +} diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/ChunkMeshCache.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/ChunkMeshCache.java deleted file mode 100644 index 41a3848..0000000 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/ChunkMeshCache.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.aaaaahhhhhhh.bananapuncher714.minietest; - -import java.io.File; -import java.util.Collection; -import java.util.HashSet; -import java.util.Map; -import java.util.TreeMap; -import java.util.concurrent.locks.ReentrantLock; - -import org.bukkit.Chunk; - -import com.aaaaahhhhhhh.bananapuncher714.minietest.objects.ChunkLocation; -import com.aaaaahhhhhhh.bananapuncher714.minietest.objects.ChunkMesh; - -public class ChunkMeshCache { - final File directory; - Map< ChunkLocation, ChunkMesh > meshes = new TreeMap< ChunkLocation, ChunkMesh >(); - Collection< ChunkLocation > shouldRemove = new HashSet< ChunkLocation >(); - ReentrantLock lock = new ReentrantLock(); - - public ChunkMeshCache( final File directory ) { - this.directory = directory; - } - - public void onChunkLoad( final Chunk chunk ) { - final ChunkLocation location = new ChunkLocation( chunk ); - - // Unqueue this chunk for removal if it's queued - shouldRemove.remove( location ); - - // TODO Add a ticket - chunk.addPluginChunkTicket( null ); - - // Does the mesh map contain the current location? - { - // If not, then load or mesh the chunk - // Emit a chunk mesh complete event - } - - } - - public void saveAndRemove( final ChunkLocation location ) { - lock.lock(); - meshes.remove( location ); - lock.unlock(); - } - - public void saveAndRemoveAll() { - lock.unlock(); - } -} diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MinieTest.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MinieTest.java deleted file mode 100644 index ff37cc4..0000000 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/MinieTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.aaaaahhhhhhh.bananapuncher714.minietest; - -import com.jme3.bullet.PhysicsSpace; -import com.jme3.bullet.PhysicsSpace.BroadphaseType; -import com.jme3.bullet.collision.shapes.BoxCollisionShape; -import com.jme3.bullet.collision.shapes.PlaneCollisionShape; -import com.jme3.bullet.objects.PhysicsBody; -import com.jme3.bullet.objects.PhysicsRigidBody; -import com.jme3.math.Plane; -import com.jme3.math.Vector3f; - -public class MinieTest { - - public static void main( String[] args ) { - System.loadLibrary( "bulletjme" ); - - System.out.println( "Testing a simple PhysicsSpace" ); - PhysicsSpace space = new PhysicsSpace( BroadphaseType.DBVT ); - - PlaneCollisionShape plane = new PlaneCollisionShape( new Plane( new Vector3f( 0, 1, 0 ), 0 ) ); - PhysicsRigidBody planeBody = new PhysicsRigidBody( plane, PhysicsBody.massForStatic ); - planeBody.setPhysicsLocation( new Vector3f( 0, 0, 0 ) ); - - BoxCollisionShape box = new BoxCollisionShape( 0.5f ); - PhysicsRigidBody rigid = new PhysicsRigidBody( box, 1f ); - rigid.setPhysicsLocation( new Vector3f( 0f, 100f, 0f ) ); - - space.addCollisionObject( rigid ); - space.addCollisionObject( planeBody ); - - for ( float i = 0; i < 9.6; i += 1 / 256.0 ) { - space.update( i ); - Vector3f loc = rigid.getPhysicsLocation(); - System.out.println( i + "\t: " + loc.getX() + ", " + loc.getY() + ", " + loc.getZ() ); - } - } -} diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/BlockDataType.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/BlockDataType.java deleted file mode 100644 index b641836..0000000 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/BlockDataType.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.aaaaahhhhhhh.bananapuncher714.minietest.objects; - -public enum BlockDataType { - NONE, COMPLEX, SOLID -} diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/IndexedPolygon.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/IndexedPolygon.java deleted file mode 100644 index 5c24e97..0000000 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/IndexedPolygon.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.aaaaahhhhhhh.bananapuncher714.minietest.objects; - -import java.util.ArrayList; -import java.util.List; - -public class IndexedPolygon { - public List< VectorReference > points = new ArrayList< VectorReference >(); -} diff --git a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/PlaneMesh.java b/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/PlaneMesh.java deleted file mode 100644 index fa4631f..0000000 --- a/plugin/environment/src/main/java/com/aaaaahhhhhhh/bananapuncher714/minietest/objects/PlaneMesh.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.aaaaahhhhhhh.bananapuncher714.minietest.objects; - -import java.util.Collection; - -import com.aaaaahhhhhhh.bananapuncher714.mesh.Polygon; - -public class PlaneMesh { - public Collection< Polygon > generatedRegions; - public Collection< IndexedPolygon > completedPolygons; -} diff --git a/plugin/pom.xml b/plugin/pom.xml index 3b807c8..0960211 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -12,6 +12,6 @@ pom - + environment \ No newline at end of file