aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMoulberry <james.jenour@student.scotch.wa.edu.au>2020-07-14 10:23:12 +0800
committerMoulberry <james.jenour@student.scotch.wa.edu.au>2020-07-14 10:23:12 +0800
commitf90f0b2f1f234d08742a4f0dd8afcd4b80e26d05 (patch)
treea3b7def680964e2015afb3e3188b955e64679f9a /src/main/java
parent2254c0fac78dbca807a93648c60c93281b8fb686 (diff)
downloadNotEnoughUpdates-f90f0b2f1f234d08742a4f0dd8afcd4b80e26d05.tar.gz
NotEnoughUpdates-f90f0b2f1f234d08742a4f0dd8afcd4b80e26d05.tar.bz2
NotEnoughUpdates-f90f0b2f1f234d08742a4f0dd8afcd4b80e26d05.zip
something something capes
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NEUCape.java192
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NEUCape2.java1
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java15
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java3
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java103
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeNode.java371
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java605
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/cosmetics/ShaderManager.java153
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/infopanes/CollectionLogInfoPane.java8
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/infopanes/CosmeticsInfoPane.java87
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java3
11 files changed, 1339 insertions, 202 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUCape.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUCape.java
deleted file mode 100644
index 1a33a798..00000000
--- a/src/main/java/io/github/moulberry/notenoughupdates/NEUCape.java
+++ /dev/null
@@ -1,192 +0,0 @@
-package io.github.moulberry.notenoughupdates;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.GlStateManager;
-import net.minecraft.client.renderer.Tessellator;
-import net.minecraft.client.renderer.WorldRenderer;
-import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
-import net.minecraft.entity.Entity;
-import net.minecraft.entity.player.EntityPlayer;
-import net.minecraftforge.client.event.RenderPlayerEvent;
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
-import org.lwjgl.input.Keyboard;
-import org.lwjgl.opengl.GL11;
-import org.lwjgl.util.vector.Vector3f;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-public class NEUCape {
-
- private List<List<Node>> nodes = null;
-
- int horzNodes = 20;
- float targetDist = 1/30f;
-
- public void createNodes(EntityPlayer player) {
- nodes = new ArrayList<>();
- for(int i=0; i<50; i++) {
- List<Node> row = new ArrayList<>();
- for(int j=0; j<horzNodes; j++) {
- row.add(new Node(-1, 2-i*targetDist, ((double)j)/(horzNodes-1)));
- }
-
- nodes.add(row);
- }
- for(int y=0; y<nodes.size(); y++) {
- for(int x=0; x<nodes.get(y).size(); x++) {
- for(Direction dir : Direction.values()) {
- for(int i=1; i<=2; i++) {
- Offset offset = new Offset(dir, i);
-
- int xNeighbor = x+offset.getXOffset();
- int yNeighbor = y+offset.getYOffset();
-
- if(xNeighbor >= 0 && xNeighbor < nodes.get(y).size()
- && yNeighbor >= 0 && yNeighbor < nodes.size()) {
- Node neighbor = nodes.get(yNeighbor).get(xNeighbor);
- nodes.get(y).get(x).neighbors.put(offset, neighbor);
- }
- }
- }
- }
- }
- }
-
- public void ensureNodesCreated(EntityPlayer player) {
- if(nodes == null) createNodes(player);
- }
-
- public enum Direction {
- LEFT(-1, 0),
- UP(0, 1),
- RIGHT(1, 0),
- DOWN(0, -1),
- UPLEFT(-1, 1),
- UPRIGHT(1, 1),
- DOWNLEFT(-1, -1),
- DOWNRIGHT(1, -1);
-
- int xOff;
- int yOff;
-
- Direction(int xOff, int yOff) {
- this.xOff = xOff;
- this.yOff = yOff;
- }
- }
-
- public static class Offset {
- Direction direction;
- int steps;
-
- public Offset(Direction direction, int steps) {
- this.direction = direction;
- this.steps = steps;
- }
-
- public int getXOffset() {
- return direction.xOff*steps;
- }
-
- public int getYOffset() {
- return direction.yOff*steps;
- }
-
- public boolean equals(Object obj) {
- if(obj instanceof Offset) {
- Offset other = (Offset) obj;
- return other.direction == direction && other.steps == steps;
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return 13*direction.ordinal() + 7*steps;
- }
- }
-
- public static class Node {
- private Vector3f position;
- private Vector3f acceleration = new Vector3f();
- private HashMap<Offset, Node> neighbors = new HashMap<>();
-
- public Node(double x, double y, double z) {
- this.position = new Vector3f((float)x, (float)y, (float)z);
- }
-
- public void updatePosition() {
-
- }
-
- public void renderNode() {
- //System.out.println(neighbors.size());
- if(neighbors.containsKey(new Offset(Direction.DOWNRIGHT, 1))) {
- //System.out.println("trying to render");
- Tessellator tessellator = Tessellator.getInstance();
- WorldRenderer worldrenderer = tessellator.getWorldRenderer();
- GlStateManager.color(1F, 1F, 1F, 1F);
- worldrenderer.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION);
-
- Vector3f node2Pos = neighbors.get(new Offset(Direction.DOWN, 1)).position;
- Vector3f node3Pos = neighbors.get(new Offset(Direction.RIGHT, 1)).position;
- Vector3f node4Pos = neighbors.get(new Offset(Direction.DOWNRIGHT, 1)).position;
-
- worldrenderer.pos(position.x, position.y, position.z).endVertex();
- worldrenderer.pos(node2Pos.x, node2Pos.y, node2Pos.z).endVertex();
- worldrenderer.pos(node3Pos.x, node3Pos.y, node3Pos.z).endVertex();
- worldrenderer.pos(node4Pos.x, node4Pos.y, node4Pos.z).endVertex();
-
- tessellator.draw();
- }
- }
- }
-
- @SubscribeEvent
- public void onRenderPlayer(RenderPlayerEvent.Post e) {
- EntityPlayer player = e.entityPlayer;
-
- ensureNodesCreated(player);
- if(Keyboard.isKeyDown(Keyboard.KEY_R)) createNodes(player);
-
- Entity viewer = Minecraft.getMinecraft().getRenderViewEntity();
- double viewerX = viewer.lastTickPosX + (viewer.posX - viewer.lastTickPosX) * e.partialRenderTick;
- double viewerY = viewer.lastTickPosY + (viewer.posY - viewer.lastTickPosY) * e.partialRenderTick;
- double viewerZ = viewer.lastTickPosZ + (viewer.posZ - viewer.lastTickPosZ) * e.partialRenderTick;
-
- GlStateManager.pushMatrix();
- GlStateManager.enableBlend();
- GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA,
- GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO);
- GlStateManager.disableTexture2D();
- GlStateManager.disableCull();
-
- //GL11.glTranslatef(-(float)viewerX, -(float)viewerY, -(float)viewerZ);
-
- updateCape(player);
- renderCape(player);
-
- //GL11.glTranslatef((float)viewerX, (float)viewerY, (float)viewerZ);
-
- GL11.glEnable(GL11.GL_CULL_FACE);
- GlStateManager.enableTexture2D();
- GlStateManager.disableBlend();
- GlStateManager.popMatrix();
- GlStateManager.color(1F, 1F, 1F, 1F);
- }
-
- private void updateCape(EntityPlayer player) {
-
- }
-
- private void renderCape(EntityPlayer player) {
- for(int y=0; y<nodes.size()-1; y++) {
- for(int x=0; x<nodes.get(y).size()-1; x++) {
- nodes.get(y).get(x).renderNode();
- }
- }
- }
-
-}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUCape2.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUCape2.java
index 4b834cbb..996809da 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NEUCape2.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUCape2.java
@@ -482,7 +482,6 @@ public class NEUCape2 {
Tessellator tessellator = Tessellator.getInstance();
WorldRenderer worldrenderer = tessellator.getWorldRenderer();
-
//Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(node1.normalY + " " + node2.normalY + " " + node3.normalY + " " + node4.normalY));
if(offset) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
index 8d01e9a9..0724a132 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
@@ -8,7 +8,9 @@ import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
import com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication;
import io.github.moulberry.notenoughupdates.auction.CustomAHGui;
import io.github.moulberry.notenoughupdates.commands.SimpleCommand;
+import io.github.moulberry.notenoughupdates.cosmetics.CapeManager;
import io.github.moulberry.notenoughupdates.infopanes.CollectionLogInfoPane;
+import io.github.moulberry.notenoughupdates.infopanes.CosmeticsInfoPane;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
@@ -95,7 +97,6 @@ public class NotEnoughUpdates {
private GuiScreen openGui = null;
- ScheduledExecutorService guiDelaySES = Executors.newScheduledThreadPool(1);
SimpleCommand collectionLogCommand = new SimpleCommand("neucl", new SimpleCommand.ProcessCommandRunnable() {
public void processCommand(ICommandSender sender, String[] args) {
if(!OpenGlHelper.isFramebufferEnabled()) {
@@ -111,6 +112,15 @@ public class NotEnoughUpdates {
}
});
+ SimpleCommand cosmeticsCommand = new SimpleCommand("neucosmetics", new SimpleCommand.ProcessCommandRunnable() {
+ public void processCommand(ICommandSender sender, String[] args) {
+ if(!(Minecraft.getMinecraft().currentScreen instanceof GuiContainer)) {
+ openGui = new GuiInventory(Minecraft.getMinecraft().thePlayer);
+ }
+ overlay.displayInformationPane(new CosmeticsInfoPane(overlay, manager));
+ }
+ });
+
SimpleCommand neuAhCommand = new SimpleCommand("neuah", new SimpleCommand.ProcessCommandRunnable() {
public void processCommand(ICommandSender sender, String[] args) {
if(!hasSkyblockScoreboard()) {
@@ -136,11 +146,12 @@ public class NotEnoughUpdates {
public void preinit(FMLPreInitializationEvent event) {
INSTANCE = this;
MinecraftForge.EVENT_BUS.register(this);
- //MinecraftForge.EVENT_BUS.register(new NEUCape());
+ MinecraftForge.EVENT_BUS.register(CapeManager.getInstance());
File f = new File(event.getModConfigurationDirectory(), "notenoughupdates");
f.mkdirs();
ClientCommandHandler.instance.registerCommand(collectionLogCommand);
+ ClientCommandHandler.instance.registerCommand(cosmeticsCommand);
ClientCommandHandler.instance.registerCommand(neuAhCommand);
neuio = new NEUIO(getAccessToken());
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java b/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java
index aad82b9f..dd02c887 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java
@@ -1028,8 +1028,6 @@ public class CustomAH extends Gui {
return;
}
- System.out.println("Updating search:"+searchField.getText());
-
lastUpdateSearch = System.currentTimeMillis();
shouldUpdateSearch = false;
@@ -1345,7 +1343,6 @@ public class CustomAH extends Gui {
}
}
- System.out.println();
Utils.playPressSound();
} else if(mouseY > guiTop+126 && mouseY < guiTop+126+16 && !leftFiller) {
priceField.setFocused(true);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java
new file mode 100644
index 00000000..9afbd17f
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java
@@ -0,0 +1,103 @@
+package io.github.moulberry.notenoughupdates.cosmetics;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraftforge.client.event.RenderPlayerEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+import org.apache.commons.lang3.tuple.MutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+public class CapeManager {
+
+ public static final CapeManager INSTANCE = new CapeManager();
+
+ private HashMap<String, Pair<NEUCape, String>> capeMap = new HashMap<>();
+ private String[] capes = new String[]{"testcape", "nullzee", "gravy", "fade", "contrib"};
+
+ public static CapeManager getInstance() {
+ return INSTANCE;
+ }
+
+ public void setCape(String player, String capename) {
+ if(capename == null) {
+ capeMap.remove(player);
+ return;
+ }
+ if(capeMap.containsKey(player)) {
+ Pair<NEUCape, String> capePair = capeMap.get(player);
+ capePair.setValue(capename);
+ } else {
+ capeMap.put(player, new MutablePair<>(new NEUCape(capename), capename));
+ }
+ }
+
+ public String getCape(String player) {
+ if(capeMap.containsKey(player)) {
+ return capeMap.get(player).getRight();
+ }
+ return null;
+ }
+
+ public EntityPlayer getPlayerForName(String name) {
+ if(Minecraft.getMinecraft().theWorld != null) {
+ for(EntityPlayer player : Minecraft.getMinecraft().theWorld.playerEntities) {
+ if(player.getName().equals(name)) {
+ return player;
+ }
+ }
+ }
+ return null;
+ }
+
+ @SubscribeEvent
+ public void onRenderPlayer(RenderPlayerEvent.Post e) {
+ if(capeMap.containsKey(e.entityPlayer.getName())) {
+ capeMap.get(e.entityPlayer.getName()).getLeft().onRenderPlayer(e);
+ }
+ }
+
+ @SubscribeEvent
+ public void onTick(TickEvent.ClientTickEvent event) {
+ Set<String> toRemove = new HashSet<>();
+ for(String playerName : capeMap.keySet()) {
+ EntityPlayer player = getPlayerForName(playerName);
+ if(player == null) {
+ toRemove.add(playerName);
+ } else {
+ String capeName = capeMap.get(playerName).getRight();
+ if(capeName != null) {
+ capeMap.get(playerName).getLeft().setCapeTexture(capeName);
+ capeMap.get(playerName).getLeft().onTick(event, player);
+ } else {
+ toRemove.add(playerName);
+ }
+ }
+ }
+ for(String playerName : toRemove) {
+ capeMap.remove(playerName);
+ }
+ }
+
+ public String[] getCapes() {
+ return capes;
+ }
+
+ public boolean getPermissionForCape(String player, String capename) {
+ if(capename == null) {
+ return false;
+ } else if(player.equalsIgnoreCase("Moulberry")) {
+ return true; //Oh yeah gimme gimme
+ } else if(capename.equals("nullzee")) {
+ return player.equalsIgnoreCase("Nullzee");
+ } else if(capename.equals("gravy")) {
+ return player.equalsIgnoreCase("ThatGravyBoat");
+ }
+ return false;
+ }
+
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeNode.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeNode.java
new file mode 100644
index 00000000..1ec2dee3
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeNode.java
@@ -0,0 +1,371 @@
+package io.github.moulberry.notenoughupdates.cosmetics;
+
+import net.minecraft.block.Block;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.WorldRenderer;
+import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
+import net.minecraft.util.BlockPos;
+import net.minecraft.util.MathHelper;
+import org.lwjgl.input.Keyboard;
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.util.vector.Vector2f;
+import org.lwjgl.util.vector.Vector3f;
+
+import java.nio.FloatBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+public class CapeNode {
+
+ private static final NEUCape.Direction[] cardinals = new NEUCape.Direction[]{NEUCape.Direction.UP, NEUCape.Direction.RIGHT, NEUCape.Direction.DOWN, NEUCape.Direction.LEFT};
+
+ public Vector3f position;
+ public Vector3f lastPosition = new Vector3f();
+ public Vector3f renderPosition = new Vector3f();
+ public final Vector3f[] oldRenderPosition = new Vector3f[5];
+ public final Vector3f velocity = new Vector3f();
+ public Vector3f normal = null;
+ public Vector3f sideNormal = null;
+ public boolean fixed = false;
+
+ public HashMap<NEUCape.Offset, CapeNode> neighbors = new HashMap<>();
+
+ public float texU = 0;
+ public float texV = 0;
+
+ public float horzDistMult = 2f;
+ public float vertDistMult = 0.5f;
+
+ public float horzSideTexU = 0;
+ public float horzSideTexVTop = 0;
+
+ public float vertSideTexU = 0;
+ public float vertSideTexVTop = 0;
+
+ public static final float gravity = 0.1f;
+ public static final float resistance = 0.5f;
+
+ public static final int FLOAT_NUM = 20;
+
+ public CapeNode(float x, float y, float z) {
+ this.position = new Vector3f(x, y, z);
+ }
+
+ private List<Vector2f> getConstaints() {
+ List<Vector2f> constaints = new ArrayList<>();
+ for(NEUCape.Direction cardinal : cardinals) {
+ for(int i=1; i<=2; i++) {
+ NEUCape.Offset offset = new NEUCape.Offset(cardinal, i);
+ CapeNode other = neighbors.get(offset);
+ if(other != null) {
+ int iOffset = offset.getXOffset() + NEUCape.HORZ_NODES * offset.getYOffset();
+ constaints.add(new Vector2f(iOffset, i*NEUCape.targetDist*(cardinal.yOff==0?horzDistMult:vertDistMult)));
+ }
+ }
+
+ }
+ return constaints;
+ }
+
+ public void loadIntoBuffer(FloatBuffer buffer) {
+ loadVec3IntoBuffer(buffer, position);
+ List<Vector2f> containts = getConstaints();
+ buffer.put(containts.size());
+ for(int i=0; i<8; i++) {
+ if(i < containts.size()) {
+ loadVec2IntoBuffer(buffer, containts.get(i));
+ } else {
+ loadVec2IntoBuffer(buffer, new Vector2f());
+ }
+ }
+ }
+
+ public void readFromBuffer(FloatBuffer buffer) {
+ readVec3FromBuffer(buffer, position);
+ buffer.position(buffer.position()+17);
+ }
+
+ private void readVec3FromBuffer(FloatBuffer buffer, Vector3f vec) {
+ vec.x = buffer.get();
+ vec.y = buffer.get();
+ vec.z = buffer.get();
+ }
+
+ private void loadVec2IntoBuffer(FloatBuffer buffer, Vector2f vec) {
+ buffer.put(vec.x);
+ buffer.put(vec.y);
+ }
+
+ private void loadVec3IntoBuffer(FloatBuffer buffer, Vector3f vec) {
+ buffer.put(vec.x);
+ buffer.put(vec.y);
+ buffer.put(vec.z);
+ }
+
+ public void update() {
+ if(!fixed) {
+ velocity.y -= gravity * (resistance)/(1-resistance);
+
+ float actualResistance = resistance;
+ BlockPos pos = new BlockPos(
+ MathHelper.floor_double(position.x),
+ MathHelper.floor_double(position.y),
+ MathHelper.floor_double(position.z));
+ Block block = Minecraft.getMinecraft().theWorld.getBlockState(pos).getBlock();
+ if(block.getMaterial().isLiquid()) {
+ actualResistance = 0.8f;
+ }
+
+ velocity.scale(1-actualResistance);
+
+ Vector3f.add(position, velocity, position);
+ }
+ }
+
+ public final CapeNode getNeighbor(NEUCape.Offset offset) {
+ return neighbors.get(offset);
+ }
+
+ public final void setNeighbor(NEUCape.Offset offset, CapeNode node) {
+ neighbors.put(offset, node);
+ }
+
+ public void applyForce(float dX, float dY, float dZ) {
+ velocity.x += dX;
+ velocity.y += dY;
+ velocity.z += dZ;
+ }
+
+ public void move(float dX, float dY, float dZ) {
+ position.x += dX;
+ position.y += dY;
+ position.z += dZ;
+ lastPosition.x = position.x;
+ lastPosition.y = position.y;
+ lastPosition.z = position.z;
+ }
+
+ public void resetNormal() {
+ normal = null;
+ sideNormal = null;
+ }
+
+ public void resolveAll(float horzDistMult, boolean opt) {
+ resolveBend(horzDistMult, opt);
+ //resolveShear();
+ resolveStruct(horzDistMult, opt);
+ }
+
+ public void resolve(CapeNode other, float targetDist, float strength, boolean opt) {
+ if(other == null || Keyboard.isKeyDown(Keyboard.KEY_H)) return;
+
+ double dX = position.x - other.position.x;
+ double dY = position.y - other.position.y;
+ double dZ = position.z - other.position.z;
+
+ double distSq = dX*dX + dY*dY + dZ*dZ;
+
+ double factor = (distSq - targetDist*targetDist)/(40*distSq)*strength;
+
+ factor = Math.max(-0.5f, factor);
+ dX *= factor;
+ dY *= factor;
+ dZ *= factor;
+
+ if(fixed || other.fixed) {
+ dX *= 2;
+ dY *= 2;
+ dZ *= 2;
+ }
+
+ if(!fixed) {
+ position.x -= dX;
+ position.y -= dY;
+ position.z -= dZ;
+ }
+
+ if(!other.fixed) {
+ other.position.x += dX;
+ other.position.y += dY;
+ other.position.z += dZ;
+ }
+ }
+
+ public void resolveStruct(float horzDistMult, boolean opt) {
+ for(NEUCape.Direction cardinal : cardinals) {
+ NEUCape.Offset offset = new NEUCape.Offset(cardinal, 1);
+ CapeNode other = neighbors.get(offset);
+ if(other != null) {
+ resolve(other, NEUCape.targetDist*(cardinal.yOff==0?horzDistMult:1), 2f*7.5f, opt);
+ }
+ }
+ }
+
+ public void resolveShear(float horzDistMult, boolean opt) {
+ for(NEUCape.Direction d : new NEUCape.Direction[]{NEUCape.Direction.DOWNLEFT, NEUCape.Direction.UPLEFT, NEUCape.Direction.DOWNRIGHT, NEUCape.Direction.DOWNLEFT}) {
+ NEUCape.Offset o = new NEUCape.Offset(d, 1);
+ CapeNode neighbor = getNeighbor(o);
+ if(neighbor != null) {
+ if(!Keyboard.isKeyDown(Keyboard.KEY_H))resolve(neighbor, 1f*NEUCape.targetDist*(d.yOff==0?horzDistMult:1f), 0.5f*7.5f, opt);
+ }
+ }
+ }
+
+ public void resolveBend(float horzDistMult, boolean opt) {
+ for(NEUCape.Direction cardinal : cardinals) {
+ NEUCape.Offset offset = new NEUCape.Offset(cardinal, 2);
+ CapeNode other = neighbors.get(offset);
+ if(other != null) {
+ resolve(other, 2f*NEUCape.targetDist*(cardinal.yOff==0?horzDistMult:1), 1f*7.5f, opt);
+ }
+ }
+ }
+
+ public Vector3f normal() {
+ if(normal != null) return normal;
+
+ normal = new Vector3f();
+ for(int i=0; i<cardinals.length; i++) {
+ NEUCape.Direction dir1 = cardinals[i];
+ NEUCape.Direction dir2 = cardinals[(i+1)%cardinals.length];
+ CapeNode node1 = getNeighbor(new NEUCape.Offset(dir1, 1));
+ CapeNode node2 = getNeighbor(new NEUCape.Offset(dir2, 1));
+
+ if(node1 == null || node2 == null) continue;
+
+ Vector3f toCapeNode1 = Vector3f.sub(node1.renderPosition, renderPosition, null);
+ Vector3f toCapeNode2 = Vector3f.sub(node2.renderPosition, renderPosition, null);
+ Vector3f cross = Vector3f.cross(toCapeNode1, toCapeNode2, null);
+ Vector3f.add(normal, cross.normalise(null), normal);
+ }
+ float l = normal.length();
+ if(l != 0) {
+ normal.scale(1f/l);
+ }
+ return normal;
+ }
+
+ public Vector3f sideNormal() {
+ if(sideNormal != null) return sideNormal;
+
+ sideNormal = new Vector3f();
+ NEUCape.Direction[] cardinals = new NEUCape.Direction[]{NEUCape.Direction.UP, NEUCape.Direction.RIGHT, NEUCape.Direction.DOWN, NEUCape.Direction.LEFT};
+ for(NEUCape.Direction cardinal : cardinals) {
+ CapeNode nodeCardinal = getNeighbor(new NEUCape.Offset(cardinal, 1));
+ if(nodeCardinal == null) {
+ NEUCape.Direction dirLeft = cardinal.rotateLeft90();
+ NEUCape.Direction dirRight = cardinal.rotateRight90();
+ CapeNode nodeLeft = getNeighbor(new NEUCape.Offset(dirLeft, 1));
+ CapeNode nodeRight = getNeighbor(new NEUCape.Offset(dirRight, 1));
+
+ if(nodeRight != null) {
+ Vector3f toOther = Vector3f.sub(nodeRight.renderPosition, renderPosition, null);
+ Vector3f cross = Vector3f.cross(normal(), toOther, null); //Inverted
+ Vector3f.add(sideNormal, cross.normalise(null), sideNormal);
+ }
+ if(nodeLeft != null) {
+ Vector3f toOther = Vector3f.sub(nodeLeft.renderPosition, renderPosition, null);
+ Vector3f cross = Vector3f.cross(toOther, normal(), null);
+ Vector3f.add(sideNormal, cross.normalise(null), sideNormal);
+ }
+ }
+ }
+ float l = sideNormal.length();
+ if(l != 0) {
+ sideNormal.scale(0.05f/l);
+ }
+ return sideNormal;
+ }
+
+ public void renderNode() {
+ CapeNode nodeLeft = getNeighbor(new NEUCape.Offset(NEUCape.Direction.LEFT, 1));
+ CapeNode nodeUp = getNeighbor(new NEUCape.Offset(NEUCape.Direction.UP, 1));
+ CapeNode nodeDown = getNeighbor(new NEUCape.Offset(NEUCape.Direction.DOWN, 1));
+ CapeNode nodeRight = getNeighbor(new NEUCape.Offset(NEUCape.Direction.RIGHT, 1));
+ CapeNode nodeDownRight = getNeighbor(new NEUCape.Offset(NEUCape.Direction.DOWNRIGHT, 1));
+
+ Tessellator tessellator = Tessellator.getInstance();
+ WorldRenderer worldrenderer = tessellator.getWorldRenderer();
+
+ if(nodeDown != null && nodeRight != null && nodeDownRight != null) {
+ //Back
+ worldrenderer.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_TEX_NORMAL);
+ for(CapeNode node : new CapeNode[]{this, nodeDown, nodeRight, nodeDownRight}) {
+ Vector3f nodeNorm = node.normal();
+ worldrenderer.pos(node.renderPosition.x, node.renderPosition.y, node.renderPosition.z)
+ .tex(1-node.texU, node.texV)
+ .normal(-nodeNorm.x, -nodeNorm.y, -nodeNorm.z).endVertex();
+ }
+ tessellator.draw();
+
+ //Front (Offset by normal)
+ worldrenderer.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_TEX_NORMAL);
+ for(CapeNode node : new CapeNode[]{this, nodeDown, nodeRight, nodeDownRight}) {
+ Vector3f nodeNorm = node.normal();
+ worldrenderer.pos(node.renderPosition.x+nodeNorm.x*0.05f, node.renderPosition.y+nodeNorm.y*0.05f, node.renderPosition.z+nodeNorm.z*0.05f)
+ .tex(node.texU, node.texV)
+ .normal(nodeNorm.x, nodeNorm.y, nodeNorm.z).endVertex();
+ }
+ tessellator.draw();
+
+ /*for(CapeNode node : new CapeNode[]{this, nodeDown, nodeRight, nodeDownRight}) {
+ Vector3f nodeNorm = node.normal();
+ worldrenderer.begin(GL11.GL_LINES, DefaultVertexFormats.POSITION_TEX_NORMAL);
+ worldrenderer.pos(node.renderPosition.x+nodeNorm.x*0.05f, node.renderPosition.y+nodeNorm.y*0.05f, node.renderPosition.z+nodeNorm.z*0.05f)
+ .tex(node.texU, node.texV)
+ .normal(nodeNorm.x, nodeNorm.y, nodeNorm.z).endVertex();
+ worldrenderer.pos(node.renderPosition.x+nodeNorm.x*0.25f, node.renderPosition.y+nodeNorm.y*0.25f, node.renderPosition.z+nodeNorm.z*0.25f)
+ .tex(node.texU, node.texV)
+ .normal(nodeNorm.x, nodeNorm.y, nodeNorm.z).endVertex();
+ tessellator.draw();
+ }*/
+ }
+
+ if(nodeLeft == null || nodeRight == null) {
+ //Render left/right edge
+ if(nodeDown != null) {
+ renderEdge(nodeDown, true);
+ }
+ }
+ if(nodeUp == null || nodeDown == null) {
+ //Render up/down edge
+ if(nodeRight != null) {
+ renderEdge(nodeRight, false);
+ }
+ }
+ }
+
+ public void renderEdge(CapeNode other, boolean lr) {
+ float thisTexU = lr ? this.horzSideTexU : this.vertSideTexU;
+ float thisTexV = lr ? this.horzSideTexVTop : this.vertSideTexVTop;
+ float otherTexU = lr ? other.horzSideTexU : other.vertSideTexU;
+ float otherTexV = lr ? other.horzSideTexVTop : other.vertSideTexVTop;
+
+ Tessellator tessellator = Tessellator.getInstance();
+ WorldRenderer worldrenderer = tessellator.getWorldRenderer();
+
+ Vector3f thisNorm = normal();
+ Vector3f otherNorm = other.normal();
+
+ Vector3f thisSideNorm = sideNormal();
+ Vector3f otherSideNorm = other.sideNormal();
+
+ worldrenderer.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_TEX_NORMAL);
+ worldrenderer.pos(this.renderPosition.x, this.renderPosition.y, this.re