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