Merge pull request #7 from GTNewHorizons/buildscript

Update buildscript & apply spotless
This commit is contained in:
boubou19 authored and GitHub committed 2023-01-05 13:00:57 +01:00
commit 9b42fa756f
114 files changed
+4080 -4539

No files matched your search

+44
View File
@@ -0,0 +1,44 @@
* text eol=lf
*.[jJ][aA][rR] binary
*.[pP][nN][gG] binary
*.[jJ][pP][gG] binary
*.[jJ][pP][eE][gG] binary
*.[gG][iI][fF] binary
*.[tT][iI][fF] binary
*.[tT][iI][fF][fF] binary
*.[iI][cC][oO] binary
*.[sS][vV][gG] text
*.[eE][pP][sS] binary
*.[xX][cC][fF] binary
*.[kK][aA][rR] binary
*.[mM]4[aA] binary
*.[mM][iI][dD] binary
*.[mM][iI][dD][iI] binary
*.[mM][pP]3 binary
*.[oO][gG][gG] binary
*.[rR][aA] binary
*.7[zZ] binary
*.[gG][zZ] binary
*.[tT][aA][rR] binary
*.[tT][gG][zZ] binary
*.[zZ][iI][pP] binary
*.[tT][cC][nN] binary
*.[sS][oO] binary
*.[dD][lL][lL] binary
*.[dD][yY][lL][iI][bB] binary
*.[pP][sS][dD] binary
*.[tT][tT][fF] binary
*.[oO][tT][fF] binary
*.[pP][aA][tT][cC][hH] -text
*.[bB][aA][tT] text eol=crlf
*.[cC][mM][dD] text eol=crlf
*.[pP][sS]1 text eol=crlf
*[aA][uU][tT][oO][gG][eE][nN][eE][rR][aA][tT][eE][dD]* binary
+608 -187
View File
File diff suppressed because it is too large. Load diff
+10
View File
@@ -0,0 +1,10 @@
plugins {
id 'com.diffplug.blowdryerSetup' version '1.6.0'
}
apply plugin: 'com.diffplug.blowdryerSetup'
blowdryerSetup {
github('GTNewHorizons/ExampleMod1.7.10', 'tag', '0.1.5')
//devLocal '.' // Use this when testing config updates locally
}
+28 -36
View File
@@ -1,20 +1,18 @@
package codechicken.lib.asm;
import static org.objectweb.asm.tree.AbstractInsnNode.*;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableMap;
import java.util.*;
import java.util.Map.Entry;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;
import java.util.*;
import java.util.Map.Entry;
import static org.objectweb.asm.tree.AbstractInsnNode.*;
public class ASMBlock
{
public class ASMBlock {
public InsnListSection list;
private BiMap<String, LabelNode> labels;
@@ -37,8 +35,7 @@ public class ASMBlock
public LabelNode getOrAdd(String s) {
LabelNode l = get(s);
if (l == null)
labels.put(s, l = new LabelNode());
if (l == null) labels.put(s, l = new LabelNode());
return l;
}
@@ -51,8 +48,8 @@ public class ASMBlock
switch (insn.getType()) {
case LABEL:
AbstractInsnNode insn2 = insn.clone(labelMap);
if (insn2 == insn)//identity mapping
continue;
if (insn2 == insn) // identity mapping
continue;
if (usedLabels.contains(insn2))
throw new IllegalStateException("LabelNode cannot be a part of two InsnLists");
list.replace(insn, insn2);
@@ -64,10 +61,9 @@ public class ASMBlock
list.replace(insn, insn.clone(labelMap));
}
for(Entry<LabelNode, LabelNode> entry : labelMap.entrySet()) {
for (Entry<LabelNode, LabelNode> entry : labelMap.entrySet()) {
String key = labels.inverse().get(entry.getKey());
if(key != null)
labels.put(key, entry.getValue());
if (key != null) labels.put(key, entry.getValue());
}
}
@@ -77,8 +73,7 @@ public class ASMBlock
public void replaceLabel(String s, LabelNode l) {
LabelNode old = get(s);
if (old != null)
replaceLabels(ImmutableMap.of(old, l));
if (old != null) replaceLabels(ImmutableMap.of(old, l));
}
/**
@@ -86,20 +81,17 @@ public class ASMBlock
* @return this
*/
public ASMBlock mergeLabels(ASMBlock other) {
if(labels.isEmpty() || other.labels.isEmpty())
return this;
if (labels.isEmpty() || other.labels.isEmpty()) return this;
//common labels, give them our nodes
// common labels, give them our nodes
HashMap<LabelNode, LabelNode> labelMap = list.identityLabelMap();
for(Entry<String, LabelNode> entry : other.labels.entrySet()) {
for (Entry<String, LabelNode> entry : other.labels.entrySet()) {
LabelNode old = labels.get(entry.getKey());
if(old != null)
labelMap.put(old, entry.getValue());
if (old != null) labelMap.put(old, entry.getValue());
}
HashSet<LabelNode> usedLabels = new HashSet<LabelNode>();
for (AbstractInsnNode insn = other.list.list.getFirst(); insn != null; insn = insn.getNext())
if(insn.getType() == LABEL)
usedLabels.add((LabelNode) insn);
if (insn.getType() == LABEL) usedLabels.add((LabelNode) insn);
replaceLabels(labelMap, usedLabels);
return this;
@@ -118,15 +110,14 @@ public class ASMBlock
BiMap<String, LabelNode> labels = HashBiMap.create();
Map<LabelNode, LabelNode> labelMap = list.cloneLabels();
for(Entry<String, LabelNode> entry : this.labels.entrySet())
for (Entry<String, LabelNode> entry : this.labels.entrySet())
labels.put(entry.getKey(), labelMap.get(entry.getValue()));
return new ASMBlock(list.copy(labelMap), labels);
}
public ASMBlock applyLabels(InsnListSection list2) {
if(labels.isEmpty())
return new ASMBlock(list2);
if (labels.isEmpty()) return new ASMBlock(list2);
Set<LabelNode> cFlowLabels1 = labels.values();
Set<LabelNode> cFlowLabels2 = InsnComparator.getControlFlowLabels(list2);
@@ -134,23 +125,23 @@ public class ASMBlock
HashMap<LabelNode, LabelNode> labelMap = new HashMap<LabelNode, LabelNode>();
for(int i = 0, k = 0; i < list.size() && k < list2.size(); ) {
for (int i = 0, k = 0; i < list.size() && k < list2.size(); ) {
AbstractInsnNode insn1 = list.get(i);
if(!InsnComparator.insnImportant(insn1, cFlowLabels1)) {
if (!InsnComparator.insnImportant(insn1, cFlowLabels1)) {
i++;
continue;
}
AbstractInsnNode insn2 = list2.get(k);
if(!InsnComparator.insnImportant(insn2, cFlowLabels2)) {
if (!InsnComparator.insnImportant(insn2, cFlowLabels2)) {
k++;
continue;
}
if(insn1.getOpcode() != insn2.getOpcode())
throw new IllegalArgumentException("Lists do not match:\n"+list+"\n\n"+list2);
if (insn1.getOpcode() != insn2.getOpcode())
throw new IllegalArgumentException("Lists do not match:\n" + list + "\n\n" + list2);
switch(insn1.getType()) {
switch (insn1.getType()) {
case LABEL:
labelMap.put((LabelNode) insn1, (LabelNode) insn2);
break;
@@ -158,10 +149,11 @@ public class ASMBlock
labelMap.put(((JumpInsnNode) insn1).label, ((JumpInsnNode) insn2).label);
break;
}
i++; k++;
i++;
k++;
}
for(Entry<String, LabelNode> entry : labels.entrySet())
for (Entry<String, LabelNode> entry : labels.entrySet())
block.labels.put(entry.getKey(), labelMap.get(entry.getValue()));
return block;
@@ -170,4 +162,4 @@ public class ASMBlock
public InsnList rawListCopy() {
return list.copy().list;
}
}
}
@@ -2,6 +2,13 @@ package codechicken.lib.asm;
import codechicken.lib.config.ConfigFile;
import codechicken.lib.config.DefaultingConfigFile;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.objectweb.asm.ClassReader;
@@ -12,48 +19,35 @@ import org.objectweb.asm.util.ASMifier;
import org.objectweb.asm.util.Textifier;
import org.objectweb.asm.util.TraceClassVisitor;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ASMHelper
{
public class ASMHelper {
public static ConfigFile config = loadConfig();
public static Logger logger = LogManager.getLogger("CCL ASM");
private static ConfigFile loadConfig() {
try {//weak reference for environments without FML
File mcDir = (File)((Object[])Class.forName("cpw.mods.fml.relauncher.FMLInjectionData").getMethod("data").invoke(null))[6];
try { // weak reference for environments without FML
File mcDir = (File) ((Object[]) Class.forName("cpw.mods.fml.relauncher.FMLInjectionData")
.getMethod("data")
.invoke(null))
[6];
File file = new File(mcDir, "config/CodeChickenLib.cfg");
if(ObfMapping.obfuscated)
return new DefaultingConfigFile(file);
else
return new ConfigFile(file).setComment("CodeChickenLib development configuration file.");
if (ObfMapping.obfuscated) return new DefaultingConfigFile(file);
else return new ConfigFile(file).setComment("CodeChickenLib development configuration file.");
} catch (Exception ignored) {
return null;//no config for these systems
return null; // no config for these systems
}
}
public static interface Acceptor
{
public static interface Acceptor {
public void accept(ClassVisitor cv) throws IOException;
}
public static MethodNode findMethod(ObfMapping methodmap, ClassNode cnode) {
for (MethodNode mnode : cnode.methods)
if (methodmap.matches(mnode))
return mnode;
for (MethodNode mnode : cnode.methods) if (methodmap.matches(mnode)) return mnode;
return null;
}
public static FieldNode findField(ObfMapping fieldmap, ClassNode cnode) {
for (FieldNode fnode : cnode.fields)
if (fieldmap.matches(fnode))
return fnode;
for (FieldNode fnode : cnode.fields) if (fieldmap.matches(fnode)) return fnode;
return null;
}
@@ -86,23 +80,24 @@ public class ASMHelper
return new InsnListSection(list).copy(labelMap).list;
}
public static List<TryCatchBlockNode> cloneTryCatchBlocks(Map<LabelNode, LabelNode> labelMap, List<TryCatchBlockNode> tcblocks) {
public static List<TryCatchBlockNode> cloneTryCatchBlocks(
Map<LabelNode, LabelNode> labelMap, List<TryCatchBlockNode> tcblocks) {
ArrayList<TryCatchBlockNode> clone = new ArrayList<TryCatchBlockNode>();
for (TryCatchBlockNode node : tcblocks)
clone.add(new TryCatchBlockNode(
labelMap.get(node.start),
labelMap.get(node.end),
labelMap.get(node.handler),
node.type));
labelMap.get(node.start), labelMap.get(node.end), labelMap.get(node.handler), node.type));
return clone;
}
public static List<LocalVariableNode> cloneLocals(Map<LabelNode, LabelNode> labelMap, List<LocalVariableNode> locals) {
public static List<LocalVariableNode> cloneLocals(
Map<LabelNode, LabelNode> labelMap, List<LocalVariableNode> locals) {
ArrayList<LocalVariableNode> clone = new ArrayList<LocalVariableNode>(locals.size());
for (LocalVariableNode node : locals)
clone.add(new LocalVariableNode(
node.name, node.desc, node.signature,
node.name,
node.desc,
node.signature,
labelMap.get(node.start),
labelMap.get(node.end),
node.index));
@@ -114,8 +109,7 @@ public class ASMHelper
Map<LabelNode, LabelNode> labelMap = cloneLabels(src.instructions);
dst.instructions = cloneInsnList(labelMap, src.instructions);
dst.tryCatchBlocks = cloneTryCatchBlocks(labelMap, src.tryCatchBlocks);
if (src.localVariables != null)
dst.localVariables = cloneLocals(labelMap, src.localVariables);
if (src.localVariables != null) dst.localVariables = cloneLocals(labelMap, src.localVariables);
dst.visibleAnnotations = src.visibleAnnotations;
dst.invisibleAnnotations = src.invisibleAnnotations;
dst.visitMaxs(src.maxStack, src.maxLocals);
@@ -130,7 +124,8 @@ public class ASMHelper
for (LocalVariableNode node : list) {
if (node.name.equals(name)) {
if (found >= 0)
throw new RuntimeException("Duplicate local variable: " + name + " not coded to handle this scenario.");
throw new RuntimeException(
"Duplicate local variable: " + name + " not coded to handle this scenario.");
found = node.index;
}
@@ -140,24 +135,21 @@ public class ASMHelper
public static void replaceMethod(MethodNode original, MethodNode replacement) {
original.instructions.clear();
if (original.localVariables != null)
original.localVariables.clear();
if (original.tryCatchBlocks != null)
original.tryCatchBlocks.clear();
if (original.localVariables != null) original.localVariables.clear();
if (original.tryCatchBlocks != null) original.tryCatchBlocks.clear();
replacement.accept(original);
}
public static void dump(Acceptor acceptor, File file, boolean filterImportant, boolean sortLocals, boolean textify) {
public static void dump(
Acceptor acceptor, File file, boolean filterImportant, boolean sortLocals, boolean textify) {
try {
if(!file.getParentFile().exists())
file.getParentFile().mkdirs();
if(!file.exists())
file.createNewFile();
if (!file.getParentFile().exists()) file.getParentFile().mkdirs();
if (!file.exists()) file.createNewFile();
PrintWriter pout = new PrintWriter(file);
ClassVisitor cv = new TraceClassVisitor(null, textify ? new Textifier() : new ASMifier(), pout);
if(filterImportant) cv = new ImportantInsnVisitor(cv);
if(sortLocals) cv = new LocalVariablesSorterVisitor(cv);
if (filterImportant) cv = new ImportantInsnVisitor(cv);
if (sortLocals) cv = new LocalVariablesSorterVisitor(cv);
acceptor.accept(cv);
pout.close();
} catch (IOException e) {
@@ -166,36 +158,50 @@ public class ASMHelper
}
public static void dump(Acceptor acceptor, File file, boolean filterImportant, boolean sortLocals) {
dump(acceptor, file, filterImportant, sortLocals, config.getTag("textify").getBooleanValue(true));
dump(
acceptor,
file,
filterImportant,
sortLocals,
config.getTag("textify").getBooleanValue(true));
}
public static void dump(final byte[] bytes, File file, boolean filterImportant, boolean sortLocals) {
dump(new Acceptor()
{
@Override
public void accept(ClassVisitor cv) {
new ClassReader(bytes).accept(cv, ClassReader.EXPAND_FRAMES);
}
}, file, filterImportant, sortLocals);
dump(
new Acceptor() {
@Override
public void accept(ClassVisitor cv) {
new ClassReader(bytes).accept(cv, ClassReader.EXPAND_FRAMES);
}
},
file,
filterImportant,
sortLocals);
}
public static void dump(final InputStream is, File file, boolean filterImportant, boolean sortLocals) {
dump(new Acceptor()
{
@Override
public void accept(ClassVisitor cv) throws IOException {
new ClassReader(is).accept(cv, ClassReader.EXPAND_FRAMES);
}
}, file, filterImportant, sortLocals);
dump(
new Acceptor() {
@Override
public void accept(ClassVisitor cv) throws IOException {
new ClassReader(is).accept(cv, ClassReader.EXPAND_FRAMES);
}
},
file,
filterImportant,
sortLocals);
}
public static void dump(final ClassNode cnode, File file, boolean filterImportant, boolean sortLocals) {
dump(new Acceptor()
{
@Override
public void accept(ClassVisitor cv) {
cnode.accept(cv);
}
}, file, filterImportant, sortLocals);
dump(
new Acceptor() {
@Override
public void accept(ClassVisitor cv) {
cnode.accept(cv);
}
},
file,
filterImportant,
sortLocals);
}
}
@@ -5,11 +5,11 @@ import net.minecraft.launchwrapper.Launch;
/**
* Initialisation class for using this package. Call this on coremod load
*/
public class ASMInit
{
public class ASMInit {
private static boolean initialised = false;
public static void init() {
if(!initialised) {
if (!initialised) {
Launch.classLoader.addTransformerExclusion("codechicken.lib.asm");
Launch.classLoader.addTransformerExclusion("codechicken.lib.config");
initialised = true;
@@ -1,18 +1,16 @@
package codechicken.lib.asm;
import org.objectweb.asm.tree.*;
import static org.objectweb.asm.Opcodes.*;
import static org.objectweb.asm.tree.AbstractInsnNode.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;
import org.objectweb.asm.tree.*;
import static org.objectweb.asm.Opcodes.*;
import static org.objectweb.asm.tree.AbstractInsnNode.*;
public class ASMReader
{
public class ASMReader {
public static Map<String, Integer> opCodes = new HashMap<String, Integer>();
public static byte[] TYPE;
@@ -175,14 +173,13 @@ public class ASMReader
opCodes.put("IFNULL", IFNULL);
opCodes.put("IFNONNULL", IFNONNULL);
//derived from classWriter, mapped to AbstractInsnNode
// derived from classWriter, mapped to AbstractInsnNode
TYPE = new byte[200];
String s = "AAAAAAAAAAAAAAAABBJ__CCCCC____________________AAAAAAAACC"
+ "CCC____________________AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+ "AAAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAHHHHHHHHHHHHHHHHCLMAA"
+ "AAAAEEEEFFFFGDBDAADDAA_NHH";
for (int i = 0; i < s.length(); i++)
TYPE[i] = (byte) (s.charAt(i) - 'A');
for (int i = 0; i < s.length(); i++) TYPE[i] = (byte) (s.charAt(i) - 'A');
}
public static Map<String, ASMBlock> loadResource(String res) {
@@ -217,10 +214,8 @@ public class ASMReader
if (i_opcode == null) {
if (split[0].equals("LINENUMBER"))
insn = new LineNumberNode(Integer.parseInt(split[1]), block.getOrAdd(split[2]));
else if (split[0].startsWith("L"))
insn = block.getOrAdd(split[0]);
else
throw new Exception("Unknown opcode " + split[0]);
else if (split[0].startsWith("L")) insn = block.getOrAdd(split[0]);
else throw new Exception("Unknown opcode " + split[0]);
} else {
int opcode = i_opcode;
switch (TYPE[opcode]) {
@@ -239,9 +234,10 @@ public class ASMReader
case FIELD_INSN:
case METHOD_INSN:
StringBuilder sb = new StringBuilder();
for (int i = 1; i < split.length; i++)
sb.append(split[i]);
insn = ObfMapping.fromDesc(sb.toString()).toClassloading().toInsn(opcode);
for (int i = 1; i < split.length; i++) sb.append(split[i]);
insn = ObfMapping.fromDesc(sb.toString())
.toClassloading()
.toInsn(opcode);
break;
case INVOKE_DYNAMIC_INSN:
throw new Exception("Found INVOKEDYNAMIC while reading");
@@ -250,20 +246,16 @@ public class ASMReader
break;
case LDC_INSN:
String cst = split[1];
if(cst.equals("*"))
insn = new LdcInsnNode(null);
else if (cst.endsWith("\""))
insn = new LdcInsnNode(cst.substring(1, cst.length() - 1));
if (cst.equals("*")) insn = new LdcInsnNode(null);
else if (cst.endsWith("\"")) insn = new LdcInsnNode(cst.substring(1, cst.length() - 1));
else if (cst.endsWith("L"))
insn = new LdcInsnNode(Long.valueOf(cst.substring(0, cst.length() - 1)));
else if (cst.endsWith("F"))
insn = new LdcInsnNode(Float.valueOf(cst.substring(0, cst.length() - 1)));
else if (cst.endsWith("D"))
insn = new LdcInsnNode(Double.valueOf(cst.substring(0, cst.length() - 1)));
else if (cst.contains("."))
insn = new LdcInsnNode(Double.valueOf(cst));
else
insn = new LdcInsnNode(Integer.valueOf(cst));
else if (cst.contains(".")) insn = new LdcInsnNode(Double.valueOf(cst));
else insn = new LdcInsnNode(Integer.valueOf(cst));
break;
case IINC_INSN:
insn = new IincInsnNode(opcode, Integer.parseInt(split[1]));
@@ -281,11 +273,9 @@ public class ASMReader
}
}
if (insn != null)
block.list.add(insn);
if (insn != null) block.list.add(insn);
} catch (Exception e) {
System.err.println("Error while reading ASM Block " +
current + " from " + res + ", line: " + line);
System.err.println("Error while reading ASM Block " + current + " from " + res + ", line: " + line);
e.printStackTrace();
}
}
@@ -2,36 +2,27 @@ package codechicken.lib.asm;
import org.objectweb.asm.ClassWriter;
public class CC_ClassWriter extends ClassWriter
{
public class CC_ClassWriter extends ClassWriter {
private final boolean runtime;
public CC_ClassWriter(int flags)
{
public CC_ClassWriter(int flags) {
this(flags, false);
}
public CC_ClassWriter(int flags, boolean runtime)
{
public CC_ClassWriter(int flags, boolean runtime) {
super(flags);
this.runtime = runtime;
}
@Override
protected String getCommonSuperClass(String type1, String type2)
{
protected String getCommonSuperClass(String type1, String type2) {
String c = type1.replace('/', '.');
String d = type2.replace('/', '.');
if(ClassHeirachyManager.classExtends(d, c))
return type1;
if(ClassHeirachyManager.classExtends(c, d))
return type2;
do
{
if (ClassHeirachyManager.classExtends(d, c)) return type1;
if (ClassHeirachyManager.classExtends(c, d)) return type2;
do {
c = ClassHeirachyManager.getSuperClass(c, runtime);
}
while(!ClassHeirachyManager.classExtends(d, c));
} while (!ClassHeirachyManager.classExtends(d, c));
return c.replace('.', '/');
}
}
@@ -1,26 +1,23 @@
package codechicken.lib.asm;
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import net.minecraft.launchwrapper.IClassTransformer;
import net.minecraft.launchwrapper.Launch;
import net.minecraft.launchwrapper.LaunchClassLoader;
import org.objectweb.asm.tree.ClassNode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
/**
* This is added as a class transformer if CodeChickenCore is installed. Adding it as a class transformer will speed evaluation up slightly by automatically caching superclasses when they are first loaded.
*/
public class ClassHeirachyManager implements IClassTransformer
{
public class ClassHeirachyManager implements IClassTransformer {
static {
ASMInit.init();
}
public static class SuperCache
{
public static class SuperCache {
String superclass;
public HashSet<String> parents = new HashSet<String>();
private boolean flattened;
@@ -30,8 +27,7 @@ public class ClassHeirachyManager implements IClassTransformer
}
public void flatten() {
if (flattened)
return;
if (flattened) return;
for (String s : new ArrayList<String>(parents)) {
SuperCache c = declareClass(s);
@@ -55,7 +51,9 @@ public class ClassHeirachyManager implements IClassTransformer
public static String unKey(String name) {
if (ObfMapping.obfuscated)
name = FMLDeobfuscatingRemapper.INSTANCE.unmap(name.replace('.', '/')).replace('/', '.');
name = FMLDeobfuscatingRemapper.INSTANCE
.unmap(name.replace('.', '/'))
.replace('/', '.');
return name;
}
@@ -68,12 +66,11 @@ public class ClassHeirachyManager implements IClassTransformer
name = toKey(name);
superclass = toKey(superclass);
if (name.equals(superclass))
return true;
if (name.equals(superclass)) return true;
SuperCache cache = declareClass(name);
if (cache == null)//just can't handle this
return false;
if (cache == null) // just can't handle this
return false;
cache.flatten();
return cache.parents.contains(superclass);
@@ -83,19 +80,15 @@ public class ClassHeirachyManager implements IClassTransformer
name = toKey(name);
SuperCache cache = superclasses.get(name);
if (cache != null)
return cache;
if (cache != null) return cache;
try {
byte[] bytes = cl.getClassBytes(unKey(name));
if (bytes != null)
cache = declareASM(bytes);
if (bytes != null) cache = declareASM(bytes);
} catch (Exception e) {
}
if (cache != null)
return cache;
if (cache != null) return cache;
try {
cache = declareReflection(name);
@@ -109,16 +102,12 @@ public class ClassHeirachyManager implements IClassTransformer
Class<?> aclass = Class.forName(name);
SuperCache cache = getOrCreateCache(name);
if (aclass.isInterface())
cache.superclass = "java.lang.Object";
else if (name.equals("java.lang.Object"))
return cache;
else
cache.superclass = toKey(aclass.getSuperclass().getName());
if (aclass.isInterface()) cache.superclass = "java.lang.Object";
else if (name.equals("java.lang.Object")) return cache;
else cache.superclass = toKey(aclass.getSuperclass().getName());
cache.add(cache.superclass);
for (Class<?> iclass : aclass.getInterfaces())
cache.add(toKey(iclass.getName()));
for (Class<?> iclass : aclass.getInterfaces()) cache.add(toKey(iclass.getName()));
return cache;
}
@@ -130,40 +119,34 @@ public class ClassHeirachyManager implements IClassTransformer
SuperCache cache = getOrCreateCache(name);
cache.superclass = toKey(node.superName.replace('/', '.'));
cache.add(cache.superclass);
for (String iclass : node.interfaces)
cache.add(toKey(iclass.replace('/', '.')));
for (String iclass : node.interfaces) cache.add(toKey(iclass.replace('/', '.')));
return cache;
}
@Override
public byte[] transform(String name, String tname, byte[] bytes) {
if (bytes == null)
return null;
if (bytes == null) return null;
if (!superclasses.containsKey(tname))
declareASM(bytes);
if (!superclasses.containsKey(tname)) declareASM(bytes);
return bytes;
}
public static SuperCache getOrCreateCache(String name) {
SuperCache cache = superclasses.get(name);
if (cache == null)
superclasses.put(name, cache = new SuperCache());
if (cache == null) superclasses.put(name, cache = new SuperCache());
return cache;
}
public static String getSuperClass(String name, boolean runtime) {
name = toKey(name);
SuperCache cache = declareClass(name);
if (cache == null)
return "java.lang.Object";
if (cache == null) return "java.lang.Object";
cache.flatten();
String s = cache.superclass;
if (!runtime)
s = FMLDeobfuscatingRemapper.INSTANCE.unmap(s);
if (!runtime) s = FMLDeobfuscatingRemapper.INSTANCE.unmap(s);
return s;
}
}
@@ -5,10 +5,8 @@ import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.MethodNode;
public class ImportantInsnVisitor extends ClassVisitor
{
public class ImportantInsnMethodVisitor extends MethodVisitor
{
public class ImportantInsnVisitor extends ClassVisitor {
public class ImportantInsnMethodVisitor extends MethodVisitor {
MethodVisitor delegate;
public ImportantInsnMethodVisitor(int access, String name, String desc, String signature, String[] exceptions) {
@@ -19,7 +17,7 @@ public class ImportantInsnVisitor extends ClassVisitor
@Override
public void visitEnd() {
super.visitEnd();
MethodNode mnode = (MethodNode)mv;
MethodNode mnode = (MethodNode) mv;
mnode.instructions = InsnComparator.getImportantList(mnode.instructions);
mnode.accept(delegate);
}
@@ -1,15 +1,13 @@
package codechicken.lib.asm;
import com.google.common.base.Function;
import com.google.common.collect.Maps;
import org.objectweb.asm.tree.*;
import java.util.*;
import static org.objectweb.asm.tree.AbstractInsnNode.*;
public class InsnComparator
{
import com.google.common.base.Function;
import com.google.common.collect.Maps;
import java.util.*;
import org.objectweb.asm.tree.*;
public class InsnComparator {
public static boolean varInsnEqual(VarInsnNode insn1, VarInsnNode insn2) {
return insn1.var == -1 || insn2.var == -1 || insn1.var == insn2.var;
}
@@ -39,8 +37,7 @@ public class InsnComparator
}
public static boolean insnEqual(AbstractInsnNode node1, AbstractInsnNode node2) {
if (node1.getOpcode() != node2.getOpcode())
return false;
if (node1.getOpcode() != node2.getOpcode()) return false;
switch (node2.getType()) {
case VAR_INSN:
@@ -63,7 +60,7 @@ public class InsnComparator
}
public static boolean insnImportant(AbstractInsnNode insn, Set<LabelNode> controlFlowLabels) {
switch(insn.getType()) {
switch (insn.getType()) {
case LINE:
case FRAME:
return false;
@@ -89,14 +86,12 @@ public class InsnComparator
case TABLESWITCH_INSN:
TableSwitchInsnNode tsinsn = (TableSwitchInsnNode) insn;
controlFlowLabels.add(tsinsn.dflt);
for (LabelNode label : tsinsn.labels)
controlFlowLabels.add(label);
for (LabelNode label : tsinsn.labels) controlFlowLabels.add(label);
break;
case LOOKUPSWITCH_INSN:
LookupSwitchInsnNode lsinsn = (LookupSwitchInsnNode) insn;
controlFlowLabels.add(lsinsn.dflt);
for (LabelNode label : lsinsn.labels)
controlFlowLabels.add(label);
for (LabelNode label : lsinsn.labels) controlFlowLabels.add(label);
break;
}
}
@@ -108,12 +103,10 @@ public class InsnComparator
}
public static InsnListSection getImportantList(InsnListSection list) {
if (list.size() == 0)
return list;
if (list.size() == 0) return list;
Set<LabelNode> controlFlowLabels = getControlFlowLabels(list);
Map<LabelNode, LabelNode> labelMap = Maps.asMap(controlFlowLabels, new Function<LabelNode, LabelNode>()
{
Map<LabelNode, LabelNode> labelMap = Maps.asMap(controlFlowLabels, new Function<LabelNode, LabelNode>() {
@Override
public LabelNode apply(LabelNode input) {
return input;
@@ -121,9 +114,8 @@ public class InsnComparator
});
InsnListSection importantNodeList = new InsnListSection();
for(AbstractInsnNode insn : list)
if (insnImportant(insn, controlFlowLabels))
importantNodeList.add(insn.clone(labelMap));
for (AbstractInsnNode insn : list)
if (insnImportant(insn, controlFlowLabels)) importantNodeList.add(insn.clone(labelMap));
return importantNodeList;
}
@@ -135,7 +127,7 @@ public class InsnComparator
InsnListSection section = matches(haystack.drop(start), needle, controlFlowLabels);
if (section != null) {
list.add(section);
start = section.end-1;
start = section.end - 1;
}
}
@@ -146,27 +138,26 @@ public class InsnComparator
return find(new InsnListSection(haystack), needle);
}
public static InsnListSection matches(InsnListSection haystack, InsnListSection needle, Set<LabelNode> controlFlowLabels) {
public static InsnListSection matches(
InsnListSection haystack, InsnListSection needle, Set<LabelNode> controlFlowLabels) {
int h = 0, n = 0;
for (; h < haystack.size() && n < needle.size(); h++) {
AbstractInsnNode insn = haystack.get(h);
if(!insnImportant(insn, controlFlowLabels))
continue;
if (!insnImportant(insn, controlFlowLabels)) continue;
if (!insnEqual(haystack.get(h), needle.get(n)))
return null;
if (!insnEqual(haystack.get(h), needle.get(n))) return null;
n++;
}
if (n != needle.size())
return null;
if (n != needle.size()) return null;
return haystack.take(h);
}
public static InsnListSection findOnce(InsnListSection haystack, InsnListSection needle) {
List<InsnListSection> list = find(haystack, needle);
if(list.size() != 1)
throw new RuntimeException("Needle found " + list.size() + " times in Haystack:\n" + haystack + "\n\n" + needle);
if (list.size() != 1)
throw new RuntimeException(
"Needle found " + list.size() + " times in Haystack:\n" + haystack + "\n\n" + needle);
return list.get(0);
}
@@ -177,8 +168,7 @@ public class InsnComparator
public static List<InsnListSection> findN(InsnListSection haystack, InsnListSection needle) {
List<InsnListSection> list = find(haystack, needle);
if(list.isEmpty())
throw new RuntimeException("Needle not found in Haystack:\n" + haystack + "\n\n" + needle);
if (list.isEmpty()) throw new RuntimeException("Needle not found in Haystack:\n" + haystack + "\n\n" + needle);
return list;
}
@@ -1,9 +1,6 @@
package codechicken.lib.asm;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.tree.*;
import org.objectweb.asm.util.Textifier;
import org.objectweb.asm.util.TraceMethodVisitor;
import static org.objectweb.asm.tree.AbstractInsnNode.*;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -12,16 +9,16 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import static org.objectweb.asm.tree.AbstractInsnNode.*;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.tree.*;
import org.objectweb.asm.util.Textifier;
import org.objectweb.asm.util.TraceMethodVisitor;
/**
* A section of an InsnList, may become invalid if the insn list is modified
*/
public class InsnListSection implements Iterable<AbstractInsnNode>
{
private class InsnListSectionIterator implements Iterator<AbstractInsnNode>
{
public class InsnListSection implements Iterable<AbstractInsnNode> {
private class InsnListSectionIterator implements Iterator<AbstractInsnNode> {
int i = 0;
@Override
@@ -51,7 +48,7 @@ public class InsnListSection implements Iterable<AbstractInsnNode>
}
public InsnListSection(InsnList list, AbstractInsnNode first, AbstractInsnNode last) {
this(list, list.indexOf(first), list.indexOf(last)+1);
this(list, list.indexOf(first), list.indexOf(last) + 1);
}
public InsnListSection(InsnList list) {
@@ -63,8 +60,7 @@ public class InsnListSection implements Iterable<AbstractInsnNode>
}
public void accept(MethodVisitor mv) {
for(AbstractInsnNode insn : this)
insn.accept(mv);
for (AbstractInsnNode insn : this) insn.accept(mv);
}
public AbstractInsnNode getFirst() {
@@ -103,35 +99,30 @@ public class InsnListSection implements Iterable<AbstractInsnNode>
public void insertBefore(InsnList insns) {
int s = insns.size();
if(this.list.size() == 0)
list.insert(insns);
else
list.insertBefore(list.get(start), insns);
start+=s;
end+=s;
if (this.list.size() == 0) list.insert(insns);
else list.insertBefore(list.get(start), insns);
start += s;
end += s;
}
public void insert(InsnList insns) {
if(end == 0)
list.insert(insns);
else
list.insert(list.get(end-1), insns);
if (end == 0) list.insert(insns);
else list.insert(list.get(end - 1), insns);
}
public void replace(InsnList insns) {
int s = insns.size();
remove();
insert(insns);
end = start+s;
end = start + s;
}
public void remove() {
while(end != start)
remove(0);
while (end != start) remove(0);
}
public void setLast(AbstractInsnNode last) {
end = list.indexOf(last)+1;
end = list.indexOf(last) + 1;
}
public void setFirst(AbstractInsnNode first) {
@@ -147,7 +138,7 @@ public class InsnListSection implements Iterable<AbstractInsnNode>
}
public InsnListSection slice(int start, int end) {
return new InsnListSection(list, this.start+start, this.start+end);
return new InsnListSection(list, this.start + start, this.start + end);
}
/**
@@ -155,11 +146,9 @@ public class InsnListSection implements Iterable<AbstractInsnNode>
* @return this
*/
public InsnListSection trim(Set<LabelNode> controlFlowLabels) {
while(start < end && !InsnComparator.insnImportant(getFirst(), controlFlowLabels))
start++;
while (start < end && !InsnComparator.insnImportant(getFirst(), controlFlowLabels)) start++;
while(start < end && !InsnComparator.insnImportant(getLast(), controlFlowLabels))
end--;
while (start < end && !InsnComparator.insnImportant(getLast(), controlFlowLabels)) end--;
return this;
}
@@ -176,38 +165,34 @@ public class InsnListSection implements Iterable<AbstractInsnNode>
System.out.println(toString());
}
public HashMap<LabelNode,LabelNode> identityLabelMap() {
public HashMap<LabelNode, LabelNode> identityLabelMap() {
HashMap<LabelNode, LabelNode> labelMap = new HashMap<LabelNode, LabelNode>();
for (AbstractInsnNode insn : this)
switch(insn.getType()) {
switch (insn.getType()) {
case LABEL:
labelMap.put((LabelNode) insn, (LabelNode) insn);
break;
case JUMP_INSN:
labelMap.put(((JumpInsnNode)insn).label, ((JumpInsnNode)insn).label);
labelMap.put(((JumpInsnNode) insn).label, ((JumpInsnNode) insn).label);
break;
case LOOKUPSWITCH_INSN:
LookupSwitchInsnNode linsn = (LookupSwitchInsnNode)insn;
LookupSwitchInsnNode linsn = (LookupSwitchInsnNode) insn;
labelMap.put(linsn.dflt, linsn.dflt);
for(LabelNode label : linsn.labels)
labelMap.put(label, label);
for (LabelNode label : linsn.labels) labelMap.put(label, label);
break;
case TABLESWITCH_INSN:
TableSwitchInsnNode tinsn = (TableSwitchInsnNode)insn;
TableSwitchInsnNode tinsn = (TableSwitchInsnNode) insn;
labelMap.put(tinsn.dflt, tinsn.dflt);
for(LabelNode label : tinsn.labels)
labelMap.put(label, label);
for (LabelNode label : tinsn.labels) labelMap.put(label, label);
break;
case FRAME:
FrameNode fnode = (FrameNode)insn;
if(fnode.local != null)
for(Object o : fnode.local)
if(o instanceof LabelNode)
labelMap.put((LabelNode) o, (LabelNode) o);
if(fnode.stack != null)
for(Object o : fnode.stack)
if(o instanceof LabelNode)
labelMap.put((LabelNode) o, (LabelNode) o);
FrameNode fnode = (FrameNode) insn;
if (fnode.local != null)
for (Object o : fnode.local)
if (o instanceof LabelNode) labelMap.put((LabelNode) o, (LabelNode) o);
if (fnode.stack != null)
for (Object o : fnode.stack)
if (o instanceof LabelNode) labelMap.put((LabelNode) o, (LabelNode) o);
break;
}
@@ -216,8 +201,7 @@ public class InsnListSection implements Iterable<AbstractInsnNode>
public Map<LabelNode, LabelNode> cloneLabels() {
Map<LabelNode, LabelNode> labelMap = identityLabelMap();
for(Entry<LabelNode, LabelNode> entry : labelMap.entrySet())
entry.setValue(new LabelNode());
for (Entry<LabelNode, LabelNode> entry : labelMap.entrySet()) entry.setValue(new LabelNode());
return labelMap;
}
@@ -228,8 +212,7 @@ public class InsnListSection implements Iterable<AbstractInsnNode>
public InsnListSection copy(Map<LabelNode, LabelNode> labelMap) {
InsnListSection copy = new InsnListSection();
for(AbstractInsnNode insn : this)
copy.add(insn.clone(labelMap));
for (AbstractInsnNode insn : this) copy.add(insn.clone(labelMap));
return copy;
}
@@ -238,4 +221,4 @@ public class InsnListSection implements Iterable<AbstractInsnNode>
public Iterator<AbstractInsnNode> iterator() {
return new InsnListSectionIterator();
}
}
}
@@ -1,37 +1,35 @@
package codechicken.lib.asm;
import java.util.Set;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.LocalVariablesSorter;
import java.util.Set;
public class LocalVariablesSorterVisitor extends ClassVisitor {
public Set<ObfMapping> methods;
public String owner;
public class LocalVariablesSorterVisitor extends ClassVisitor
{
public Set<ObfMapping> methods;
public String owner;
public LocalVariablesSorterVisitor(Set<ObfMapping> methods, ClassVisitor cv) {
super(Opcodes.ASM4, cv);
this.methods = methods;
}
public LocalVariablesSorterVisitor(ClassVisitor cv) {
this(null, cv);
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
owner = name;
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
return methods == null || methods.contains(new ObfMapping(owner, name, desc)) ? new LocalVariablesSorter(access, desc, mv) : mv;
}
public LocalVariablesSorterVisitor(Set<ObfMapping> methods, ClassVisitor cv) {
super(Opcodes.ASM4, cv);
this.methods = methods;
}
public LocalVariablesSorterVisitor(ClassVisitor cv) {
this(null, cv);
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
owner = name;
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
return methods == null || methods.contains(new ObfMapping(owner, name, desc))
? new LocalVariablesSorter(access, desc, mv)
: mv;
}
}
@@ -1,19 +1,16 @@
package codechicken.lib.asm;
import static codechicken.lib.asm.ASMHelper.*;
import java.io.File;
import java.util.*;
import org.objectweb.asm.*;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.MethodNode;
import java.io.File;
import java.util.*;
import static codechicken.lib.asm.ASMHelper.*;
public class ModularASMTransformer
{
public static class ClassNodeTransformerList
{
public class ModularASMTransformer {
public static class ClassNodeTransformerList {
List<ClassNodeTransformer> transformers = new LinkedList<ClassNodeTransformer>();
HashSet<ObfMapping> methodsToSort = new HashSet<ObfMapping>();
@@ -26,31 +23,30 @@ public class ModularASMTransformer
ClassNode cnode = new ClassNode();
ClassReader reader = new ClassReader(bytes);
ClassVisitor cv = cnode;
if(!methodsToSort.isEmpty())
cv = new LocalVariablesSorterVisitor(methodsToSort, cv);
if (!methodsToSort.isEmpty()) cv = new LocalVariablesSorterVisitor(methodsToSort, cv);
reader.accept(cv, ClassReader.EXPAND_FRAMES);
try {
int writeFlags = 0;
for(ClassNodeTransformer t : transformers) {
for (ClassNodeTransformer t : transformers) {
t.transform(cnode);
writeFlags|=t.writeFlags;
writeFlags |= t.writeFlags;
}
bytes = createBytes(cnode, writeFlags);
if(config.getTag("dump_asm").getBooleanValue(false))
dump(bytes, new File("asm/ccl_modular/"+cnode.name.replace('/', '#')+".txt"), false, false);
if (config.getTag("dump_asm").getBooleanValue(false))
dump(bytes, new File("asm/ccl_modular/" + cnode.name.replace('/', '#') + ".txt"), false, false);
return bytes;
} catch (RuntimeException e) {
dump(bytes, new File("asm/ccl_modular/"+cnode.name.replace('/', '#')+".txt"), false, false);
dump(bytes, new File("asm/ccl_modular/" + cnode.name.replace('/', '#') + ".txt"), false, false);
throw e;
}
}
}
public static abstract class ClassNodeTransformer
{
public abstract static class ClassNodeTransformer {
public int writeFlags;
public ClassNodeTransformer(int writeFlags) {
this.writeFlags = writeFlags;
}
@@ -60,13 +56,13 @@ public class ModularASMTransformer
}
public abstract String className();
public abstract void transform(ClassNode cnode);
public void addMethodsToSort(Set<ObfMapping> set) {}
}
public static abstract class MethodTransformer extends ClassNodeTransformer
{
public abstract static class MethodTransformer extends ClassNodeTransformer {
public final ObfMapping method;
public MethodTransformer(ObfMapping method) {
@@ -81,28 +77,26 @@ public class ModularASMTransformer
@Override
public void transform(ClassNode cnode) {
MethodNode mv = findMethod(method, cnode);
if (mv == null)
throw new RuntimeException("Method not found: " + method);
if (mv == null) throw new RuntimeException("Method not found: " + method);
try {
transform(mv);
} catch (Exception e) {
throw new RuntimeException("Error transforming method: "+method, e);
throw new RuntimeException("Error transforming method: " + method, e);
}
}
public abstract void transform(MethodNode mv);
}
public static class MethodWriter extends ClassNodeTransformer
{
public static class MethodWriter extends ClassNodeTransformer {
public final int access;
public final ObfMapping method;
public final String[] exceptions;
public InsnList list;
public MethodWriter(int access, ObfMapping method) {
this(access, method, null, (InsnList)null);
this(access, method, null, (InsnList) null);
}
public MethodWriter(int access, ObfMapping method, InsnList list) {
@@ -114,7 +108,7 @@ public class ModularASMTransformer
}
public MethodWriter(int access, ObfMapping method, String[] exceptions) {
this(access, method, exceptions, (InsnList)null);
this(access, method, exceptions, (InsnList) null);
}
public MethodWriter(int access, ObfMapping method, String[] exceptions, InsnList list) {
@@ -136,28 +130,24 @@ public class ModularASMTransformer
@Override
public void transform(ClassNode cnode) {
MethodNode mv = findMethod(method, cnode);
if(mv == null)
mv = (MethodNode) method.visitMethod(cnode, access, exceptions);
if (mv == null) mv = (MethodNode) method.visitMethod(cnode, access, exceptions);
else {
mv.access = access;
mv.instructions.clear();
if (mv.localVariables != null)
mv.localVariables.clear();
if (mv.tryCatchBlocks != null)
mv.tryCatchBlocks.clear();
if (mv.localVariables != null) mv.localVariables.clear();
if (mv.tryCatchBlocks != null) mv.tryCatchBlocks.clear();
}
write(mv);
}
public void write(MethodNode mv) {
logger.debug("Writing method "+method);
logger.debug("Writing method " + method);
list.accept(mv);
}
}
public static class MethodInjector extends MethodTransformer
{
public static class MethodInjector extends MethodTransformer {
public ASMBlock needle;
public ASMBlock injection;
public boolean before;
@@ -188,29 +178,24 @@ public class ModularASMTransformer
@Override
public void transform(MethodNode mv) {
if(needle == null) {
logger.debug("Injecting "+(before ? "before" : "after")+" method "+method);
if (before)
mv.instructions.insert(injection.rawListCopy());
else
mv.instructions.add(injection.rawListCopy());
}
else {
if (needle == null) {
logger.debug("Injecting " + (before ? "before" : "after") + " method " + method);
if (before) mv.instructions.insert(injection.rawListCopy());
else mv.instructions.add(injection.rawListCopy());
} else {
for (InsnListSection key : InsnComparator.findN(mv.instructions, needle.list)) {
logger.debug("Injecting "+(before ? "before" : "after")+" method "+method+" @ "+key.start+" - "+key.end);
logger.debug("Injecting " + (before ? "before" : "after") + " method " + method + " @ " + key.start
+ " - " + key.end);
ASMBlock injectBlock = injection.copy().mergeLabels(needle.applyLabels(key));
if (before)
key.insertBefore(injectBlock.list.list);
else
key.insert(injectBlock.list.list);
if (before) key.insertBefore(injectBlock.list.list);
else key.insert(injectBlock.list.list);
}
}
}
}
public static class MethodReplacer extends MethodTransformer
{
public static class MethodReplacer extends MethodTransformer {
public ASMBlock needle;
public ASMBlock replacement;
@@ -232,15 +217,14 @@ public class ModularASMTransformer
@Override
public void transform(MethodNode mv) {
for (InsnListSection key : InsnComparator.findN(mv.instructions, needle.list)) {
logger.debug("Replacing method "+method+" @ "+key.start+" - "+key.end);
logger.debug("Replacing method " + method + " @ " + key.start + " - " + key.end);
ASMBlock replaceBlock = replacement.copy().pullLabels(needle.applyLabels(key));
key.insert(replaceBlock.list.list);
}
}
}
public static class FieldWriter extends ClassNodeTransformer
{
public static class FieldWriter extends ClassNodeTransformer {
public final ObfMapping field;
public final int access;
public final Object value;
@@ -270,14 +254,12 @@ public class ModularASMTransformer
public void add(ClassNodeTransformer t) {
ClassNodeTransformerList list = transformers.get(t.className());
if(list == null)
transformers.put(t.className(), list = new ClassNodeTransformerList());
if (list == null) transformers.put(t.className(), list = new ClassNodeTransformerList());
list.add(t);
}
public byte[] transform(String name, byte[] bytes) {
if(bytes == null)
return null;
if (bytes == null) return null;
ClassNodeTransformerList list = transformers.get(name);
return list == null ? bytes : list.transform(bytes);
@@ -7,6 +7,13 @@ import com.google.common.io.LineProcessor;
import com.google.common.io.Resources;
import cpw.mods.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
import cpw.mods.fml.relauncher.FMLInjectionData;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.*;
import net.minecraft.launchwrapper.Launch;
import net.minecraftforge.common.ForgeVersion;
import org.objectweb.asm.ClassVisitor;
@@ -15,18 +22,8 @@ import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.commons.Remapper;
import org.objectweb.asm.tree.*;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class ObfMapping
{
public static class ObfRemapper extends Remapper
{
public class ObfMapping {
public static class ObfRemapper extends Remapper {
private HashMap<String, String> fields = new HashMap<String, String>();
private HashMap<String, String> funcs = new HashMap<String, String>();
@@ -36,20 +33,27 @@ public class ObfMapping
Field rawMethodMapsField = FMLDeobfuscatingRemapper.class.getDeclaredField("rawMethodMaps");
rawFieldMapsField.setAccessible(true);
rawMethodMapsField.setAccessible(true);
Map<String, Map<String, String>> rawFieldMaps = (Map<String, Map<String, String>>) rawFieldMapsField.get(FMLDeobfuscatingRemapper.INSTANCE);
Map<String, Map<String, String>> rawMethodMaps = (Map<String, Map<String, String>>) rawMethodMapsField.get(FMLDeobfuscatingRemapper.INSTANCE);
Map<String, Map<String, String>> rawFieldMaps =
(Map<String, Map<String, String>>) rawFieldMapsField.get(FMLDeobfuscatingRemapper.INSTANCE);
Map<String, Map<String, String>> rawMethodMaps =
(Map<String, Map<String, String>>) rawMethodMapsField.get(FMLDeobfuscatingRemapper.INSTANCE);
if (rawFieldMaps == null)
throw new IllegalStateException("codechicken.lib.asm.ObfMapping loaded too early. Make sure all references are in or after the asm transformer load stage");
throw new IllegalStateException(
"codechicken.lib.asm.ObfMapping loaded too early. Make sure all references are in or after the asm transformer load stage");
for (Map<String, String> map : rawFieldMaps.values())
for (Entry<String, String> entry : map.entrySet())
if (entry.getValue().startsWith("field"))
fields.put(entry.getValue(), entry.getKey().substring(0, entry.getKey().indexOf(':')));
fields.put(
entry.getValue(),
entry.getKey().substring(0, entry.getKey().indexOf(':')));
for (Map<String, String> map : rawMethodMaps.values())
for (Entry<String, String> entry : map.entrySet())
if (entry.getValue().startsWith("func"))
funcs.put(entry.getValue(), entry.getKey().substring(0, entry.getKey().indexOf('(')));
funcs.put(
entry.getValue(),
entry.getKey().substring(0, entry.getKey().indexOf('(')));
} catch (Exception e) {
throw new RuntimeException(e);
@@ -82,21 +86,20 @@ public class ObfMapping
}
}
public static class MCPRemapper extends Remapper implements LineProcessor<Void>
{
public static class MCPRemapper extends Remapper implements LineProcessor<Void> {
public static File[] getConfFiles() {
ConfigTag tag = ASMHelper.config.getTag("mappingDir").setComment("Path to directory holding packaged.srg, fields.csv and methods.csv for mcp remapping");
for (int i = 0; i < DIR_GUESSES+DIR_ASKS; i++) {
ConfigTag tag = ASMHelper.config
.getTag("mappingDir")
.setComment("Path to directory holding packaged.srg, fields.csv and methods.csv for mcp remapping");
for (int i = 0; i < DIR_GUESSES + DIR_ASKS; i++) {
File dir = confDirectoryGuess(i, tag);
if (dir == null || dir.isFile())
continue;
if (dir == null || dir.isFile()) continue;
File[] mappings;
try {
mappings = parseConfDir(dir);
} catch (Exception e) {
if (i >= DIR_GUESSES)
e.printStackTrace();
if (i >= DIR_GUESSES) e.printStackTrace();
continue;
}
@@ -109,6 +112,7 @@ public class ObfMapping
private static final int DIR_GUESSES = 5;
private static final int DIR_ASKS = 3;
public static File confDirectoryGuess(int i, ConfigTag tag) {
File mcDir = (File) FMLInjectionData.data()[6];
switch (i) {
@@ -119,11 +123,15 @@ public class ObfMapping
case 2:
return new File(mcDir, "../build/unpacked/conf");
case 3:
return new File(System.getProperty("user.home"), ".gradle/caches/minecraft/net/minecraftforge/forge/"+
FMLInjectionData.data()[4]+"-"+ ForgeVersion.getVersion()+"/unpacked/conf");
return new File(
System.getProperty("user.home"),
".gradle/caches/minecraft/net/minecraftforge/forge/" + FMLInjectionData.data()[4] + "-"
+ ForgeVersion.getVersion() + "/unpacked/conf");
case 4:
return new File(System.getProperty("user.home"), ".gradle/caches/minecraft/net/minecraftforge/forge/"+
FMLInjectionData.data()[4]+"-"+ ForgeVersion.getVersion()+"-"+FMLInjectionData.data()[4]+"/unpacked/conf");
return new File(
System.getProperty("user.home"),
".gradle/caches/minecraft/net/minecraftforge/forge/" + FMLInjectionData.data()[4] + "-"
+ ForgeVersion.getVersion() + "-" + FMLInjectionData.data()[4] + "/unpacked/conf");
default:
JFileChooser fc = new JFileChooser(mcDir);
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
@@ -135,27 +143,21 @@ public class ObfMapping
public static File[] parseConfDir(File confDir) {
File srgDir = new File(confDir, "conf");
if (!srgDir.exists())
srgDir = confDir;
if (!srgDir.exists()) srgDir = confDir;
File srgs = new File(srgDir, "packaged.srg");
if (!srgs.exists())
srgs = new File(srgDir, "joined.srg");
if (!srgs.exists())
throw new RuntimeException("Could not find packaged.srg or joined.srg");
if (!srgs.exists()) srgs = new File(srgDir, "joined.srg");
if (!srgs.exists()) throw new RuntimeException("Could not find packaged.srg or joined.srg");
File mapDir = new File(confDir, "mappings");
if (!mapDir.exists())
mapDir = confDir;
if (!mapDir.exists()) mapDir = confDir;
File methods = new File(mapDir, "methods.csv");
if (!methods.exists())
throw new RuntimeException("Could not find methods.csv");
if (!methods.exists()) throw new RuntimeException("Could not find methods.csv");
File fields = new File(mapDir, "fields.csv");
if (!fields.exists())
throw new RuntimeException("Could not find fields.csv");
if (!fields.exists()) throw new RuntimeException("Could not find fields.csv");
return new File[]{srgs, methods, fields};
return new File[] {srgs, methods, fields};
}
private HashMap<String, String> fields = new HashMap<String, String>();
@@ -204,8 +206,7 @@ public class ObfMapping
public static Remapper mcpMapper = null;
public static void loadMCPRemapper() {
if (mcpMapper == null)
mcpMapper = new MCPRemapper();
if (mcpMapper == null) mcpMapper = new MCPRemapper();
}
public static final boolean obfuscated;
@@ -214,10 +215,10 @@ public class ObfMapping
boolean obf = true;
try {
obf = Launch.classLoader.getClassBytes("net.minecraft.world.World") == null;
} catch (IOException ignored) {}
} catch (IOException ignored) {
}
obfuscated = obf;
if (!obf)
loadMCPRemapper();
if (!obf) loadMCPRemapper();
}
public String s_owner;
@@ -233,8 +234,7 @@ public class ObfMapping
this.s_name = name;
this.s_desc = desc;
if (s_owner.contains("."))
throw new IllegalArgumentException(s_owner);
if (s_owner.contains(".")) throw new IllegalArgumentException(s_owner);
}
public ObfMapping(ObfMapping descmap, String subclass) {
@@ -243,20 +243,18 @@ public class ObfMapping
public static ObfMapping fromDesc(String s) {
int lastDot = s.lastIndexOf('.');
if (lastDot < 0)
return new ObfMapping(s, "", "");
int sep = s.indexOf('(');//methods
if (lastDot < 0) return new ObfMapping(s, "", "");
int sep = s.indexOf('('); // methods
int sep_end = sep;
if (sep < 0) {
sep = s.indexOf(' ');//some stuffs
sep = s.indexOf(' '); // some stuffs
sep_end = sep + 1;
}
if (sep < 0) {
sep = s.indexOf(':');//fields
sep = s.indexOf(':'); // fields
sep_end = sep + 1;
}
if (sep < 0)
return new ObfMapping(s.substring(0, lastDot), s.substring(lastDot + 1), "");
if (sep < 0) return new ObfMapping(s.substring(0, lastDot), s.substring(lastDot + 1), "");
return new ObfMapping(s.substring(0, lastDot), s.substring(lastDot + 1, sep), s.substring(sep_end));
}
@@ -274,12 +272,9 @@ public class ObfMapping
}
public AbstractInsnNode toInsn(int opcode) {
if (isClass())
return new TypeInsnNode(opcode, s_owner);
else if (isMethod())
return new MethodInsnNode(opcode, s_owner, s_name, s_desc);
else
return new FieldInsnNode(opcode, s_owner, s_name, s_desc);
if (isClass()) return new TypeInsnNode(opcode, s_owner);
else if (isMethod()) return new MethodInsnNode(opcode, s_owner, s_name, s_desc);
else return new FieldInsnNode(opcode, s_owner, s_name, s_desc);
}
public void visitTypeInsn(MethodVisitor mv, int opcode) {
@@ -324,8 +319,7 @@ public class ObfMapping
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ObfMapping))
return false;
if (!(obj instanceof ObfMapping)) return false;
ObfMapping desc = (ObfMapping) obj;
return s_owner.equals(desc.s_owner) && s_name.equals(desc.s_name) && s_desc.equals(desc.s_desc);
@@ -338,10 +332,8 @@ public class ObfMapping
@Override
public String toString() {
if (s_name.length() == 0)
return "[" + s_owner + "]";
if (s_desc.length() == 0)
return "[" + s_owner + "." + s_name + "]";
if (s_name.length() == 0) return "[" + s_owner + "]";
if (s_desc.length() == 0) return "[" + s_owner + "." + s_name + "]";
return "[" + (isMethod() ? methodDesc() : fieldDesc()) + "]";
}
@@ -366,20 +358,15 @@ public class ObfMapping
}
public ObfMapping map(Remapper mapper) {
if (mapper == null)
return this;
if (mapper == null) return this;
if (isMethod())
s_name = mapper.mapMethodName(s_owner, s_name, s_desc);
else if (isField())
s_name = mapper.mapFieldName(s_owner, s_name, s_desc);
if (isMethod()) s_name = mapper.mapMethodName(s_owner, s_name, s_desc);
else if (isField()) s_name = mapper.mapFieldName(s_owner, s_name, s_desc);
s_owner = mapper.mapType(s_owner);
if (isMethod())
s_desc = mapper.mapMethodDesc(s_desc);
else if (s_desc.length() > 0)
s_desc = mapper.mapDesc(s_desc);
if (isMethod()) s_desc = mapper.mapMethodDesc(s_desc);
else if (s_desc.length() > 0) s_desc = mapper.mapDesc(s_desc);
return this;
}
@@ -390,10 +377,8 @@ public class ObfMapping
}
public ObfMapping toClassloading() {
if(!obfuscated)
map(mcpMapper);
else if(obfMapper.isObf(s_owner))
map(obfMapper);
if (!obfuscated) map(mcpMapper);
else if (obfMapper.isObf(s_owner)) map(obfMapper);
return this;
}
@@ -5,28 +5,25 @@ import codechicken.lib.math.MathHelper;
import codechicken.lib.util.Copyable;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import org.lwjgl.opengl.GL11;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.lwjgl.opengl.GL11;
public abstract class Colour implements Copyable<Colour>
{
public static IConfigType<Colour> configRGB = new IConfigType<Colour>()
{
public abstract class Colour implements Copyable<Colour> {
public static IConfigType<Colour> configRGB = new IConfigType<Colour>() {
@Override
public String configValue(Colour entry) {
String s = Long.toString(((long) entry.rgb()) << 32 >>> 32, 16);
while (s.length() < 6)
s = "0" + s;
while (s.length() < 6) s = "0" + s;
return "0x" + s.toUpperCase();
}
private final Pattern patternRGB = Pattern.compile("(\\d+),(\\d+),(\\d+)");
@Override
public Colour valueOf(String text) throws Exception {
Matcher matcherRGB = patternRGB.matcher(text.replaceAll("\\s", ""));
if(matcherRGB.matches())
if (matcherRGB.matches())
return new ColourRGBA(
Integer.parseInt(matcherRGB.group(1)),
Integer.parseInt(matcherRGB.group(2)),
@@ -34,7 +31,7 @@ public abstract class Colour implements Copyable<Colour>
0xFF);
int hex = (int) Long.parseLong(text.replace("0x", ""), 16);
return new ColourRGBA(hex<<8|0xFF);
return new ColourRGBA(hex << 8 | 0xFF);
}
};
@@ -43,16 +40,14 @@ public abstract class Colour implements Copyable<Colour>
public byte b;
public byte a;
public Colour(int r, int g, int b, int a)
{
public Colour(int r, int g, int b, int a) {
this.r = (byte) r;
this.g = (byte) g;
this.b = (byte) b;
this.a = (byte) a;
}
public Colour(Colour colour)
{
public Colour(Colour colour) {
r = colour.r;
g = colour.g;
b = colour.b;
@@ -60,27 +55,23 @@ public abstract class Colour implements Copyable<Colour>
}
@SideOnly(Side.CLIENT)
public void glColour()
{
public void glColour() {
GL11.glColor4ub(r, g, b, a);
}
@SideOnly(Side.CLIENT)
public void glColour(int a)
{
public void glColour(int a) {
GL11.glColor4ub(r, g, b, (byte) a);
}
public abstract int pack();
@Override
public String toString()
{
public String toString() {
return getClass().getSimpleName() + "[0x" + Integer.toHexString(pack()).toUpperCase() + "]";
}
public Colour add(Colour colour2)
{
public Colour add(Colour colour2) {
a += colour2.a;
r += colour2.r;
g += colour2.g;
@@ -88,8 +79,7 @@ public abstract class Colour implements Copyable<Colour>
return this;
}
public Colour sub(Colour colour2)
{
public Colour sub(Colour colour2) {
int ia = (a & 0xFF) - (colour2.a & 0xFF);
int ir = (r & 0xFF) - (colour2.r & 0xFF);
int ig = (g & 0xFF) - (colour2.g & 0xFF);
@@ -101,8 +91,7 @@ public abstract class Colour implements Copyable<Colour>
return this;
}
public Colour invert()
{
public Colour invert() {
a = (byte) (0xFF - (a & 0xFF));
r = (byte) (0xFF - (r & 0xFF));
g = (byte) (0xFF - (g & 0xFF));
@@ -110,8 +99,7 @@ public abstract class Colour implements Copyable<Colour>
return this;
}
public Colour multiply(Colour colour2)
{
public Colour multiply(Colour colour2) {
a = (byte) ((a & 0xFF) * ((colour2.a & 0xFF) / 255D));
r = (byte) ((r & 0xFF) * ((colour2.r & 0xFF) / 255D));
g = (byte) ((g & 0xFF) * ((colour2.g & 0xFF) / 255D));
@@ -119,8 +107,7 @@ public abstract class Colour implements Copyable<Colour>
return this;
}
public Colour scale(double d)
{
public Colour scale(double d) {
a = (byte) ((a & 0xFF) * d);
r = (byte) ((r & 0xFF) * d);
g = (byte) ((g & 0xFF) * d);
@@ -128,13 +115,11 @@ public abstract class Colour implements Copyable<Colour>
return this;
}
public Colour interpolate(Colour colour2, double d)
{
public Colour interpolate(Colour colour2, double d) {
return this.add(colour2.copy().sub(this).scale(d));
}
public Colour multiplyC(double d)
{
public Colour multiplyC(double d) {
r = (byte) MathHelper.clip((r & 0xFF) * d, 0, 255);
g = (byte) MathHelper.clip((g & 0xFF) * d, 0, 255);
b = (byte) MathHelper.clip((b & 0xFF) * d, 0, 255);
@@ -144,23 +129,19 @@ public abstract class Colour implements Copyable<Colour>
public abstract Colour copy();
public int rgb()
{
public int rgb() {
return (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF);
}
public int argb()
{
public int argb() {
return (a & 0xFF) << 24 | (r & 0xFF) << 16 | (g & 0xFF) << 8 | (b & 0xFF);
}
public int rgba()
{
public int rgba() {
return (r & 0xFF) << 24 | (g & 0xFF) << 16 | (b & 0xFF) << 8 | (a & 0xFF);
}
public Colour set(Colour colour)
{
public Colour set(Colour colour) {
r = colour.r;
g = colour.g;
b = colour.b;
@@ -168,8 +149,7 @@ public abstract class Colour implements Copyable<Colour>
return this;
}
public boolean equals(Colour colour)
{
public boolean equals(Colour colour) {
return colour != null && rgba() == colour.rgba();
}
}
@@ -1,34 +1,27 @@
package codechicken.lib.colour;
public class ColourARGB extends Colour
{
public ColourARGB(int colour)
{
public class ColourARGB extends Colour {
public ColourARGB(int colour) {
super((colour >> 16) & 0xFF, (colour >> 8) & 0xFF, colour & 0xFF, (colour >> 24) & 0xFF);
}
public ColourARGB(int a, int r, int g, int b)
{
public ColourARGB(int a, int r, int g, int b) {
super(r, g, b, a);
}
public ColourARGB(ColourARGB colour)
{
public ColourARGB(ColourARGB colour) {
super(colour);
}
public ColourARGB copy()
{
public ColourARGB copy() {
return new ColourARGB(this);
}
public int pack()
{
public int pack() {
return pack(this);
}
public static int pack(Colour colour)
{
return (colour.a&0xFF) << 24 | (colour.r&0xFF) << 16 | (colour.g&0xFF) << 8 | (colour.b&0xFF);
public static int pack(Colour colour) {
return (colour.a & 0xFF) << 24 | (colour.r & 0xFF) << 16 | (colour.g & 0xFF) << 8 | (colour.b & 0xFF);
}
}
@@ -31,19 +31,19 @@ public class ColourRGBA extends Colour {
}
public static int multiply(int c1, int c2) {
if(c1 == -1) return c2;
if(c2 == -1) return c1;
if (c1 == -1) return c2;
if (c2 == -1) return c1;
int r = (((c1 >>> 24) * (c2 >>> 24)) & 0xFF00) << 16;
int g = (((c1 >> 16 & 0xFF) * (c2 >> 16 & 0xFF)) & 0xFF00) << 8;
int b = ((c1 >> 8 & 0xFF) * (c2 >> 8 & 0xFF)) & 0xFF00;
int a = ((c1 & 0xFF) * (c2 & 0xFF)) >> 8;
return r|g|b|a;
return r | g | b | a;
}
public static int multiplyC(int c, float f) {
int r = (int) ((c >>> 24) * f);
int g = (int) ((c >> 16 & 0xFF) * f);
int b = (int) ((c >> 8 & 0xFF) * f);
return r<<24 | g<<16 | b<<8 | c&0xFF;
return r << 24 | g << 16 | b << 8 | c & 0xFF;
}
}
@@ -2,35 +2,28 @@ package codechicken.lib.colour;
import codechicken.lib.math.MathHelper;
import codechicken.lib.render.TextureUtils;
import java.awt.image.BufferedImage;
import net.minecraft.util.ResourceLocation;
import java.awt.image.BufferedImage;
public class CustomGradient
{
public class CustomGradient {
public int[] gradient;
public CustomGradient(ResourceLocation textureFile)
{
public CustomGradient(ResourceLocation textureFile) {
BufferedImage img = TextureUtils.loadBufferedImage(textureFile);
if(img == null)
throw new RuntimeException("File not found: "+textureFile.toString());
if (img == null) throw new RuntimeException("File not found: " + textureFile.toString());
int[] data = new int[img.getWidth()];
img.getRGB(0, 0, img.getWidth(), 1, data, 0, img.getWidth());
gradient = new int[img.getWidth()];
for(int i = 0; i < data.length; i++)
gradient[i] = (data[i]<<8)|(((data[i])>>24)&0xFF);
for (int i = 0; i < data.length; i++) gradient[i] = (data[i] << 8) | (((data[i]) >> 24) & 0xFF);
}
public ColourRGBA getColour(double position)
{
public ColourRGBA getColour(double position) {
return new ColourRGBA(getColourI(position));
}
public int getColourI(double position)
{
int off = (int)MathHelper.clip(gradient.length*position, 0, gradient.length-1);
public int getColourI(double position) {
int off = (int) MathHelper.clip(gradient.length * position, 0, gradient.length - 1);
return gradient[off];
}
}
@@ -2,9 +2,8 @@ package codechicken.lib.config;
import java.io.*;
public class ConfigFile extends ConfigTagParent
{
public static final byte[] crlf = new byte[]{0xD, 0xA};
public class ConfigFile extends ConfigTagParent {
public static final byte[] crlf = new byte[] {0xD, 0xA};
public File file;
private boolean loading;
@@ -18,10 +17,8 @@ public class ConfigFile extends ConfigTagParent
protected void load(File file) {
try {
if(!file.getParentFile().exists())
file.getParentFile().mkdirs();
if (!file.exists())
file.createNewFile();
if (!file.getParentFile().exists()) file.getParentFile().mkdirs();
if (!file.exists()) file.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -39,10 +36,8 @@ public class ConfigFile extends ConfigTagParent
reader.mark(2000);
String line = reader.readLine();
if (line != null && line.startsWith("#")) {
if (comment == null || comment.equals(""))
comment = line.substring(1);
else
comment = comment + "\n" + line.substring(1);
if (comment == null || comment.equals("")) comment = line.substring(1);
else comment = comment + "\n" + line.substring(1);
} else {
reader.reset();
break;
@@ -81,15 +76,13 @@ public class ConfigFile extends ConfigTagParent
}
public static void writeLine(PrintWriter writer, String line, int tabs) {
for (int i = 0; i < tabs; i++)
writer.print('\t');
for (int i = 0; i < tabs; i++) writer.print('\t');
writer.println(line);
}
public void saveConfig() {
if (loading)
return;
if (loading) return;
PrintWriter writer;
try {
@@ -2,10 +2,8 @@ package codechicken.lib.config;
import java.io.PrintWriter;
public class ConfigTag extends ConfigTagParent
{
public interface IConfigType<T>
{
public class ConfigTag extends ConfigTagParent {
public interface IConfigType<T> {
public String configValue(T entry);
public T valueOf(String text) throws Exception;
@@ -81,9 +79,9 @@ public class ConfigTag extends ConfigTagParent
public int getIntValue(int defaultValue) {
try {
if (value != null)
return getIntValue();
} catch (NumberFormatException ignored) {}
if (value != null) return getIntValue();
} catch (NumberFormatException ignored) {
}
setIntValue(defaultValue);
return defaultValue;
@@ -91,19 +89,17 @@ public class ConfigTag extends ConfigTagParent
public boolean getBooleanValue() {
String value = getValue();
if (value != null && (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes")))
return true;
else if (value != null && (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no")))
return false;
if (value != null && (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes"))) return true;
else if (value != null && (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no"))) return false;
throw new NumberFormatException(qualifiedname + ".value=" + value);
}
public boolean getBooleanValue(boolean defaultValue) {
try {
if (value != null)
return getBooleanValue();
} catch (NumberFormatException ignored) {}
if (value != null) return getBooleanValue();
} catch (NumberFormatException ignored) {
}
setBooleanValue(defaultValue);
return defaultValue;
@@ -115,9 +111,9 @@ public class ConfigTag extends ConfigTagParent
public int getHexValue(int defaultValue) {
try {
if (value != null)
return getHexValue();
} catch (NumberFormatException ignored) {}
if (value != null) return getHexValue();
} catch (NumberFormatException ignored) {
}
setHexValue(defaultValue);
return defaultValue;
@@ -133,9 +129,9 @@ public class ConfigTag extends ConfigTagParent
public <T> T get(IConfigType<T> type, T defaultValue) {
try {
if (value != null)
return get(type);
} catch (Exception ignored) {}
if (value != null) return get(type);
} catch (Exception ignored) {
}
set(type, defaultValue);
return defaultValue;
@@ -145,22 +141,17 @@ public class ConfigTag extends ConfigTagParent
String vname;
if (qualifiedname.contains(".") && bracequalifier.length() > 0)
vname = qualifiedname.substring(bracequalifier.length() + 1);
else
vname = qualifiedname;
else vname = qualifiedname;
if (newline && !first)
ConfigFile.writeLine(writer, "", tabs);
if (newline && !first) ConfigFile.writeLine(writer, "", tabs);
writeComment(writer, tabs);
if (value != null)
ConfigFile.writeLine(writer, vname + "=" + value, tabs);
if (value != null) ConfigFile.writeLine(writer, vname + "=" + value, tabs);
if (!hasChildTags())
return;
if (!hasChildTags()) return;
if (brace) {
if (value == null)
ConfigFile.writeLine(writer, vname, tabs);
if (value == null) ConfigFile.writeLine(writer, vname, tabs);
ConfigFile.writeLine(writer, "{", tabs);
saveTagTree(writer, tabs + 1, qualifiedname);
ConfigFile.writeLine(writer, "}", tabs);
@@ -189,8 +180,7 @@ public class ConfigTag extends ConfigTagParent
public ConfigTag useBraces() {
brace = true;
if (parent.newlinemode == 1)
newline = true;
if (parent.newlinemode == 1) newline = true;
saveConfig();
return this;
@@ -6,10 +6,8 @@ import java.io.PrintWriter;
import java.util.*;
import java.util.Map.Entry;
public abstract class ConfigTagParent
{
public static class TagOrderComparator implements Comparator<ConfigTag>
{
public abstract class ConfigTagParent {
public static class TagOrderComparator implements Comparator<ConfigTag> {
int sortMode;
public TagOrderComparator(int sortMode) {
@@ -17,18 +15,13 @@ public abstract class ConfigTagParent
}
public int compare(ConfigTag o1, ConfigTag o2) {
if (o1.position != o2.position)
return compareInt(o1.position, o2.position);
if (o1.brace != o2.brace)
return o1.brace ? 1 : -1;//braced one goes after
if (o1.position != o2.position) return compareInt(o1.position, o2.position);
if (o1.brace != o2.brace) return o1.brace ? 1 : -1; // braced one goes after
switch (sortMode) {
case 1:
if (o1.value == o2.value)
return 0;
if (o1.value == null)
return 1;
if (o2.value == null)
return -1;
if (o1.value == o2.value) return 0;
if (o1.value == null) return 1;
if (o2.value == null) return -1;
return o1.value.compareTo(o2.value);
default:
return o1.name.compareTo(o2.name);
@@ -72,12 +65,9 @@ public abstract class ConfigTagParent
newlinemode = mode;
for (Entry<String, ConfigTag> entry : childtags.entrySet()) {
ConfigTag tag = entry.getValue();
if (newlinemode == 0)
tag.newline = false;
else if (newlinemode == 1)
tag.newline = tag.brace;
else if (newlinemode == 2)
tag.newline = true;
if (newlinemode == 0) tag.newline = false;
else if (newlinemode == 1) tag.newline = tag.brace;
else if (newlinemode == 2) tag.newline = true;
}
saveConfig();
return this;
@@ -104,14 +94,12 @@ public abstract class ConfigTagParent
String basetagname = dotpos == -1 ? tagname : tagname.substring(0, dotpos);
ConfigTag basetag = childtags.get(basetagname);
if (basetag == null) {
if (!create)
return null;
if (!create) return null;
basetag = getNewTag(basetagname);
saveConfig();
}
if (dotpos == -1)
return basetag;
if (dotpos == -1) return basetag;
return basetag.getTag(tagname.substring(dotpos + 1), create);
}
@@ -122,15 +110,13 @@ public abstract class ConfigTagParent
public boolean removeTag(String tagname) {
ConfigTag tag = getTag(tagname, false);
if (tag == null)
return false;
if (tag == null) return false;
int dotpos = tagname.lastIndexOf(".");
String lastpart = dotpos == -1 ? tagname : tagname.substring(dotpos + 1, tagname.length());
if (tag.parent != null) {
boolean ret = tag.parent.childtags.remove(lastpart) != null;
if (ret)
saveConfig();
if (ret) saveConfig();
return ret;
}
@@ -143,8 +129,7 @@ public abstract class ConfigTagParent
public <T extends ConfigTag> ArrayList<T> getSortedTagList() {
ArrayList<T> taglist = new ArrayList<T>(childtags.size());
for (Entry<String, ConfigTag> tag : childtags.entrySet())
taglist.add((T) tag.getValue());
for (Entry<String, ConfigTag> tag : childtags.entrySet()) taglist.add((T) tag.getValue());
Collections.sort(taglist, new TagOrderComparator(sortMode));
return taglist;
@@ -156,13 +141,10 @@ public abstract class ConfigTagParent
try {
while (true) {
String line = ConfigFile.readLine(reader);
if (line == null)
break;
if (line == null) break;
if (line.startsWith("#")) {
if (comment.equals(""))
comment = line.substring(1);
else
comment = comment + "\n" + line.substring(1);
if (comment.equals("")) comment = line.substring(1);
else comment = comment + "\n" + line.substring(1);
} else if (line.contains("=")) {
String qualifiedname = line.substring(0, line.indexOf("="));
getTag(qualifiedname)
@@ -197,8 +179,7 @@ public abstract class ConfigTagParent
public void writeComment(PrintWriter writer, int tabs) {
if (comment != null && !comment.equals("")) {
String[] comments = comment.split("\n");
for (int i = 0; i < comments.length; i++)
ConfigFile.writeLine(writer, "#" + comments[i], tabs);
for (int i = 0; i < comments.length; i++) ConfigFile.writeLine(writer, "#" + comments[i], tabs);
}
}
}
@@ -2,17 +2,14 @@ package codechicken.lib.config;
import java.io.File;
public class DefaultingConfigFile extends ConfigFile
{
public class DefaultingConfigFile extends ConfigFile {
public DefaultingConfigFile(File file) {
super();
if(file.exists())
load(file);
if (file.exists()) load(file);
}
@Override
public void saveConfig() {
if(file != null)
super.saveConfig();
if (file != null) super.saveConfig();
}
}
@@ -5,142 +5,116 @@ import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map.Entry;
public class SimpleProperties
{
public class SimpleProperties {
public HashMap<String, String> propertyMap = new HashMap<String, String>();
public File propertyFile;
public boolean saveOnChange = false;
public String encoding;
private boolean loading = false;
public SimpleProperties(File file, boolean saveOnChange, String encoding)
{
public SimpleProperties(File file, boolean saveOnChange, String encoding) {
propertyFile = file;
this.saveOnChange = saveOnChange;
this.encoding = encoding;
}
public SimpleProperties(File file, boolean saveOnChange)
{
public SimpleProperties(File file, boolean saveOnChange) {
this(file, saveOnChange, Charset.defaultCharset().name());
}
public SimpleProperties(File file)
{
public SimpleProperties(File file) {
this(file, true);
}
public void load()
{
public void load() {
clear();
loading = true;
try
{
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(propertyFile), encoding));
while(true)
{
try {
BufferedReader reader =
new BufferedReader(new InputStreamReader(new FileInputStream(propertyFile), encoding));
while (true) {
String read = reader.readLine();
if(read == null)
break;
if (read == null) break;
int equalIndex = read.indexOf('=');
if(equalIndex == -1)
continue;
setProperty(read.substring(0, equalIndex), read.substring(equalIndex+1));
if (equalIndex == -1) continue;
setProperty(read.substring(0, equalIndex), read.substring(equalIndex + 1));
}
reader.close();
}
catch(Exception e)
{
} catch (Exception e) {
throw new RuntimeException(e);
}
loading = false;
}
public void save()
{
try
{
public void save() {
try {
PrintStream writer = new PrintStream(propertyFile);
for(Entry<String, String> entry : propertyMap.entrySet())
{
writer.println(entry.getKey()+"="+entry.getValue());
for (Entry<String, String> entry : propertyMap.entrySet()) {
writer.println(entry.getKey() + "=" + entry.getValue());
}
writer.close();
}
catch(Exception e)
{
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void clear()
{
public void clear() {
propertyMap.clear();
}
public boolean hasProperty(String key)
{
public boolean hasProperty(String key) {
return propertyMap.containsKey(key);
}
public void removeProperty(String key)
{
if(propertyMap.remove(key) != null && saveOnChange && !loading)
save();
public void removeProperty(String key) {
if (propertyMap.remove(key) != null && saveOnChange && !loading) save();
}
public void setProperty(String key, int value)
{
public void setProperty(String key, int value) {
setProperty(key, Integer.toString(value));
}
public void setProperty(String key, boolean value)
{
public void setProperty(String key, boolean value) {
setProperty(key, Boolean.toString(value));
}
public void setProperty(String key, String value)
{
public void setProperty(String key, String value) {
propertyMap.put(key, value);
if(saveOnChange && !loading)
save();
if (saveOnChange && !loading) save();
}
public int getProperty(String property, int defaultvalue)
{
public int getProperty(String property, int defaultvalue) {
try {
return Integer.parseInt(getProperty(property, Integer.toString(defaultvalue)));
} catch(NumberFormatException nfe)
{return defaultvalue;}
} catch (NumberFormatException nfe) {
return defaultvalue;
}
}
public boolean getProperty(String property, boolean defaultvalue)
{
public boolean getProperty(String property, boolean defaultvalue) {
try {
return Boolean.parseBoolean(getProperty(property, Boolean.toString(defaultvalue)));
} catch(NumberFormatException nfe)
{return defaultvalue;}
} catch (NumberFormatException nfe) {
return defaultvalue;
}
}
public String getProperty(String property, String defaultvalue)
{
public String getProperty(String property, String defaultvalue) {
String value = propertyMap.get(property);
if(value == null)
{
if (value == null) {
setProperty(property, defaultvalue);
return defaultvalue;
}
return value;
}
public String getProperty(String property)
{
public String getProperty(String property) {
return propertyMap.get(property);
}
}
@@ -5,24 +5,40 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidStack;
public interface MCDataInput
{
public interface MCDataInput {
public long readLong();
public int readInt();
public short readShort();
public int readUShort();
public byte readByte();
public short readUByte();
public double readDouble();
public float readFloat();
public boolean readBoolean();
public char readChar();
public int readVarShort();
public int readVarInt();
public byte[] readByteArray(int length);
public String readString();
public BlockCoord readCoord();
public NBTTagCompound readNBTTagCompound();
public ItemStack readItemStack();
public FluidStack readFluidStack();
}
@@ -2,18 +2,15 @@ package codechicken.lib.data;
import java.io.InputStream;
public class MCDataInputStream extends InputStream
{
public class MCDataInputStream extends InputStream {
private MCDataInput in;
public MCDataInputStream(MCDataInput in)
{
public MCDataInputStream(MCDataInput in) {
this.in = in;
}
@Override
public int read()
{
return in.readByte()&0xFF;
public int read() {
return in.readByte() & 0xFF;
}
}
@@ -5,23 +5,38 @@ import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidStack;
public interface MCDataOutput
{
public interface MCDataOutput {
public MCDataOutput writeLong(long l);
public MCDataOutput writeInt(int i);
public MCDataOutput writeShort(int s);
public MCDataOutput writeByte(int b);
public MCDataOutput writeDouble(double d);
public MCDataOutput writeFloat(float f);
public MCDataOutput writeBoolean(boolean b);
public MCDataOutput writeChar(char c);
public MCDataOutput writeVarInt(int i);
public MCDataOutput writeVarShort(int s);
public MCDataOutput writeByteArray(byte[] array);
public MCDataOutput writeString(String s);
public MCDataOutput writeCoord(int x, int y, int z);
public MCDataOutput writeCoord(BlockCoord coord);
public MCDataOutput writeNBTTagCompound(NBTTagCompound tag);
public MCDataOutput writeItemStack(ItemStack stack);
public MCDataOutput writeFluidStack(FluidStack liquid);
}
@@ -2,18 +2,15 @@ package codechicken.lib.data;
import java.io.OutputStream;
public class MCDataOutputStream extends OutputStream
{
public class MCDataOutputStream extends OutputStream {
private MCDataOutput out;
public MCDataOutputStream(MCDataOutput out)
{
public MCDataOutputStream(MCDataOutput out) {
this.out = out;
}
@Override
public void write(int b)
{
public void write(int b) {
out.writeByte(b);
}
}
@@ -3,6 +3,8 @@ package codechicken.lib.data;
import codechicken.lib.vec.BlockCoord;
import com.google.common.base.Charsets;
import cpw.mods.fml.common.network.ByteBufUtils;
import java.io.DataOutput;
import java.io.IOException;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools;
@@ -10,11 +12,7 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidStack;
import org.apache.commons.lang3.Validate;
import java.io.DataOutput;
import java.io.IOException;
public class MCDataOutputWrapper implements MCDataOutput
{
public class MCDataOutputWrapper implements MCDataOutput {
/**
* Mimics ByteBufUtils
* Write an integer using variable length encoding.
@@ -41,11 +39,9 @@ public class MCDataOutputWrapper implements MCDataOutput
public static void writeVarShort(DataOutput to, int s) throws IOException {
int low = s & 0x7FFF;
int high = (s & 0x7F8000) >> 15;
if (high != 0)
low |= 0x8000;
if (high != 0) low |= 0x8000;
to.writeShort(low);
if (high != 0)
to.writeByte(high);
if (high != 0) to.writeByte(high);
}
/**
@@ -57,7 +53,8 @@ public class MCDataOutputWrapper implements MCDataOutput
*/
public static void writeUTF8String(DataOutput to, String string) throws IOException {
byte[] utf8Bytes = string.getBytes(Charsets.UTF_8);
Validate.isTrue(ByteBufUtils.varIntByteCount(utf8Bytes.length) < 3, "The string is too long for this encoding.");
Validate.isTrue(
ByteBufUtils.varIntByteCount(utf8Bytes.length) < 3, "The string is too long for this encoding.");
writeVarInt(to, utf8Bytes.length);
to.write(utf8Bytes);
}
@@ -203,10 +200,8 @@ public class MCDataOutputWrapper implements MCDataOutput
writeShort(-1);
} else {
writeShort(Item.getIdFromItem(stack.getItem()));
if (large)
writeInt(stack.stackSize);
else
writeByte(stack.stackSize);
if (large) writeInt(stack.stackSize);
else writeByte(stack.stackSize);
writeShort(stack.getItemDamage());
writeNBTTagCompound(stack.stackTagCompound);
}
@@ -6,8 +6,7 @@ import codechicken.lib.render.TextureUtils;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.ResourceLocation;
public class Canvas9Seg
{
public class Canvas9Seg {
public final ResourceLocation tex;
public float[] seg_u = new float[4];
public float[] seg_v = new float[4];
@@ -24,12 +23,11 @@ public class Canvas9Seg
int marker = 1;
int prev_col = data.data[0];
for(int i = 1; i < size; i++) {
if(data.data[i*stride] != prev_col) {
for (int i = 1; i < size; i++) {
if (data.data[i * stride] != prev_col) {
markers[marker] = i;
prev_col = data.data[i*stride];
if(++marker == 4)
break;
prev_col = data.data[i * stride];
if (++marker == 4) break;
}
}
@@ -40,10 +38,9 @@ public class Canvas9Seg
private void parseMarkers(TextureDataHolder data, int stride, int size, int[] sizes, float[] texcoords) {
int[] markers = readMarkers(data, stride, size);
for(int i = 0; i < 4; i++) {
texcoords[i] = markers[i]/(float)size;
if(i > 0)
sizes[i-1] = markers[i]-markers[i-1];
for (int i = 0; i < 4; i++) {
texcoords[i] = markers[i] / (float) size;
if (i > 0) sizes[i - 1] = markers[i] - markers[i - 1];
}
}
@@ -55,11 +52,12 @@ public class Canvas9Seg
private void drawSeg(int[] sw, int[] sh, int seg) {
Tessellator t = Tessellator.instance;
int u = seg%3; int v = seg/3;
int u = seg % 3;
int v = seg / 3;
t.addVertexWithUV(sw[u], sh[v], 0, seg_u[u], seg_v[v]);
t.addVertexWithUV(sw[u], sh[v+1], 0, seg_u[u], seg_v[v+1]);
t.addVertexWithUV(sw[u+1], sh[v+1], 0, seg_u[u+1], seg_v[v+1]);
t.addVertexWithUV(sw[u+1], sh[v], 0, seg_u[u+1], seg_v[v]);
t.addVertexWithUV(sw[u], sh[v + 1], 0, seg_u[u], seg_v[v + 1]);
t.addVertexWithUV(sw[u + 1], sh[v + 1], 0, seg_u[u + 1], seg_v[v + 1]);
t.addVertexWithUV(sw[u + 1], sh[v], 0, seg_u[u + 1], seg_v[v]);
}
public void draw(int x, int y, int w, int h) {
@@ -67,11 +65,10 @@ public class Canvas9Seg
CCRenderState.reset();
CCRenderState.startDrawing();
int[] sw = new int[]{x, x+seg_w[0], x+w-seg_w[2], x+w};
int[] sh = new int[]{y, y+seg_h[0], y+h-seg_h[2], y+h};
int[] sw = new int[] {x, x + seg_w[0], x + w - seg_w[2], x + w};
int[] sh = new int[] {y, y + seg_h[0], y + h - seg_h[2], y + h};
for(int seg = 0; seg < 9; seg++)
drawSeg(sw, sh, seg);
for (int seg = 0; seg < 9; seg++) drawSeg(sw, sh, seg);
CCRenderState.draw();
}
+23 -30
View File
@@ -2,27 +2,23 @@ package codechicken.lib.gui;
import codechicken.lib.math.MathHelper;
import codechicken.lib.render.CCRenderState;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class GuiDraw
{
public static class GuiHook extends Gui
{
public class GuiDraw {
public static class GuiHook extends Gui {
public void setZLevel(float f) {
zLevel = f;
}
@@ -58,10 +54,8 @@ public class GuiDraw
}
public static void drawString(String text, int x, int y, int colour, boolean shadow) {
if (shadow)
fontRenderer.drawStringWithShadow(text, x, y, colour);
else
fontRenderer.drawString(text, x, y, colour);
if (shadow) fontRenderer.drawStringWithShadow(text, x, y, colour);
else fontRenderer.drawString(text, x, y, colour);
}
public static void drawString(String text, int x, int y, int colour) {
@@ -137,10 +131,10 @@ public class GuiDraw
* Have a string in the tooltip list with TOOLTIP_HANDLER + getTipLineId(handler) for a custom handler
*/
public static final String TOOLTIP_HANDLER = "\u00A7x";
private static List<ITooltipLineHandler> tipLineHandlers = new ArrayList<ITooltipLineHandler>();
public static interface ITooltipLineHandler
{
public static interface ITooltipLineHandler {
public Dimension getSize();
public void draw(int x, int y);
@@ -148,12 +142,11 @@ public class GuiDraw
public static int getTipLineId(ITooltipLineHandler handler) {
tipLineHandlers.add(handler);
return tipLineHandlers.size()-1;
return tipLineHandlers.size() - 1;
}
public static ITooltipLineHandler getTipLine(String line) {
if(!line.startsWith(TOOLTIP_HANDLER))
return null;
if (!line.startsWith(TOOLTIP_HANDLER)) return null;
return tipLineHandlers.get(Integer.parseInt(line.substring(2)));
}
@@ -162,8 +155,7 @@ public class GuiDraw
}
public static void drawMultilineTip(FontRenderer font, int x, int y, List<String> list) {
if (list.isEmpty())
return;
if (list.isEmpty()) return;
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
GL11.glDisable(GL11.GL_DEPTH_TEST);
@@ -174,17 +166,19 @@ public class GuiDraw
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
ITooltipLineHandler line = getTipLine(s);
Dimension d = line != null ?
line.getSize() :
new Dimension(font.getStringWidth(s), list.get(i).endsWith(TOOLTIP_LINESPACE) && i + 1 < list.size() ? 12 : 10);
Dimension d = line != null
? line.getSize()
: new Dimension(
font.getStringWidth(s),
list.get(i).endsWith(TOOLTIP_LINESPACE) && i + 1 < list.size() ? 12 : 10);
w = Math.max(w, d.width);
h += d.height;
}
if (x < 8) x = 8;
else if (x > displaySize().width - w - 8) {
x -= 24 + w;//flip side of cursor
if(x < 8) x = 8;
x -= 24 + w; // flip side of cursor
if (x < 8) x = 8;
}
y = (int) MathHelper.clip(y, 8, displaySize().height - 8 - h);
@@ -192,11 +186,10 @@ public class GuiDraw
drawTooltipBox(x - 4, y - 4, w + 7, h + 7);
for (String s : list) {
ITooltipLineHandler line = getTipLine(s);
if(line != null) {
if (line != null) {
line.draw(x, y);
y += line.getSize().height;
}
else {
} else {
font.drawStringWithShadow(s, x, y, -1);
y += s.endsWith(TOOLTIP_LINESPACE) ? 12 : 10;
}
@@ -214,7 +207,7 @@ public class GuiDraw
int bg = 0xf0100010;
drawGradientRect(x + 1, y, w - 1, 1, bg, bg);
drawGradientRect(x + 1, y + h, w - 1, 1, bg, bg);
drawGradientRect(x + 1, y + 1, w - 1, h - 1, bg, bg);//center
drawGradientRect(x + 1, y + 1, w - 1, h - 1, bg, bg); // center
drawGradientRect(x, y + 1, 1, h - 1, bg, bg);
drawGradientRect(x + w, y + 1, 1, h - 1, bg, bg);
int grad1 = 0x505000ff;
@@ -1,22 +1,21 @@
package codechicken.lib.inventory;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import codechicken.lib.packet.PacketCustom;
import codechicken.lib.packet.PacketCustom.IClientPacketHandler;
import codechicken.lib.packet.PacketCustom.IServerPacketHandler;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.relauncher.Side;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ICrafting;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.network.play.INetHandlerPlayClient;
import net.minecraft.network.play.INetHandlerPlayServer;
import org.apache.logging.log4j.LogManager;
@@ -26,37 +25,30 @@ import org.apache.logging.log4j.LogManager;
* Easy shift-click handling.
* Hooks for slot clicks, large stack sizes and some networking.
*/
public abstract class ContainerExtended extends Container implements ICrafting
{
public abstract class ContainerExtended extends Container implements ICrafting {
private static final String netChannel = "CCL:Container";
private static int nextNetworkID = 0;
static {
PacketCustom.assignHandler(netChannel, new IClientPacketHandler()
{
PacketCustom.assignHandler(netChannel, new IClientPacketHandler() {
@Override
public void handlePacket(PacketCustom packet, Minecraft mc, INetHandlerPlayClient handler) {
Container cont = mc.thePlayer.openContainer;
if(!(cont instanceof ContainerExtended))
return;
if (!(cont instanceof ContainerExtended)) return;
ContainerExtended c = (ContainerExtended)cont;
if(packet.getType() == 1)
c.netID = packet.readInt();
else if(c.netID == packet.readInt())
c.handleClientPacket(packet);
ContainerExtended c = (ContainerExtended) cont;
if (packet.getType() == 1) c.netID = packet.readInt();
else if (c.netID == packet.readInt()) c.handleClientPacket(packet);
}
});
PacketCustom.assignHandler(netChannel, new IServerPacketHandler()
{
PacketCustom.assignHandler(netChannel, new IServerPacketHandler() {
@Override
public void handlePacket(PacketCustom packet, EntityPlayerMP sender, INetHandlerPlayServer handler) {
Container cont = sender.openContainer;
if(!(cont instanceof ContainerExtended))
return;
if (!(cont instanceof ContainerExtended)) return;
ContainerExtended c = (ContainerExtended)cont;
if(c.netID == packet.readInt())
c.handleServerPacket(packet);
ContainerExtended c = (ContainerExtended) cont;
if (c.netID == packet.readInt()) c.handleServerPacket(packet);
}
});
}
@@ -66,8 +58,7 @@ public abstract class ContainerExtended extends Container implements ICrafting
public ContainerExtended() {
crafters.add(this);
if(FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER)
netID = ++nextNetworkID;
if (FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) netID = ++nextNetworkID;
}
@Override
@@ -77,23 +68,18 @@ public abstract class ContainerExtended extends Container implements ICrafting
sendNetID((EntityPlayerMP) icrafting);
sendContainerAndContentsToPlayer(this, getInventory(), Arrays.asList((EntityPlayerMP) icrafting));
detectAndSendChanges();
} else
super.addCraftingToCrafters(icrafting);
} else super.addCraftingToCrafters(icrafting);
}
private void sendNetID(EntityPlayerMP player) {
if(netID == 0)
LogManager.getLogger("CodeChickenLib").error("Player added to container with 0 network ID");
else
new PacketCustom(netChannel, 1).writeInt(netID).sendToPlayer(player);
if (netID == 0) LogManager.getLogger("CodeChickenLib").error("Player added to container with 0 network ID");
else new PacketCustom(netChannel, 1).writeInt(netID).sendToPlayer(player);
}
@Override
public void removeCraftingFromCrafters(ICrafting icrafting) {
if (icrafting instanceof EntityPlayerMP)
playerCrafters.remove(icrafting);
else
super.removeCraftingFromCrafters(icrafting);
if (icrafting instanceof EntityPlayerMP) playerCrafters.remove(icrafting);
else super.removeCraftingFromCrafters(icrafting);
}
@Override
@@ -101,51 +87,43 @@ public abstract class ContainerExtended extends Container implements ICrafting
sendContainerAndContentsToPlayer(container, list, playerCrafters);
}
public void sendContainerAndContentsToPlayer(Container container, List<ItemStack> list, List<EntityPlayerMP> playerCrafters) {
public void sendContainerAndContentsToPlayer(
Container container, List<ItemStack> list, List<EntityPlayerMP> playerCrafters) {
LinkedList<ItemStack> largeStacks = new LinkedList<ItemStack>();
for (int i = 0; i < list.size(); i++) {
ItemStack stack = list.get(i);
if (stack != null && stack.stackSize > Byte.MAX_VALUE) {
list.set(i, null);
largeStacks.add(stack);
} else
largeStacks.add(null);
} else largeStacks.add(null);
}
for (EntityPlayerMP player : playerCrafters)
player.sendContainerAndContentsToPlayer(container, list);
for (EntityPlayerMP player : playerCrafters) player.sendContainerAndContentsToPlayer(container, list);
for (int i = 0; i < largeStacks.size(); i++) {
ItemStack stack = largeStacks.get(i);
if (stack != null)
sendLargeStack(stack, i, playerCrafters);
if (stack != null) sendLargeStack(stack, i, playerCrafters);
}
}
public void sendLargeStack(ItemStack stack, int slot, List<EntityPlayerMP> players) {
}
public void sendLargeStack(ItemStack stack, int slot, List<EntityPlayerMP> players) {}
@Override
public void sendProgressBarUpdate(Container container, int i, int j) {
for (EntityPlayerMP player : playerCrafters)
player.sendProgressBarUpdate(container, i, j);
for (EntityPlayerMP player : playerCrafters) player.sendProgressBarUpdate(container, i, j);
}
@Override
public void sendSlotContents(Container container, int slot, ItemStack stack) {
if (stack != null && stack.stackSize > Byte.MAX_VALUE)
sendLargeStack(stack, slot, playerCrafters);
else
for (EntityPlayerMP player : playerCrafters)
player.sendSlotContents(container, slot, stack);
if (stack != null && stack.stackSize > Byte.MAX_VALUE) sendLargeStack(stack, slot, playerCrafters);
else for (EntityPlayerMP player : playerCrafters) player.sendSlotContents(container, slot, stack);
}
@Override
public ItemStack slotClick(int par1, int par2, int par3, EntityPlayer player) {
if (par1 >= 0 && par1 < inventorySlots.size()) {
Slot slot = getSlot(par1);
if (slot instanceof SlotHandleClicks)
return ((SlotHandleClicks) slot).slotClick(this, player, par2, par3);
if (slot instanceof SlotHandleClicks) return ((SlotHandleClicks) slot).slotClick(this, player, par2, par3);
}
return super.slotClick(par1, par2, par3, player);
}
@@ -159,13 +137,10 @@ public abstract class ContainerExtended extends Container implements ICrafting
ItemStack stack = slot.getStack();
transferredStack = stack.copy();
if (!doMergeStackAreas(slotIndex, stack))
return null;
if (!doMergeStackAreas(slotIndex, stack)) return null;
if (stack.stackSize == 0)
slot.putStack(null);
else
slot.onSlotChanged();
if (stack.stackSize == 0) slot.putStack(null);
else slot.onSlotChanged();
}
return transferredStack;
@@ -176,18 +151,18 @@ public abstract class ContainerExtended extends Container implements ICrafting
boolean merged = false;
int slotIndex = reverse ? endIndex - 1 : startIndex;
if (stack == null)
return false;
if (stack == null) return false;
if (stack.isStackable())//search for stacks to increase
if (stack.isStackable()) // search for stacks to increase
{
while (stack.stackSize > 0 && (reverse ? slotIndex >= startIndex : slotIndex < endIndex)) {
Slot slot = (Slot) inventorySlots.get(slotIndex);
ItemStack slotStack = slot.getStack();
if (slotStack != null && slotStack.getItem() == stack.getItem() &&
(!stack.getHasSubtypes() || stack.getItemDamage() == slotStack.getItemDamage()) &&
ItemStack.areItemStackTagsEqual(stack, slotStack)) {
if (slotStack != null
&& slotStack.getItem() == stack.getItem()
&& (!stack.getHasSubtypes() || stack.getItemDamage() == slotStack.getItemDamage())
&& ItemStack.areItemStackTagsEqual(stack, slotStack)) {
int totalStackSize = slotStack.stackSize + stack.stackSize;
int maxStackSize = Math.min(stack.getMaxStackSize(), slot.getSlotStackLimit());
if (totalStackSize <= maxStackSize) {
@@ -207,7 +182,7 @@ public abstract class ContainerExtended extends Container implements ICrafting
}
}
if (stack.stackSize > 0)//normal transfer :)
if (stack.stackSize > 0) // normal transfer :)
{
slotIndex = reverse ? endIndex - 1 : startIndex;
@@ -253,8 +228,7 @@ public abstract class ContainerExtended extends Container implements ICrafting
for (int row = 0; row < 3; row++)
for (int col = 0; col < 9; col++)
addSlotToContainer(new Slot(inventoryPlayer, col + row * 9 + 9, x + col * 18, y + row * 18));
for (int slot = 0; slot < 9; slot++)
addSlotToContainer(new Slot(inventoryPlayer, slot, x + slot * 18, y + 58));
for (int slot = 0; slot < 9; slot++) addSlotToContainer(new Slot(inventoryPlayer, slot, x + slot * 18, y + 58));
}
@Override
@@ -263,8 +237,7 @@ public abstract class ContainerExtended extends Container implements ICrafting
}
public void sendContainerPacket(PacketCustom packet) {
for (EntityPlayerMP player : playerCrafters)
packet.sendToPlayer(player);
for (EntityPlayerMP player : playerCrafters) packet.sendToPlayer(player);
}
/**
@@ -272,10 +245,11 @@ public abstract class ContainerExtended extends Container implements ICrafting
* @return A packet on the CCL inventory channel that will be recieved by this container on the other network side
*/
public PacketCustom getPacket(int type) {
if(netID == 0)
if (netID == 0)
LogManager.getLogger("CodeChickenLib").error("Tried to get packet for container with 0 network ID");
if(type == 1)
throw new IllegalArgumentException("Packet type 1 is reserved for network synchronisation in ContainerExtended");
if (type == 1)
throw new IllegalArgumentException(
"Packet type 1 is reserved for network synchronisation in ContainerExtended");
return new PacketCustom(netChannel, type).writeInt(netID);
}
@@ -291,7 +265,6 @@ public abstract class ContainerExtended extends Container implements ICrafting
public void handleServerPacket(PacketCustom packet) {}
public void sendProgressBarUpdate(int barID, int value) {
for (ICrafting crafting : (List<ICrafting>) crafters)
crafting.sendProgressBarUpdate(this, barID, value);
for (ICrafting crafting : (List<ICrafting>) crafters) crafting.sendProgressBarUpdate(this, barID, value);
}
}
@@ -1,17 +1,14 @@
package codechicken.lib.inventory;
import codechicken.lib.packet.PacketCustom;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
import codechicken.lib.packet.PacketCustom;
public abstract class ContainerSynchronised extends ContainerExtended
{
public abstract class ContainerSynchronised extends ContainerExtended {
private ArrayList<IContainerSyncVar> syncVars = new ArrayList<IContainerSyncVar>();
/**
@@ -39,7 +36,8 @@ public abstract class ContainerSynchronised extends ContainerExtended
}
@Override
public void sendContainerAndContentsToPlayer(Container container, List<ItemStack> list, List<EntityPlayerMP> playerCrafters) {
public void sendContainerAndContentsToPlayer(
Container container, List<ItemStack> list, List<EntityPlayerMP> playerCrafters) {
super.sendContainerAndContentsToPlayer(container, list, playerCrafters);
for (int i = 0; i < syncVars.size(); i++) {
IContainerSyncVar var = syncVars.get(i);
@@ -47,8 +45,7 @@ public abstract class ContainerSynchronised extends ContainerExtended
packet.writeByte(i);
var.writeChange(packet);
var.reset();
for (EntityPlayerMP player : playerCrafters)
packet.sendToPlayer(player);
for (EntityPlayerMP player : playerCrafters) packet.sendToPlayer(player);
}
}
@@ -2,13 +2,12 @@ package codechicken.lib.inventory;
import codechicken.lib.packet.PacketCustom;
public interface IContainerSyncVar
{
public interface IContainerSyncVar {
public boolean changed();
public void reset();
public void writeChange(PacketCustom packet);
public void readChange(PacketCustom packet);
}
@@ -2,33 +2,28 @@ package codechicken.lib.inventory;
import codechicken.lib.packet.PacketCustom;
public abstract class IntegerSync implements IContainerSyncVar
{
public abstract class IntegerSync implements IContainerSyncVar {
public int c_value;
@Override
public boolean changed()
{
public boolean changed() {
return getValue() != c_value;
}
@Override
public void reset()
{
public void reset() {
c_value = getValue();
}
@Override
public void writeChange(PacketCustom packet)
{
public void writeChange(PacketCustom packet) {
packet.writeInt(getValue());
}
@Override
public void readChange(PacketCustom packet)
{
public void readChange(PacketCustom packet) {
c_value = packet.readInt();
}
public abstract int getValue();
}
@@ -7,35 +7,28 @@ import net.minecraft.item.ItemStack;
/**
* Creates a copy of an IInventory for extended simulation
*/
public class InventoryCopy implements IInventory
{
public class InventoryCopy implements IInventory {
public boolean[] accessible;
public ItemStack[] items;
public IInventory inv;
public InventoryCopy(IInventory inv)
{
public InventoryCopy(IInventory inv) {
items = new ItemStack[inv.getSizeInventory()];
accessible = new boolean[inv.getSizeInventory()];
this.inv = inv;
update();
}
public void update()
{
for(int i = 0; i < items.length; i++)
{
public void update() {
for (int i = 0; i < items.length; i++) {
ItemStack stack = inv.getStackInSlot(i);
if(stack != null)
items[i] = stack.copy();
if (stack != null) items[i] = stack.copy();
}
}
public InventoryCopy open(InventoryRange access)
{
public InventoryCopy open(InventoryRange access) {
int lslot = access.lastSlot();
if(lslot > accessible.length)
{
if (lslot > accessible.length) {
boolean[] l_accessible = new boolean[lslot];
ItemStack[] l_items = new ItemStack[lslot];
System.arraycopy(accessible, 0, l_accessible, 0, accessible.length);
@@ -44,83 +37,66 @@ public class InventoryCopy implements IInventory
items = l_items;
}
for(int slot : access.slots)
accessible[slot] = true;
for (int slot : access.slots) accessible[slot] = true;
return this;
}
@Override
public int getSizeInventory()
{
public int getSizeInventory() {
return items.length;
}
@Override
public ItemStack getStackInSlot(int slot)
{
public ItemStack getStackInSlot(int slot) {
return items[slot];
}
public ItemStack decrStackSize(int slot, int amount)
{
public ItemStack decrStackSize(int slot, int amount) {
return InventoryUtils.decrStackSize(this, slot, amount);
}
@Override
public ItemStack getStackInSlotOnClosing(int slot)
{
public ItemStack getStackInSlotOnClosing(int slot) {
return InventoryUtils.getStackInSlotOnClosing(this, slot);
}
@Override
public void setInventorySlotContents(int slot, ItemStack stack)
{
public void setInventorySlotContents(int slot, ItemStack stack) {
items[slot] = stack;
markDirty();
}
@Override
public String getInventoryName()
{
public String getInventoryName() {
return "copy";
}
@Override
public boolean isUseableByPlayer(EntityPlayer player)
{
public boolean isUseableByPlayer(EntityPlayer player) {
return true;
}
@Override
public void openInventory()
{
}
public void openInventory() {}
@Override
public void closeInventory()
{
}
public void closeInventory() {}
@Override
public int getInventoryStackLimit()
{
public int getInventoryStackLimit() {
return 64;
}
@Override
public void markDirty()
{
}
public void markDirty() {}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
public boolean isItemValidForSlot(int i, ItemStack itemstack) {
return inv.isItemValidForSlot(i, itemstack);
}
@Override
public boolean hasCustomInventoryName()
{
public boolean hasCustomInventoryName() {
return true;
}
}
@@ -8,103 +8,83 @@ import net.minecraft.nbt.NBTTagCompound;
/**
* IInventory implementation which saves and loads from an NBT tag
*/
public class InventoryNBT implements IInventory
{
public class InventoryNBT implements IInventory {
protected ItemStack[] items;
protected NBTTagCompound tag;
public InventoryNBT(int size, NBTTagCompound tag)
{
public InventoryNBT(int size, NBTTagCompound tag) {
this.tag = tag;
items = new ItemStack[size];
readNBT();
}
private void writeNBT()
{
private void writeNBT() {
tag.setTag("items", InventoryUtils.writeItemStacksToTag(items, getInventoryStackLimit()));
}
private void readNBT()
{
if(tag.hasKey("items"))
InventoryUtils.readItemStacksFromTag(items, tag.getTagList("items", 10));
private void readNBT() {
if (tag.hasKey("items")) InventoryUtils.readItemStacksFromTag(items, tag.getTagList("items", 10));
}
@Override
public int getSizeInventory()
{
public int getSizeInventory() {
return items.length;
}
@Override
public ItemStack getStackInSlot(int slot)
{
public ItemStack getStackInSlot(int slot) {
return items[slot];
}
@Override
public ItemStack decrStackSize(int slot, int amount)
{
public ItemStack decrStackSize(int slot, int amount) {
return InventoryUtils.decrStackSize(this, slot, amount);
}
@Override
public ItemStack getStackInSlotOnClosing(int slot)
{
public ItemStack getStackInSlotOnClosing(int slot) {
return InventoryUtils.getStackInSlotOnClosing(this, slot);
}
@Override
public void setInventorySlotContents(int slot, ItemStack stack)
{
public void setInventorySlotContents(int slot, ItemStack stack) {
items[slot] = stack;
markDirty();
}
@Override
public String getInventoryName()
{
public String getInventoryName() {
return "NBT";
}
@Override
public int getInventoryStackLimit()
{
public int getInventoryStackLimit() {
return 64;
}
@Override
public void markDirty()
{
public void markDirty() {
writeNBT();
}
@Override
public boolean isUseableByPlayer(EntityPlayer var1)
{
public boolean isUseableByPlayer(EntityPlayer var1) {
return true;
}
@Override
public void openInventory()
{
public void openInventory() {}
@Override
public void closeInventory() {}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack) {
return true;
}
@Override
public void closeInventory()
{
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
return true;
}
@Override
public boolean hasCustomInventoryName()
{
public boolean hasCustomInventoryName() {
return true;
}
}
@@ -7,68 +7,52 @@ import net.minecraft.item.ItemStack;
/**
* Inventory wrapper for unified ISided/IInventory access
*/
public class InventoryRange
{
public class InventoryRange {
public IInventory inv;
public int side;
public ISidedInventory sidedInv;
public int[] slots;
public InventoryRange(IInventory inv, int side)
{
public InventoryRange(IInventory inv, int side) {
this.inv = inv;
this.side = side;
if(inv instanceof ISidedInventory)
{
sidedInv = (ISidedInventory)inv;
if (inv instanceof ISidedInventory) {
sidedInv = (ISidedInventory) inv;
slots = sidedInv.getAccessibleSlotsFromSide(side);
}
else
{
} else {
slots = new int[inv.getSizeInventory()];
for(int i = 0; i < slots.length; i++)
slots[i] = i;
for (int i = 0; i < slots.length; i++) slots[i] = i;
}
}
public InventoryRange(IInventory inv)
{
public InventoryRange(IInventory inv) {
this(inv, 0);
}
public InventoryRange(IInventory inv, int fslot, int size)
{
public InventoryRange(IInventory inv, int fslot, int size) {
this.inv = inv;
slots = new int[size];
for(int i = 0; i < slots.length; i++)
slots[i] = fslot+i;
for (int i = 0; i < slots.length; i++) slots[i] = fslot + i;
}
public InventoryRange(IInventory inv, InventoryRange access)
{
public InventoryRange(IInventory inv, InventoryRange access) {
this.inv = inv;
this.slots = access.slots;
this.side = access.side;
if(inv instanceof ISidedInventory)
sidedInv = (ISidedInventory) inv;
if (inv instanceof ISidedInventory) sidedInv = (ISidedInventory) inv;
}
public boolean canInsertItem(int slot, ItemStack item)
{
public boolean canInsertItem(int slot, ItemStack item) {
return sidedInv == null ? inv.isItemValidForSlot(slot, item) : sidedInv.canInsertItem(slot, item, side);
}
public boolean canExtractItem(int slot, ItemStack item)
{
public boolean canExtractItem(int slot, ItemStack item) {
return sidedInv == null ? inv.isItemValidForSlot(slot, item) : sidedInv.canExtractItem(slot, item, side);
}
public int lastSlot()
{
public int lastSlot() {
int last = 0;
for(int slot : slots)
if(slot > last)
last = slot;
for (int slot : slots) if (slot > last) last = slot;
return last;
}
}
@@ -7,127 +7,102 @@ import net.minecraft.item.ItemStack;
/**
* Simple IInventory implementation with an array of items, name and maximum stack size
*/
public class InventorySimple implements IInventory
{
public class InventorySimple implements IInventory {
public ItemStack[] items;
public int limit;
public String name;
public InventorySimple(ItemStack[] items, int limit, String name)
{
public InventorySimple(ItemStack[] items, int limit, String name) {
this.items = items;
this.limit = limit;
this.name = name;
}
public InventorySimple(ItemStack[] items, String name)
{
public InventorySimple(ItemStack[] items, String name) {
this(items, 64, name);
}
public InventorySimple(ItemStack[] items, int limit)
{
public InventorySimple(ItemStack[] items, int limit) {
this(items, limit, "inv");
}
public InventorySimple(ItemStack[] items)
{
public InventorySimple(ItemStack[] items) {
this(items, 64, "inv");
}
public InventorySimple(int size, int limit, String name)
{
public InventorySimple(int size, int limit, String name) {
this(new ItemStack[size], limit, name);
}
public InventorySimple(int size, int limit)
{
public InventorySimple(int size, int limit) {
this(size, limit, "inv");
}
public InventorySimple(int size, String name)
{
public InventorySimple(int size, String name) {
this(size, 64, name);
}
public InventorySimple(int size)
{
public InventorySimple(int size) {
this(size, 64, "inv");
}
@Override
public int getSizeInventory()
{
public int getSizeInventory() {
return items.length;
}
@Override
public ItemStack getStackInSlot(int slot)
{
public ItemStack getStackInSlot(int slot) {
return items[slot];
}
@Override
public ItemStack decrStackSize(int slot, int amount)
{
public ItemStack decrStackSize(int slot, int amount) {
return InventoryUtils.decrStackSize(this, slot, amount);
}
@Override
public ItemStack getStackInSlotOnClosing(int slot)
{
public ItemStack getStackInSlotOnClosing(int slot) {
return InventoryUtils.getStackInSlotOnClosing(this, slot);
}
@Override
public void setInventorySlotContents(int slot, ItemStack stack)
{
public void setInventorySlotContents(int slot, ItemStack stack) {
items[slot] = stack;
markDirty();
}
@Override
public String getInventoryName()
{
public String getInventoryName() {
return name;
}
@Override
public int getInventoryStackLimit()
{
public int getInventoryStackLimit() {
return limit;
}
@Override
public boolean isUseableByPlayer(EntityPlayer var1)
{
public boolean isUseableByPlayer(EntityPlayer var1) {
return true;
}
@Override
public void openInventory()
{
public void openInventory() {}
@Override
public void closeInventory() {}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack) {
return true;
}
@Override
public void closeInventory()
{
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack)
{
public boolean hasCustomInventoryName() {
return true;
}
@Override
public boolean hasCustomInventoryName()
{
return true;
}
@Override
public void markDirty()
{
}
public void markDirty() {}
}
@@ -17,8 +17,7 @@ import net.minecraft.tileentity.TileEntityChest;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
public class InventoryUtils
{
public class InventoryUtils {
/**
* Constructor for ItemStack with tag
*/
@@ -48,10 +47,8 @@ public class InventoryUtils
return item;
}
ItemStack itemstack1 = item.splitStack(size);
if (item.stackSize == 0)
inv.setInventorySlotContents(slot, null);
else
inv.setInventorySlotContents(slot, item);
if (item.stackSize == 0) inv.setInventorySlotContents(slot, null);
else inv.setInventorySlotContents(slot, item);
inv.markDirty();
return itemstack1;
@@ -72,8 +69,7 @@ public class InventoryUtils
* @return The quantity of items from addition that can be added to base
*/
public static int incrStackSize(ItemStack base, ItemStack addition) {
if (canStack(base, addition))
return incrStackSize(base, addition.stackSize);
if (canStack(base, addition)) return incrStackSize(base, addition.stackSize);
return 0;
}
@@ -84,10 +80,8 @@ public class InventoryUtils
public static int incrStackSize(ItemStack base, int addition) {
int totalSize = base.stackSize + addition;
if (totalSize <= base.getMaxStackSize())
return addition;
else if (base.stackSize < base.getMaxStackSize())
return base.getMaxStackSize() - base.stackSize;
if (totalSize <= base.getMaxStackSize()) return addition;
else if (base.stackSize < base.getMaxStackSize()) return base.getMaxStackSize() - base.stackSize;
return 0;
}
@@ -110,10 +104,8 @@ public class InventoryUtils
tag.setShort("Slot", (short) i);
items[i].writeToNBT(tag);
if (maxQuantity > Short.MAX_VALUE)
tag.setInteger("Quantity", items[i].stackSize);
else if (maxQuantity > Byte.MAX_VALUE)
tag.setShort("Quantity", (short) items[i].stackSize);
if (maxQuantity > Short.MAX_VALUE) tag.setInteger("Quantity", items[i].stackSize);
else if (maxQuantity > Byte.MAX_VALUE) tag.setShort("Quantity", (short) items[i].stackSize);
tagList.appendTag(tag);
}
@@ -149,8 +141,7 @@ public class InventoryUtils
* Copies an itemstack with a new quantity
*/
public static ItemStack copyStack(ItemStack stack, int quantity) {
if (stack == null)
return null;
if (stack == null) return null;
stack = stack.copy();
stack.stackSize = quantity;
@@ -163,8 +154,7 @@ public class InventoryUtils
public static int getInsertibleQuantity(InventoryRange inv, ItemStack stack) {
int quantity = 0;
stack = copyStack(stack, Integer.MAX_VALUE);
for (int slot : inv.slots)
quantity += fitStackInSlot(inv, slot, stack);
for (int slot : inv.slots) quantity += fitStackInSlot(inv, slot, stack);
return quantity;
}
@@ -175,10 +165,11 @@ public class InventoryUtils
public static int fitStackInSlot(InventoryRange inv, int slot, ItemStack stack) {
ItemStack base = inv.inv.getStackInSlot(slot);
if (!canStack(base, stack) || !inv.canInsertItem(slot, stack))
return 0;
if (!canStack(base, stack) || !inv.canInsertItem(slot, stack)) return 0;
int fit = base != null ? incrStackSize(base, inv.inv.getInventoryStackLimit() - base.stackSize) : inv.inv.getInventoryStackLimit();
int fit = base != null
? incrStackSize(base, inv.inv.getInventoryStackLimit() - base.stackSize)
: inv.inv.getInventoryStackLimit();
return Math.min(fit, stack.stackSize);
}
@@ -195,11 +186,9 @@ public class InventoryUtils
for (int pass = 0; pass < 2; pass++) {
for (int slot : inv.slots) {
ItemStack base = inv.inv.getStackInSlot(slot);
if((pass == 0) == (base == null))
continue;
if ((pass == 0) == (base == null)) continue;
int fit = fitStackInSlot(inv, slot, stack);
if (fit == 0)
continue;
if (fit == 0) continue;
if (base != null) {
stack.stackSize -= fit;
@@ -208,12 +197,10 @@ public class InventoryUtils
inv.inv.setInventorySlotContents(slot, base);
}
} else {
if (!simulate)
inv.inv.setInventorySlotContents(slot, copyStack(stack, fit));
if (!simulate) inv.inv.setInventorySlotContents(slot, copyStack(stack, fit));
stack.stackSize -= fit;
}
if (stack.stackSize == 0)
return 0;
if (stack.stackSize == 0) return 0;
}
}
return stack.stackSize;
@@ -228,8 +215,7 @@ public class InventoryUtils
*/
public static ItemStack getExtractableStack(InventoryRange inv, int slot) {
ItemStack stack = inv.inv.getStackInSlot(slot);
if (stack == null || !inv.canExtractItem(slot, stack))
return null;
if (stack == null || !inv.canExtractItem(slot, stack)) return null;
return stack;
}
@@ -239,8 +225,7 @@ public class InventoryUtils
}
public static boolean areStacksIdentical(ItemStack stack1, ItemStack stack2) {
if (stack1 == null || stack2 == null)
return stack1 == stack2;
if (stack1 == null || stack2 == null) return stack1 == stack2;
return stack1.getItem() == stack2.getItem()
&& stack1.getItemDamage() == stack2.getItemDamage()
@@ -253,32 +238,42 @@ public class InventoryUtils
*/
public static IInventory getInventory(World world, int x, int y, int z) {
TileEntity tile = world.getTileEntity(x, y, z);
if (!(tile instanceof IInventory))
return null;
if (!(tile instanceof IInventory)) return null;
if (tile instanceof TileEntityChest)
return getChest((TileEntityChest) tile);
if (tile instanceof TileEntityChest) return getChest((TileEntityChest) tile);
return (IInventory) tile;
}
public static final ForgeDirection[] chestSides = new ForgeDirection[]{ForgeDirection.WEST, ForgeDirection.EAST, ForgeDirection.NORTH, ForgeDirection.SOUTH};
public static final ForgeDirection[] chestSides =
new ForgeDirection[] {ForgeDirection.WEST, ForgeDirection.EAST, ForgeDirection.NORTH, ForgeDirection.SOUTH};
public static IInventory getChest(TileEntityChest chest) {
for (ForgeDirection fside : chestSides) {
if (chest.getWorldObj().getBlock(chest.xCoord + fside.offsetX, chest.yCoord + fside.offsetY, chest.zCoord + fside.offsetZ) == chest.getBlockType())
return new InventoryLargeChest("container.chestDouble",
(TileEntityChest) chest.getWorldObj().getTileEntity(chest.xCoord + fside.offsetX, chest.yCoord + fside.offsetY, chest.zCoord + fside.offsetZ), chest);
if (chest.getWorldObj()
.getBlock(
chest.xCoord + fside.offsetX,
chest.yCoord + fside.offsetY,
chest.zCoord + fside.offsetZ)
== chest.getBlockType())
return new InventoryLargeChest(
"container.chestDouble",
(TileEntityChest) chest.getWorldObj()
.getTileEntity(
chest.xCoord + fside.offsetX,
chest.yCoord + fside.offsetY,
chest.zCoord + fside.offsetZ),
chest);
}
return chest;
}
public static boolean canStack(ItemStack stack1, ItemStack stack2) {
return stack1 == null || stack2 == null ||
(stack1.getItem() == stack2.getItem() &&
(!stack2.getHasSubtypes() || stack2.getItemDamage() == stack1.getItemDamage()) &&
ItemStack.areItemStackTagsEqual(stack2, stack1)) &&
stack1.isStackable();
return stack1 == null
|| stack2 == null
|| (stack1.getItem() == stack2.getItem()
&& (!stack2.getHasSubtypes() || stack2.getItemDamage() == stack1.getItemDamage())
&& ItemStack.areItemStackTagsEqual(stack2, stack1))
&& stack1.isStackable();
}
/**
@@ -309,8 +304,7 @@ public class InventoryUtils
public static void dropOnClose(EntityPlayer player, IInventory inv) {
for (int i = 0; i < inv.getSizeInventory(); i++) {
ItemStack stack = inv.getStackInSlotOnClosing(i);
if (stack != null)
player.dropPlayerItemWithRandomChoice(stack, false);
if (stack != null) player.dropPlayerItemWithRandomChoice(stack, false);
}
}
@@ -324,12 +318,11 @@ public class InventoryUtils
public static ItemStack loadPersistant(NBTTagCompound tag) {
String name = tag.getString("name");
Item item = (Item) Item.itemRegistry.getObject(name);
if(item == null) return null;
if (item == null) return null;
int count = tag.hasKey("Count") ? tag.getByte("Count") : 1;
int damage = tag.hasKey("Damage") ? tag.getShort("Damage") : 0;
ItemStack stack = new ItemStack(item, count, damage);
if(tag.hasKey("tag", 10))
stack.stackTagCompound = tag.getCompoundTag("tag");
if (tag.hasKey("tag", 10)) stack.stackTagCompound = tag.getCompoundTag("tag");
return stack;
}
}
@@ -1,18 +1,17 @@
package codechicken.lib.inventory;
import static codechicken.lib.inventory.InventoryUtils.actualDamage;
import com.google.common.base.Objects;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.oredict.OreDictionary;
import static codechicken.lib.inventory.InventoryUtils.actualDamage;
/**
* Comparable ItemStack with a hashCode implementation.
*/
public class ItemKey implements Comparable<ItemKey>
{
public class ItemKey implements Comparable<ItemKey> {
public ItemStack stack;
private int hashcode = 0;
@@ -35,18 +34,19 @@ public class ItemKey implements Comparable<ItemKey>
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ItemKey))
return false;
if (!(obj instanceof ItemKey)) return false;
ItemKey k = (ItemKey) obj;
return stack.getItem() == k.stack.getItem() &&
actualDamage(stack) == actualDamage(k.stack) &&
Objects.equal(stack.stackTagCompound, k.stack.stackTagCompound);
return stack.getItem() == k.stack.getItem()
&& actualDamage(stack) == actualDamage(k.stack)
&& Objects.equal(stack.stackTagCompound, k.stack.stackTagCompound);
}
@Override
public int hashCode() {
return hashcode != 0 ? hashcode : (hashcode = Objects.hashCode(stack.getItem(), actualDamage(stack), stack.stackTagCompound));
return hashcode != 0
? hashcode
: (hashcode = Objects.hashCode(stack.getItem(), actualDamage(stack), stack.stackTagCompound));
}
public int compareInt(int a, int b) {
@@ -57,8 +57,7 @@ public class ItemKey implements Comparable<ItemKey>
public int compareTo(ItemKey o) {
if (stack.getItem() != o.stack.getItem())
return compareInt(Item.getIdFromItem(stack.getItem()), Item.getIdFromItem(o.stack.getItem()));
if (actualDamage(stack) != actualDamage(o.stack))
return compareInt(actualDamage(stack), actualDamage(o.stack));
if (actualDamage(stack) != actualDamage(o.stack)) return compareInt(actualDamage(stack), actualDamage(o.stack));
return 0;
}
}
@@ -4,69 +4,51 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
public class SlotDummy extends SlotHandleClicks
{
public class SlotDummy extends SlotHandleClicks {
public final int stackLimit;
public SlotDummy(IInventory inv, int slot, int x, int y)
{
public SlotDummy(IInventory inv, int slot, int x, int y) {
this(inv, slot, x, y, 64);
}
public SlotDummy(IInventory inv, int slot, int x, int y, int limit)
{
public SlotDummy(IInventory inv, int slot, int x, int y, int limit) {
super(inv, slot, x, y);
stackLimit = limit;
}
@Override
public ItemStack slotClick(ContainerExtended container, EntityPlayer player, int button, int modifier)
{
public ItemStack slotClick(ContainerExtended container, EntityPlayer player, int button, int modifier) {
ItemStack held = player.inventory.getItemStack();
boolean shift = modifier == 1;
slotClick(held, button, shift);
return null;
}
public void slotClick(ItemStack held, int button, boolean shift)
{
public void slotClick(ItemStack held, int button, boolean shift) {
ItemStack tstack = getStack();
if(held != null && (tstack == null || !InventoryUtils.canStack(held, tstack)))
{
if (held != null && (tstack == null || !InventoryUtils.canStack(held, tstack))) {
int quantity = Math.min(held.stackSize, stackLimit);
if(shift)
quantity = Math.min(stackLimit, held.getMaxStackSize()*16);
if(button == 1)
quantity = 1;
if (shift) quantity = Math.min(stackLimit, held.getMaxStackSize() * 16);
if (button == 1) quantity = 1;
putStack(InventoryUtils.copyStack(held, quantity));
}
else if(tstack != null)
{
} else if (tstack != null) {
int inc;
if(held != null)
{
if (held != null) {
inc = button == 1 ? -held.stackSize : held.stackSize;
if(shift)
inc *= 16;
}
else
{
if (shift) inc *= 16;
} else {
inc = button == 1 ? -1 : 1;
if(shift)
inc *= 16;
if (shift) inc *= 16;
}
int quantity = tstack.stackSize+inc;
if(quantity <= 0)
putStack(null);
else
putStack(InventoryUtils.copyStack(tstack, quantity));
int quantity = tstack.stackSize + inc;
if (quantity <= 0) putStack(null);
else putStack(InventoryUtils.copyStack(tstack, quantity));
}
}
@Override
public void putStack(ItemStack stack)
{
if(stack != null && stack.stackSize > stackLimit)
stack = InventoryUtils.copyStack(stack, stackLimit);
public void putStack(ItemStack stack) {
if (stack != null && stack.stackSize > stackLimit) stack = InventoryUtils.copyStack(stack, stackLimit);
super.putStack(stack);
}
}
@@ -4,16 +4,13 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
public class SlotDummyOutput extends SlotHandleClicks
{
public SlotDummyOutput(IInventory inv, int slot, int x, int y)
{
public class SlotDummyOutput extends SlotHandleClicks {
public SlotDummyOutput(IInventory inv, int slot, int x, int y) {
super(inv, slot, x, y);
}
@Override
public ItemStack slotClick(ContainerExtended container, EntityPlayer player, int button, int modifier)
{
public ItemStack slotClick(ContainerExtended container, EntityPlayer player, int button, int modifier) {
return null;
}
}
@@ -5,10 +5,8 @@ import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
public abstract class SlotHandleClicks extends Slot
{
public SlotHandleClicks(IInventory inv, int slot, int x, int y)
{
public abstract class SlotHandleClicks extends Slot {
public SlotHandleClicks(IInventory inv, int slot, int x, int y) {
super(inv, slot, x, y);
}
@@ -5,8 +5,7 @@ import codechicken.lib.util.Copyable;
import codechicken.lib.vec.Rotation;
import codechicken.lib.vec.Vector3;
public class LC implements Copyable<LC>
{
public class LC implements Copyable<LC> {
public int side;
public float fa;
public float fb;
@@ -40,8 +39,7 @@ public class LC implements Copyable<LC>
public LC compute(Vector3 vec, Vector3 normal) {
int side = CCModel.findSide(normal);
if (side < 0)
return set(12, 1, 0, 0, 0);
if (side < 0) return set(12, 1, 0, 0, 0);
return compute(vec, side);
}
@@ -67,8 +65,7 @@ public class LC implements Copyable<LC>
offset = vec.x >= 1;
break;
}
if (!offset)
side += 6;
if (!offset) side += 6;
return computeO(vec, side);
}
@@ -86,4 +83,4 @@ public class LC implements Copyable<LC>
public LC copy() {
return new LC(side, fa, fb, fc, fd);
}
}
}
@@ -10,8 +10,7 @@ import net.minecraft.world.IBlockAccess;
/**
* Note that when using the class as a vertex transformer, the vertices are assumed to be within the BB (x, y, z) -> (x+1, y+1, z+1)
*/
public class LightMatrix implements CCRenderState.IVertexOperation
{
public class LightMatrix implements CCRenderState.IVertexOperation {
public static final int operationIndex = CCRenderState.registerOperation();
public int computed = 0;
@@ -28,30 +27,34 @@ public class LightMatrix implements CCRenderState.IVertexOperation
/**
* The 9 positions in the sample array for each side, sides >= 6 are centered on sample 13 (the block itself)
*/
public static final int[][] ssamplem = new int[][]{
{ 0, 1, 2, 3, 4, 5, 6, 7, 8},
{18,19,20,21,22,23,24,25,26},
{ 0, 9,18, 1,10,19, 2,11,20},
{ 6,15,24, 7,16,25, 8,17,26},
{ 0, 3, 6, 9,12,15,18,21,24},
{ 2, 5, 8,11,14,17,20,23,26},
{ 9,10,11,12,13,14,15,16,17},
{ 9,10,11,12,13,14,15,16,17},
{ 3,12,21, 4,13,22, 5,14,23},
{ 3,12,21, 4,13,22, 5,14,23},
{ 1, 4, 7,10,13,16,19,22,25},
{ 1, 4, 7,10,13,16,19,22,25},
{13,13,13,13,13,13,13,13,13}};
public static final int[][] qsamplem = new int[][]{//the positions in the side sample array for each corner
{0,1,3,4},
{5,1,2,4},
{6,7,3,4},
{5,7,8,4}};
public static final float[] sideao = new float[]{
public static final int[][] ssamplem = new int[][] {
{0, 1, 2, 3, 4, 5, 6, 7, 8},
{18, 19, 20, 21, 22, 23, 24, 25, 26},
{0, 9, 18, 1, 10, 19, 2, 11, 20},
{6, 15, 24, 7, 16, 25, 8, 17, 26},
{0, 3, 6, 9, 12, 15, 18, 21, 24},
{2, 5, 8, 11, 14, 17, 20, 23, 26},
{9, 10, 11, 12, 13, 14, 15, 16, 17},
{9, 10, 11, 12, 13, 14, 15, 16, 17},
{3, 12, 21, 4, 13, 22, 5, 14, 23},
{3, 12, 21, 4, 13, 22, 5, 14, 23},
{1, 4, 7, 10, 13, 16, 19, 22, 25},
{1, 4, 7, 10, 13, 16, 19, 22, 25},
{13, 13, 13, 13, 13, 13, 13, 13, 13}
};
public static final int[][] qsamplem = new int[][] { // the positions in the side sample array for each corner
{0, 1, 3, 4},
{5, 1, 2, 4},
{6, 7, 3, 4},
{5, 7, 8, 4}
};
public static final float[] sideao = new float[] {
0.5F, 1F, 0.8F, 0.8F, 0.6F, 0.6F,
0.5F, 1F, 0.8F, 0.8F, 0.6F, 0.6F,
1F};
1F
};
/*static
{
int[][] os = new int[][]{
@@ -61,7 +64,7 @@ public class LightMatrix implements CCRenderState.IVertexOperation
{0,0, 1},
{-1,0,0},
{ 1,0,0}};
for(int s = 0; s < 12; s++)
{
int[] d0 = s < 6 ? new int[]{os[s][0]+1, os[s][1]+1, os[s][2]+1} : new int[]{1, 1, 1};
@@ -110,16 +113,18 @@ public class LightMatrix implements CCRenderState.IVertexOperation
int[] qsample = qsamplem[q];
if (Minecraft.isAmbientOcclusionEnabled())
interp(side, q, ssample[qsample[0]], ssample[qsample[1]], ssample[qsample[2]], ssample[qsample[3]]);
else
interp(side, q, ssample[4], ssample[4], ssample[4], ssample[4]);
else interp(side, q, ssample[4], ssample[4], ssample[4], ssample[4]);
}
computed |= 1 << side;
}
}
private void interp(int s, int q, int a, int b, int c, int d) {
sample(a); sample(b); sample(c); sample(d);
ao[s][q] = interpAO(aSamples[a], aSamples[b], aSamples[c], aSamples[d])*sideao[s];
sample(a);
sample(b);
sample(c);
sample(d);
ao[s][q] = interpAO(aSamples[a], aSamples[b], aSamples[c], aSamples[d]) * sideao[s];
brightness[s][q] = interpBrightness(bSamples[a], bSamples[b], bSamples[c], bSamples[d]);
}
@@ -128,19 +133,15 @@ public class LightMatrix implements CCRenderState.IVertexOperation
}
public static int interpBrightness(int a, int b, int c, int d) {
if (a == 0)
a = d;
if (b == 0)
b = d;
if (c == 0)
c = d;
if (a == 0) a = d;
if (b == 0) b = d;
if (c == 0) c = d;
return (a + b + c + d) >> 2 & 0xFF00FF;
}
@Override
public boolean load() {
if(!CCRenderState.computeLighting)
return false;
if (!CCRenderState.computeLighting) return false;
CCRenderState.pipeline.addDependency(CCRenderState.colourAttrib);
CCRenderState.pipeline.addDependency(CCRenderState.lightCoordAttrib);
@@ -161,4 +162,4 @@ public class LightMatrix implements CCRenderState.IVertexOperation
public int operationID() {
return operationIndex;
}
}
}
@@ -4,12 +4,10 @@ import codechicken.lib.render.CCRenderState;
import codechicken.lib.vec.Rotation;
import codechicken.lib.vec.Vector3;
public class LightModel implements CCRenderState.IVertexOperation
{
public class LightModel implements CCRenderState.IVertexOperation {
public static final int operationIndex = CCRenderState.registerOperation();
public static class Light
{
public static class Light {
public Vector3 ambient = new Vector3();
public Vector3 diffuse = new Vector3();
public Vector3 position;
@@ -28,17 +26,16 @@ public class LightModel implements CCRenderState.IVertexOperation
return this;
}
}
public static LightModel standardLightModel;
static {
standardLightModel = new LightModel()
.setAmbient(new Vector3(0.4, 0.4, 0.4))
.addLight(new Light(new Vector3(0.2, 1, -0.7))
.setDiffuse(new Vector3(0.6, 0.6, 0.6)))
.addLight(new Light(new Vector3(-0.2, 1, 0.7))
.setDiffuse(new Vector3(0.6, 0.6, 0.6)));
.addLight(new Light(new Vector3(0.2, 1, -0.7)).setDiffuse(new Vector3(0.6, 0.6, 0.6)))
.addLight(new Light(new Vector3(-0.2, 1, 0.7)).setDiffuse(new Vector3(0.6, 0.6, 0.6)));
}
private Vector3 ambient = new Vector3();
private Light[] lights = new Light[8];
private int lightCount;
@@ -69,21 +66,20 @@ public class LightModel implements CCRenderState.IVertexOperation
n_colour.z += light.ambient.z + f * light.diffuse.z * n_l;
}
if (n_colour.x > 1)
n_colour.x = 1;
if (n_colour.y > 1)
n_colour.y = 1;
if (n_colour.z > 1)
n_colour.z = 1;
if (n_colour.x > 1) n_colour.x = 1;
if (n_colour.y > 1) n_colour.y = 1;
if (n_colour.z > 1) n_colour.z = 1;
n_colour.multiply((colour >>> 24) / 255D, (colour >> 16 & 0xFF) / 255D, (colour >> 8 & 0xFF) / 255D);
return (int) (n_colour.x * 255) << 24 | (int) (n_colour.y * 255) << 16 | (int) (n_colour.z * 255) << 8 | colour & 0xFF;
return (int) (n_colour.x * 255) << 24
| (int) (n_colour.y * 255) << 16
| (int) (n_colour.z * 255) << 8
| colour & 0xFF;
}
@Override
public boolean load() {
if(!CCRenderState.computeLighting)
return false;
if (!CCRenderState.computeLighting) return false;
CCRenderState.pipeline.addDependency(CCRenderState.normalAttrib);
CCRenderState.pipeline.addDependency(CCRenderState.colourAttrib);
@@ -102,8 +98,7 @@ public class LightModel implements CCRenderState.IVertexOperation
public PlanarLightModel reducePlanar() {
int[] colours = new int[6];
for (int i = 0; i < 6; i++)
colours[i] = apply(-1, Rotation.axes[i]);
for (int i = 0; i < 6; i++) colours[i] = apply(-1, Rotation.axes[i]);
return new PlanarLightModel(colours);
}
}
@@ -5,8 +5,7 @@ import codechicken.lib.vec.BlockCoord;
import net.minecraft.block.Block;
import net.minecraft.world.IBlockAccess;
public class PlanarLightMatrix extends PlanarLightModel
{
public class PlanarLightMatrix extends PlanarLightModel {
public static final int operationIndex = CCRenderState.registerOperation();
public static PlanarLightMatrix instance = new PlanarLightMatrix();
@@ -28,9 +27,10 @@ public class PlanarLightMatrix extends PlanarLightModel
}
public int brightness(int side) {
if((sampled & 1 << side) == 0) {
if ((sampled & 1 << side) == 0) {
Block b = access.getBlock(pos.x, pos.y, pos.z);
brightness[side] = access.getLightBrightnessForSkyBlocks(pos.x, pos.y, pos.z, b.getLightValue(access, pos.x, pos.y, pos.z));
brightness[side] = access.getLightBrightnessForSkyBlocks(
pos.x, pos.y, pos.z, b.getLightValue(access, pos.x, pos.y, pos.z));
sampled |= 1 << side;
}
return brightness[side];
@@ -6,8 +6,7 @@ import codechicken.lib.render.CCRenderState;
/**
* Faster precomputed version of LightModel that only works for axis planar sides
*/
public class PlanarLightModel implements CCRenderState.IVertexOperation
{
public class PlanarLightModel implements CCRenderState.IVertexOperation {
public static PlanarLightModel standardLightModel = LightModel.standardLightModel.reducePlanar();
public int[] colours;
@@ -18,8 +17,7 @@ public class PlanarLightModel implements CCRenderState.IVertexOperation
@Override
public boolean load() {
if(!CCRenderState.computeLighting)
return false;
if (!CCRenderState.computeLighting) return false;
CCRenderState.pipeline.addDependency(CCRenderState.sideAttrib);
CCRenderState.pipeline.addDependency(CCRenderState.colourAttrib);
@@ -8,8 +8,7 @@ import net.minecraft.world.IBlockAccess;
/**
* Faster precomputed version of LightModel that only works for axis planar sides
*/
public class SimpleBrightnessModel implements CCRenderState.IVertexOperation
{
public class SimpleBrightnessModel implements CCRenderState.IVertexOperation {
public static final int operationIndex = CCRenderState.registerOperation();
public static SimpleBrightnessModel instance = new SimpleBrightnessModel();
@@ -30,7 +29,8 @@ public class SimpleBrightnessModel implements CCRenderState.IVertexOperation
if ((sampled & 1 << side) == 0) {
c.set(pos).offset(side);
Block block = access.getBlock(c.x, c.y, c.z);
samples[side] = access.getLightBrightnessForSkyBlocks(c.x, c.y, c.z, block.getLightValue(access, c.x, c.y, c.z));
samples[side] =
access.getLightBrightnessForSkyBlocks(c.x, c.y, c.z, block.getLightValue(access, c.x, c.y, c.z));
sampled |= 1 << side;
}
return samples[side];
@@ -1,59 +1,49 @@
package codechicken.lib.math;
public class MathHelper
{
public class MathHelper {
public static final double phi = 1.618033988749894;
public static final double pi = Math.PI;
public static final double todeg = 57.29577951308232;
public static final double torad = 0.017453292519943;
public static final double sqrt2 = 1.414213562373095;
public static double[] SIN_TABLE = new double[65536];
static
{
for (int i = 0; i < 65536; ++i)
SIN_TABLE[i] = Math.sin(i / 65536D * 2 * Math.PI);
static {
for (int i = 0; i < 65536; ++i) SIN_TABLE[i] = Math.sin(i / 65536D * 2 * Math.PI);
SIN_TABLE[0] = 0;
SIN_TABLE[16384] = 1;
SIN_TABLE[32768] = 0;
SIN_TABLE[49152] = 1;
}
public static double sin(double d)
{
return SIN_TABLE[(int)((float)d * 10430.378F) & 65535];
public static double sin(double d) {
return SIN_TABLE[(int) ((float) d * 10430.378F) & 65535];
}
public static double cos(double d)
{
return SIN_TABLE[(int)((float)d * 10430.378F + 16384.0F) & 65535];
public static double cos(double d) {
return SIN_TABLE[(int) ((float) d * 10430.378F + 16384.0F) & 65535];
}
/**
* @param a The value
* @param b The value to approach
* @param max The maximum step
* @return the closed value to b no less than max from a
*/
public static float approachLinear(float a, float b, float max)
{
return (a > b) ?
(a - b < max ? b : a-max) :
(b - a < max ? b : a+max);
public static float approachLinear(float a, float b, float max) {
return (a > b) ? (a - b < max ? b : a - max) : (b - a < max ? b : a + max);
}
/**
* @param a The value
* @param b The value to approach
* @param max The maximum step
* @return the closed value to b no less than max from a
*/
public static double approachLinear(double a, double b, double max)
{
return (a > b) ?
(a - b < max ? b : a-max) :
(b - a < max ? b : a+max);
public static double approachLinear(double a, double b, double max) {
return (a > b) ? (a - b < max ? b : a - max) : (b - a < max ? b : a + max);
}
/**
@@ -62,9 +52,8 @@ public class MathHelper
* @param d The interpolation factor, between 0 and 1
* @return a+(b-a)*d
*/
public static float interpolate(float a, float b, float d)
{
return a+(b-a)*d;
public static float interpolate(float a, float b, float d) {
return a + (b - a) * d;
}
/**
@@ -73,20 +62,18 @@ public class MathHelper
* @param d The interpolation factor, between 0 and 1
* @return a+(b-a)*d
*/
public static double interpolate(double a, double b, double d)
{
return a+(b-a)*d;
public static double interpolate(double a, double b, double d) {
return a + (b - a) * d;
}
/**
* @param a The value
* @param b The value to approach
* @param ratio The ratio to reduce the difference by
* @return a+(b-a)*ratio
*/
public static double approachExp(double a, double b, double ratio)
{
return a+(b-a)*ratio;
public static double approachExp(double a, double b, double ratio) {
return a + (b - a) * ratio;
}
/**
@@ -96,12 +83,10 @@ public class MathHelper
* @param cap The maximum amount to advance by
* @return a+(b-a)*ratio
*/
public static double approachExp(double a, double b, double ratio, double cap)
{
double d = (b-a)*ratio;
if(Math.abs(d) > cap)
d = Math.signum(d)*cap;
return a+d;
public static double approachExp(double a, double b, double ratio, double cap) {
double d = (b - a) * ratio;
if (Math.abs(d) > cap) d = Math.signum(d) * cap;
return a + d;
}
/**
@@ -112,67 +97,55 @@ public class MathHelper
* @param kick The difference when a == c
* @return
*/
public static double retreatExp(double a, double b, double c, double ratio, double kick)
{
double d = (Math.abs(c-a)+kick)*ratio;
if(d > Math.abs(b-a))
return b;
return a+Math.signum(b-a)*d;
public static double retreatExp(double a, double b, double c, double ratio, double kick) {
double d = (Math.abs(c - a) + kick) * ratio;
if (d > Math.abs(b - a)) return b;
return a + Math.signum(b - a) * d;
}
/**
*
*
* @param value The value
* @param min The min value
* @param max The max value
* @return The clipped value between min and max
*/
public static double clip(double value, double min, double max)
{
if(value > max)
value = max;
if(value < min)
value = min;
public static double clip(double value, double min, double max) {
if (value > max) value = max;
if (value < min) value = min;
return value;
}
/**
* @return a <= x <= b
*/
public static boolean between(double a, double x, double b)
{
public static boolean between(double a, double x, double b) {
return a <= x && x <= b;
}
public static int approachExpI(int a, int b, double ratio)
{
int r = (int)Math.round(approachExp(a, b, ratio));
public static int approachExpI(int a, int b, double ratio) {
int r = (int) Math.round(approachExp(a, b, ratio));
return r == a ? b : r;
}
public static int retreatExpI(int a, int b, int c, double ratio, int kick)
{
int r = (int)Math.round(retreatExp(a, b, c, ratio, kick));
public static int retreatExpI(int a, int b, int c, double ratio, int kick) {
int r = (int) Math.round(retreatExp(a, b, c, ratio, kick));
return r == a ? b : r;
}
public static int floor_double(double d)
{
public static int floor_double(double d) {
return net.minecraft.util.MathHelper.floor_double(d);
}
public static int roundAway(double d)
{
public static int roundAway(double d) {
return (int) (d < 0 ? Math.floor(d) : Math.ceil(d));
}
public static int compare(int a, int b)
{
public static int compare(int a, int b) {
return a == b ? 0 : a < b ? -1 : 1;
}
public static int compare(double a, double b)
{
public static int compare(double a, double b) {
return a == b ? 0 : a < b ? -1 : 1;
}
}
@@ -1,6 +1,5 @@
package codechicken.lib.packet;
public interface ICustomPacketTile
{
public interface ICustomPacketTile {
public void handleDescriptionPacket(PacketCustom packet);
}
@@ -1,6 +1,5 @@
package codechicken.lib.packet;
import codechicken.lib.data.MCDataInput;
import codechicken.lib.data.MCDataOutput;
import codechicken.lib.vec.BlockCoord;
@@ -19,6 +18,10 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.AttributeKey;
import java.util.EnumMap;
import java.util.List;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
@@ -38,32 +41,21 @@ import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import java.util.EnumMap;
import java.util.List;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
public final class PacketCustom implements MCDataInput, MCDataOutput {
public static interface ICustomPacketHandler {}
public final class PacketCustom implements MCDataInput, MCDataOutput
{
public static interface ICustomPacketHandler
{
}
public interface IClientPacketHandler extends ICustomPacketHandler
{
public interface IClientPacketHandler extends ICustomPacketHandler {
public void handlePacket(PacketCustom packetCustom, Minecraft mc, INetHandlerPlayClient handler);
}
public interface IServerPacketHandler extends ICustomPacketHandler
{
public interface IServerPacketHandler extends ICustomPacketHandler {
public void handlePacket(PacketCustom packetCustom, EntityPlayerMP sender, INetHandlerPlayServer handler);
}
public static AttributeKey<CustomInboundHandler> cclHandler = new AttributeKey<CustomInboundHandler>("ccl:handler");
@ChannelHandler.Sharable
public static class CustomInboundHandler extends SimpleChannelInboundHandler<FMLProxyPacket>
{
public static class CustomInboundHandler extends SimpleChannelInboundHandler<FMLProxyPacket> {
public EnumMap<Side, CustomHandler> handlers = Maps.newEnumMap(Side.class);
@Override
@@ -75,19 +67,18 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
@Override
protected void channelRead0(ChannelHandlerContext ctx, FMLProxyPacket msg) throws Exception {
handlers.get(ctx.channel().attr(NetworkRegistry.CHANNEL_SOURCE).get())
.handle(ctx.channel().attr(NetworkRegistry.NET_HANDLER).get(),
.handle(
ctx.channel().attr(NetworkRegistry.NET_HANDLER).get(),
ctx.channel().attr(NetworkRegistry.FML_CHANNEL).get(),
new PacketCustom(msg.payload()));
}
}
private static interface CustomHandler
{
private static interface CustomHandler {
public void handle(INetHandler handler, String channel, PacketCustom packet) throws Exception;
}
public static class ClientInboundHandler implements CustomHandler
{
public static class ClientInboundHandler implements CustomHandler {
private IClientPacketHandler handler;
public ClientInboundHandler(ICustomPacketHandler handler) {
@@ -98,13 +89,11 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
public void handle(INetHandler netHandler, String channel, PacketCustom packet) throws Exception {
if (netHandler instanceof INetHandlerPlayClient)
handler.handlePacket(packet, Minecraft.getMinecraft(), (INetHandlerPlayClient) netHandler);
else
System.err.println("Invalid INetHandler for PacketCustom on channel: " + channel);
else System.err.println("Invalid INetHandler for PacketCustom on channel: " + channel);
}
}
public static class ServerInboundHandler implements CustomHandler
{
public static class ServerInboundHandler implements CustomHandler {
private IServerPacketHandler handler;
public ServerInboundHandler(ICustomPacketHandler handler) {
@@ -114,19 +103,17 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
@Override
public void handle(INetHandler netHandler, String channel, PacketCustom packet) throws Exception {
if (netHandler instanceof NetHandlerPlayServer)
handler.handlePacket(packet, ((NetHandlerPlayServer) netHandler).playerEntity, (INetHandlerPlayServer) netHandler);
else
System.err.println("Invalid INetHandler for PacketCustom on channel: " + channel);
handler.handlePacket(
packet, ((NetHandlerPlayServer) netHandler).playerEntity, (INetHandlerPlayServer) netHandler);
else System.err.println("Invalid INetHandler for PacketCustom on channel: " + channel);
}
}
public static interface IHandshakeHandler
{
public static interface IHandshakeHandler {
public void handshakeRecieved(NetHandlerPlayServer netHandler);
}
public static class HandshakeInboundHandler extends ChannelInboundHandlerAdapter
{
public static class HandshakeInboundHandler extends ChannelInboundHandlerAdapter {
public IHandshakeHandler handler;
public HandshakeInboundHandler(IHandshakeHandler handler) {
@@ -136,25 +123,27 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof NetworkHandshakeEstablished) {
INetHandler netHandler = ((NetworkDispatcher) ctx.channel().attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).get()).getNetHandler();
INetHandler netHandler = ((NetworkDispatcher) ctx.channel()
.attr(FMLOutboundHandler.FML_MESSAGETARGETARGS)
.get())
.getNetHandler();
if (netHandler instanceof NetHandlerPlayServer)
handler.handshakeRecieved((NetHandlerPlayServer) netHandler);
} else
ctx.fireUserEventTriggered(evt);
} else ctx.fireUserEventTriggered(evt);
}
}
public static String channelName(Object channelKey) {
if (channelKey instanceof String)
return (String) channelKey;
if (channelKey instanceof String) return (String) channelKey;
ModContainer mc = channelKey instanceof ModContainer ?
(ModContainer) channelKey :
FMLCommonHandler.instance().findContainerFor(channelKey);
ModContainer mc = channelKey instanceof ModContainer
? (ModContainer) channelKey
: FMLCommonHandler.instance().findContainerFor(channelKey);
if (mc != null) {
String s = mc.getModId();
if(s.length() > 20)
throw new IllegalArgumentException("Mod ID ("+s+") too long for use as channel (20 chars). Use a string identifier");
if (s.length() > 20)
throw new IllegalArgumentException(
"Mod ID (" + s + ") too long for use as channel (20 chars). Use a string identifier");
return s;
}
@@ -171,7 +160,10 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
String channelName = channelName(channelKey);
Side side = handler instanceof IServerPacketHandler ? Side.SERVER : Side.CLIENT;
FMLEmbeddedChannel channel = getOrCreateChannel(channelName, side);
channel.attr(cclHandler).get().handlers.put(side, side == Side.SERVER ? new ServerInboundHandler(handler) : new ClientInboundHandler(handler));
channel.attr(cclHandler)
.get()
.handlers
.put(side, side == Side.SERVER ? new ServerInboundHandler(handler) : new ClientInboundHandler(handler));
}
public static void assignHandshakeHandler(Object channelKey, IHandshakeHandler handler) {
@@ -187,8 +179,7 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
byteBuf = payload;
type = byteBuf.readUnsignedByte();
if (type > 0x80)
decompress();
if (type > 0x80) decompress();
type &= 0x7F;
}
@@ -233,8 +224,8 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
deflater.finish();
ByteBuf out = Unpooled.buffer(len + 5);
int clen = deflater.deflate(out.array(), 5, len);
if (clen >= len - 5 || !deflater.finished())//not worth compressing, gets larger
return;
if (clen >= len - 5 || !deflater.finished()) // not worth compressing, gets larger
return;
out.setByte(0, type | 0x80);
out.setInt(1, len);
@@ -261,10 +252,8 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
}
public PacketCustom compress() {
if (incoming())
throw new IllegalStateException("Tried to compress an incoming packet");
if ((type & 0x80) != 0)
throw new IllegalStateException("Packet already compressed");
if (incoming()) throw new IllegalStateException("Tried to compress an incoming packet");
if ((type & 0x80) != 0) throw new IllegalStateException("Packet already compressed");
type |= 0x80;
return this;
}
@@ -354,10 +343,8 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
writeShort(-1);
} else {
writeShort(Item.getIdFromItem(stack.getItem()));
if (large)
writeInt(stack.stackSize);
else
writeByte(stack.stackSize);
if (large) writeInt(stack.stackSize);
else writeByte(stack.stackSize);
writeShort(stack.getItemDamage());
writeNBTTagCompound(stack.stackTagCompound);
}
@@ -468,20 +455,17 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
public FluidStack readFluidStack() {
Fluid fluid = FluidRegistry.getFluid(readShort());
if(fluid == null)
fluid = FluidRegistry.WATER;
if (fluid == null) fluid = FluidRegistry.WATER;
return new FluidStack(fluid, readVarInt(), readNBTTagCompound());
}
public FMLProxyPacket toPacket() {
if (incoming())
throw new IllegalStateException("Tried to write an incoming packet");
if (incoming()) throw new IllegalStateException("Tried to write an incoming packet");
if (byteBuf.readableBytes() > 32000 || (type & 0x80) != 0)
do_compress();
if (byteBuf.readableBytes() > 32000 || (type & 0x80) != 0) do_compress();
//FML packet impl returns the whole of the backing array, copy used portion of array to another ByteBuf
// FML packet impl returns the whole of the backing array, copy used portion of array to another ByteBuf
return new FMLProxyPacket(byteBuf.copy(), channel);
}
@@ -490,10 +474,8 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
}
public static void sendToPlayer(Packet packet, EntityPlayer player) {
if (player == null)
sendToClients(packet);
else
((EntityPlayerMP) player).playerNetServerHandler.sendPacket(packet);
if (player == null) sendToClients(packet);
else ((EntityPlayerMP) player).playerNetServerHandler.sendPacket(packet);
}
public void sendToClients() {
@@ -525,10 +507,10 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
}
public static void sendToChunk(Packet packet, World world, int chunkX, int chunkZ) {
PlayerManager playerManager = ((WorldServer)world).getPlayerManager();
for (EntityPlayerMP player : (List<EntityPlayerMP>) MinecraftServer.getServer().getConfigurationManager().playerEntityList)
if(playerManager.isPlayerWatchingChunk(player, chunkX, chunkZ))
sendToPlayer(packet, player);
PlayerManager playerManager = ((WorldServer) world).getPlayerManager();
for (EntityPlayerMP player :
(List<EntityPlayerMP>) MinecraftServer.getServer().getConfigurationManager().playerEntityList)
if (playerManager.isPlayerWatchingChunk(player, chunkX, chunkZ)) sendToPlayer(packet, player);
/* Commented until forge accepts access tranformer request
PlayerInstance p = ((WorldServer) world).getPlayerManager().getOrCreateChunkWatcher(chunkX, chunkZ, false);
@@ -541,7 +523,8 @@ public final class PacketCustom implements MCDataInput, MCDataOutput
}
public static void sendToOps(Packet packet) {
for (EntityPlayerMP player : (List<EntityPlayerMP>) MinecraftServer.getServer().getConfigurationManager().playerEntityList)
for (EntityPlayerMP player :
(List<EntityPlayerMP>) MinecraftServer.getServer().getConfigurationManager().playerEntityList)
if (MinecraftServer.getServer().getConfigurationManager().func_152596_g(player.getGameProfile()))
sendToPlayer(packet, player);
}
@@ -4,28 +4,24 @@ import net.minecraft.entity.Entity;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
public class ExtendedMOP extends MovingObjectPosition implements Comparable<ExtendedMOP>
{
public class ExtendedMOP extends MovingObjectPosition implements Comparable<ExtendedMOP> {
public Object data;
/**
* The square distance from the start of the raytrace.
*/
public double dist;
public ExtendedMOP(Entity entity, Object data)
{
public ExtendedMOP(Entity entity, Object data) {
super(entity);
setData(data);
}
public ExtendedMOP(int x, int y, int z, int side, Vec3 hit, Object data)
{
public ExtendedMOP(int x, int y, int z, int side, Vec3 hit, Object data) {
super(x, y, z, side, hit);
setData(data);
}
public ExtendedMOP(MovingObjectPosition mop, Object data, double dist)
{
public ExtendedMOP(MovingObjectPosition mop, Object data, double dist) {
super(0, 0, 0, 0, mop.hitVec);
typeOfHit = mop.typeOfHit;
blockX = mop.blockX;
@@ -37,25 +33,20 @@ public class ExtendedMOP extends MovingObjectPosition implements Comparable<Exte
this.dist = dist;
}
public void setData(Object data)
{
if(data instanceof Integer)
subHit = ((Integer) data).intValue();
public void setData(Object data) {
if (data instanceof Integer) subHit = ((Integer) data).intValue();
this.data = data;
}
@SuppressWarnings("unchecked")
public static <T> T getData(MovingObjectPosition mop)
{
if(mop instanceof ExtendedMOP)
return (T)((ExtendedMOP)mop).data;
return (T)Integer.valueOf(mop.subHit);
public static <T> T getData(MovingObjectPosition mop) {
if (mop instanceof ExtendedMOP) return (T) ((ExtendedMOP) mop).data;
return (T) Integer.valueOf(mop.subHit);
}
@Override
public int compareTo(ExtendedMOP o)
{
public int compareTo(ExtendedMOP o) {
return dist == o.dist ? 0 : dist < o.dist ? -1 : 1;
}
}
@@ -2,13 +2,11 @@ package codechicken.lib.raytracer;
import codechicken.lib.vec.Cuboid6;
public class IndexedCuboid6 extends Cuboid6
{
public class IndexedCuboid6 extends Cuboid6 {
public Object data;
public IndexedCuboid6(Object data, Cuboid6 cuboid)
{
public IndexedCuboid6(Object data, Cuboid6 cuboid) {
super(cuboid);
this.data = data;
}
}
}
@@ -6,9 +6,9 @@ import codechicken.lib.vec.Cuboid6;
import codechicken.lib.vec.Vector3;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.MovingObjectPosition;
@@ -16,10 +16,7 @@ import net.minecraft.util.MovingObjectPosition.MovingObjectType;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import java.util.List;
public class RayTracer
{
public class RayTracer {
private Vector3 vec = new Vector3();
private Vector3 vec2 = new Vector3();
@@ -27,23 +24,19 @@ public class RayTracer
private double s_dist;
private int s_side;
private IndexedCuboid6 c_cuboid;
private static ThreadLocal<RayTracer> t_inst = new ThreadLocal<RayTracer>();
public static RayTracer instance()
{
public static RayTracer instance() {
RayTracer inst = t_inst.get();
if(inst == null)
t_inst.set(inst = new RayTracer());
if (inst == null) t_inst.set(inst = new RayTracer());
return inst;
}
private void traceSide(int side, Vector3 start, Vector3 end, Cuboid6 cuboid)
{
private void traceSide(int side, Vector3 start, Vector3 end, Cuboid6 cuboid) {
vec.set(start);
Vector3 hit = null;
switch(side)
{
switch (side) {
case 0:
hit = vec.XZintercept(end, cuboid.min.y);
break;
@@ -63,87 +56,78 @@ public class RayTracer
hit = vec.YZintercept(end, cuboid.max.x);
break;
}
if(hit == null)
return;
switch(side)
{
if (hit == null) return;
switch (side) {
case 0:
case 1:
if(!MathHelper.between(cuboid.min.x, hit.x, cuboid.max.x) || !MathHelper.between(cuboid.min.z, hit.z, cuboid.max.z)) return;
if (!MathHelper.between(cuboid.min.x, hit.x, cuboid.max.x)
|| !MathHelper.between(cuboid.min.z, hit.z, cuboid.max.z)) return;
break;
case 2:
case 3:
if(!MathHelper.between(cuboid.min.x, hit.x, cuboid.max.x) || !MathHelper.between(cuboid.min.y, hit.y, cuboid.max.y)) return;
if (!MathHelper.between(cuboid.min.x, hit.x, cuboid.max.x)
|| !MathHelper.between(cuboid.min.y, hit.y, cuboid.max.y)) return;
break;
case 4:
case 5:
if(!MathHelper.between(cuboid.min.y, hit.y, cuboid.max.y) || !MathHelper.between(cuboid.min.z, hit.z, cuboid.max.z)) return;
if (!MathHelper.between(cuboid.min.y, hit.y, cuboid.max.y)
|| !MathHelper.between(cuboid.min.z, hit.z, cuboid.max.z)) return;
break;
}
double dist = vec2.set(hit).subtract(start).magSquared();
if(dist < s_dist)
{
if (dist < s_dist) {
s_side = side;
s_dist = dist;
s_vec.set(vec);
}
}
public MovingObjectPosition rayTraceCuboid(Vector3 start, Vector3 end, Cuboid6 cuboid)
{
public MovingObjectPosition rayTraceCuboid(Vector3 start, Vector3 end, Cuboid6 cuboid) {
s_dist = Double.MAX_VALUE;
s_side = -1;
for(int i = 0; i < 6; i++)
traceSide(i, start, end, cuboid);
if(s_side < 0)
return null;
for (int i = 0; i < 6; i++) traceSide(i, start, end, cuboid);
if (s_side < 0) return null;
MovingObjectPosition mop = new MovingObjectPosition(0, 0, 0, s_side, s_vec.toVec3D());
mop.typeOfHit = null;
return mop;
}
public MovingObjectPosition rayTraceCuboids(Vector3 start, Vector3 end, List<IndexedCuboid6> cuboids)
{
public MovingObjectPosition rayTraceCuboids(Vector3 start, Vector3 end, List<IndexedCuboid6> cuboids) {
double c_dist = Double.MAX_VALUE;
MovingObjectPosition c_hit = null;
for(IndexedCuboid6 cuboid : cuboids)
{
for (IndexedCuboid6 cuboid : cuboids) {
MovingObjectPosition mop = rayTraceCuboid(start, end, cuboid);
if(mop != null && s_dist < c_dist)
{
if (mop != null && s_dist < c_dist) {
mop = new ExtendedMOP(mop, cuboid.data, s_dist);
c_dist = s_dist;
c_hit = mop;
c_cuboid = cuboid;
}
}
return c_hit;
}
public MovingObjectPosition rayTraceCuboids(Vector3 start, Vector3 end, List<IndexedCuboid6> cuboids, BlockCoord pos, Block block)
{
public MovingObjectPosition rayTraceCuboids(
Vector3 start, Vector3 end, List<IndexedCuboid6> cuboids, BlockCoord pos, Block block) {
MovingObjectPosition mop = rayTraceCuboids(start, end, cuboids);
if(mop != null)
{
if (mop != null) {
mop.typeOfHit = MovingObjectType.BLOCK;
mop.blockX = pos.x;
mop.blockY = pos.y;
mop.blockZ = pos.z;
if(block != null)
c_cuboid.add(new Vector3(-pos.x, -pos.y, -pos.z)).setBlockBounds(block);
if (block != null) c_cuboid.add(new Vector3(-pos.x, -pos.y, -pos.z)).setBlockBounds(block);
}
return mop;
}
public static MovingObjectPosition retraceBlock(World world, EntityPlayer player, int x, int y, int z)
{
public static MovingObjectPosition retraceBlock(World world, EntityPlayer player, int x, int y, int z) {
Block block = world.getBlock(x, y, z);
Vec3 headVec = getCorrectedHeadVec(player);
@@ -153,56 +137,49 @@ public class RayTracer
return block.collisionRayTrace(world, x, y, z, headVec, endVec);
}
private static double getBlockReachDistance_server(EntityPlayerMP player)
{
private static double getBlockReachDistance_server(EntityPlayerMP player) {
return player.theItemInWorldManager.getBlockReachDistance();
}
@SideOnly(Side.CLIENT)
private static double getBlockReachDistance_client()
{
private static double getBlockReachDistance_client() {
return Minecraft.getMinecraft().playerController.getBlockReachDistance();
}
public static MovingObjectPosition reTrace(World world, EntityPlayer player)
{
public static MovingObjectPosition reTrace(World world, EntityPlayer player) {
return reTrace(world, player, getBlockReachDistance(player));
}
public static MovingObjectPosition reTrace(World world, EntityPlayer player, double reach)
{
public static MovingObjectPosition reTrace(World world, EntityPlayer player, double reach) {
Vec3 headVec = getCorrectedHeadVec(player);
Vec3 lookVec = player.getLook(1);
Vec3 endVec = headVec.addVector(lookVec.xCoord * reach, lookVec.yCoord * reach, lookVec.zCoord * reach);
return world.func_147447_a(headVec, endVec, true, false, true);
}
public static Vec3 getCorrectedHeadVec(EntityPlayer player)
{
public static Vec3 getCorrectedHeadVec(EntityPlayer player) {
Vec3 v = Vec3.createVectorHelper(player.posX, player.posY, player.posZ);
if(player.worldObj.isRemote) {
v.yCoord+=player.getEyeHeight()-player.getDefaultEyeHeight();//compatibility with eye height changing mods
if (player.worldObj.isRemote) {
v.yCoord +=
player.getEyeHeight() - player.getDefaultEyeHeight(); // compatibility with eye height changing mods
} else {
v.yCoord+=player.getEyeHeight();
if(player instanceof EntityPlayerMP && player.isSneaking())
v.yCoord-=0.08;
v.yCoord += player.getEyeHeight();
if (player instanceof EntityPlayerMP && player.isSneaking()) v.yCoord -= 0.08;
}
return v;
}
public static Vec3 getStartVec(EntityPlayer player)
{
public static Vec3 getStartVec(EntityPlayer player) {
return getCorrectedHeadVec(player);
}
public static double getBlockReachDistance(EntityPlayer player)
{
return player.worldObj.isRemote ? getBlockReachDistance_client() :
player instanceof EntityPlayerMP ? getBlockReachDistance_server((EntityPlayerMP) player) : 5D;
public static double getBlockReachDistance(EntityPlayer player) {
return player.worldObj.isRemote
? getBlockReachDistance_client()
: player instanceof EntityPlayerMP ? getBlockReachDistance_server((EntityPlayerMP) player) : 5D;
}
public static Vec3 getEndVec(EntityPlayer player)
{
public static Vec3 getEndVec(EntityPlayer player) {
Vec3 headVec = getCorrectedHeadVec(player);
Vec3 lookVec = player.getLook(1.0F);
double reach = getBlockReachDistance(player);
@@ -4,12 +4,10 @@ import codechicken.lib.lighting.LC;
import codechicken.lib.render.CCRenderState.VertexAttribute;
import codechicken.lib.vec.Cuboid6;
public class BlockRenderer
{
public static class BlockFace implements CCRenderState.IVertexSource
{
public Vertex5[] verts = new Vertex5[]{new Vertex5(), new Vertex5(), new Vertex5(), new Vertex5()};
public LC[] lightCoords = new LC[]{new LC(), new LC(), new LC(), new LC()};
public class BlockRenderer {
public static class BlockFace implements CCRenderState.IVertexSource {
public Vertex5[] verts = new Vertex5[] {new Vertex5(), new Vertex5(), new Vertex5(), new Vertex5()};
public LC[] lightCoords = new LC[] {new LC(), new LC(), new LC(), new LC()};
public boolean lcComputed = false;
public int side;
@@ -20,7 +18,7 @@ public class BlockRenderer
@Override
public <T> T getAttributes(CCRenderState.VertexAttribute<T> attr) {
return attr == CCRenderState.lightCoordAttrib && lcComputed ? (T)lightCoords : null;
return attr == CCRenderState.lightCoordAttrib && lcComputed ? (T) lightCoords : null;
}
@Override
@@ -34,9 +32,8 @@ public class BlockRenderer
}
public BlockFace computeLightCoords() {
if(!lcComputed) {
for (int i = 0; i < 4; i++)
lightCoords[i].compute(verts[i].vec, side);
if (!lcComputed) {
for (int i = 0; i < 4; i++) lightCoords[i].compute(verts[i].vec, side);
lcComputed = true;
}
return this;
@@ -49,54 +46,69 @@ public class BlockRenderer
double y2 = c.max.y;
double z1 = c.min.z;
double z2 = c.max.z;
double u1; double u2; double v1; double v2;
double u1;
double u2;
double v1;
double v2;
this.side = side;
lcComputed = false;
switch(side) {
switch (side) {
case 0:
u1 = x1; v1 = z1;
u2 = x2; v2 = z2;
u1 = x1;
v1 = z1;
u2 = x2;
v2 = z2;
verts[0].set(x1, y1, z2, u1, v2, 0);
verts[1].set(x1, y1, z1, u1, v1, 0);
verts[2].set(x2, y1, z1, u2, v1, 0);
verts[3].set(x2, y1, z2, u2, v2, 0);
break;
case 1:
u1 = x1; v1 = z1;
u2 = x2; v2 = z2;
u1 = x1;
v1 = z1;
u2 = x2;
v2 = z2;
verts[0].set(x2, y2, z2, u2, v2, 1);
verts[1].set(x2, y2, z1, u2, v1, 1);
verts[2].set(x1, y2, z1, u1, v1, 1);
verts[3].set(x1, y2, z2, u1, v2, 1);
break;
case 2:
u1 = 1-x1; v1 = 1-y2;
u2 = 1-x2; v2 = 1-y1;
u1 = 1 - x1;
v1 = 1 - y2;
u2 = 1 - x2;
v2 = 1 - y1;
verts[0].set(x1, y1, z1, u1, v2, 2);
verts[1].set(x1, y2, z1, u1, v1, 2);
verts[2].set(x2, y2, z1, u2, v1, 2);
verts[3].set(x2, y1, z1, u2, v2, 2);
break;
case 3:
u1 = x1; v1 = 1-y2;
u2 = x2; v2 = 1-y1;
u1 = x1;
v1 = 1 - y2;
u2 = x2;
v2 = 1 - y1;
verts[0].set(x2, y1, z2, u2, v2, 3);
verts[1].set(x2, y2, z2, u2, v1, 3);
verts[2].set(x1, y2, z2, u1, v1, 3);
verts[3].set(x1, y1, z2, u1, v2, 3);
break;
case 4:
u1 = z1; v1 = 1-y2;
u2 = z2; v2 = 1-y1;
u1 = z1;
v1 = 1 - y2;
u2 = z2;
v2 = 1 - y1;
verts[0].set(x1, y1, z2, u2, v2, 4);
verts[1].set(x1, y2, z2, u2, v1, 4);
verts[2].set(x1, y2, z1, u1, v1, 4);
verts[3].set(x1, y1, z1, u1, v2, 4);
break;
case 5:
u1 = 1-z1; v1 = 1-y2;
u2 = 1-z2; v2 = 1-y1;
u1 = 1 - z1;
v1 = 1 - y2;
u2 = 1 - z2;
v2 = 1 - y1;
verts[0].set(x2, y1, z1, u1, v2, 5);
verts[1].set(x2, y2, z1, u1, v1, 5);
verts[2].set(x2, y2, z2, u2, v1, 5);
@@ -106,14 +118,12 @@ public class BlockRenderer
}
}
public static class FullBlock implements CCRenderState.IVertexSource
{
public static class FullBlock implements CCRenderState.IVertexSource {
public Vertex5[] verts = CCModel.quadModel(24).generateBlock(0, Cuboid6.full).verts;
public LC[] lightCoords = new LC[24];
public FullBlock() {
for(int i = 0; i < 24; i++)
lightCoords[i] = new LC().compute(verts[i].vec, i/4);
for (int i = 0; i < 24; i++) lightCoords[i] = new LC().compute(verts[i].vec, i / 4);
}
@Override
@@ -133,11 +143,12 @@ public class BlockRenderer
@Override
public void prepareVertex() {
CCRenderState.side = CCRenderState.vertexIndex>>2;
CCRenderState.side = CCRenderState.vertexIndex >> 2;
}
}
public static FullBlock fullBlock = new FullBlock();
public static void renderFullBlock(int sideMask) {
CCRenderState.setModel(fullBlock);
renderFaces(sideMask);
@@ -148,10 +159,10 @@ public class BlockRenderer
* @param sideMask A mask of faces not to render
*/
public static void renderFaces(int sideMask) {
if(sideMask == 0x3F) return;
for(int s = 0; s < 6; s++)
if((sideMask & 1<<s) == 0) {
CCRenderState.setVertexRange(s*4, (s+1)*4);
if (sideMask == 0x3F) return;
for (int s = 0; s < 6; s++)
if ((sideMask & 1 << s) == 0) {
CCRenderState.setVertexRange(s * 4, (s + 1) * 4);
CCRenderState.render();
}
}
@@ -163,11 +174,11 @@ public class BlockRenderer
* @param sideMask A mask of faces not to render
*/
public static void renderCuboid(Cuboid6 bounds, int sideMask) {
if(sideMask == 0x3F) return;
if (sideMask == 0x3F) return;
CCRenderState.setModel(face);
for(int s = 0; s < 6; s++)
if((sideMask & 1<<s) == 0) {
for (int s = 0; s < 6; s++)
if ((sideMask & 1 << s) == 0) {
face.loadCuboidFace(bounds, s);
CCRenderState.render();
}
File diff suppressed because it is too large. Load diff
@@ -1,89 +1,91 @@
package codechicken.lib.render;
import codechicken.lib.vec.*;
import static codechicken.lib.math.MathHelper.phi;
public class CCModelLibrary
{
import codechicken.lib.vec.*;
public class CCModelLibrary {
public static CCModel icosahedron4;
public static CCModel icosahedron7;
private static int i;
static
{
static {
generateIcosahedron();
}
private static void generateIcosahedron()
{
private static void generateIcosahedron() {
Vector3[] verts = new Vector3[12];
verts[0] = new Vector3(-1, phi, 0);
verts[1] = new Vector3( 1, phi, 0);
verts[2] = new Vector3( 1,-phi, 0);
verts[3] = new Vector3(-1,-phi, 0);
verts[1] = new Vector3(1, phi, 0);
verts[2] = new Vector3(1, -phi, 0);
verts[3] = new Vector3(-1, -phi, 0);
verts[4] = new Vector3(0,-1, phi);
verts[4] = new Vector3(0, -1, phi);
verts[5] = new Vector3(0, 1, phi);
verts[6] = new Vector3(0, 1,-phi);
verts[7] = new Vector3(0,-1,-phi);
verts[6] = new Vector3(0, 1, -phi);
verts[7] = new Vector3(0, -1, -phi);
verts[8] = new Vector3( phi, 0,-1);
verts[9] = new Vector3( phi, 0, 1);
verts[8] = new Vector3(phi, 0, -1);
verts[9] = new Vector3(phi, 0, 1);
verts[10] = new Vector3(-phi, 0, 1);
verts[11] = new Vector3(-phi, 0,-1);
verts[11] = new Vector3(-phi, 0, -1);
Quat quat = Quat.aroundAxis(0, 0, 1, Math.atan(1 / phi));
for (Vector3 vec : verts) quat.rotate(vec);
Quat quat = Quat.aroundAxis(0, 0, 1, Math.atan(1/phi));
for(Vector3 vec : verts)
quat.rotate(vec);
icosahedron4 = CCModel.newModel(4, 60);
icosahedron7 = CCModel.newModel(7, 80);
i = 0;
//top
// top
addIcosahedronTriangle(verts[1], 0.5, 0, verts[0], 0, 0.25, verts[5], 1, 0.25);
addIcosahedronTriangle(verts[1], 0.5, 0, verts[5], 0, 0.25, verts[9], 1, 0.25);
addIcosahedronTriangle(verts[1], 0.5, 0, verts[9], 0, 0.25, verts[8], 1, 0.25);
addIcosahedronTriangle(verts[1], 0.5, 0, verts[8], 0, 0.25, verts[6], 1, 0.25);
addIcosahedronTriangle(verts[1], 0.5, 0, verts[6], 0, 0.25, verts[0], 1, 0.25);
//centre 1vert top
addIcosahedronTriangle(verts[0], 0.5, 0.25, verts[11],0, 0.75, verts[10],1, 0.75);
addIcosahedronTriangle(verts[5], 0.5, 0.25, verts[10],0, 0.75, verts[4], 1, 0.75);
// centre 1vert top
addIcosahedronTriangle(verts[0], 0.5, 0.25, verts[11], 0, 0.75, verts[10], 1, 0.75);
addIcosahedronTriangle(verts[5], 0.5, 0.25, verts[10], 0, 0.75, verts[4], 1, 0.75);
addIcosahedronTriangle(verts[9], 0.5, 0.25, verts[4], 0, 0.75, verts[2], 1, 0.75);
addIcosahedronTriangle(verts[8], 0.5, 0.25, verts[2], 0, 0.75, verts[7], 1, 0.75);
addIcosahedronTriangle(verts[6], 0.5, 0.25, verts[7], 0, 0.75, verts[11],1, 0.75);
//centre 1vert bottom
addIcosahedronTriangle(verts[6], 0.5, 0.25, verts[7], 0, 0.75, verts[11], 1, 0.75);
// centre 1vert bottom
addIcosahedronTriangle(verts[2], 0.5, 0.75, verts[8], 0, 0.25, verts[9], 1, 0.25);
addIcosahedronTriangle(verts[7], 0.5, 0.75, verts[6], 0, 0.25, verts[8], 1, 0.25);
addIcosahedronTriangle(verts[11],0.5, 0.75, verts[0], 0, 0.25, verts[6], 1, 0.25);
addIcosahedronTriangle(verts[10],0.5, 0.75, verts[5], 0, 0.25, verts[0], 1, 0.25);
addIcosahedronTriangle(verts[11], 0.5, 0.75, verts[0], 0, 0.25, verts[6], 1, 0.25);
addIcosahedronTriangle(verts[10], 0.5, 0.75, verts[5], 0, 0.25, verts[0], 1, 0.25);
addIcosahedronTriangle(verts[4], 0.5, 0.75, verts[9], 0, 0.25, verts[5], 1, 0.25);
//bottom
// bottom
addIcosahedronTriangle(verts[3], 0.5, 1, verts[2], 0, 0.75, verts[4], 1, 0.75);
addIcosahedronTriangle(verts[3], 0.5, 1, verts[7], 0, 0.75, verts[2], 1, 0.75);
addIcosahedronTriangle(verts[3], 0.5, 1, verts[11],0, 0.75, verts[7], 1, 0.75);
addIcosahedronTriangle(verts[3], 0.5, 1, verts[10],0, 0.75, verts[11],1, 0.75);
addIcosahedronTriangle(verts[3], 0.5, 1, verts[4], 0, 0.75, verts[10],1, 0.75);
addIcosahedronTriangle(verts[3], 0.5, 1, verts[11], 0, 0.75, verts[7], 1, 0.75);
addIcosahedronTriangle(verts[3], 0.5, 1, verts[10], 0, 0.75, verts[11], 1, 0.75);
addIcosahedronTriangle(verts[3], 0.5, 1, verts[4], 0, 0.75, verts[10], 1, 0.75);
icosahedron4.computeNormals().smoothNormals();
icosahedron7.computeNormals().smoothNormals();
}
private static void addIcosahedronTriangle(Vector3 vec1, double u1, double v1,
Vector3 vec2, double u2, double v2,
Vector3 vec3, double u3, double v3)
{
icosahedron4.verts[i*3] = icosahedron7.verts[i*4] = new Vertex5(vec1, u1, v1);
icosahedron4.verts[i*3+1] = icosahedron7.verts[i*4+1] = new Vertex5(vec2, u2, v2);
icosahedron4.verts[i*3+2] = icosahedron7.verts[i*4+2] = icosahedron7.verts[i*4+3] = new Vertex5(vec3, u3, v3);
private static void addIcosahedronTriangle(
Vector3 vec1,
double u1,
double v1,
Vector3 vec2,
double u2,
double v2,
Vector3 vec3,
double u3,
double v3) {
icosahedron4.verts[i * 3] = icosahedron7.verts[i * 4] = new Vertex5(vec1, u1, v1);
icosahedron4.verts[i * 3 + 1] = icosahedron7.verts[i * 4 + 1] = new Vertex5(vec2, u2, v2);
icosahedron4.verts[i * 3 + 2] =
icosahedron7.verts[i * 4 + 2] = icosahedron7.verts[i * 4 + 3] = new Vertex5(vec3, u3, v3);
i++;
}
public static Matrix4 getRenderMatrix(Vector3 position, Rotation rotation, double scale)
{
public static Matrix4 getRenderMatrix(Vector3 position, Rotation rotation, double scale) {
return new Matrix4().translate(position).apply(new Scale(scale)).apply(rotation);
}
}
@@ -2,21 +2,17 @@ package codechicken.lib.render;
import codechicken.lib.render.CCRenderState.IVertexOperation;
import codechicken.lib.render.CCRenderState.VertexAttribute;
import java.util.ArrayList;
public class CCRenderPipeline
{
public class PipelineBuilder
{
public class CCRenderPipeline {
public class PipelineBuilder {
public PipelineBuilder add(IVertexOperation op) {
ops.add(op);
return this;
}
public PipelineBuilder add(IVertexOperation... ops) {
for(int i = 0; i < ops.length; i++)
CCRenderPipeline.this.ops.add(ops[i]);
for (int i = 0; i < ops.length; i++) CCRenderPipeline.this.ops.add(ops[i]);
return this;
}
@@ -30,17 +26,14 @@ public class CCRenderPipeline
}
}
private class PipelineNode
{
private class PipelineNode {
public ArrayList<PipelineNode> deps = new ArrayList<PipelineNode>();
public IVertexOperation op;
public void add() {
if(op == null)
return;
if (op == null) return;
for(int i = 0; i < deps.size(); i++)
deps.get(i).add();
for (int i = 0; i < deps.size(); i++) deps.get(i).add();
deps.clear();
sorted.add(op);
op = null;
@@ -56,8 +49,7 @@ public class CCRenderPipeline
public void setPipeline(IVertexOperation... ops) {
this.ops.clear();
for(int i = 0; i < ops.length; i++)
this.ops.add(ops[i]);
for (int i = 0; i < ops.length; i++) this.ops.add(ops[i]);
rebuild();
}
@@ -67,44 +59,34 @@ public class CCRenderPipeline
}
private void unbuild() {
for(int i = 0; i < attribs.size(); i++)
attribs.get(i).active = false;
for (int i = 0; i < attribs.size(); i++) attribs.get(i).active = false;
attribs.clear();
sorted.clear();
}
public void rebuild() {
if(ops.isEmpty() || CCRenderState.model == null)
return;
if (ops.isEmpty() || CCRenderState.model == null) return;
//ensure enough nodes for all ops
while(nodes.size() < CCRenderState.operationCount())
nodes.add(new PipelineNode());
// ensure enough nodes for all ops
while (nodes.size() < CCRenderState.operationCount()) nodes.add(new PipelineNode());
unbuild();
if(CCRenderState.useNormals)
addAttribute(CCRenderState.normalAttrib);
if(CCRenderState.useColour)
addAttribute(CCRenderState.colourAttrib);
if(CCRenderState.computeLighting)
addAttribute(CCRenderState.lightingAttrib);
if (CCRenderState.useNormals) addAttribute(CCRenderState.normalAttrib);
if (CCRenderState.useColour) addAttribute(CCRenderState.colourAttrib);
if (CCRenderState.computeLighting) addAttribute(CCRenderState.lightingAttrib);
for(int i = 0; i < ops.size(); i++) {
for (int i = 0; i < ops.size(); i++) {
IVertexOperation op = ops.get(i);
loading = nodes.get(op.operationID());
boolean loaded = op.load();
if(loaded)
loading.op = op;
if (loaded) loading.op = op;
if(op instanceof VertexAttribute)
if(loaded)
attribs.add((VertexAttribute)op);
else
((VertexAttribute)op).active = false;
if (op instanceof VertexAttribute)
if (loaded) attribs.add((VertexAttribute) op);
else ((VertexAttribute) op).active = false;
}
for(int i = 0; i < nodes.size(); i++)
nodes.get(i).add();
for (int i = 0; i < nodes.size(); i++) nodes.get(i).add();
}
public void addRequirement(int opRef) {
@@ -117,15 +99,14 @@ public class CCRenderPipeline
}
public void addAttribute(VertexAttribute attrib) {
if(!attrib.active) {
if (!attrib.active) {
ops.add(attrib);
attrib.active = true;
}
}
public void operate() {
for(int i = 0; i < sorted.size(); i++)
sorted.get(i).operate();
for (int i = 0; i < sorted.size(); i++) sorted.get(i).operate();
}
public PipelineBuilder builder() {
@@ -7,20 +7,18 @@ import codechicken.lib.util.Copyable;
import codechicken.lib.vec.Rotation;
import codechicken.lib.vec.Transformation;
import codechicken.lib.vec.Vector3;
import java.util.ArrayList;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.IBlockAccess;
import java.util.ArrayList;
/**
* The core of the CodeChickenLib render system.
* Rendering operations are written to avoid object allocations by reusing static variables.
*/
public class CCRenderState
{
public class CCRenderState {
private static int nextOperationIndex;
public static int registerOperation() {
@@ -34,8 +32,7 @@ public class CCRenderState
/**
* Represents an operation to be run for each vertex that operates on and modifies the current state
*/
public static interface IVertexOperation
{
public static interface IVertexOperation {
/**
* Load any required references and add dependencies to the pipeline based on the current model (may be null)
* Return false if this operation is redundant in the pipeline with the given model
@@ -55,9 +52,10 @@ public class CCRenderState
}
private static ArrayList<VertexAttribute<?>> vertexAttributes = new ArrayList<VertexAttribute<?>>();
private static int registerVertexAttribute(VertexAttribute<?> attr) {
vertexAttributes.add(attr);
return vertexAttributes.size()-1;
return vertexAttributes.size() - 1;
}
public static VertexAttribute<?> getAttribute(int index) {
@@ -69,8 +67,7 @@ public class CCRenderState
* This class should handle the loading of the attrute from an array provided by IVertexSource.getAttributes or the computation of this attrute from others
* @param <T> The array type for this attrute eg. int[], Vector3[]
*/
public static abstract class VertexAttribute<T> implements IVertexOperation
{
public abstract static class VertexAttribute<T> implements IVertexOperation {
public final int attributeIndex = registerVertexAttribute(this);
private final int operationIndex = registerOperation();
/**
@@ -91,23 +88,20 @@ public class CCRenderState
public static void arrayCopy(Object src, int srcPos, Object dst, int destPos, int length) {
System.arraycopy(src, srcPos, dst, destPos, length);
if(dst instanceof Copyable[]) {
Object[] oa = (Object[])dst;
Copyable<Object>[] c = (Copyable[])dst;
for(int i = destPos; i < destPos+length; i++)
if(c[i] != null)
oa[i] = c[i].copy();
if (dst instanceof Copyable[]) {
Object[] oa = (Object[]) dst;
Copyable<Object>[] c = (Copyable[]) dst;
for (int i = destPos; i < destPos + length; i++) if (c[i] != null) oa[i] = c[i].copy();
}
}
public static <T> T copyOf(VertexAttribute<T> attr, T src, int length) {
T dst = attr.newArray(length);
arrayCopy(src, 0, dst, 0, ((Object[])src).length);
arrayCopy(src, 0, dst, 0, ((Object[]) src).length);
return dst;
}
public static interface IVertexSource
{
public static interface IVertexSource {
public Vertex5[] getVertices();
/**
@@ -140,22 +134,20 @@ public class CCRenderState
@Override
public boolean load() {
normalRef = model.getAttributes(this);
if(model.hasAttribute(this))
return normalRef != null;
if (model.hasAttribute(this)) return normalRef != null;
if(model.hasAttribute(sideAttrib)) {
if (model.hasAttribute(sideAttrib)) {
pipeline.addDependency(sideAttrib);
return true;
}
throw new IllegalStateException("Normals requested but neither normal or side attrutes are provided by the model");
throw new IllegalStateException(
"Normals requested but neither normal or side attrutes are provided by the model");
}
@Override
public void operate() {
if(normalRef != null)
setNormal(normalRef[vertexIndex]);
else
setNormal(Rotation.axes[side]);
if (normalRef != null) setNormal(normalRef[vertexIndex]);
else setNormal(Rotation.axes[side]);
}
};
public static VertexAttribute<int[]> colourAttrib = new VertexAttribute<int[]>() {
@@ -174,10 +166,8 @@ public class CCRenderState
@Override
public void operate() {
if(colourRef != null)
setColour(ColourRGBA.multiply(baseColour, colourRef[vertexIndex]));
else
setColour(baseColour);
if (colourRef != null) setColour(ColourRGBA.multiply(baseColour, colourRef[vertexIndex]));
else setColour(baseColour);
}
};
public static VertexAttribute<int[]> lightingAttrib = new VertexAttribute<int[]>() {
@@ -190,11 +180,10 @@ public class CCRenderState
@Override
public boolean load() {
if(!computeLighting || !useColour || !model.hasAttribute(this))
return false;
if (!computeLighting || !useColour || !model.hasAttribute(this)) return false;
colourRef = model.getAttributes(this);
if(colourRef != null) {
if (colourRef != null) {
pipeline.addDependency(colourAttrib);
return true;
}
@@ -217,8 +206,7 @@ public class CCRenderState
@Override
public boolean load() {
sideRef = model.getAttributes(this);
if(model.hasAttribute(this))
return sideRef != null;
if (model.hasAttribute(this)) return sideRef != null;
pipeline.addDependency(normalAttrib);
return true;
@@ -226,10 +214,8 @@ public class CCRenderState
@Override
public void operate() {
if(sideRef != null)
side = sideRef[vertexIndex];
else
side = CCModel.findSide(normal);
if (sideRef != null) side = sideRef[vertexIndex];
else side = CCModel.findSide(normal);
}
};
/**
@@ -237,7 +223,7 @@ public class CCRenderState
*/
public static VertexAttribute<LC[]> lightCoordAttrib = new VertexAttribute<LC[]>() {
private LC[] lcRef;
private Vector3 vec = new Vector3();//for computation
private Vector3 vec = new Vector3(); // for computation
private Vector3 pos = new Vector3();
@Override
@@ -248,8 +234,7 @@ public class CCRenderState
@Override
public boolean load() {
lcRef = model.getAttributes(this);
if(model.hasAttribute(this))
return lcRef != null;
if (model.hasAttribute(this)) return lcRef != null;
pos.set(lightMatrix.pos.x, lightMatrix.pos.y, lightMatrix.pos.z);
pipeline.addDependency(sideAttrib);
@@ -259,21 +244,19 @@ public class CCRenderState
@Override
public void operate() {
if(lcRef != null)
lc.set(lcRef[vertexIndex]);
else
lc.compute(vec.set(vert.vec).sub(pos), side);
if (lcRef != null) lc.set(lcRef[vertexIndex]);
else lc.compute(vec.set(vert.vec).sub(pos), side);
}
};
//pipeline state
// pipeline state
public static IVertexSource model;
public static int firstVertexIndex;
public static int lastVertexIndex;
public static int vertexIndex;
public static CCRenderPipeline pipeline = new CCRenderPipeline();
//context
// context
public static int baseColour;
public static int alphaOverride;
public static boolean useNormals;
@@ -281,7 +264,7 @@ public class CCRenderState
public static boolean useColour;
public static LightMatrix lightMatrix = new LightMatrix();
//vertex outputs
// vertex outputs
public static Vertex5 vert = new Vertex5();
public static boolean hasNormal;
public static Vector3 normal = new Vector3();
@@ -290,7 +273,7 @@ public class CCRenderState
public static boolean hasBrightness;
public static int brightness;
//attrute storage
// attrute storage
public static int side;
public static LC lc = new LC();
@@ -313,7 +296,7 @@ public class CCRenderState
}
public static void bindModel(IVertexSource model) {
if(CCRenderState.model != model) {
if (CCRenderState.model != model) {
CCRenderState.model = model;
pipeline.rebuild();
}
@@ -340,7 +323,7 @@ public class CCRenderState
public static void render() {
Vertex5[] verts = model.getVertices();
for(vertexIndex = firstVertexIndex; vertexIndex < lastVertexIndex; vertexIndex++) {
for (vertexIndex = firstVertexIndex; vertexIndex < lastVertexIndex; vertexIndex++) {
model.prepareVertex();
vert.set(verts[vertexIndex]);
runPipeline();
@@ -353,12 +336,14 @@ public class CCRenderState
}
public static void writeVert() {
if(hasNormal)
Tessellator.instance.setNormal((float)normal.x, (float)normal.y, (float)normal.z);
if(hasColour)
Tessellator.instance.setColorRGBA(colour>>>24, colour>>16 & 0xFF, colour>>8 & 0xFF, alphaOverride >= 0 ? alphaOverride : colour & 0xFF);
if(hasBrightness)
Tessellator.instance.setBrightness(brightness);
if (hasNormal) Tessellator.instance.setNormal((float) normal.x, (float) normal.y, (float) normal.z);
if (hasColour)
Tessellator.instance.setColorRGBA(
colour >>> 24,
colour >> 16 & 0xFF,
colour >> 8 & 0xFF,
alphaOverride >= 0 ? alphaOverride : colour & 0xFF);
if (hasBrightness) Tessellator.instance.setBrightness(brightness);
Tessellator.instance.addVertexWithUV(vert.vec.x, vert.vec.y, vert.vec.z, vert.uv.u, vert.uv.v);
}
@@ -387,7 +372,7 @@ public class CCRenderState
}
public static void pullLightmap() {
setBrightness((int)OpenGlHelper.lastBrightnessY << 16 | (int)OpenGlHelper.lastBrightnessX);
setBrightness((int) OpenGlHelper.lastBrightnessY << 16 | (int) OpenGlHelper.lastBrightnessX);
}
public static void pushLightmap() {
@@ -416,10 +401,13 @@ public class CCRenderState
public static void startDrawing(int mode) {
Tessellator.instance.startDrawing(mode);
if(hasColour)
Tessellator.instance.setColorRGBA(colour>>>24, colour>>16 & 0xFF, colour>>8 & 0xFF, alphaOverride >= 0 ? alphaOverride : colour & 0xFF);
if(hasBrightness)
Tessellator.instance.setBrightness(brightness);
if (hasColour)
Tessellator.instance.setColorRGBA(
colour >>> 24,
colour >> 16 & 0xFF,
colour >> 8 & 0xFF,
alphaOverride >= 0 ? alphaOverride : colour & 0xFF);
if (hasBrightness) Tessellator.instance.setBrightness(brightness);
}
public static void draw() {
@@ -2,8 +2,7 @@ package codechicken.lib.render;
import codechicken.lib.colour.ColourRGBA;
public class ColourMultiplier implements CCRenderState.IVertexOperation
{
public class ColourMultiplier implements CCRenderState.IVertexOperation {
private static ColourMultiplier instance = new ColourMultiplier(-1);
public static ColourMultiplier instance(int colour) {
@@ -20,7 +19,7 @@ public class ColourMultiplier implements CCRenderState.IVertexOperation
@Override
public boolean load() {
if(colour == -1) {
if (colour == -1) {
CCRenderState.setColour(-1);
return false;
}
@@ -8,23 +8,20 @@ import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.IIcon;
import net.minecraft.world.World;
public class EntityDigIconFX extends EntityFX
{
public EntityDigIconFX(World world, double x, double y, double z, double dx, double dy, double dz, IIcon icon)
{
public class EntityDigIconFX extends EntityFX {
public EntityDigIconFX(World world, double x, double y, double z, double dx, double dy, double dz, IIcon icon) {
super(world, x, y, z, dx, dy, dz);
particleIcon = icon;
particleGravity = 1;
particleRed = particleGreen = particleBlue = 0.6F;
particleScale /= 2.0F;
}
@Override
public int getFXLayer()
{
public int getFXLayer() {
return 1;
}
public void setScale(float scale) {
particleScale = scale;
}
@@ -32,91 +29,94 @@ public class EntityDigIconFX extends EntityFX
public float getScale() {
return particleScale;
}
public void setMaxAge(int age){
public void setMaxAge(int age) {
particleMaxAge = age;
}
public int getMaxAge(){
public int getMaxAge() {
return particleMaxAge;
}
/**
* copy pasted from EntityDiggingFX
*/
@Override
public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7)
{
public void renderParticle(
Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) {
float f6 = (particleTextureIndexX + particleTextureJitterX / 4.0F) / 16.0F;
float f7 = f6 + 0.015609375F;
float f8 = (particleTextureIndexY + particleTextureJitterY / 4.0F) / 16.0F;
float f9 = f8 + 0.015609375F;
float f10 = 0.1F * particleScale;
if (particleIcon != null)
{
if (particleIcon != null) {
f6 = particleIcon.getInterpolatedU(particleTextureJitterX / 4.0F * 16.0F);
f7 = particleIcon.getInterpolatedU((particleTextureJitterX + 1.0F) / 4.0F * 16.0F);
f8 = particleIcon.getInterpolatedV(particleTextureJitterY / 4.0F * 16.0F);
f9 = particleIcon.getInterpolatedV((particleTextureJitterY + 1.0F) / 4.0F * 16.0F);
}
float f11 = (float)(prevPosX + (posX - prevPosX) * par2 - interpPosX);
float f12 = (float)(prevPosY + (posY - prevPosY) * par2 - interpPosY);
float f13 = (float)(prevPosZ + (posZ - prevPosZ) * par2 - interpPosZ);
float f11 = (float) (prevPosX + (posX - prevPosX) * par2 - interpPosX);
float f12 = (float) (prevPosY + (posY - prevPosY) * par2 - interpPosY);
float f13 = (float) (prevPosZ + (posZ - prevPosZ) * par2 - interpPosZ);
float f14 = 1.0F;
par1Tessellator.setColorOpaque_F(f14 * particleRed, f14 * particleGreen, f14 * particleBlue);
par1Tessellator.addVertexWithUV(f11 - par3 * f10 - par6 * f10, f12 - par4 * f10, f13 - par5 * f10 - par7 * f10, f6, f9);
par1Tessellator.addVertexWithUV(f11 - par3 * f10 + par6 * f10, f12 + par4 * f10, f13 - par5 * f10 + par7 * f10, f6, f8);
par1Tessellator.addVertexWithUV(f11 + par3 * f10 + par6 * f10, f12 + par4 * f10, f13 + par5 * f10 + par7 * f10, f7, f8);
par1Tessellator.addVertexWithUV(f11 + par3 * f10 - par6 * f10, f12 - par4 * f10, f13 + par5 * f10 - par7 * f10, f7, f9);
par1Tessellator.addVertexWithUV(
f11 - par3 * f10 - par6 * f10, f12 - par4 * f10, f13 - par5 * f10 - par7 * f10, f6, f9);
par1Tessellator.addVertexWithUV(
f11 - par3 * f10 + par6 * f10, f12 + par4 * f10, f13 - par5 * f10 + par7 * f10, f6, f8);
par1Tessellator.addVertexWithUV(
f11 + par3 * f10 + par6 * f10, f12 + par4 * f10, f13 + par5 * f10 + par7 * f10, f7, f8);
par1Tessellator.addVertexWithUV(
f11 + par3 * f10 - par6 * f10, f12 - par4 * f10, f13 + par5 * f10 - par7 * f10, f7, f9);
}
public static void addBlockHitEffects(World world, Cuboid6 bounds, int side, IIcon icon, EffectRenderer effectRenderer)
{
public static void addBlockHitEffects(
World world, Cuboid6 bounds, int side, IIcon icon, EffectRenderer effectRenderer) {
float border = 0.1F;
Vector3 diff = bounds.max.copy().subtract(bounds.min).add(-2*border);
diff.x*=world.rand.nextDouble();
diff.y*=world.rand.nextDouble();
diff.z*=world.rand.nextDouble();
Vector3 diff = bounds.max.copy().subtract(bounds.min).add(-2 * border);
diff.x *= world.rand.nextDouble();
diff.y *= world.rand.nextDouble();
diff.z *= world.rand.nextDouble();
Vector3 pos = diff.add(bounds.min).add(border);
if (side == 0)
diff.y = bounds.min.y - border;
if (side == 1)
diff.y = bounds.max.y + border;
if (side == 2)
diff.z = bounds.min.z - border;
if (side == 3)
diff.z = bounds.max.z + border;
if (side == 4)
diff.x = bounds.min.x - border;
if (side == 5)
diff.x = bounds.max.x + border;
effectRenderer.addEffect(
new EntityDigIconFX(world, pos.x, pos.y, pos.z, 0, 0, 0, icon)
.multiplyVelocity(0.2F).multipleParticleScaleBy(0.6F));
if (side == 0) diff.y = bounds.min.y - border;
if (side == 1) diff.y = bounds.max.y + border;
if (side == 2) diff.z = bounds.min.z - border;
if (side == 3) diff.z = bounds.max.z + border;
if (side == 4) diff.x = bounds.min.x - border;
if (side == 5) diff.x = bounds.max.x + border;
effectRenderer.addEffect(new EntityDigIconFX(world, pos.x, pos.y, pos.z, 0, 0, 0, icon)
.multiplyVelocity(0.2F)
.multipleParticleScaleBy(0.6F));
}
public static void addBlockDestroyEffects(World world, Cuboid6 bounds, IIcon[] icons, EffectRenderer effectRenderer)
{
public static void addBlockDestroyEffects(
World world, Cuboid6 bounds, IIcon[] icons, EffectRenderer effectRenderer) {
Vector3 diff = bounds.max.copy().subtract(bounds.min);
Vector3 center = bounds.min.copy().add(bounds.max).multiply(0.5);
Vector3 density = diff.copy().multiply(4);
density.x = Math.ceil(density.x);
density.y = Math.ceil(density.y);
density.z = Math.ceil(density.z);
for (int i = 0; i < density.x; ++i)
for (int j = 0; j < density.y; ++j)
for (int k = 0; k < density.z; ++k)
{
double x = bounds.min.x+(i+0.5)*diff.x/density.x;
double y = bounds.min.y+(j+0.5)*diff.y/density.y;
double z = bounds.min.z+(k+0.5)*diff.z/density.z;
effectRenderer.addEffect(
new EntityDigIconFX(world, x, y, z, x-center.x, y-center.y, z-center.z, icons[world.rand.nextInt(icons.length)]));
for (int k = 0; k < density.z; ++k) {
double x = bounds.min.x + (i + 0.5) * diff.x / density.x;
double y = bounds.min.y + (j + 0.5) * diff.y / density.y;
double z = bounds.min.z + (k + 0.5) * diff.z / density.z;
effectRenderer.addEffect(new EntityDigIconFX(
world,
x,
y,
z,
x - center.x,
y - center.y,
z - center.z,
icons[world.rand.nextInt(icons.length)]));
}
}
}
@@ -5,62 +5,53 @@ import net.minecraft.client.gui.FontRenderer;
import net.minecraft.item.ItemStack;
import org.lwjgl.opengl.GL11;
public class FontUtils
{
public class FontUtils {
public static FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer;
public static void drawCenteredString(String s, int xCenter, int y, int colour)
{
fontRenderer.drawString(s, xCenter-fontRenderer.getStringWidth(s)/2, y, colour);
public static void drawCenteredString(String s, int xCenter, int y, int colour) {
fontRenderer.drawString(s, xCenter - fontRenderer.getStringWidth(s) / 2, y, colour);
}
public static void drawRightString(String s, int xRight, int y, int colour)
{
fontRenderer.drawString(s, xRight-fontRenderer.getStringWidth(s), y, colour);
public static void drawRightString(String s, int xRight, int y, int colour) {
fontRenderer.drawString(s, xRight - fontRenderer.getStringWidth(s), y, colour);
}
public static final String[] prefixes = new String[]{"K", "M", "G"};
public static void drawItemQuantity(int x, int y, ItemStack item, String quantity, int mode)
{
if(item == null || (quantity == null && item.stackSize <= 1))
return;
if(quantity == null)
{
switch(mode)
{
public static final String[] prefixes = new String[] {"K", "M", "G"};
public static void drawItemQuantity(int x, int y, ItemStack item, String quantity, int mode) {
if (item == null || (quantity == null && item.stackSize <= 1)) return;
if (quantity == null) {
switch (mode) {
case 2:
int q = item.stackSize;
String postfix = "";
for(int p = 0; p < 3 && q > 1000; p++)
{
q/=1000;
for (int p = 0; p < 3 && q > 1000; p++) {
q /= 1000;
postfix = prefixes[p];
}
quantity = Integer.toString(q)+postfix;
quantity = Integer.toString(q) + postfix;
case 1:
quantity = "";
if(item.stackSize/64 > 0)
quantity+=item.stackSize/64 + "s";
if(item.stackSize%64 > 0)
quantity+=item.stackSize%64;
break;
if (item.stackSize / 64 > 0) quantity += item.stackSize / 64 + "s";
if (item.stackSize % 64 > 0) quantity += item.stackSize % 64;
break;
default:
quantity = Integer.toString(item.stackSize);
break;
break;
}
}
double scale = quantity.length() > 2 ? 0.5 : 1;
double sheight = 8*scale;
double swidth = fontRenderer.getStringWidth(quantity)*scale;
double sheight = 8 * scale;
double swidth = fontRenderer.getStringWidth(quantity) * scale;
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glPushMatrix();
GL11.glTranslated(x+16-swidth, y+16-sheight, 0);
GL11.glScaled(scale, scale, 1);
fontRenderer.drawStringWithShadow(quantity, 0, 0, 0xFFFFFF);
GL11.glTranslated(x + 16 - swidth, y + 16 - sheight, 0);
GL11.glScaled(scale, scale, 1);
fontRenderer.drawStringWithShadow(quantity, 0, 0, 0xFFFFFF);
GL11.glPopMatrix();
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_DEPTH_TEST);
@@ -1,6 +1,5 @@
package codechicken.lib.render;
public interface IFaceRenderer
{
public interface IFaceRenderer {
public void renderFace(Vertex5[] face, int side);
}
@@ -1,29 +1,23 @@
package codechicken.lib.render;
public class ManagedTextureFX extends TextureFX
{
public class ManagedTextureFX extends TextureFX {
public boolean changed;
public ManagedTextureFX(int size, String name)
{
public ManagedTextureFX(int size, String name) {
super(size, name);
imageData = new int[size*size];
imageData = new int[size * size];
}
@Override
public void setup()
{
}
public void setData(int[] data)
{
public void setup() {}
public void setData(int[] data) {
System.arraycopy(data, 0, imageData, 0, imageData.length);
changed = true;
}
@Override
public boolean changed()
{
public boolean changed() {
boolean r = changed;
changed = false;
return r;
@@ -4,8 +4,7 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
public class PlaceholderTexture extends TextureAtlasSprite
{
public class PlaceholderTexture extends TextureAtlasSprite {
protected PlaceholderTexture(String par1) {
super(par1);
}
@@ -5,20 +5,17 @@ import codechicken.lib.render.uv.UVScale;
import codechicken.lib.vec.*;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
import javax.imageio.ImageIO;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.util.IIcon;
import net.minecraft.util.ResourceLocation;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
public class QBImporter
{
private static class ImagePackNode
{
public class QBImporter {
private static class ImagePackNode {
Rectangle4i rect;
ImagePackNode child1;
ImagePackNode child2;
@@ -29,59 +26,49 @@ public class QBImporter
}
public boolean pack(QBImage img) {
if(child1 != null)
return child1.pack(img) || child2.pack(img);
if (child1 != null) return child1.pack(img) || child2.pack(img);
if(packed != null)
return false;
if (packed != null) return false;
int fit = getFit(img.width(), img.height());
if(fit == 0)
return false;
if (fit == 0) return false;
if((fit & 2) != 0) {//exact fit
if ((fit & 2) != 0) { // exact fit
packed = img;
img.packSlot = rect;
img.packT = new ImageTransform((fit&1)<<2);
img.packT = new ImageTransform((fit & 1) << 2);
return true;
}
int w = (fit & 1) == 0 ? img.width() : img.height();
int h = (fit & 1) == 0 ? img.height() : img.width();
if(rect.w - w > rect.h - h) {//create split with biggest leftover space
if (rect.w - w > rect.h - h) { // create split with biggest leftover space
child1 = new ImagePackNode(rect.x, rect.y, w, rect.h);
child2 = new ImagePackNode(rect.x+w, rect.y, rect.w-w, rect.h);
child2 = new ImagePackNode(rect.x + w, rect.y, rect.w - w, rect.h);
} else {
child1 = new ImagePackNode(rect.x, rect.y, rect.w, h);
child2 = new ImagePackNode(rect.x, rect.y+h, rect.w, rect.h-h);
child2 = new ImagePackNode(rect.x, rect.y + h, rect.w, rect.h - h);
}
return child1.pack(img);
}
private int getFit(int w, int h) {
if(w == rect.w && h == rect.h)
return 2;
if(w == rect.h && h == rect.w)
return 3;
if(rect.w >= w && rect.h >= h)
return 4;
if(rect.w >= h && rect.h >= w)
return 5;
if (w == rect.w && h == rect.h) return 2;
if (w == rect.h && h == rect.w) return 3;
if (rect.w >= w && rect.h >= h) return 4;
if (rect.w >= h && rect.h >= w) return 5;
return 0;
}
private static void nextSize(Rectangle4i rect, boolean square) {
if(square) {
if (square) {
rect.w <<= 1;
rect.h <<= 1;
}
else {
if(rect.w == rect.h)
rect.w *= 2;
else
rect.h *= 2;
} else {
if (rect.w == rect.h) rect.w *= 2;
else rect.h *= 2;
}
}
@@ -89,23 +76,20 @@ public class QBImporter
Collections.sort(images);
int area = 0;
for(QBImage img : images)
area+=img.area();
for (QBImage img : images) area += img.area();
ImagePackNode node = new ImagePackNode(0, 0, 2, 2);
while(node.rect.area() < area)
nextSize(node.rect, square);
while (node.rect.area() < area) nextSize(node.rect, square);
while(true) {
while (true) {
boolean packed = true;
for(QBImage img : images)
if(!node.pack(img)) {
for (QBImage img : images)
if (!node.pack(img)) {
packed = false;
break;
}
if(packed)
return node;
if (packed) return node;
node.child1 = node.child2 = null;
nextSize(node.rect, square);
@@ -119,23 +103,21 @@ public class QBImporter
}
private void write(BufferedImage img) {
if(child1 != null) {
if (child1 != null) {
child1.write(img);
child2.write(img);
}
else if(packed != null) {
} else if (packed != null) {
ImageTransform t = packed.packT;
for(int u = 0; u < rect.w; u++)
for(int v = 0; v < rect.h; v++) {
for (int u = 0; u < rect.w; u++)
for (int v = 0; v < rect.h; v++) {
int rgba = t.access(packed, u, v);
img.setRGB(u+rect.x, v+rect.y, rgba>>>8 | rgba<<24);
img.setRGB(u + rect.x, v + rect.y, rgba >>> 8 | rgba << 24);
}
}
}
}
private static class ImageTransform
{
private static class ImageTransform {
int transform;
public ImageTransform(int i) {
@@ -147,44 +129,43 @@ public class QBImporter
}
public boolean transpose() {
return (transform&4) != 0;
return (transform & 4) != 0;
}
public boolean flipU() {
return (transform&1) != 0;
return (transform & 1) != 0;
}
public boolean flipV() {
return (transform&2) != 0;
return (transform & 2) != 0;
}
public int access(QBImage img, int u, int v) {
if(transpose()) {
int tmp = u; u = v; v = tmp;
if (transpose()) {
int tmp = u;
u = v;
v = tmp;
}
if(flipU())
u = img.width()-1-u;
if(flipV())
v = img.height()-1-v;
if (flipU()) u = img.width() - 1 - u;
if (flipV()) v = img.height() - 1 - v;
return img.data[u][v];
}
public UV transform(UV uv) {
if(transpose()) {
double tmp = uv.u; uv.u = uv.v; uv.v = tmp;
if (transpose()) {
double tmp = uv.u;
uv.u = uv.v;
uv.v = tmp;
}
if(flipU())
uv.u = 1-uv.u;
if(flipV())
uv.v = 1-uv.v;
if (flipU()) uv.u = 1 - uv.u;
if (flipV()) uv.v = 1 - uv.v;
return uv;
}
}
public static class QBImage implements Comparable<QBImage>
{
public static class QBImage implements Comparable<QBImage> {
int[][] data;
ImageTransform packT;
Rectangle4i packSlot;
@@ -198,57 +179,54 @@ public class QBImporter
}
public int area() {
return width()*height();
return width() * height();
}
@Override
public int compareTo(QBImage o) {
int a = area(); int b = o.area();
int a = area();
int b = o.area();
return a > b ? -1 : a == b ? 0 : 1;
}
public ImageTransform transformTo(QBImage img) {
if(width() == img.width() && height() == img.height())
for(int i = 0; i < 4; i++) {
if (width() == img.width() && height() == img.height())
for (int i = 0; i < 4; i++) {
ImageTransform t = new ImageTransform(i);
if(equals(img, t))
return t;
if (equals(img, t)) return t;
}
if(width() == img.height() && height() == img.width())
for(int i = 4; i < 8; i++) {
if (width() == img.height() && height() == img.width())
for (int i = 4; i < 8; i++) {
ImageTransform t = new ImageTransform(i);
if(equals(img, t))
return t;
if (equals(img, t)) return t;
}
return null;
}
public boolean equals(QBImage img, ImageTransform t) {
for(int u = 0; u < img.width(); u++)
for(int v = 0; v < img.height(); v++)
if(t.access(this, u, v) != img.data[u][v])
return false;
for (int u = 0; u < img.width(); u++)
for (int v = 0; v < img.height(); v++) if (t.access(this, u, v) != img.data[u][v]) return false;
return true;
}
public void transform(UV uv) {
packT.transform(uv);
uv.u*=packSlot.w;
uv.v*=packSlot.h;
uv.u+=packSlot.x;
uv.v+=packSlot.y;
uv.u *= packSlot.w;
uv.v *= packSlot.h;
uv.u += packSlot.x;
uv.v += packSlot.y;
}
}
private static final int[][] vertOrder = new int[][] {//clockwise because MC is left handed
{3, 0},
{1, 0},
{1, 2},
{3, 2}};
private static final int[][] vertOrder = new int[][] { // clockwise because MC is left handed
{3, 0},
{1, 0},
{1, 2},
{3, 2}
};
public static class QBQuad
{
public static class QBQuad {
public Vertex5[] verts = new Vertex5[4];
public QBImage image = new QBImage();
public ImageTransform t = new ImageTransform();
@@ -259,24 +237,24 @@ public class QBImporter
}
public void applyImageT() {
for(Vertex5 vert : verts) {
for (Vertex5 vert : verts) {
t.transform(vert.uv);
image.transform(vert.uv);
}
}
public static QBQuad restore(Rectangle4i flat, int side, double d, QBImage img) {
QBQuad quad = new QBQuad(side);
quad.image = img;
Transformation t = new Scale(-1, 1, -1).with(Rotation.sideOrientation(side, 0)).with(new Translation(new Vector3().setSide(side, d)));
Transformation t = new Scale(-1, 1, -1)
.with(Rotation.sideOrientation(side, 0))
.with(new Translation(new Vector3().setSide(side, d)));
quad.verts[0] = new Vertex5(flat.x, 0, flat.y, 0, 0);
quad.verts[1] = new Vertex5(flat.x+flat.w, 0, flat.y, 1, 0);
quad.verts[2] = new Vertex5(flat.x+flat.w, 0, flat.y+flat.h, 1, 1);
quad.verts[3] = new Vertex5(flat.x, 0, flat.y+flat.h, 0, 1);
for(Vertex5 vert : quad.verts)
vert.apply(t);
quad.verts[1] = new Vertex5(flat.x + flat.w, 0, flat.y, 1, 0);
quad.verts[2] = new Vertex5(flat.x + flat.w, 0, flat.y + flat.h, 1, 1);
quad.verts[3] = new Vertex5(flat.x, 0, flat.y + flat.h, 0, 1);
for (Vertex5 vert : quad.verts) vert.apply(t);
return quad;
}
@@ -285,12 +263,11 @@ public class QBImporter
Transformation t = Rotation.sideOrientation(side, 0).inverse().with(new Scale(-1, 0, -1));
Vector3 vmin = verts[0].vec.copy().apply(t);
Vector3 vmax = verts[2].vec.copy().apply(t);
return new Rectangle4i((int)vmin.x, (int)vmin.z, (int)(vmax.x-vmin.x), (int)(vmax.z-vmin.z));
return new Rectangle4i((int) vmin.x, (int) vmin.z, (int) (vmax.x - vmin.x), (int) (vmax.z - vmin.z));
}
}
public static class QBCuboid
{
public static class QBCuboid {
public QBMatrix mat;
public CuboidCoord c;
public int sides;
@@ -304,16 +281,16 @@ public class QBImporter
public static boolean intersects(QBCuboid a, QBCuboid b) {
CuboidCoord c = a.c;
CuboidCoord d = b.c;
return c.min.x <= d.max.x &&
d.min.x <= c.max.x &&
c.min.y <= d.max.y &&
d.min.y <= c.max.y &&
c.min.z <= d.max.z &&
d.min.z <= c.max.z;
return c.min.x <= d.max.x
&& d.min.x <= c.max.x
&& c.min.y <= d.max.y
&& d.min.y <= c.max.y
&& c.min.z <= d.max.z
&& d.min.z <= c.max.z;
}
public static void clip(QBCuboid a, QBCuboid b) {
if(intersects(a, b)) {
if (intersects(a, b)) {
a.clip(b);
b.clip(a);
}
@@ -321,22 +298,21 @@ public class QBImporter
public void clip(QBCuboid o) {
CuboidCoord d = o.c;
for(int a = 0; a < 6; a+=2)
{
int a1 = (a+2)%6;
int a2 = (a+4)%6;
if(c.getSide(a1+1) <= d.getSide(a1+1) &&
c.getSide(a1) >= d.getSide(a1) &&
c.getSide(a2+1) <= d.getSide(a2+1) &&
c.getSide(a2) >= d.getSide(a2)) {
for (int a = 0; a < 6; a += 2) {
int a1 = (a + 2) % 6;
int a2 = (a + 4) % 6;
if (c.getSide(a1 + 1) <= d.getSide(a1 + 1)
&& c.getSide(a1) >= d.getSide(a1)
&& c.getSide(a2 + 1) <= d.getSide(a2 + 1)
&& c.getSide(a2) >= d.getSide(a2)) {
if(c.getSide(a) <= d.getSide(a+1) && c.getSide(a) >= d.getSide(a)) {
if (c.getSide(a) <= d.getSide(a + 1) && c.getSide(a) >= d.getSide(a)) {
c.setSide(a, d.getSide(a + 1) + 1);
sides|=1<<a;
sides |= 1 << a;
}
if(c.getSide(a+1) >= d.getSide(a) && c.getSide(a+1) <= d.getSide(a+1)) {
if (c.getSide(a + 1) >= d.getSide(a) && c.getSide(a + 1) <= d.getSide(a + 1)) {
c.setSide(a + 1, d.getSide(a) - 1);
sides|=2<<a;
sides |= 2 << a;
}
}
}
@@ -344,24 +320,22 @@ public class QBImporter
public void extractQuads(List<QBQuad> quads) {
Cuboid6 box = c.bounds();
for(int s = 0; s < 6; s++)
if((sides & 1<<s) == 0)
quads.add(extractQuad(s, box));
for (int s = 0; s < 6; s++) if ((sides & 1 << s) == 0) quads.add(extractQuad(s, box));
}
private QBQuad extractQuad(int side, Cuboid6 box) {
double[] da = new double[3];
da[side>>1] = box.getSide(side);
da[side >> 1] = box.getSide(side);
QBQuad quad = new QBQuad(side);
for(int i = 0; i < 4; i++) {
for (int i = 0; i < 4; i++) {
int rU = vertOrder[i][0];
int rV = vertOrder[i][1];
int sideU = Rotation.rotateSide(side, rU);
int sideV = Rotation.rotateSide(side, rV);
da[sideU>>1] = box.getSide(sideU);
da[sideV>>1] = box.getSide(sideV);
quad.verts[i] = new Vertex5(Vector3.fromAxes(da), (3-rU)/2, rV/2);
da[sideU >> 1] = box.getSide(sideU);
da[sideV >> 1] = box.getSide(sideV);
quad.verts[i] = new Vertex5(Vector3.fromAxes(da), (3 - rU) / 2, rV / 2);
}
int sideU = Rotation.rotateSide(side, 1);
@@ -370,47 +344,44 @@ public class QBImporter
QBImage image = quad.image;
int[] ia = new int[3];
ia[side>>1] = c.getSide(side); ia[sideU>>1] = c.getSide(sideU^1); ia[sideV>>1] = c.getSide(sideV^1);
ia[side >> 1] = c.getSide(side);
ia[sideU >> 1] = c.getSide(sideU ^ 1);
ia[sideV >> 1] = c.getSide(sideV ^ 1);
BlockCoord b = BlockCoord.fromAxes(ia);
BlockCoord bU = BlockCoord.sideOffsets[sideU];
BlockCoord bV = BlockCoord.sideOffsets[sideV];
for(int u = 0; u < image.width(); u++)
for(int v = 0; v < image.height(); v++)
image.data[u][v] = mat.matrix[b.x+bU.x*u+bV.x*v][b.y+bU.y*u+bV.y*v][b.z+bU.z*u+bV.z*v];
for (int u = 0; u < image.width(); u++)
for (int v = 0; v < image.height(); v++)
image.data[u][v] =
mat.matrix[b.x + bU.x * u + bV.x * v][b.y + bU.y * u + bV.y * v][b.z + bU.z * u + bV.z * v];
return quad;
}
}
public static class QBMatrix
{
public static class QBMatrix {
public String name;
public BlockCoord pos;
public BlockCoord size;
public int[][][] matrix;
public void readMatrix(DataInputStream din, boolean compressed) throws IOException {
if(compressed) {
if (compressed) {
int z = 0;
while (z < size.z)
{
while (z < size.z) {
int index = 0;
while (true)
{
while (true) {
int data = din.readInt();
if (data == NEXTSLICEFLAG)
break;
if (data == NEXTSLICEFLAG) break;
if (data == CODEFLAG) {
int count = readTni(din);
data = din.readInt();
for(int j = 0; j < count; j++, index++)
matrix[index % size.x][index / size.x][z] = data;
}
else {
for (int j = 0; j < count; j++, index++) matrix[index % size.x][index / size.x][z] = data;
} else {
matrix[index % size.x][index / size.x][z] = data;
index++;
}
@@ -418,28 +389,23 @@ public class QBImporter
z++;
}
} else {
for(int z = 0; z < size.z; z++)
for(int y = 0; y < size.y; y++)
for(int x = 0; x < size.x; x++)
matrix[x][y][z] = din.readInt();
for (int z = 0; z < size.z; z++)
for (int y = 0; y < size.y; y++) for (int x = 0; x < size.x; x++) matrix[x][y][z] = din.readInt();
}
}
public void convertBGRAtoRGBA() {
for(int z = 0; z < size.z; z++)
for(int y = 0; y < size.y; y++)
for(int x = 0; x < size.x; x++) {
for (int z = 0; z < size.z; z++)
for (int y = 0; y < size.y; y++)
for (int x = 0; x < size.x; x++) {
int i = matrix[x][y][z];
matrix[x][y][z] = Integer.reverseBytes(i>>>8)|i&0xFF;
matrix[x][y][z] = Integer.reverseBytes(i >>> 8) | i & 0xFF;
}
}
private boolean voxelFull(boolean[][][] solid, CuboidCoord c) {
for(BlockCoord b : c)
if(matrix[b.x][b.y][b.z] == 0)
return false;
for(BlockCoord b : c)
solid[b.x][b.y][b.z] = false;
for (BlockCoord b : c) if (matrix[b.x][b.y][b.z] == 0) return false;
for (BlockCoord b : c) solid[b.x][b.y][b.z] = false;
return true;
}
@@ -447,14 +413,13 @@ public class QBImporter
CuboidCoord c = new CuboidCoord(b);
solid[b.x][b.y][b.z] = false;
for(int s = 0; s < 6; s++) {
for (int s = 0; s < 6; s++) {
CuboidCoord slice = c.copy();
slice.expand(s^1, -(slice.size(s)-1));
slice.expand(s ^ 1, -(slice.size(s) - 1));
slice.expand(s, 1);
while(slice.getSide(s) >= 0 && slice.getSide(s) < size.getSide(s)) {
if(!voxelFull(solid, slice))
break;
while (slice.getSide(s) >= 0 && slice.getSide(s) < size.getSide(s)) {
if (!voxelFull(solid, slice)) break;
slice.expand(s ^ 1, -1);
slice.expand(s, 1);
c.expand(s, 1);
@@ -466,105 +431,93 @@ public class QBImporter
public List<QBCuboid> rectangulate() {
List<QBCuboid> list = new ArrayList<QBCuboid>();
boolean[][][] solid = new boolean[size.x][size.y][size.z];
for(int z = 0; z < size.z; z++)
for(int y = 0; y < size.y; y++)
for(int x = 0; x < size.x; x++)
solid[x][y][z] = matrix[x][y][z] != 0;
for (int z = 0; z < size.z; z++)
for (int y = 0; y < size.y; y++) for (int x = 0; x < size.x; x++) solid[x][y][z] = matrix[x][y][z] != 0;
for(int x = 0; x < size.x; x++)
for(int z = 0; z < size.z; z++)
for(int y = 0; y < size.y; y++)
if(solid[x][y][z])
list.add(expand(solid, new BlockCoord(x, y, z)));
for (int x = 0; x < size.x; x++)
for (int z = 0; z < size.z; z++)
for (int y = 0; y < size.y; y++)
if (solid[x][y][z]) list.add(expand(solid, new BlockCoord(x, y, z)));
for(int i = 0; i < list.size(); i++)
for(int j = i+1; j < list.size(); j++)
QBCuboid.clip(list.get(i), list.get(j));
for (int i = 0; i < list.size(); i++)
for (int j = i + 1; j < list.size(); j++) QBCuboid.clip(list.get(i), list.get(j));
return list;
}
public List<QBQuad> extractQuads(boolean texturePlanes) {
List<QBQuad> quads = new LinkedList<QBQuad>();
for(QBCuboid c : rectangulate())
c.extractQuads(quads);
for (QBCuboid c : rectangulate()) c.extractQuads(quads);
if(texturePlanes)
optimisePlanes(quads);
if (texturePlanes) optimisePlanes(quads);
return quads;
}
private void optimisePlanes(List<QBQuad> quads) {
Multimap<Integer, QBQuad> map = HashMultimap.create();
for(QBQuad quad : quads)
map.put(quad.side | ((int)quad.verts[0].vec.getSide(quad.side))<<3, quad);
for (QBQuad quad : quads) map.put(quad.side | ((int) quad.verts[0].vec.getSide(quad.side)) << 3, quad);
quads.clear();
for(Integer key : map.keySet()) {
for (Integer key : map.keySet()) {
Collection<QBQuad> plane = map.get(key);
if(plane.size() == 1) {
if (plane.size() == 1) {
quads.add(plane.iterator().next());
continue;
}
int side = key&7;
int side = key & 7;
Rectangle4i rect = null;
for(QBQuad q : plane)
if(rect == null)
rect = q.flatten();
else
rect.include(q.flatten());
for (QBQuad q : plane)
if (rect == null) rect = q.flatten();
else rect.include(q.flatten());
QBImage img = new QBImage();
img.data = new int[rect.w][rect.h];
for(QBQuad q : plane) {
for (QBQuad q : plane) {
QBImage from = q.image;
Rectangle4i r = q.flatten();
int du = r.x-rect.x;
int dv = r.y-rect.y;
for(int u = 0; u < from.width(); u++)
for(int v = 0; v < from.height(); v++)
img.data[du+u][dv+v] = from.data[u][v];
int du = r.x - rect.x;
int dv = r.y - rect.y;
for (int u = 0; u < from.width(); u++)
for (int v = 0; v < from.height(); v++) img.data[du + u][dv + v] = from.data[u][v];
}
quads.add(QBQuad.restore(rect, side, key>>3, img));
quads.add(QBQuad.restore(rect, side, key >> 3, img));
}
}
public CCModel buildModel(List<QBQuad> quads, BufferedImage img, boolean scaleMC) {
CCModel m = CCModel.quadModel(quads.size()*4);
CCModel m = CCModel.quadModel(quads.size() * 4);
int i = 0;
for(QBQuad quad : quads) {
for (QBQuad quad : quads) {
quad.applyImageT();
m.verts[i++] = quad.verts[0];
m.verts[i++] = quad.verts[1];
m.verts[i++] = quad.verts[2];
m.verts[i++] = quad.verts[3];
}
m.apply(new UVScale(1D/img.getWidth(), 1D/img.getHeight()));
m.apply(new UVScale(1D / img.getWidth(), 1D / img.getHeight()));
m.apply(new Translation(pos.x, pos.y, pos.z));
if(scaleMC)
m.apply(new Scale(1/16D));
if (scaleMC) m.apply(new Scale(1 / 16D));
m.computeNormals();
return m;
}
private static void addImages(List<QBQuad> quads, List<QBImage> images) {
for(QBQuad q : quads) {
for (QBQuad q : quads) {
QBImage img = q.image;
boolean matched = false;
for(QBImage img2 : images) {
for (QBImage img2 : images) {
ImageTransform t = img.transformTo(img2);
if(t != null) {
if (t != null) {
q.t = t;
q.image = img2;
matched = true;
break;
}
}
if(!matched)
images.add(img);
if (!matched) images.add(img);
}
}
}
@@ -573,8 +526,8 @@ public class QBImporter
public static final int SQUARETEXTURE = 2;
public static final int MERGETEXTURES = 4;
public static final int SCALEMC = 8;
public static class QBModel
{
public static class QBModel {
public QBMatrix[] matrices;
public boolean rightHanded;
@@ -588,21 +541,21 @@ public class QBImporter
boolean mergeTextures = (flags & MERGETEXTURES) != 0;
boolean scaleMC = (flags & SCALEMC) != 0;
for(QBMatrix mat : matrices) {
for (QBMatrix mat : matrices) {
List<QBQuad> quads = mat.extractQuads(texturePlanes);
modelQuads.add(quads);
QBMatrix.addImages(quads, qbImages);
if(!mergeTextures) {
if (!mergeTextures) {
images.add(ImagePackNode.pack(qbImages, squareTextures).toImage());
qbImages.clear();
}
}
if(mergeTextures)
if (mergeTextures)
images.add(ImagePackNode.pack(qbImages, squareTextures).toImage());
RasterisedModel m = new RasterisedModel(images);
for(int i = 0; i < matrices.length; i++) {
for (int i = 0; i < matrices.length; i++) {
QBMatrix mat = matrices[i];
BufferedImage img = images.get(mergeTextures ? 0 : i);
m.add(mat.name, mat.buildModel(modelQuads.get(i), img, scaleMC));
@@ -611,8 +564,7 @@ public class QBImporter
}
}
public static class RasterisedModel
{
public static class RasterisedModel {
private class Holder {
CCModel m;
int img;
@@ -633,7 +585,7 @@ public class QBImporter
}
public void add(String name, CCModel m) {
map.put(name, new Holder(m, Math.min(map.size(), images.size()-1)));
map.put(name, new Holder(m, Math.min(map.size(), images.size() - 1)));
}
public CCModel getModel(String key) {
@@ -642,41 +594,37 @@ public class QBImporter
public IIcon getIcon(String key, IIconRegister r, String iconName) {
int img = map.get(key).img;
if(icons[img] != null && !iconName.equals(icons[img]))
throw new IllegalArgumentException("Attempted to get a previously registered icon by a different name: "+icons[img]+", "+iconName);
if(icons[img] != null)
return r.registerIcon(iconName);
if (icons[img] != null && !iconName.equals(icons[img]))
throw new IllegalArgumentException("Attempted to get a previously registered icon by a different name: "
+ icons[img] + ", " + iconName);
if (icons[img] != null) return r.registerIcon(iconName);
icons[img] = iconName;
return TextureUtils.getTextureSpecial(r, iconName).addTexture(new TextureDataHolder(images.get(img)));
}
private void exportImg(BufferedImage img, File imgFile) throws IOException {
if(!imgFile.exists())
imgFile.createNewFile();
if (!imgFile.exists()) imgFile.createNewFile();
ImageIO.write(img, "PNG", imgFile);
}
public void export(File objFile, File imgDir) {
try {
if(!objFile.exists())
objFile.createNewFile();
if(!imgDir.exists())
imgDir.mkdirs();
if (!objFile.exists()) objFile.createNewFile();
if (!imgDir.exists()) imgDir.mkdirs();
Map<String, CCModel> modelMap = new HashMap<String, CCModel>();
for(Map.Entry<String, Holder> e : map.entrySet())
modelMap.put(e.getKey(), e.getValue().m);
for (Map.Entry<String, Holder> e : map.entrySet()) modelMap.put(e.getKey(), e.getValue().m);
PrintWriter p = new PrintWriter(objFile);
CCModel.exportObj(modelMap, p);
p.close();
if(images.size() < map.size())
if (images.size() < map.size())
exportImg(images.get(0), new File(imgDir, objFile.getName().replaceAll("(.+)\\..+", "$1.png")));
else
for(Map.Entry<String, Holder> e : map.entrySet())
exportImg(images.get(e.getValue().img), new File(imgDir, e.getKey()+".png"));
for (Map.Entry<String, Holder> e : map.entrySet())
exportImg(images.get(e.getValue().img), new File(imgDir, e.getKey() + ".png"));
} catch (IOException e) {
throw new RuntimeException(e);
@@ -685,7 +633,7 @@ public class QBImporter
}
private static String readAsciiString(DataInputStream din) throws IOException {
byte[] bytes = new byte[din.readByte()&0xFF];
byte[] bytes = new byte[din.readByte() & 0xFF];
din.readFully(bytes);
return new String(bytes, "US-ASCII");
}
@@ -696,6 +644,7 @@ public class QBImporter
private static final int CODEFLAG = Integer.reverseBytes(2);
private static final int NEXTSLICEFLAG = Integer.reverseBytes(6);
public static QBModel loadQB(InputStream input) throws IOException {
DataInputStream din = new DataInputStream(input);
@@ -706,11 +655,10 @@ public class QBImporter
boolean compressed = din.readInt() != 0;
boolean visEncoded = din.readInt() != 0;
if(visEncoded)
throw new IllegalArgumentException("Encoded Visiblity States not supported");
if (visEncoded) throw new IllegalArgumentException("Encoded Visiblity States not supported");
m.matrices = new QBMatrix[readTni(din)];
for(int i = 0; i < m.matrices.length; i++) {
for (int i = 0; i < m.matrices.length; i++) {
QBMatrix mat = new QBMatrix();
m.matrices[i] = mat;
mat.name = readAsciiString(din);
@@ -718,8 +666,7 @@ public class QBImporter
mat.pos = new BlockCoord(readTni(din), readTni(din), readTni(din));
mat.matrix = new int[mat.size.x][mat.size.y][mat.size.z];
mat.readMatrix(din, compressed);
if(colorFormat == 1)
mat.convertBGRAtoRGBA();
if (colorFormat == 1) mat.convertBGRAtoRGBA();
}
return m;
@@ -727,9 +674,12 @@ public class QBImporter
public static QBModel loadQB(ResourceLocation res) {
try {
return loadQB(Minecraft.getMinecraft().getResourceManager().getResource(res).getInputStream());
} catch(Exception e) {
throw new RuntimeException("failed to load model: "+res, e);
return loadQB(Minecraft.getMinecraft()
.getResourceManager()
.getResource(res)
.getInputStream());
} catch (Exception e) {
throw new RuntimeException("failed to load model: " + res, e);
}
}
@@ -741,8 +691,8 @@ public class QBImporter
} finally {
fin.close();
}
} catch(Exception e) {
throw new RuntimeException("failed to load model: "+file.getPath(), e);
} catch (Exception e) {
throw new RuntimeException("failed to load model: " + file.getPath(), e);
}
}
}
@@ -1,5 +1,8 @@
package codechicken.lib.render;
import static net.minecraftforge.client.IItemRenderer.ItemRenderType.ENTITY;
import static net.minecraftforge.client.IItemRenderer.ItemRendererHelper.BLOCK_3D;
import codechicken.lib.vec.Cuboid6;
import codechicken.lib.vec.Rectangle4i;
import codechicken.lib.vec.Vector3;
@@ -19,35 +22,32 @@ import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import org.lwjgl.opengl.GL11;
import static net.minecraftforge.client.IItemRenderer.ItemRenderType.ENTITY;
import static net.minecraftforge.client.IItemRenderer.ItemRendererHelper.BLOCK_3D;
public class RenderUtils
{
public class RenderUtils {
static Vector3[] vectors = new Vector3[8];
static RenderItem uniformRenderItem = new RenderItem()
{
public boolean shouldBob()
{
static RenderItem uniformRenderItem = new RenderItem() {
public boolean shouldBob() {
return false;
}
};
static EntityItem entityItem;
static
{
for(int i = 0; i < vectors.length; i++)
vectors[i] = new Vector3();
static {
for (int i = 0; i < vectors.length; i++) vectors[i] = new Vector3();
uniformRenderItem.setRenderManager(RenderManager.instance);
entityItem = new EntityItem(null);
entityItem.hoverStart = 0;
}
public static void renderFluidQuad(Vector3 point1, Vector3 point2, Vector3 point3, Vector3 point4, IIcon icon, double res)
{
renderFluidQuad(point2, vectors[0].set(point4).subtract(point1), vectors[1].set(point1).subtract(point2), icon, res);
public static void renderFluidQuad(
Vector3 point1, Vector3 point2, Vector3 point3, Vector3 point4, IIcon icon, double res) {
renderFluidQuad(
point2,
vectors[0].set(point4).subtract(point1),
vectors[1].set(point1).subtract(point2),
icon,
res);
}
/**
@@ -57,60 +57,60 @@ public class RenderUtils
* @param high The left side of the quad
* @param res Units per icon
*/
public static void renderFluidQuad(Vector3 base, Vector3 wide, Vector3 high, IIcon icon, double res)
{
public static void renderFluidQuad(Vector3 base, Vector3 wide, Vector3 high, IIcon icon, double res) {
Tessellator t = Tessellator.instance;
double u1 = icon.getMinU();
double du = icon.getMaxU()-icon.getMinU();
double du = icon.getMaxU() - icon.getMinU();
double v2 = icon.getMaxV();
double dv = icon.getMaxV()-icon.getMinV();
double dv = icon.getMaxV() - icon.getMinV();
double wlen = wide.mag();
double hlen = high.mag();
double x = 0;
while(x < wlen)
{
while (x < wlen) {
double rx = wlen - x;
if(rx > res)
rx = res;
if (rx > res) rx = res;
double y = 0;
while(y < hlen)
{
double ry = hlen-y;
if(ry > res)
ry = res;
while (y < hlen) {
double ry = hlen - y;
if (ry > res) ry = res;
Vector3 dx1 = vectors[2].set(wide).multiply(x/wlen);
Vector3 dx2 = vectors[3].set(wide).multiply((x+rx)/wlen);
Vector3 dy1 = vectors[4].set(high).multiply(y/hlen);
Vector3 dy2 = vectors[5].set(high).multiply((y+ry)/hlen);
Vector3 dx1 = vectors[2].set(wide).multiply(x / wlen);
Vector3 dx2 = vectors[3].set(wide).multiply((x + rx) / wlen);
Vector3 dy1 = vectors[4].set(high).multiply(y / hlen);
Vector3 dy2 = vectors[5].set(high).multiply((y + ry) / hlen);
t.addVertexWithUV(base.x+dx1.x+dy2.x, base.y+dx1.y+dy2.y, base.z+dx1.z+dy2.z, u1, v2-ry/res*dv);
t.addVertexWithUV(base.x+dx1.x+dy1.x, base.y+dx1.y+dy1.y, base.z+dx1.z+dy1.z, u1, v2);
t.addVertexWithUV(base.x+dx2.x+dy1.x, base.y+dx2.y+dy1.y, base.z+dx2.z+dy1.z, u1+rx/res*du, v2);
t.addVertexWithUV(base.x+dx2.x+dy2.x, base.y+dx2.y+dy2.y, base.z+dx2.z+dy2.z, u1+rx/res*du, v2-ry/res*dv);
y+=ry;
t.addVertexWithUV(
base.x + dx1.x + dy2.x, base.y + dx1.y + dy2.y, base.z + dx1.z + dy2.z, u1, v2 - ry / res * dv);
t.addVertexWithUV(base.x + dx1.x + dy1.x, base.y + dx1.y + dy1.y, base.z + dx1.z + dy1.z, u1, v2);
t.addVertexWithUV(
base.x + dx2.x + dy1.x, base.y + dx2.y + dy1.y, base.z + dx2.z + dy1.z, u1 + rx / res * du, v2);
t.addVertexWithUV(
base.x + dx2.x + dy2.x,
base.y + dx2.y + dy2.y,
base.z + dx2.z + dy2.z,
u1 + rx / res * du,
v2 - ry / res * dv);
y += ry;
}
x+=rx;
x += rx;
}
}
public static void translateToWorldCoords(Entity entity, float frame)
{
public static void translateToWorldCoords(Entity entity, float frame) {
double interpPosX = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * frame;
double interpPosY = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * frame;
double interpPosZ = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * frame;
GL11.glTranslated(-interpPosX, -interpPosY, -interpPosZ);
}
public static void drawCuboidOutline(Cuboid6 c)
{
public static void drawCuboidOutline(Cuboid6 c) {
Tessellator var2 = Tessellator.instance;
var2.startDrawing(3);
var2.addVertex(c.min.x, c.min.y, c.min.z);
@@ -137,130 +137,130 @@ public class RenderUtils
var2.addVertex(c.min.x, c.max.y, c.max.z);
var2.draw();
}
public static void renderFluidCuboid(Cuboid6 bound, IIcon tex, double res)
{
renderFluidQuad(//bottom
public static void renderFluidCuboid(Cuboid6 bound, IIcon tex, double res) {
renderFluidQuad( // bottom
new Vector3(bound.min.x, bound.min.y, bound.min.z),
new Vector3(bound.max.x, bound.min.y, bound.min.z),
new Vector3(bound.max.x, bound.min.y, bound.max.z),
new Vector3(bound.min.x, bound.min.y, bound.max.z),
tex, res);
renderFluidQuad(//top
new Vector3(bound.min.x, bound.min.y, bound.max.z),
tex,
res);
renderFluidQuad( // top
new Vector3(bound.min.x, bound.max.y, bound.min.z),
new Vector3(bound.min.x, bound.max.y, bound.max.z),
new Vector3(bound.max.x, bound.max.y, bound.max.z),
new Vector3(bound.max.x, bound.max.y, bound.min.z),
tex, res);
renderFluidQuad(//-x
new Vector3(bound.max.x, bound.max.y, bound.min.z),
tex,
res);
renderFluidQuad( // -x
new Vector3(bound.min.x, bound.max.y, bound.min.z),
new Vector3(bound.min.x, bound.min.y, bound.min.z),
new Vector3(bound.min.x, bound.min.y, bound.max.z),
new Vector3(bound.min.x, bound.max.y, bound.max.z),
tex, res);
renderFluidQuad(//+x
new Vector3(bound.min.x, bound.max.y, bound.max.z),
tex,
res);
renderFluidQuad( // +x
new Vector3(bound.max.x, bound.max.y, bound.max.z),
new Vector3(bound.max.x, bound.min.y, bound.max.z),
new Vector3(bound.max.x, bound.min.y, bound.min.z),
new Vector3(bound.max.x, bound.max.y, bound.min.z),
tex, res);
renderFluidQuad(//-z
new Vector3(bound.max.x, bound.max.y, bound.min.z),
tex,
res);
renderFluidQuad( // -z
new Vector3(bound.max.x, bound.max.y, bound.min.z),
new Vector3(bound.max.x, bound.min.y, bound.min.z),
new Vector3(bound.min.x, bound.min.y, bound.min.z),
new Vector3(bound.min.x, bound.max.y, bound.min.z),
tex, res);
renderFluidQuad(//+z
new Vector3(bound.min.x, bound.max.y, bound.min.z),
tex,
res);
renderFluidQuad( // +z
new Vector3(bound.min.x, bound.max.y, bound.max.z),
new Vector3(bound.min.x, bound.min.y, bound.max.z),
new Vector3(bound.max.x, bound.min.y, bound.max.z),
new Vector3(bound.max.x, bound.max.y, bound.max.z),
tex, res);
new Vector3(bound.max.x, bound.max.y, bound.max.z),
tex,
res);
}
public static void renderBlockOverlaySide(int x, int y, int z, int side, double tx1, double tx2, double ty1, double ty2)
{
double[] points = new double[]{x - 0.009, x + 1.009, y - 0.009, y + 1.009, z - 0.009, z + 1.009};
public static void renderBlockOverlaySide(
int x, int y, int z, int side, double tx1, double tx2, double ty1, double ty2) {
double[] points = new double[] {x - 0.009, x + 1.009, y - 0.009, y + 1.009, z - 0.009, z + 1.009};
Tessellator tessellator = Tessellator.instance;
switch(side)
{
switch (side) {
case 0:
tessellator.addVertexWithUV(points[0], points[2], points[4], tx1, ty1);
tessellator.addVertexWithUV(points[1], points[2], points[4], tx2, ty1);
tessellator.addVertexWithUV(points[1], points[2], points[5], tx2, ty2);
tessellator.addVertexWithUV(points[0], points[2], points[5], tx1, ty2);
break;
break;
case 1:
tessellator.addVertexWithUV(points[1], points[3], points[4], tx2, ty1);
tessellator.addVertexWithUV(points[0], points[3], points[4], tx1, ty1);
tessellator.addVertexWithUV(points[0], points[3], points[5], tx1, ty2);
tessellator.addVertexWithUV(points[1], points[3], points[5], tx2, ty2);
break;
break;
case 2:
tessellator.addVertexWithUV(points[0], points[3], points[4], tx2, ty1);
tessellator.addVertexWithUV(points[1], points[3], points[4], tx1, ty1);
tessellator.addVertexWithUV(points[1], points[2], points[4], tx1, ty2);
tessellator.addVertexWithUV(points[0], points[2], points[4], tx2, ty2);
break;
break;
case 3:
tessellator.addVertexWithUV(points[1], points[3], points[5], tx2, ty1);
tessellator.addVertexWithUV(points[0], points[3], points[5], tx1, ty1);
tessellator.addVertexWithUV(points[0], points[2], points[5], tx1, ty2);
tessellator.addVertexWithUV(points[1], points[2], points[5], tx2, ty2);
break;
break;
case 4:
tessellator.addVertexWithUV(points[0], points[3], points[5], tx2, ty1);
tessellator.addVertexWithUV(points[0], points[3], points[4], tx1, ty1);
tessellator.addVertexWithUV(points[0], points[2], points[4], tx1, ty2);
tessellator.addVertexWithUV(points[0], points[2], points[5], tx2, ty2);
break;
break;
case 5:
tessellator.addVertexWithUV(points[1], points[3], points[4], tx2, ty1);
tessellator.addVertexWithUV(points[1], points[3], points[5], tx1, ty1);
tessellator.addVertexWithUV(points[1], points[2], points[5], tx1, ty2);
tessellator.addVertexWithUV(points[1], points[2], points[4], tx2, ty2);
break;
break;
}
}
public static boolean shouldRenderFluid(FluidStack stack)
{
public static boolean shouldRenderFluid(FluidStack stack) {
return stack.amount > 0 && stack.getFluid() != null;
}
/**
* @param stack The fluid stack to render
* @return The icon of the fluid
*/
public static IIcon prepareFluidRender(FluidStack stack, int alpha)
{
public static IIcon prepareFluidRender(FluidStack stack, int alpha) {
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
Fluid fluid = stack.getFluid();
CCRenderState.setColour(fluid.getColor(stack)<<8|alpha);
CCRenderState.setColour(fluid.getColor(stack) << 8 | alpha);
TextureUtils.bindAtlas(fluid.getSpriteNumber());
return TextureUtils.safeIcon(fluid.getIcon(stack));
}
/**
* Re-enables lighting and disables blending.
*/
public static void postFluidRender()
{
public static void postFluidRender() {
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_BLEND);
}
public static double fluidDensityToAlpha(double density)
{
public static double fluidDensityToAlpha(double density) {
return Math.pow(density, 0.4);
}
/**
* Renders a fluid within a bounding box.
* Renders a fluid within a bounding box.
* If the fluid is a liquid it will render as a normal tank with height equal to density/bound.height.
* If the fluid is a gas, it will render the full box with an alpha equal to density.
* Warning, bound will be mutated if the fluid is a liquid
@@ -269,50 +269,43 @@ public class RenderUtils
* @param density The volume of fluid / the capacity of the tank. For gases this determines the alpha, for liquids this determines the height.
* @param res The resolution to render at.
*/
public static void renderFluidCuboid(FluidStack stack, Cuboid6 bound, double density, double res)
{
if(!shouldRenderFluid(stack))
return;
public static void renderFluidCuboid(FluidStack stack, Cuboid6 bound, double density, double res) {
if (!shouldRenderFluid(stack)) return;
int alpha = 255;
if(stack.getFluid().isGaseous())
alpha = (int) (fluidDensityToAlpha(density)*255);
else
bound.max.y = bound.min.y+(bound.max.y-bound.min.y)*density;
if (stack.getFluid().isGaseous()) alpha = (int) (fluidDensityToAlpha(density) * 255);
else bound.max.y = bound.min.y + (bound.max.y - bound.min.y) * density;
IIcon tex = prepareFluidRender(stack, alpha);
CCRenderState.startDrawing();
renderFluidCuboid(bound, tex, res);
CCRenderState.draw();
postFluidRender();
}
public static void renderFluidGauge(FluidStack stack, Rectangle4i rect, double density, double res)
{
if(!shouldRenderFluid(stack))
return;
public static void renderFluidGauge(FluidStack stack, Rectangle4i rect, double density, double res) {
if (!shouldRenderFluid(stack)) return;
int alpha = 255;
if(stack.getFluid().isGaseous())
alpha = (int) (fluidDensityToAlpha(density)*255);
else
{
int height = (int) (rect.h*density);
rect.y +=rect.h-height;
if (stack.getFluid().isGaseous()) alpha = (int) (fluidDensityToAlpha(density) * 255);
else {
int height = (int) (rect.h * density);
rect.y += rect.h - height;
rect.h = height;
}
IIcon tex = prepareFluidRender(stack, alpha);
CCRenderState.startDrawing();
renderFluidQuad(
new Vector3(rect.x, rect.y+rect.h, 0),
new Vector3(rect.w,0, 0),
new Vector3(0, -rect.h, 0), tex, res);
new Vector3(rect.x, rect.y + rect.h, 0),
new Vector3(rect.w, 0, 0),
new Vector3(0, -rect.h, 0),
tex,
res);
CCRenderState.draw();
postFluidRender();
}
/**
* Renders items and blocks in the world at 0,0,0 with transformations that size them appropriately
*/
@@ -324,33 +317,29 @@ public class RenderUtils
* Renders items and blocks in the world at 0,0,0 with transformations that size them appropriately
* @param spin The spin angle of the item around the y axis in degrees
*/
public static void renderItemUniform(ItemStack item, double spin)
{
public static void renderItemUniform(ItemStack item, double spin) {
IItemRenderer customRenderer = MinecraftForgeClient.getItemRenderer(item, ENTITY);
boolean is3D = customRenderer != null && customRenderer.shouldUseRenderHelper(ENTITY, item, BLOCK_3D);
boolean larger = false;
if (item.getItem() instanceof ItemBlock && RenderBlocks.renderItemIn3d(Block.getBlockFromItem(item.getItem()).getRenderType()))
{
if (item.getItem() instanceof ItemBlock
&& RenderBlocks.renderItemIn3d(
Block.getBlockFromItem(item.getItem()).getRenderType())) {
int renderType = Block.getBlockFromItem(item.getItem()).getRenderType();
larger = !(renderType == 1 || renderType == 19 || renderType == 12 || renderType == 2);
}
else if(is3D)
{
} else if (is3D) {
larger = true;
}
double d = 2;
double d1 = 1/d;
if(larger)
GL11.glScaled(d, d, d);
double d1 = 1 / d;
if (larger) GL11.glScaled(d, d, d);
GL11.glColor4f(1, 1, 1, 1);
entityItem.setEntityItemStack(item);
uniformRenderItem.doRender(entityItem, 0, larger ? 0.09 : 0.06, 0, 0, (float)(spin*9/Math.PI));
if(larger)
GL11.glScaled(d1, d1, d1);
uniformRenderItem.doRender(entityItem, 0, larger ? 0.09 : 0.06, 0, 0, (float) (spin * 9 / Math.PI));
if (larger) GL11.glScaled(d1, d1, d1);
}
}
@@ -1,137 +1,109 @@
package codechicken.lib.render;
import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.ARBVertexShader;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Matrix4f;
import static org.lwjgl.opengl.ARBShaderObjects.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.ARBVertexShader;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Matrix4f;
import static org.lwjgl.opengl.ARBShaderObjects.*;
public class ShaderProgram
{
public class ShaderProgram {
int programID;
public ShaderProgram()
{
public ShaderProgram() {
programID = glCreateProgramObjectARB();
if(programID == 0)
throw new RuntimeException("Unable to allocate shader program object.");
if (programID == 0) throw new RuntimeException("Unable to allocate shader program object.");
}
public void attach(int shaderType, String resource)
{
public void attach(int shaderType, String resource) {
InputStream stream = ShaderProgram.class.getResourceAsStream(resource);
if(stream == null)
throw new RuntimeException("Unable to locate resource: "+resource);
if (stream == null) throw new RuntimeException("Unable to locate resource: " + resource);
attach(shaderType, stream);
}
public void use()
{
public void use() {
glUseProgramObjectARB(programID);
}
public static void restore()
{
public static void restore() {
glUseProgramObjectARB(0);
}
public void link()
{
public void link() {
glLinkProgramARB(programID);
if(glGetObjectParameteriARB(programID, GL_OBJECT_LINK_STATUS_ARB) == GL11.GL_FALSE)
throw new RuntimeException("Error linking program: "+getInfoLog(programID));
if (glGetObjectParameteriARB(programID, GL_OBJECT_LINK_STATUS_ARB) == GL11.GL_FALSE)
throw new RuntimeException("Error linking program: " + getInfoLog(programID));
glValidateProgramARB(programID);
if(glGetObjectParameteriARB(programID, GL_OBJECT_VALIDATE_STATUS_ARB) == GL11.GL_FALSE)
throw new RuntimeException("Error validating program: "+getInfoLog(programID));
if (glGetObjectParameteriARB(programID, GL_OBJECT_VALIDATE_STATUS_ARB) == GL11.GL_FALSE)
throw new RuntimeException("Error validating program: " + getInfoLog(programID));
use();
onLink();
restore();
}
public void attach(int shaderType, InputStream stream)
{
if(stream == null)
throw new RuntimeException("Invalid shader inputstream");
public void attach(int shaderType, InputStream stream) {
if (stream == null) throw new RuntimeException("Invalid shader inputstream");
int shaderID = 0;
try
{
try {
shaderID = glCreateShaderObjectARB(shaderType);
if(shaderID == 0)
throw new RuntimeException("Unable to allocate shader object.");
try
{
if (shaderID == 0) throw new RuntimeException("Unable to allocate shader object.");
try {
glShaderSourceARB(shaderID, asString(stream));
}
catch(IOException e)
{
} catch (IOException e) {
throw new RuntimeException("Error reading inputstream.", e);
}
glCompileShaderARB(shaderID);
if(glGetObjectParameteriARB(shaderID, GL_OBJECT_COMPILE_STATUS_ARB) == GL11.GL_FALSE)
throw new RuntimeException("Error compiling shader: "+getInfoLog(shaderID));
if (glGetObjectParameteriARB(shaderID, GL_OBJECT_COMPILE_STATUS_ARB) == GL11.GL_FALSE)
throw new RuntimeException("Error compiling shader: " + getInfoLog(shaderID));
glAttachObjectARB(programID, shaderID);
}
catch(RuntimeException e)
{
} catch (RuntimeException e) {
glDeleteObjectARB(shaderID);
throw e;
}
}
}
public static String asString(InputStream stream) throws IOException
{
public static String asString(InputStream stream) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader bin = new BufferedReader(new InputStreamReader(stream));
String line;
while((line = bin.readLine()) != null)
sb.append(line).append('\n');
while ((line = bin.readLine()) != null) sb.append(line).append('\n');
stream.close();
return sb.toString();
}
private static String getInfoLog(int shaderID)
{
private static String getInfoLog(int shaderID) {
return glGetInfoLogARB(shaderID, glGetObjectParameteriARB(shaderID, GL_OBJECT_INFO_LOG_LENGTH_ARB));
}
public int getUniformLoc(String name)
{
public int getUniformLoc(String name) {
return ARBShaderObjects.glGetUniformLocationARB(programID, name);
}
public int getAttribLoc(String name)
{
public int getAttribLoc(String name) {
return ARBVertexShader.glGetAttribLocationARB(programID, name);
}
public void uniformTexture(String name, int textureIndex)
{
public void uniformTexture(String name, int textureIndex) {
ARBShaderObjects.glUniform1iARB(getUniformLoc(name), textureIndex);
}
public void onLink()
{
}
public void glVertexAttributeMat4(int loc, Matrix4f matrix)
{
ARBVertexShader.glVertexAttrib4fARB(loc , matrix.m00, matrix.m01, matrix.m02, matrix.m03);
ARBVertexShader.glVertexAttrib4fARB(loc+1, matrix.m10, matrix.m11, matrix.m12, matrix.m13);
ARBVertexShader.glVertexAttrib4fARB(loc+2, matrix.m20, matrix.m21, matrix.m22, matrix.m23);
ARBVertexShader.glVertexAttrib4fARB(loc+3, matrix.m30, matrix.m31, matrix.m32, matrix.m33);
public void onLink() {}
public void glVertexAttributeMat4(int loc, Matrix4f matrix) {
ARBVertexShader.glVertexAttrib4fARB(loc, matrix.m00, matrix.m01, matrix.m02, matrix.m03);
ARBVertexShader.glVertexAttrib4fARB(loc + 1, matrix.m10, matrix.m11, matrix.m12, matrix.m13);
ARBVertexShader.glVertexAttrib4fARB(loc + 2, matrix.m20, matrix.m21, matrix.m22, matrix.m23);
ARBVertexShader.glVertexAttrib4fARB(loc + 3, matrix.m30, matrix.m31, matrix.m32, matrix.m33);
}
}
@@ -3,19 +3,16 @@ package codechicken.lib.render;
import codechicken.lib.render.TextureUtils.IIconSelfRegister;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.util.ArrayList;
import java.util.HashMap;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.util.IIcon;
import net.minecraft.util.ResourceLocation;
import java.util.ArrayList;
import java.util.HashMap;
public class SpriteSheetManager
{
public class SpriteSheetManager {
@SideOnly(Side.CLIENT)
public static class SpriteSheet implements IIconSelfRegister
{
public static class SpriteSheet implements IIconSelfRegister {
private int tilesX;
private int tilesY;
private ArrayList<Integer> newSprites = new ArrayList<Integer>();
@@ -24,119 +21,106 @@ public class SpriteSheetManager
private TextureDataHolder texture;
private int spriteWidth;
private int spriteHeight;
public int atlasIndex;
private SpriteSheet(int tilesX, int tilesY, ResourceLocation textureFile)
{
private SpriteSheet(int tilesX, int tilesY, ResourceLocation textureFile) {
this.tilesX = tilesX;
this.tilesY = tilesY;
this.resource = textureFile;
sprites = new TextureSpecial[tilesX*tilesY];
sprites = new TextureSpecial[tilesX * tilesY];
}
public void requestIndicies(int... indicies)
{
for(int i : indicies)
setupSprite(i);
public void requestIndicies(int... indicies) {
for (int i : indicies) setupSprite(i);
}
public void registerIcons(IIconRegister register)
{
TextureMap textureMap = (TextureMap)register;
if(TextureUtils.refreshTexture(textureMap, resource.getResourcePath()))
{
public void registerIcons(IIconRegister register) {
TextureMap textureMap = (TextureMap) register;
if (TextureUtils.refreshTexture(textureMap, resource.getResourcePath())) {
reloadTexture();
for (TextureSpecial sprite : sprites)
if (sprite != null)
textureMap.setTextureEntry(sprite.getIconName(), sprite);
}
else
{
for(int i : newSprites)
textureMap.setTextureEntry(sprites[i].getIconName(), sprites[i]);
if (sprite != null) textureMap.setTextureEntry(sprite.getIconName(), sprite);
} else {
for (int i : newSprites) textureMap.setTextureEntry(sprites[i].getIconName(), sprites[i]);
}
newSprites.clear();
}
public TextureSpecial setupSprite(int i)
{
if(sprites[i] == null)
{
String name = resource+"_"+i;
public TextureSpecial setupSprite(int i) {
if (sprites[i] == null) {
String name = resource + "_" + i;
sprites[i] = new TextureSpecial(name).baseFromSheet(this, i);
newSprites.add(i);
}
return sprites[i];
}
private void reloadTexture()
{
private void reloadTexture() {
texture = TextureUtils.loadTexture(resource);
spriteWidth = texture.width/tilesX;
spriteHeight = texture.height/tilesY;
spriteWidth = texture.width / tilesX;
spriteHeight = texture.height / tilesY;
}
public IIcon getSprite(int index)
{
public IIcon getSprite(int index) {
IIcon i = sprites[index];
if(i == null)
throw new IllegalArgumentException("Sprite at index: "+index+" from texture file "+resource+" was not preloaded.");
if (i == null)
throw new IllegalArgumentException(
"Sprite at index: " + index + " from texture file " + resource + " was not preloaded.");
return i;
}
public TextureDataHolder createSprite(int spriteIndex)
{
int sx = spriteIndex%tilesX;
int sy = spriteIndex/tilesX;
public TextureDataHolder createSprite(int spriteIndex) {
int sx = spriteIndex % tilesX;
int sy = spriteIndex / tilesX;
TextureDataHolder sprite = new TextureDataHolder(spriteWidth, spriteHeight);
TextureUtils.copySubImg(texture.data, texture.width, sx*spriteWidth, sy*spriteHeight,
spriteWidth, spriteHeight,
sprite.data, spriteWidth, 0, 0);
TextureUtils.copySubImg(
texture.data,
texture.width,
sx * spriteWidth,
sy * spriteHeight,
spriteWidth,
spriteHeight,
sprite.data,
spriteWidth,
0,
0);
return sprite;
}
public int spriteWidth()
{
public int spriteWidth() {
return spriteWidth;
}
public int spriteHeight()
{
public int spriteHeight() {
return spriteHeight;
}
public TextureSpecial bindTextureFX(int i, TextureFX textureFX)
{
public TextureSpecial bindTextureFX(int i, TextureFX textureFX) {
return setupSprite(i).addTextureFX(textureFX);
}
public SpriteSheet selfRegister(int atlas)
{
public SpriteSheet selfRegister(int atlas) {
TextureUtils.addIconRegistrar(this);
return this;
}
@Override
public int atlasIndex()
{
public int atlasIndex() {
return atlasIndex;
}
}
private static HashMap<String, SpriteSheet> spriteSheets = new HashMap<String, SpriteSheet>();
public static SpriteSheet getSheet(ResourceLocation resource)
{
public static SpriteSheet getSheet(ResourceLocation resource) {
return getSheet(16, 16, resource);
}
public static SpriteSheet getSheet(int tilesX, int tilesY, ResourceLocation resource)
{
public static SpriteSheet getSheet(int tilesX, int tilesY, ResourceLocation resource) {
SpriteSheet sheet = spriteSheets.get(resource.toString());
if(sheet == null)
spriteSheets.put(resource.toString(), sheet = new SpriteSheet(tilesX, tilesY, resource));
if (sheet == null) spriteSheets.put(resource.toString(), sheet = new SpriteSheet(tilesX, tilesY, resource));
return sheet;
}
}
}
@@ -2,34 +2,29 @@ package codechicken.lib.render;
import java.awt.image.BufferedImage;
public class TextureDataHolder
{
public class TextureDataHolder {
public int width;
public int height;
public int[] data;
public TextureDataHolder(int width, int height)
{
public TextureDataHolder(int width, int height) {
this.width = width;
this.height = height;
data = new int[width*height];
data = new int[width * height];
}
public TextureDataHolder(int[] data, int width)
{
public TextureDataHolder(int[] data, int width) {
this.data = data;
this.width = width;
height = data.length/width;
height = data.length / width;
}
public TextureDataHolder(BufferedImage img)
{
public TextureDataHolder(BufferedImage img) {
this(img.getWidth(), img.getHeight());
img.getRGB(0, 0, width, height, data, 0, width);
}
public TextureDataHolder copyData()
{
public TextureDataHolder copyData() {
int[] copy = new int[data.length];
System.arraycopy(data, 0, copy, 0, data.length);
data = copy;
@@ -6,8 +6,7 @@ import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
@SideOnly(Side.CLIENT)
public class TextureFX
{
public class TextureFX {
public int[] imageData;
public int tileSizeBase = 16;
public int tileSizeSquare = 256;
@@ -50,8 +49,7 @@ public class TextureFX
onTick();
}
public void onTick() {
}
public void onTick() {}
public boolean changed() {
return true;
@@ -1,10 +1,11 @@
package codechicken.lib.render;
import codechicken.lib.asm.ObfMapping;
import codechicken.lib.render.SpriteSheetManager.SpriteSheet;
import codechicken.lib.render.TextureUtils.IIconSelfRegister;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
@@ -15,16 +16,13 @@ import net.minecraft.client.resources.data.AnimationMetadataSection;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.util.ResourceLocation;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
@SideOnly(Side.CLIENT)
public class TextureSpecial extends TextureAtlasSprite implements IIconSelfRegister {
//sprite sheet fields
// sprite sheet fields
private int spriteIndex;
private SpriteSheet spriteSheet;
//textureFX fields
// textureFX fields
private TextureFX textureFX;
private int mipmapLevels;
private int rawWidth;
@@ -41,8 +39,7 @@ public class TextureSpecial extends TextureAtlasSprite implements IIconSelfRegis
}
public TextureSpecial addTexture(TextureDataHolder t) {
if (baseTextures == null)
baseTextures = new ArrayList<TextureDataHolder>();
if (baseTextures == null) baseTextures = new ArrayList<TextureDataHolder>();
baseTextures.add(t);
return this;
}
@@ -61,8 +58,7 @@ public class TextureSpecial extends TextureAtlasSprite implements IIconSelfRegis
@Override
public void initSprite(int sheetWidth, int sheetHeight, int originX, int originY, boolean rotated) {
super.initSprite(sheetWidth, sheetHeight, originX, originY, rotated);
if (textureFX != null)
textureFX.onTextureDimensionsUpdate(rawWidth, rawHeight);
if (textureFX != null) textureFX.onTextureDimensionsUpdate(rawWidth, rawHeight);
}
@Override
@@ -79,25 +75,19 @@ public class TextureSpecial extends TextureAtlasSprite implements IIconSelfRegis
}
}
/**
* Copy paste mojang code because it's private, and CCL can't have access transformers or reflection
*/
public int[][] prepareAnisotropicFiltering(int[][] mipmaps) {
if (Minecraft.getMinecraft().gameSettings.anisotropicFiltering <= 1)
{
if (Minecraft.getMinecraft().gameSettings.anisotropicFiltering <= 1) {
return mipmaps;
}
else
{
} else {
int[][] aint1 = new int[mipmaps.length][];
for (int k = 0; k < mipmaps.length; ++k)
{
for (int k = 0; k < mipmaps.length; ++k) {
int[] aint2 = mipmaps[k];
if (aint2 != null)
{
if (aint2 != null) {
int[] aint3 = new int[(rawWidth + 16 >> k) * (rawHeight + 16 >> k)];
System.arraycopy(aint2, 0, aint3, 0, aint2.length);
aint1[k] = TextureUtil.prepareAnisotropicData(aint3, rawWidth >> k, rawHeight >> k, 8 >> k);
@@ -109,7 +99,8 @@ public class TextureSpecial extends TextureAtlasSprite implements IIconSelfRegis
}
@Override
public void loadSprite(BufferedImage[] images, AnimationMetadataSection animationMeta, boolean anisotropicFiltering) {
public void loadSprite(
BufferedImage[] images, AnimationMetadataSection animationMeta, boolean anisotropicFiltering) {
rawWidth = images[0].getWidth();
rawHeight = images[0].getHeight();
super.loadSprite(images, animationMeta, anisotropicFiltering);
@@ -128,7 +119,7 @@ public class TextureSpecial extends TextureAtlasSprite implements IIconSelfRegis
public void addFrame(int[] data, int width, int height) {
GameSettings settings = Minecraft.getMinecraft().gameSettings;
BufferedImage[] images = new BufferedImage[settings.mipmapLevels+1];
BufferedImage[] images = new BufferedImage[settings.mipmapLevels + 1];
images[0] = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
images[0].setRGB(0, 0, width, height, data, 0, width);
@@ -138,19 +129,15 @@ public class TextureSpecial extends TextureAtlasSprite implements IIconSelfRegis
@Override
public boolean load(IResourceManager manager, ResourceLocation location) {
if (baseTextures != null) {
for (TextureDataHolder tex : baseTextures)
addFrame(tex.data, tex.width, tex.height);
}
else if (spriteSheet != null) {
for (TextureDataHolder tex : baseTextures) addFrame(tex.data, tex.width, tex.height);
} else if (spriteSheet != null) {
TextureDataHolder tex = spriteSheet.createSprite(spriteIndex);
addFrame(tex.data, tex.width, tex.height);
}
else if (blankSize > 0) {
} else if (blankSize > 0) {
addFrame(new int[blankSize * blankSize], blankSize, blankSize);
}
if (framesTextureData.isEmpty())
throw new RuntimeException("No base frame for texture: " + getIconName());
if (framesTextureData.isEmpty()) throw new RuntimeException("No base frame for texture: " + getIconName());
return false;
}
@@ -162,8 +149,7 @@ public class TextureSpecial extends TextureAtlasSprite implements IIconSelfRegis
@Override
public int getFrameCount() {
if (textureFX != null)
return 1;
if (textureFX != null) return 1;
return super.getFrameCount();
}
@@ -181,8 +167,7 @@ public class TextureSpecial extends TextureAtlasSprite implements IIconSelfRegis
@Override
public void registerIcons(IIconRegister register) {
if (selfRegister)
((TextureMap) register).setTextureEntry(getIconName(), this);
if (selfRegister) ((TextureMap) register).setTextureEntry(getIconName(), this);
}
@Override
@@ -3,6 +3,11 @@ package codechicken.lib.render;
import codechicken.lib.colour.Colour;
import codechicken.lib.colour.ColourARGB;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.client.renderer.texture.TextureManager;
@@ -14,16 +19,8 @@ import net.minecraftforge.common.MinecraftForge;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
public class TextureUtils
{
public static interface IIconSelfRegister
{
public class TextureUtils {
public static interface IIconSelfRegister {
public void registerIcons(IIconRegister register);
public int atlasIndex();
@@ -42,8 +39,7 @@ public class TextureUtils
@SubscribeEvent
public void textureLoad(TextureStitchEvent.Pre event) {
for (IIconSelfRegister reg : iconRegistrars)
if (reg.atlasIndex() == event.map.getTextureType())
reg.registerIcons(event.map);
if (reg.atlasIndex() == event.map.getTextureType()) reg.registerIcons(event.map);
}
/**
@@ -56,13 +52,15 @@ public class TextureUtils
public static Colour[] loadTextureColours(ResourceLocation resource) {
int[] idata = loadTextureData(resource);
Colour[] data = new Colour[idata.length];
for (int i = 0; i < data.length; i++)
data[i] = new ColourARGB(idata[i]);
for (int i = 0; i < data.length; i++) data[i] = new ColourARGB(idata[i]);
return data;
}
public static InputStream getTextureResource(ResourceLocation textureFile) throws IOException {
return Minecraft.getMinecraft().getResourceManager().getResource(textureFile).getInputStream();
return Minecraft.getMinecraft()
.getResourceManager()
.getResource(textureFile)
.getInputStream();
}
public static BufferedImage loadBufferedImage(ResourceLocation textureFile) {
@@ -85,7 +83,17 @@ public class TextureUtils
return Minecraft.getMinecraft().renderEngine;
}
public static void copySubImg(int[] fromTex, int fromWidth, int fromX, int fromY, int width, int height, int[] toTex, int toWidth, int toX, int toY) {
public static void copySubImg(
int[] fromTex,
int fromWidth,
int fromX,
int fromY,
int width,
int height,
int[] toTex,
int toWidth,
int toX,
int toY) {
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++) {
int fp = (y + fromY) * fromWidth + x + fromX;
@@ -112,8 +120,7 @@ public class TextureUtils
public static TextureSpecial getTextureSpecial(IIconRegister iconRegister, String name) {
TextureMap textureMap = (TextureMap) iconRegister;
IIcon entry = textureMap.getTextureExtry(name);
if (entry != null)
throw new IllegalStateException("Texture: " + name + " is already registered");
if (entry != null) throw new IllegalStateException("Texture: " + name + " is already registered");
TextureSpecial icon = new TextureSpecial(name);
textureMap.setTextureEntry(name, icon);
@@ -136,8 +143,7 @@ public class TextureUtils
public static TextureDataHolder loadTexture(ResourceLocation resource) {
BufferedImage img = loadBufferedImage(resource);
if (img == null)
throw new RuntimeException("Texture not found: " + resource);
if (img == null) throw new RuntimeException("Texture not found: " + resource);
return new TextureDataHolder(img);
}
@@ -160,8 +166,7 @@ public class TextureUtils
}
public static boolean isMissing(IIcon icon, ResourceLocation atlas) {
if(icon == null)
return true;
if (icon == null) return true;
IIcon missing = ((TextureMap) engine().getTexture(atlas)).getAtlasSprite("missingno");
return icon.getMinU() == missing.getMinU() && icon.getMinV() == missing.getMinV();
@@ -5,13 +5,11 @@ import codechicken.lib.render.uv.UVTransformation;
import codechicken.lib.util.Copyable;
import codechicken.lib.vec.Transformation;
import codechicken.lib.vec.Vector3;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
public class Vertex5 implements Copyable<Vertex5>
{
public class Vertex5 implements Copyable<Vertex5> {
public Vector3 vec;
public UV uv;
@@ -64,8 +62,9 @@ public class Vertex5 implements Copyable<Vertex5>
public String toString() {
MathContext cont = new MathContext(4, RoundingMode.HALF_UP);
return "Vertex: (" + new BigDecimal(vec.x, cont) + ", " + new BigDecimal(vec.y, cont) + ", " + new BigDecimal(vec.z, cont) + ") " +
"(" + new BigDecimal(uv.u, cont) + ", " + new BigDecimal(uv.v, cont) + ") ("+uv.tex+")";
return "Vertex: (" + new BigDecimal(vec.x, cont) + ", " + new BigDecimal(vec.y, cont) + ", "
+ new BigDecimal(vec.z, cont) + ") " + "(" + new BigDecimal(uv.u, cont) + ", "
+ new BigDecimal(uv.v, cont) + ") (" + uv.tex + ")";
}
public Vertex5 apply(Transformation t) {
@@ -1,7 +1,6 @@
package codechicken.lib.render.uv;
import codechicken.lib.util.Copyable;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
@@ -11,8 +10,7 @@ public class UV implements Copyable<UV> {
public double v;
public int tex;
public UV() {
}
public UV() {}
public UV(double u, double v) {
this(u, v, 0);
@@ -71,9 +69,8 @@ public class UV implements Copyable<UV> {
@Override
public boolean equals(Object o) {
if (!(o instanceof UV))
return false;
if (!(o instanceof UV)) return false;
UV uv = (UV) o;
return u == uv.u && v == uv.v;
}
}
}
@@ -1,13 +1,11 @@
package codechicken.lib.render.uv;
import codechicken.lib.math.MathHelper;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
public class UVRotation extends UVTransformation
{
public class UVRotation extends UVTransformation {
public double angle;
/**
@@ -21,8 +19,8 @@ public class UVRotation extends UVTransformation
public void apply(UV uv) {
double c = MathHelper.cos(angle);
double s = MathHelper.sin(angle);
double u2 = c*uv.u + s*uv.v;
uv.v = - s*uv.u + c*uv.v;
double u2 = c * uv.u + s * uv.v;
uv.v = -s * uv.u + c * uv.v;
uv.u = u2;
}
@@ -33,8 +31,7 @@ public class UVRotation extends UVTransformation
@Override
public UVTransformation merge(UVTransformation next) {
if(next instanceof UVRotation)
return new UVRotation(angle+((UVRotation)next).angle);
if (next instanceof UVRotation) return new UVRotation(angle + ((UVRotation) next).angle);
return null;
}
@@ -45,8 +42,7 @@ public class UVRotation extends UVTransformation
}
@Override
public String toString()
{
public String toString() {
MathContext cont = new MathContext(4, RoundingMode.HALF_UP);
return "UVRotation(" + new BigDecimal(angle, cont) + ")";
}
@@ -6,12 +6,13 @@ import codechicken.lib.vec.ITransformation;
/**
* Abstract supertype for any UV transformation
*/
public abstract class UVTransformation extends ITransformation<UV, UVTransformation> implements CCRenderState.IVertexOperation
{
public abstract class UVTransformation extends ITransformation<UV, UVTransformation>
implements CCRenderState.IVertexOperation {
public static final int operationIndex = CCRenderState.registerOperation();
public UVTransformation at(UV point) {
return new UVTransformationList(new UVTranslation(-point.u, -point.v), this, new UVTranslation(point.u, point.v));
return new UVTransformationList(
new UVTranslation(-point.u, -point.v), this, new UVTranslation(point.u, point.v));
}
public UVTransformationList with(UVTransformation t) {
@@ -33,5 +34,3 @@ public abstract class UVTransformation extends ITransformation<UV, UVTransformat
return operationIndex;
}
}
@@ -3,52 +3,38 @@ package codechicken.lib.render.uv;
import java.util.ArrayList;
import java.util.Iterator;
public class UVTransformationList extends UVTransformation
{
public class UVTransformationList extends UVTransformation {
private ArrayList<UVTransformation> transformations = new ArrayList<UVTransformation>();
public UVTransformationList(UVTransformation... transforms)
{
for(UVTransformation t : transforms)
if(t instanceof UVTransformationList)
transformations.addAll(((UVTransformationList)t).transformations);
else
transformations.add(t);
public UVTransformationList(UVTransformation... transforms) {
for (UVTransformation t : transforms)
if (t instanceof UVTransformationList) transformations.addAll(((UVTransformationList) t).transformations);
else transformations.add(t);
compact();
}
@Override
public void apply(UV uv)
{
for(int i = 0; i < transformations.size(); i++)
transformations.get(i).apply(uv);
public void apply(UV uv) {
for (int i = 0; i < transformations.size(); i++) transformations.get(i).apply(uv);
}
@Override
public UVTransformationList with(UVTransformation t)
{
if(t.isRedundant())
return this;
public UVTransformationList with(UVTransformation t) {
if (t.isRedundant()) return this;
if(t instanceof UVTransformationList)
transformations.addAll(((UVTransformationList)t).transformations);
else
transformations.add(t);
if (t instanceof UVTransformationList) transformations.addAll(((UVTransformationList) t).transformations);
else transformations.add(t);
compact();
return this;
}
public UVTransformationList prepend(UVTransformation t)
{
if(t.isRedundant())
return this;
public UVTransformationList prepend(UVTransformation t) {
if (t.isRedundant()) return this;
if(t instanceof UVTransformationList)
transformations.addAll(0, ((UVTransformationList)t).transformations);
else
transformations.add(0, t);
if (t instanceof UVTransformationList) transformations.addAll(0, ((UVTransformationList) t).transformations);
else transformations.add(0, t);
compact();
return this;
@@ -58,27 +44,21 @@ public class UVTransformationList extends UVTransformation
ArrayList<UVTransformation> newList = new ArrayList<UVTransformation>(transformations.size());
Iterator<UVTransformation> iterator = transformations.iterator();
UVTransformation prev = null;
while(iterator.hasNext()) {
while (iterator.hasNext()) {
UVTransformation t = iterator.next();
if(t.isRedundant())
continue;
if (t.isRedundant()) continue;
if(prev != null) {
if (prev != null) {
UVTransformation m = prev.merge(t);
if(m == null)
newList.add(prev);
else if(m.isRedundant())
t = null;
else
t = m;
if (m == null) newList.add(prev);
else if (m.isRedundant()) t = null;
else t = m;
}
prev = t;
}
if(prev != null)
newList.add(prev);
if (prev != null) newList.add(prev);
if(newList.size() < transformations.size())
transformations = newList;
if (newList.size() < transformations.size()) transformations = newList;
}
@Override
@@ -87,20 +67,17 @@ public class UVTransformationList extends UVTransformation
}
@Override
public UVTransformation inverse()
{
public UVTransformation inverse() {
UVTransformationList rev = new UVTransformationList();
for(int i = transformations.size()-1; i >= 0; i--)
for (int i = transformations.size() - 1; i >= 0; i--)
rev.with(transformations.get(i).inverse());
return rev;
}
@Override
public String toString()
{
public String toString() {
String s = "";
for(UVTransformation t : transformations)
s+="\n"+t.toString();
for (UVTransformation t : transformations) s += "\n" + t.toString();
return s.trim();
}
}
@@ -1,7 +1,6 @@
package codechicken.lib.render.uv;
import codechicken.lib.math.MathHelper;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
@@ -34,8 +33,8 @@ public class UVTranslation extends UVTransformation {
@Override
public UVTransformation merge(UVTransformation next) {
if (next instanceof UVTranslation) {
UVTranslation t = (UVTranslation)next;
return new UVTranslation(du+t.du, dv+t.dv);
UVTranslation t = (UVTranslation) next;
return new UVTranslation(du + t.du, dv + t.dv);
}
return null;
@@ -11,64 +11,56 @@ import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;
public class LibDownloader
{
public class LibDownloader {
private static String[] libs = new String[] {
"org/ow2/asm/asm-debug-all/5.0.3/asm-debug-all-5.0.3.jar",
"com/google/guava/guava/14.0/guava-14.0.jar",
"net/sf/jopt-simple/jopt-simple/4.5/jopt-simple-4.5.jar",
"org/apache/logging/log4j/log4j-core/2.0-beta9/log4j-core-2.0-beta9.jar",
"org/apache/logging/log4j/log4j-api/2.0-beta9/log4j-api-2.0-beta9.jar"};
"org/ow2/asm/asm-debug-all/5.0.3/asm-debug-all-5.0.3.jar",
"com/google/guava/guava/14.0/guava-14.0.jar",
"net/sf/jopt-simple/jopt-simple/4.5/jopt-simple-4.5.jar",
"org/apache/logging/log4j/log4j-core/2.0-beta9/log4j-core-2.0-beta9.jar",
"org/apache/logging/log4j/log4j-api/2.0-beta9/log4j-api-2.0-beta9.jar"
};
private static File libDir = new File("lib");
private static ByteBuffer downloadBuffer = ByteBuffer.allocateDirect(1 << 23);
public static void load() {
if(!libDir.exists())
libDir.mkdir();
if(!libDir.isDirectory())
throw new RuntimeException("/lib is not a directory");
if (!libDir.exists()) libDir.mkdir();
if (!libDir.isDirectory()) throw new RuntimeException("/lib is not a directory");
List<String> missing = checkExists();
for(String lib : missing)
download(lib);
for (String lib : missing) download(lib);
addPaths(libs);
}
private static void addPaths(String[] libs) {
try {
URLClassLoader cl = (URLClassLoader) ClassLoader.getSystemClassLoader();
Method m_addURL = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
Method m_addURL = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] {URL.class});
m_addURL.setAccessible(true);
for(String lib : libs)
for (String lib : libs)
m_addURL.invoke(cl, new File(libDir, fileName(lib)).toURI().toURL());
}
catch (Exception e) {
} catch (Exception e) {
throw new RuntimeException("Failed to add libraries to classpath", e);
}
}
private static void download(String lib) {
File libFile = new File(libDir, fileName(lib));
try
{
URL libDownload = new URL("http://repo1.maven.org/maven2/"+lib);
try {
URL libDownload = new URL("http://repo1.maven.org/maven2/" + lib);
URLConnection connection = libDownload.openConnection();
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.setRequestProperty("User-Agent", "CodeChickenLib Downloader");
int sizeGuess = connection.getContentLength();
download(connection.getInputStream(), sizeGuess, libFile);
}
catch (Exception e)
{
} catch (Exception e) {
libFile.delete();
throw new RuntimeException("A download error occured", e);
}
}
private static void download(InputStream is, int sizeGuess, File target) throws Exception
{
private static void download(InputStream is, int sizeGuess, File target) throws Exception {
String name = target.getName();
if (sizeGuess > downloadBuffer.capacity())
throw new Exception(String.format("The file %s is too large to be downloaded", name));
@@ -88,8 +80,7 @@ public class LibDownloader
is.close();
downloadBuffer.limit(fullLength);
if(!target.exists())
target.createNewFile();
if (!target.exists()) target.createNewFile();
downloadBuffer.position(0);
FileOutputStream fos = new FileOutputStream(target);
@@ -103,12 +94,10 @@ public class LibDownloader
private static List<String> checkExists() {
LinkedList<String> list = new LinkedList<String>();
for(String lib : libs) {
for (String lib : libs) {
File file = new File(libDir, fileName(lib));
if(!file.exists())
list.add(lib);
if (!file.exists()) list.add(lib);
}
return list;
}
}
@@ -1,6 +1,7 @@
package codechicken.lib.tool;
import codechicken.lib.asm.ASMHelper;
import java.util.Iterator;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
@@ -9,16 +10,13 @@ import org.objectweb.asm.commons.RemappingMethodAdapter;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import java.util.Iterator;
public class MCStripTransformer {
public static class ReferenceDetector extends Remapper {
boolean found = false;
@Override
public String map(String typeName) {
if(typeName.startsWith("net/minecraft") || !typeName.contains("/"))
found = true;
if (typeName.startsWith("net/minecraft") || !typeName.contains("/")) found = true;
return typeName;
}
}
@@ -28,17 +26,16 @@ public class MCStripTransformer {
boolean changed = false;
Iterator<MethodNode> it = cnode.methods.iterator();
while(it.hasNext()) {
while (it.hasNext()) {
MethodNode mnode = it.next();
ReferenceDetector r = new ReferenceDetector();
mnode.accept(new RemappingMethodAdapter(mnode.access, mnode.desc, new MethodVisitor(Opcodes.ASM4) {}, r));
if(r.found) {
if (r.found) {
it.remove();
changed = true;
}
}
if(changed)
bytes = ASMHelper.createBytes(cnode, 0);
if (changed) bytes = ASMHelper.createBytes(cnode, 0);
return bytes;
}
}
+2 -3
View File
@@ -1,12 +1,11 @@
package codechicken.lib.tool;
public class Main
{
public class Main {
public static void main(String[] args) {
LibDownloader.load();
try {
Class<?> c_toolMain = new StripClassLoader().loadClass("codechicken.lib.tool.ToolMain");
c_toolMain.getDeclaredMethod("main", String[].class).invoke(null, new Object[]{args});
c_toolMain.getDeclaredMethod("main", String[].class).invoke(null, new Object[] {args});
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -6,27 +6,24 @@ import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
public class StripClassLoader extends URLClassLoader
{
public class StripClassLoader extends URLClassLoader {
public StripClassLoader() {
super(new URL[0], StripClassLoader.class.getClassLoader());
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
if(!name.startsWith("codechicken.lib"))
return super.loadClass(name);
if (!name.startsWith("codechicken.lib")) return super.loadClass(name);
try {
String resName = name.replace('.', '/')+".class";
String resName = name.replace('.', '/') + ".class";
InputStream res = getResourceAsStream(resName);
if(res == null)
throw new ClassNotFoundException("Could not find resource: "+resName);
if (res == null) throw new ClassNotFoundException("Could not find resource: " + resName);
byte[] bytes = readFully(res);
bytes = transform(bytes);
return defineClass(name, bytes, 0, bytes.length);
} catch(IOException e) {
} catch (IOException e) {
throw new ClassNotFoundException(name, e);
}
}
@@ -36,8 +33,7 @@ public class StripClassLoader extends URLClassLoader
int read;
byte[] data = new byte[16384];
while ((read = is.read(data, 0, data.length)) > 0)
buffer.write(data, 0, read);
while ((read = is.read(data, 0, data.length)) > 0) buffer.write(data, 0, read);
return buffer.toByteArray();
}
@@ -2,38 +2,36 @@ package codechicken.lib.tool;
import codechicken.lib.tool.module.ModuleQBConverter;
public class ToolMain
{
public class ToolMain {
public static interface Module {
public void main(String[] args);
public String name();
public void printHelp();
}
public static Module[] modules = new Module[]{
new ModuleQBConverter()
};
public static Module[] modules = new Module[] {new ModuleQBConverter()};
private static void printHelp() {
System.out.println("Usage: [module] [args]");
System.out.println(" Modules: ");
for(Module m : modules)
System.out.println(" - "+m.name());
for (Module m : modules) System.out.println(" - " + m.name());
System.out.println("-h [module] for module help");
}
public static void main(String[] args) {
if(args.length > 0) {
for(Module m : modules)
if(args[0].equals(m.name())) {
String[] args2 = new String[args.length-1];
if (args.length > 0) {
for (Module m : modules)
if (args[0].equals(m.name())) {
String[] args2 = new String[args.length - 1];
System.arraycopy(args, 1, args2, 0, args2.length);
m.main(args2);
return;
}
if(args[0].equals("-h") && args.length >= 2) {
for(Module m : modules)
if(args[1].equals(m.name())) {
if (args[0].equals("-h") && args.length >= 2) {
for (Module m : modules)
if (args[1].equals(m.name())) {
m.printHelp();
return;
}
@@ -1,36 +1,28 @@
package codechicken.lib.tool.module;
import codechicken.lib.tool.ToolMain;
import java.io.IOException;
import joptsimple.OptionException;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import java.io.IOException;
public abstract class JOptModule implements ToolMain.Module
{
public abstract class JOptModule implements ToolMain.Module {
OptionParser parser = new OptionParser();
@Override
public void main(String[] args) {
OptionSet options;
try
{
try {
options = parser.parse(args);
}
catch(OptionException ex)
{
} catch (OptionException ex) {
System.err.println(ex.getLocalizedMessage());
System.exit(-1);
return;
}
try
{
try {
main(parser, options);
}
catch(Exception e)
{
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@@ -1,22 +1,26 @@
package codechicken.lib.tool.module;
import codechicken.lib.render.QBImporter;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import java.io.File;
import static java.util.Arrays.asList;
public class ModuleQBConverter extends JOptModule
{
import codechicken.lib.render.QBImporter;
import java.io.File;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
public class ModuleQBConverter extends JOptModule {
public ModuleQBConverter() {
parser.acceptsAll(asList("?", "h", "help"), "Show the help");
parser.acceptsAll(asList("i", "input"), "comma separated list of paths to models (.qb or directories)")
.withRequiredArg().ofType(File.class).withValuesSeparatedBy(',').required();
.withRequiredArg()
.ofType(File.class)
.withValuesSeparatedBy(',')
.required();
parser.acceptsAll(asList("o", "out"), "Output Directory")
.withRequiredArg().ofType(File.class);
parser.acceptsAll(asList("o2", "textureplanes"), "2nd level optimisation. Merges coplanar polygons. Increases texture size");
.withRequiredArg()
.ofType(File.class);
parser.acceptsAll(
asList("o2", "textureplanes"),
"2nd level optimisation. Merges coplanar polygons. Increases texture size");
parser.acceptsAll(asList("s", "squaretextures"), "Produce square textures");
parser.acceptsAll(asList("t", "mergetextures"), "Use the same texture for all models");
parser.acceptsAll(asList("r", "scalemc"), "Resize model to mc standard (shrink by factor of 16)");
@@ -24,41 +28,35 @@ public class ModuleQBConverter extends JOptModule
protected void main(OptionParser parser, OptionSet options) {
int flags = 0;
if(options.has("o2")) flags |= QBImporter.TEXTUREPLANES;
if(options.has("s")) flags |= QBImporter.SQUARETEXTURE;
if(options.has("t")) flags |= QBImporter.MERGETEXTURES;
if(options.has("r")) flags |= QBImporter.SCALEMC;
if (options.has("o2")) flags |= QBImporter.TEXTUREPLANES;
if (options.has("s")) flags |= QBImporter.SQUARETEXTURE;
if (options.has("t")) flags |= QBImporter.MERGETEXTURES;
if (options.has("r")) flags |= QBImporter.SCALEMC;
File[] input = options.valuesOf("input").toArray(new File[0]);
File[] outDir = new File[input.length];
if(options.has("out")) {
File output = (File)options.valueOf("out");
if(output.isFile())
throw new RuntimeException("Output Path is not a directory");
if(!output.exists())
output.mkdirs();
if (options.has("out")) {
File output = (File) options.valueOf("out");
if (output.isFile()) throw new RuntimeException("Output Path is not a directory");
if (!output.exists()) output.mkdirs();
for(int i = 0; i < input.length; i++)
outDir[i] = output;
for (int i = 0; i < input.length; i++) outDir[i] = output;
} else {
for(int i = 0; i < input.length; i++)
for (int i = 0; i < input.length; i++)
outDir[i] = input[i].isDirectory() ? input[i] : input[i].getParentFile();
}
for(int i = 0; i < input.length; i++) {
for (int i = 0; i < input.length; i++) {
File file = input[i];
if(file.isDirectory()) {
for(File file2 : file.listFiles())
if(file2.getName().endsWith(".qb"))
convert(file2, outDir[i], flags);
}
else
convert(file, outDir[i], flags);
if (file.isDirectory()) {
for (File file2 : file.listFiles())
if (file2.getName().endsWith(".qb")) convert(file2, outDir[i], flags);
} else convert(file, outDir[i], flags);
}
}
private void convert(File in, File outDir, int flags) {
System.out.println("Converting: "+in.getName());
System.out.println("Converting: " + in.getName());
QBImporter.RasterisedModel m = QBImporter.loadQB(in).toRasterisedModel(flags);
m.export(new File(outDir, in.getName().replace(".qb", ".obj")), outDir);
}
@@ -2,19 +2,18 @@ package codechicken.lib.util;
import net.minecraft.util.StatCollector;
public class LangProxy
{
public class LangProxy {
public final String namespace;
public LangProxy(String namespace) {
this.namespace = namespace+".";
this.namespace = namespace + ".";
}
public String translate(String key) {
return StatCollector.translateToLocal(namespace+key);
return StatCollector.translateToLocal(namespace + key);
}
public String format(String key, Object... params) {
return StatCollector.translateToLocalFormatted(namespace+key, params);
return StatCollector.translateToLocalFormatted(namespace + key, params);
}
}
@@ -1,21 +1,39 @@
package codechicken.lib.vec;
public class AxisCycle
{
public static Transformation[] cycles = new Transformation[]{
public class AxisCycle {
public static Transformation[] cycles = new Transformation[] {
new RedundantTransformation(),
new VariableTransformation(new Matrix4(0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1)){
@Override public void apply(Vector3 vec){
double d0 = vec.x; double d1 = vec.y; double d2 = vec.z;
vec.x = d2; vec.y = d0; vec.z = d1;
} @Override public Transformation inverse(){
new VariableTransformation(new Matrix4(0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1)) {
@Override
public void apply(Vector3 vec) {
double d0 = vec.x;
double d1 = vec.y;
double d2 = vec.z;
vec.x = d2;
vec.y = d0;
vec.z = d1;
}
@Override
public Transformation inverse() {
return cycles[2];
}},
new VariableTransformation(new Matrix4(0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1)){
@Override public void apply(Vector3 vec){
double d0 = vec.x; double d1 = vec.y; double d2 = vec.z;
vec.x = d1; vec.y = d2; vec.z = d0;
} @Override public Transformation inverse(){
}
},
new VariableTransformation(new Matrix4(0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1)) {
@Override
public void apply(Vector3 vec) {
double d0 = vec.x;
double d1 = vec.y;
double d2 = vec.z;
vec.x = d1;
vec.y = d2;
vec.z = d0;
}
@Override
public Transformation inverse() {
return cycles[1];
}}};
}
}
};
}
+90 -120
View File
@@ -4,157 +4,131 @@ import codechicken.lib.math.MathHelper;
import codechicken.lib.util.Copyable;
import net.minecraft.tileentity.TileEntity;
public class BlockCoord implements Comparable<BlockCoord>, Copyable<BlockCoord>
{
public class BlockCoord implements Comparable<BlockCoord>, Copyable<BlockCoord> {
public int x;
public int y;
public int z;
public BlockCoord(int x, int y, int z)
{
public BlockCoord(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public BlockCoord(Vector3 v)
{
public BlockCoord(Vector3 v) {
this(MathHelper.floor_double(v.x), MathHelper.floor_double(v.y), MathHelper.floor_double(v.z));
}
public BlockCoord(TileEntity tile)
{
public BlockCoord(TileEntity tile) {
this(tile.xCoord, tile.yCoord, tile.zCoord);
}
public BlockCoord(int[] ia)
{
public BlockCoord(int[] ia) {
this(ia[0], ia[1], ia[2]);
}
public BlockCoord()
{
}
public BlockCoord() {}
public static BlockCoord fromAxes(int[] ia)
{
public static BlockCoord fromAxes(int[] ia) {
return new BlockCoord(ia[2], ia[0], ia[1]);
}
@Override
public boolean equals(Object obj)
{
if(!(obj instanceof BlockCoord))
return false;
BlockCoord o2 = (BlockCoord)obj;
public boolean equals(Object obj) {
if (!(obj instanceof BlockCoord)) return false;
BlockCoord o2 = (BlockCoord) obj;
return x == o2.x && y == o2.y && z == o2.z;
}
@Override
public int hashCode()
{
return (x^z)*31 + y;
public int hashCode() {
return (x ^ z) * 31 + y;
}
public int compareTo(BlockCoord o)
{
if(x != o.x)return x < o.x ? 1 : -1;
if(y != o.y)return y < o.y ? 1 : -1;
if(z != o.z)return z < o.z ? 1 : -1;
public int compareTo(BlockCoord o) {
if (x != o.x) return x < o.x ? 1 : -1;
if (y != o.y) return y < o.y ? 1 : -1;
if (z != o.z) return z < o.z ? 1 : -1;
return 0;
}
public Vector3 toVector3Centered()
{
return new Vector3(x+0.5, y+0.5, z+0.5);
public Vector3 toVector3Centered() {
return new Vector3(x + 0.5, y + 0.5, z + 0.5);
}
public BlockCoord multiply(int i)
{
x*=i;
y*=i;
z*=i;
public BlockCoord multiply(int i) {
x *= i;
y *= i;
z *= i;
return this;
}
public double mag()
{
return Math.sqrt(x*x+y*y+z*z);
public double mag() {
return Math.sqrt(x * x + y * y + z * z);
}
public int mag2()
{
return x*x+y*y+z*z;
public int mag2() {
return x * x + y * y + z * z;
}
public boolean isZero()
{
public boolean isZero() {
return x == 0 && y == 0 && z == 0;
}
public boolean isAxial()
{
public boolean isAxial() {
return x == 0 ? (y == 0 || z == 0) : (y == 0 && z == 0);
}
public BlockCoord add(BlockCoord coord2)
{
x+=coord2.x;
y+=coord2.y;
z+=coord2.z;
public BlockCoord add(BlockCoord coord2) {
x += coord2.x;
y += coord2.y;
z += coord2.z;
return this;
}
public BlockCoord add(int i, int j, int k)
{
x+=i;
y+=j;
z+=k;
public BlockCoord add(int i, int j, int k) {
x += i;
y += j;
z += k;
return this;
}
public BlockCoord sub(BlockCoord coord2)
{
x-=coord2.x;
y-=coord2.y;
z-=coord2.z;
public BlockCoord sub(BlockCoord coord2) {
x -= coord2.x;
y -= coord2.y;
z -= coord2.z;
return this;
}
public BlockCoord sub(int i, int j, int k)
{
x-=i;
y-=j;
z-=k;
public BlockCoord sub(int i, int j, int k) {
x -= i;
y -= j;
z -= k;
return this;
}
public BlockCoord offset(int side)
{
public BlockCoord offset(int side) {
return offset(side, 1);
}
public BlockCoord offset(int side, int amount)
{
public BlockCoord offset(int side, int amount) {
BlockCoord offset = sideOffsets[side];
x+=offset.x*amount;
y+=offset.y*amount;
z+=offset.z*amount;
x += offset.x * amount;
y += offset.y * amount;
z += offset.z * amount;
return this;
}
public BlockCoord inset(int side)
{
public BlockCoord inset(int side) {
return inset(side, 1);
}
public BlockCoord inset(int side, int amount)
{
public BlockCoord inset(int side, int amount) {
return offset(side, -amount);
}
public int getSide(int side) {
switch(side) {
switch (side) {
case 0:
case 1:
return y;
@@ -168,54 +142,55 @@ public class BlockCoord implements Comparable<BlockCoord>, Copyable<BlockCoord>
throw new IndexOutOfBoundsException("Switch Falloff");
}
public BlockCoord setSide(int s, int v)
{
switch(s)
{
public BlockCoord setSide(int s, int v) {
switch (s) {
case 0:
case 1: y = v; break;
case 1:
y = v;
break;
case 2:
case 3: z = v; break;
case 3:
z = v;
break;
case 4:
case 5: x = v; break;
default: throw new IndexOutOfBoundsException("Switch Falloff");
case 5:
x = v;
break;
default:
throw new IndexOutOfBoundsException("Switch Falloff");
}
return this;
}
public static final BlockCoord[] sideOffsets = new BlockCoord[]{
new BlockCoord( 0,-1, 0),
new BlockCoord( 0, 1, 0),
new BlockCoord( 0, 0,-1),
new BlockCoord( 0, 0, 1),
public static final BlockCoord[] sideOffsets = new BlockCoord[] {
new BlockCoord(0, -1, 0),
new BlockCoord(0, 1, 0),
new BlockCoord(0, 0, -1),
new BlockCoord(0, 0, 1),
new BlockCoord(-1, 0, 0),
new BlockCoord( 1, 0, 0)};
new BlockCoord(1, 0, 0)
};
public int[] intArray()
{
return new int[]{x, y, z};
public int[] intArray() {
return new int[] {x, y, z};
}
public BlockCoord copy()
{
public BlockCoord copy() {
return new BlockCoord(x, y, z);
}
public BlockCoord set(int i, int j, int k)
{
public BlockCoord set(int i, int j, int k) {
x = i;
y = j;
z = k;
return this;
}
public BlockCoord set(BlockCoord coord)
{
public BlockCoord set(BlockCoord coord) {
return set(coord.x, coord.y, coord.z);
}
public BlockCoord set(int[] ia)
{
public BlockCoord set(int[] ia) {
return set(ia[0], ia[1], ia[2]);
}
@@ -223,28 +198,23 @@ public class BlockCoord implements Comparable<BlockCoord>, Copyable<BlockCoord>
return set(tile.xCoord, tile.yCoord, tile.zCoord);
}
public int toSide()
{
if(!isAxial()) return -1;
if(y < 0) return 0;
if(y > 0) return 1;
if(z < 0) return 2;
if(z > 0) return 3;
if(x < 0) return 4;
if(x > 0) return 5;
public int toSide() {
if (!isAxial()) return -1;
if (y < 0) return 0;
if (y > 0) return 1;
if (z < 0) return 2;
if (z > 0) return 3;
if (x < 0) return 4;
if (x > 0) return 5;
return -1;
}
public int absSum()
{
return (x < 0 ? -x : x) +
(y < 0 ? -y : y) +
(z < 0 ? -z : z);
public int absSum() {
return (x < 0 ? -x : x) + (y < 0 ? -y : y) + (z < 0 ? -z : z);
}
public String toString()
{
return "("+x+", "+y+", "+z+")";
public String toString() {
return "(" + x + ", " + y + ", " + z + ")";
}
}
+111 -102
View File
@@ -1,51 +1,43 @@
package codechicken.lib.vec;
import codechicken.lib.util.Copyable;
import net.minecraft.block.Block;
import net.minecraft.util.AxisAlignedBB;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import net.minecraft.block.Block;
import net.minecraft.util.AxisAlignedBB;
public class Cuboid6 implements Copyable<Cuboid6>
{
public class Cuboid6 implements Copyable<Cuboid6> {
public static Cuboid6 full = new Cuboid6(0, 0, 0, 1, 1, 1);
public Vector3 min;
public Vector3 max;
public Cuboid6(Vector3 min, Vector3 max)
{
public Cuboid6(Vector3 min, Vector3 max) {
this.min = min;
this.max = max;
}
public Cuboid6(AxisAlignedBB aabb)
{
public Cuboid6(AxisAlignedBB aabb) {
min = new Vector3(aabb.minX, aabb.minY, aabb.minZ);
max = new Vector3(aabb.maxX, aabb.maxY, aabb.maxZ);
max = new Vector3(aabb.maxX, aabb.maxY, aabb.maxZ);
}
public Cuboid6(Cuboid6 cuboid)
{
public Cuboid6(Cuboid6 cuboid) {
min = cuboid.min.copy();
max = cuboid.max.copy();
}
public Cuboid6(double minx, double miny, double minz, double maxx, double maxy, double maxz)
{
public Cuboid6(double minx, double miny, double minz, double maxx, double maxy, double maxz) {
min = new Vector3(minx, miny, minz);
max = new Vector3(maxx, maxy, maxz);
}
public AxisAlignedBB toAABB()
{
public AxisAlignedBB toAABB() {
return AxisAlignedBB.getBoundingBox(min.x, min.y, min.z, max.x, max.y, max.z);
}
public Cuboid6 copy()
{
public Cuboid6 copy() {
return new Cuboid6(this);
}
@@ -65,127 +57,144 @@ public class Cuboid6 implements Copyable<Cuboid6>
return this;
}
public Cuboid6 add(Vector3 vec)
{
public Cuboid6 add(Vector3 vec) {
min.add(vec);
max.add(vec);
return this;
}
public Cuboid6 sub(Vector3 vec)
{
public Cuboid6 sub(Vector3 vec) {
min.subtract(vec);
max.subtract(vec);
return this;
}
public Cuboid6 expand(double d)
{
public Cuboid6 expand(double d) {
return expand(new Vector3(d, d, d));
}
public Cuboid6 expand(Vector3 vec)
{
public Cuboid6 expand(Vector3 vec) {
min.sub(vec);
max.add(vec);
return this;
}
public void setBlockBounds(Block block)
{
block.setBlockBounds((float)min.x, (float)min.y, (float)min.z, (float)max.x, (float)max.y, (float)max.z);
public void setBlockBounds(Block block) {
block.setBlockBounds((float) min.x, (float) min.y, (float) min.z, (float) max.x, (float) max.y, (float) max.z);
}
public boolean intersects(Cuboid6 b)
{
return max.x-1E-5 > b.min.x &&
b.max.x-1E-5 > min.x &&
max.y-1E-5 > b.min.y &&
b.max.y-1E-5 > min.y &&
max.z-1E-5 > b.min.z &&
b.max.z-1E-5 > min.z;
public boolean intersects(Cuboid6 b) {
return max.x - 1E-5 > b.min.x
&& b.max.x - 1E-5 > min.x
&& max.y - 1E-5 > b.min.y
&& b.max.y - 1E-5 > min.y
&& max.z - 1E-5 > b.min.z
&& b.max.z - 1E-5 > min.z;
}
public Cuboid6 offset(Cuboid6 o)
{
public Cuboid6 offset(Cuboid6 o) {
min.add(o.min);
max.add(o.max);
return this;
}
public Vector3 center()
{
public Vector3 center() {
return min.copy().add(max).multiply(0.5);
}
public static boolean intersects(Cuboid6 a, Cuboid6 b)
{
public static boolean intersects(Cuboid6 a, Cuboid6 b) {
return a != null && b != null && a.intersects(b);
}
public String toString()
{
public String toString() {
MathContext cont = new MathContext(4, RoundingMode.HALF_UP);
return "Cuboid: ("+new BigDecimal(min.x, cont)+", "+new BigDecimal(min.y, cont)+", "+new BigDecimal(min.z, cont)+") -> ("+
new BigDecimal(max.x, cont)+", "+new BigDecimal(max.y, cont)+", "+new BigDecimal(max.z, cont)+")";
return "Cuboid: (" + new BigDecimal(min.x, cont) + ", " + new BigDecimal(min.y, cont) + ", "
+ new BigDecimal(min.z, cont) + ") -> (" + new BigDecimal(max.x, cont) + ", "
+ new BigDecimal(max.y, cont) + ", " + new BigDecimal(max.z, cont) + ")";
}
public Cuboid6 enclose(Vector3 vec)
{
if(min.x > vec.x) min.x = vec.x;
if(min.y > vec.y) min.y = vec.y;
if(min.z > vec.z) min.z = vec.z;
if(max.x < vec.x) max.x = vec.x;
if(max.y < vec.y) max.y = vec.y;
if(max.z < vec.z) max.z = vec.z;
public Cuboid6 enclose(Vector3 vec) {
if (min.x > vec.x) min.x = vec.x;
if (min.y > vec.y) min.y = vec.y;
if (min.z > vec.z) min.z = vec.z;
if (max.x < vec.x) max.x = vec.x;
if (max.y < vec.y) max.y = vec.y;
if (max.z < vec.z) max.z = vec.z;
return this;
}
public Cuboid6 enclose(Cuboid6 c)
{
if(min.x > c.min.x) min.x = c.min.x;
if(min.y > c.min.y) min.y = c.min.y;
if(min.z > c.min.z) min.z = c.min.z;
if(max.x < c.max.x) max.x = c.max.x;
if(max.y < c.max.y) max.y = c.max.y;
if(max.z < c.max.z) max.z = c.max.z;
public Cuboid6 enclose(Cuboid6 c) {
if (min.x > c.min.x) min.x = c.min.x;
if (min.y > c.min.y) min.y = c.min.y;
if (min.z > c.min.z) min.z = c.min.z;
if (max.x < c.max.x) max.x = c.max.x;
if (max.y < c.max.y) max.y = c.max.y;
if (max.z < c.max.z) max.z = c.max.z;
return this;
}
public Cuboid6 apply(Transformation t)
{
public Cuboid6 apply(Transformation t) {
t.apply(min);
t.apply(max);
double temp;
if(min.x > max.x) {temp = min.x; min.x = max.x; max.x = temp;}
if(min.y > max.y) {temp = min.y; min.y = max.y; max.y = temp;}
if(min.z > max.z) {temp = min.z; min.z = max.z; max.z = temp;}
if (min.x > max.x) {
temp = min.x;
min.x = max.x;
max.x = temp;
}
if (min.y > max.y) {
temp = min.y;
min.y = max.y;
max.y = temp;
}
if (min.z > max.z) {
temp = min.z;
min.z = max.z;
max.z = temp;
}
return this;
}
public double getSide(int s)
{
switch(s) {
case 0: return min.y;
case 1: return max.y;
case 2: return min.z;
case 3: return max.z;
case 4: return min.x;
case 5: return max.x;
public double getSide(int s) {
switch (s) {
case 0:
return min.y;
case 1:
return max.y;
case 2:
return min.z;
case 3:
return max.z;
case 4:
return min.x;
case 5:
return max.x;
}
throw new IndexOutOfBoundsException("Switch Falloff");
}
public Cuboid6 setSide(int s, double d)
{
switch(s) {
case 0: min.y = d; break;
case 1: max.y = d; break;
case 2: min.z = d; break;
case 3: max.z = d; break;
case 4: min.x = d; break;
case 5: max.x = d; break;
default: throw new IndexOutOfBoundsException("Switch Falloff");
public Cuboid6 setSide(int s, double d) {
switch (s) {
case 0:
min.y = d;
break;
case 1:
max.y = d;
break;
case 2:
min.z = d;
break;
case 3:
max.z = d;
break;
case 4:
min.x = d;
break;
case 5:
max.x = d;
break;
default:
throw new IndexOutOfBoundsException("Switch Falloff");
}
return this;
}
@@ -1,12 +1,10 @@
package codechicken.lib.vec;
import codechicken.lib.util.Copyable;
import java.util.Iterator;
import net.minecraft.util.AxisAlignedBB;
import java.util.Iterator;
public class CuboidCoord implements Iterable<BlockCoord>, Copyable<CuboidCoord>
{
public class CuboidCoord implements Iterable<BlockCoord>, Copyable<CuboidCoord> {
public BlockCoord min;
public BlockCoord max;
@@ -43,10 +41,9 @@ public class CuboidCoord implements Iterable<BlockCoord>, Copyable<CuboidCoord>
}
public CuboidCoord expand(int side, int amount) {
if (side % 2 == 0)//negative side
min = min.offset(side, amount);
else
max = max.offset(side, amount);
if (side % 2 == 0) // negative side
min = min.offset(side, amount);
else max = max.offset(side, amount);
return this;
}
@@ -61,58 +58,78 @@ public class CuboidCoord implements Iterable<BlockCoord>, Copyable<CuboidCoord>
max.add(x, y, z);
return this;
}
public int size(int s) {
switch(s) {
switch (s) {
case 0:
case 1:
return max.y - min.y+1;
return max.y - min.y + 1;
case 2:
case 3:
return max.z - min.z+1;
return max.z - min.z + 1;
case 4:
case 5:
return max.x - min.x+1;
return max.x - min.x + 1;
default:
return 0;
}
}
public int getSide(int s) {
switch(s) {
case 0: return min.y;
case 1: return max.y;
case 2: return min.z;
case 3: return max.z;
case 4: return min.x;
case 5: return max.x;
switch (s) {
case 0:
return min.y;
case 1:
return max.y;
case 2:
return min.z;
case 3:
return max.z;
case 4:
return min.x;
case 5:
return max.x;
}
throw new IndexOutOfBoundsException("Switch Falloff");
}
public CuboidCoord setSide(int s, int v) {
switch(s) {
case 0: min.y = v; break;
case 1: max.y = v; break;
case 2: min.z = v; break;
case 3: max.z = v; break;
case 4: min.x = v; break;
case 5: max.x = v; break;
default: throw new IndexOutOfBoundsException("Switch Falloff");
switch (s) {
case 0:
min.y = v;
break;
case 1:
max.y = v;
break;
case 2:
min.z = v;
break;
case 3:
max.z = v;
break;
case 4:
min.x = v;
break;
case 5:
max.x = v;
break;
default:
throw new IndexOutOfBoundsException("Switch Falloff");
}
return this;
}
public int getVolume() {
return (max.x-min.x+1)*(max.y-min.y+1)*(max.z-min.z+1);
return (max.x - min.x + 1) * (max.y - min.y + 1) * (max.z - min.z + 1);
}
public Vector3 getCenterVec() {
return new Vector3(min.x+(max.x-min.x+1)/2D, min.y+(max.y-min.y+1)/2D, min.z+(max.z-min.z+1)/2D);
return new Vector3(
min.x + (max.x - min.x + 1) / 2D, min.y + (max.y - min.y + 1) / 2D, min.z + (max.z - min.z + 1) / 2D);
}
public BlockCoord getCenter(BlockCoord store) {
store.set(min.x+(max.x-min.x)/2, min.y+(max.y-min.y)/2, min.z+(max.z-min.z)/2);
store.set(min.x + (max.x - min.x) / 2, min.y + (max.y - min.y) / 2, min.z + (max.z - min.z) / 2);
return store;
}
@@ -121,13 +138,11 @@ public class CuboidCoord implements Iterable<BlockCoord>, Copyable<CuboidCoord>
}
public boolean contains(int x, int y, int z) {
return x >= min.x && x <= max.x
&& y >= min.y && y <= max.y
&& z >= min.z && z <= max.z;
return x >= min.x && x <= max.x && y >= min.y && y <= max.y && z >= min.z && z <= max.z;
}
public int[] intArray() {
return new int[]{min.x, min.y, min.z, max.x, max.y, max.z};
return new int[] {min.x, min.y, min.z, max.x, max.y, max.z};
}
public CuboidCoord copy() {
@@ -171,12 +186,12 @@ public class CuboidCoord implements Iterable<BlockCoord>, Copyable<CuboidCoord>
}
public CuboidCoord include(int x, int y, int z) {
if(x < min.x) min.x = x;
else if(x > max.x) max.x = x;
if(y < min.y) min.y = y;
else if(y > max.y) max.y = y;
if(z < min.z) min.z = z;
else if(z > max.z) max.z = z;
if (x < min.x) min.x = x;
else if (x > max.x) max.x = x;
if (y < min.y) min.y = y;
else if (y > max.y) max.y = y;
if (z < min.z) min.z = z;
else if (z > max.z) max.z = z;
return this;
}
@@ -189,15 +204,12 @@ public class CuboidCoord implements Iterable<BlockCoord>, Copyable<CuboidCoord>
}
public BlockCoord next() {
if(b == null)
b = min.copy();
if (b == null) b = min.copy();
else {
if(b.z != max.z)
b.z++;
if (b.z != max.z) b.z++;
else {
b.z = min.z;
if(b.y != max.y)
b.y++;
if (b.y != max.y) b.y++;
else {
b.y = min.y;
b.x++;
@@ -5,8 +5,7 @@ package codechicken.lib.vec;
* @param <Vector> The vector type
* @param <Transformation> The transformation type
*/
public abstract class ITransformation<Vector, Transformation extends ITransformation>
{
public abstract class ITransformation<Vector, Transformation extends ITransformation> {
/**
* Applies this transformation to vec
*/
@@ -1,18 +1,15 @@
package codechicken.lib.vec;
@SuppressWarnings("serial")
public class IrreversibleTransformationException extends RuntimeException
{
public class IrreversibleTransformationException extends RuntimeException {
public ITransformation t;
public IrreversibleTransformationException(ITransformation t)
{
public IrreversibleTransformationException(ITransformation t) {
this.t = t;
}
@Override
public String getMessage()
{
return "The following transformation is irreversible:\n"+t;
public String getMessage() {
return "The following transformation is irreversible:\n" + t;
}
}
+18 -20
View File
@@ -1,27 +1,22 @@
package codechicken.lib.vec;
public class Line3
{
public class Line3 {
public static final double tol = 0.0001D;
public Vector3 pt1;
public Vector3 pt2;
public Line3(Vector3 pt1, Vector3 pt2)
{
public Line3(Vector3 pt1, Vector3 pt2) {
this.pt1 = pt1;
this.pt2 = pt2;
}
public Line3()
{
public Line3() {
this(new Vector3(), new Vector3());
}
public static boolean intersection2D(Line3 line1, Line3 line2, Vector3 store)
{
// calculate differences
public static boolean intersection2D(Line3 line1, Line3 line2, Vector3 store) {
// calculate differences
double xD1 = line1.pt2.x - line1.pt1.x;
double zD1 = line1.pt2.z - line1.pt1.z;
double xD2 = line2.pt2.x - line2.pt1.x;
@@ -29,18 +24,21 @@ public class Line3
double xD3 = line1.pt1.x - line2.pt1.x;
double zD3 = line1.pt1.z - line2.pt1.z;
double div = zD2 * xD1 - xD2 * zD1;
if(div == 0)//lines are parallel
return false;
if (div == 0) // lines are parallel
return false;
double ua = (xD2 * zD3 - zD2 * xD3) / div;
store.set(line1.pt1.x + ua * xD1, 0, line1.pt1.z + ua * zD1);
if(store.x >= Math.min(line1.pt1.x, line1.pt2.x)-tol && store.x >= Math.min(line2.pt1.x, line2.pt2.x)-tol
&& store.z >= Math.min(line1.pt1.z, line1.pt2.z)-tol && store.z >= Math.min(line2.pt1.z, line2.pt2.z)-tol
&& store.x <= Math.max(line1.pt1.x, line1.pt2.x)+tol && store.x <= Math.max(line2.pt1.x, line2.pt2.x)+tol
&& store.z <= Math.max(line1.pt1.z, line1.pt2.z)+tol && store.z <= Math.max(line2.pt1.z, line2.pt2.z)+tol)
return true;
if (store.x >= Math.min(line1.pt1.x, line1.pt2.x) - tol
&& store.x >= Math.min(line2.pt1.x, line2.pt2.x) - tol
&& store.z >= Math.min(line1.pt1.z, line1.pt2.z) - tol
&& store.z >= Math.min(line2.pt1.z, line2.pt2.z) - tol
&& store.x <= Math.max(line1.pt1.x, line1.pt2.x) + tol
&& store.x <= Math.max(line2.pt1.x, line2.pt2.x) + tol
&& store.z <= Math.max(line1.pt1.z, line1.pt2.z) + tol
&& store.z <= Math.max(line2.pt1.z, line2.pt2.z) + tol) return true;
return false;
}
+115 -108
View File
@@ -3,32 +3,42 @@ package codechicken.lib.vec;
import codechicken.lib.util.Copyable;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import org.lwjgl.opengl.GL11;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.DoubleBuffer;
import org.lwjgl.opengl.GL11;
public class Matrix4 extends Transformation implements Copyable<Matrix4>
{
private static DoubleBuffer glBuf = ByteBuffer.allocateDirect(16*8).order(ByteOrder.nativeOrder()).asDoubleBuffer();
//m<row><column>
public class Matrix4 extends Transformation implements Copyable<Matrix4> {
private static DoubleBuffer glBuf =
ByteBuffer.allocateDirect(16 * 8).order(ByteOrder.nativeOrder()).asDoubleBuffer();
// m<row><column>
public double m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33;
public Matrix4()
{
public Matrix4() {
m00 = m11 = m22 = m33 = 1;
}
public Matrix4(double d00, double d01, double d02, double d03,
double d10, double d11, double d12, double d13,
double d20, double d21, double d22, double d23,
double d30, double d31, double d32, double d33)
{
public Matrix4(
double d00,
double d01,
double d02,
double d03,
double d10,
double d11,
double d12,
double d13,
double d20,
double d21,
double d22,
double d23,
double d30,
double d31,
double d32,
double d33) {
m00 = d00;
m01 = d01;
m02 = d02;
@@ -46,32 +56,28 @@ public class Matrix4 extends Transformation implements Copyable<Matrix4>
m32 = d32;
m33 = d33;
}
public Matrix4(Matrix4 mat)
{
public Matrix4(Matrix4 mat) {
set(mat);
}
public Matrix4 setIdentity()
{
public Matrix4 setIdentity() {
m00 = m11 = m22 = m33 = 1;
m01 = m02 = m03 = m10 = m12 = m13 = m20 = m21 = m23 = m30 = m31 = m32 = 0;
return this;
}
public Matrix4 translate(Vector3 vec)
{
public Matrix4 translate(Vector3 vec) {
m03 += m00 * vec.x + m01 * vec.y + m02 * vec.z;
m13 += m10 * vec.x + m11 * vec.y + m12 * vec.z;
m23 += m20 * vec.x + m21 * vec.y + m22 * vec.z;
m33 += m30 * vec.x + m31 * vec.y + m32 * vec.z;
return this;
}
public Matrix4 scale(Vector3 vec)
{
public Matrix4 scale(Vector3 vec) {
m00 *= vec.x;
m10 *= vec.x;
m20 *= vec.x;
@@ -84,33 +90,32 @@ public class Matrix4 extends Transformation implements Copyable<Matrix4>
m12 *= vec.z;
m22 *= vec.z;
m32 *= vec.z;
return this;
}
public Matrix4 rotate(double angle, Vector3 axis)
{
public Matrix4 rotate(double angle, Vector3 axis) {
double c = Math.cos(angle);
double s = Math.sin(angle);
double mc = 1.0f - c;
double xy = axis.x*axis.y;
double yz = axis.y*axis.z;
double xz = axis.x*axis.z;
double xs = axis.x*s;
double ys = axis.y*s;
double zs = axis.z*s;
double xy = axis.x * axis.y;
double yz = axis.y * axis.z;
double xz = axis.x * axis.z;
double xs = axis.x * s;
double ys = axis.y * s;
double zs = axis.z * s;
double f00 = axis.x*axis.x*mc+c;
double f10 = xy*mc+zs;
double f20 = xz*mc-ys;
double f01 = xy*mc-zs;
double f11 = axis.y*axis.y*mc+c;
double f21 = yz*mc+xs;
double f02 = xz*mc+ys;
double f12 = yz*mc-xs;
double f22 = axis.z*axis.z*mc+c;
double f00 = axis.x * axis.x * mc + c;
double f10 = xy * mc + zs;
double f20 = xz * mc - ys;
double f01 = xy * mc - zs;
double f11 = axis.y * axis.y * mc + c;
double f21 = yz * mc + xs;
double f02 = xz * mc + ys;
double f12 = yz * mc - xs;
double f22 = axis.z * axis.z * mc + c;
double t00 = m00 * f00 + m01 * f10 + m02 * f20;
double t10 = m10 * f00 + m11 * f10 + m12 * f20;
@@ -132,18 +137,16 @@ public class Matrix4 extends Transformation implements Copyable<Matrix4>
m11 = t11;
m21 = t21;
m31 = t31;
return this;
}
public Matrix4 rotate(Rotation rotation)
{
public Matrix4 rotate(Rotation rotation) {
rotation.apply(this);
return this;
}
public Matrix4 leftMultiply(Matrix4 mat)
{
public Matrix4 leftMultiply(Matrix4 mat) {
double n00 = m00 * mat.m00 + m10 * mat.m01 + m20 * mat.m02 + m30 * mat.m03;
double n01 = m01 * mat.m00 + m11 * mat.m01 + m21 * mat.m02 + m31 * mat.m03;
double n02 = m02 * mat.m00 + m12 * mat.m01 + m22 * mat.m02 + m32 * mat.m03;
@@ -177,12 +180,11 @@ public class Matrix4 extends Transformation implements Copyable<Matrix4>
m31 = n31;
m32 = n32;
m33 = n33;
return this;
}
public Matrix4 multiply(Matrix4 mat)
{
public Matrix4 multiply(Matrix4 mat) {
double n00 = m00 * mat.m00 + m01 * mat.m10 + m02 * mat.m20 + m03 * mat.m30;
double n01 = m00 * mat.m01 + m01 * mat.m11 + m02 * mat.m21 + m03 * mat.m31;
double n02 = m00 * mat.m02 + m01 * mat.m12 + m02 * mat.m22 + m03 * mat.m32;
@@ -216,12 +218,11 @@ public class Matrix4 extends Transformation implements Copyable<Matrix4>
m31 = n31;
m32 = n32;
m33 = n33;
return this;
}
public Matrix4 transpose()
{
public Matrix4 transpose() {
double n00 = m00;
double n10 = m01;
double n20 = m02;
@@ -255,17 +256,15 @@ public class Matrix4 extends Transformation implements Copyable<Matrix4>
m31 = n31;
m32 = n32;
m33 = n33;
return this;
}
public Matrix4 copy()
{
public Matrix4 copy() {
return new Matrix4(this);
}
public Matrix4 set(Matrix4 mat)
{
public Matrix4 set(Matrix4 mat) {
m00 = mat.m00;
m01 = mat.m01;
m02 = mat.m02;
@@ -282,72 +281,80 @@ public class Matrix4 extends Transformation implements Copyable<Matrix4>
m31 = mat.m31;
m32 = mat.m32;
m33 = mat.m33;
return this;
}
@Override
public void apply(Matrix4 mat)
{
public void apply(Matrix4 mat) {
mat.multiply(this);
}
private void mult3x3(Vector3 vec)
{
private void mult3x3(Vector3 vec) {
double x = m00 * vec.x + m01 * vec.y + m02 * vec.z;
double y = m10 * vec.x + m11 * vec.y + m12 * vec.z;
double z = m20 * vec.x + m21 * vec.y + m22 * vec.z;
vec.x = x;
vec.y = y;
vec.z = z;
}
@Override
public void apply(Vector3 vec)
{
public void apply(Vector3 vec) {
mult3x3(vec);
vec.add(m03, m13, m23);
}
@Override
public void applyN(Vector3 vec)
{
public void applyN(Vector3 vec) {
mult3x3(vec);
vec.normalize();
}
@Override
public String toString()
{
public String toString() {
MathContext cont = new MathContext(4, RoundingMode.HALF_UP);
return "["+new BigDecimal(m00, cont)+","+new BigDecimal(m01, cont)+","+new BigDecimal(m02, cont)+","+new BigDecimal(m03, cont)+"]\n"+
"["+new BigDecimal(m10, cont)+","+new BigDecimal(m11, cont)+","+new BigDecimal(m12, cont)+","+new BigDecimal(m13, cont)+"]\n"+
"["+new BigDecimal(m20, cont)+","+new BigDecimal(m21, cont)+","+new BigDecimal(m22, cont)+","+new BigDecimal(m23, cont)+"]\n"+
"["+new BigDecimal(m30, cont)+","+new BigDecimal(m31, cont)+","+new BigDecimal(m32, cont)+","+new BigDecimal(m33, cont)+"]";
return "[" + new BigDecimal(m00, cont) + "," + new BigDecimal(m01, cont) + "," + new BigDecimal(m02, cont) + ","
+ new BigDecimal(m03, cont) + "]\n" + "["
+ new BigDecimal(m10, cont) + "," + new BigDecimal(m11, cont) + "," + new BigDecimal(m12, cont) + ","
+ new BigDecimal(m13, cont) + "]\n" + "["
+ new BigDecimal(m20, cont) + "," + new BigDecimal(m21, cont) + "," + new BigDecimal(m22, cont) + ","
+ new BigDecimal(m23, cont) + "]\n" + "["
+ new BigDecimal(m30, cont) + "," + new BigDecimal(m31, cont) + "," + new BigDecimal(m32, cont) + ","
+ new BigDecimal(m33, cont) + "]";
}
public Matrix4 apply(Transformation t)
{
public Matrix4 apply(Transformation t) {
t.apply(this);
return this;
}
@Override
@SideOnly(Side.CLIENT)
public void glApply()
{
glBuf.put(m00).put(m10).put(m20).put(m30)
.put(m01).put(m11).put(m21).put(m31)
.put(m02).put(m12).put(m22).put(m32)
.put(m03).put(m13).put(m23).put(m33);
public void glApply() {
glBuf.put(m00)
.put(m10)
.put(m20)
.put(m30)
.put(m01)
.put(m11)
.put(m21)
.put(m31)
.put(m02)
.put(m12)
.put(m22)
.put(m32)
.put(m03)
.put(m13)
.put(m23)
.put(m33);
glBuf.flip();
GL11.glMultMatrix(glBuf);
}
@Override
public Transformation inverse()
{
throw new IrreversibleTransformationException(this);//Don't waste your cpu with matrix inverses
public Transformation inverse() {
throw new IrreversibleTransformationException(this); // Don't waste your cpu with matrix inverses
}
}
+29 -48
View File
@@ -2,86 +2,74 @@ package codechicken.lib.vec;
import codechicken.lib.math.MathHelper;
import codechicken.lib.util.Copyable;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
public class Quat implements Copyable<Quat>
{
public class Quat implements Copyable<Quat> {
public double x;
public double y;
public double z;
public double s;
public Quat()
{
public Quat() {
s = 1;
x = 0;
y = 0;
z = 0;
}
public Quat(Quat quat)
{
public Quat(Quat quat) {
x = quat.x;
y = quat.y;
z = quat.z;
s = quat.s;
}
public Quat(double d, double d1, double d2, double d3)
{
public Quat(double d, double d1, double d2, double d3) {
x = d1;
y = d2;
z = d3;
s = d;
}
public Quat set(Quat quat)
{
public Quat set(Quat quat) {
x = quat.x;
y = quat.y;
z = quat.z;
s = quat.s;
return this;
}
public Quat set(double d, double d1, double d2, double d3)
{
public Quat set(double d, double d1, double d2, double d3) {
x = d1;
y = d2;
z = d3;
s = d;
return this;
}
public static Quat aroundAxis(double ax, double ay, double az, double angle)
{
public static Quat aroundAxis(double ax, double ay, double az, double angle) {
return new Quat().setAroundAxis(ax, ay, az, angle);
}
public static Quat aroundAxis(Vector3 axis, double angle)
{
public static Quat aroundAxis(Vector3 axis, double angle) {
return aroundAxis(axis.x, axis.y, axis.z, angle);
}
public Quat setAroundAxis(double ax, double ay, double az, double angle)
{
public Quat setAroundAxis(double ax, double ay, double az, double angle) {
angle *= 0.5;
double d4 = MathHelper.sin(angle);
return set(MathHelper.cos(angle), ax * d4, ay * d4, az * d4);
}
public Quat setAroundAxis(Vector3 axis, double angle)
{
public Quat setAroundAxis(Vector3 axis, double angle) {
return setAroundAxis(axis.x, axis.y, axis.z, angle);
}
public Quat multiply(Quat quat)
{
public Quat multiply(Quat quat) {
double d = s * quat.s - x * quat.x - y * quat.y - z * quat.z;
double d1 = s * quat.x + x * quat.s - y * quat.z + z * quat.y;
double d2 = s * quat.y + x * quat.z + y * quat.s - z * quat.x;
@@ -90,12 +78,11 @@ public class Quat implements Copyable<Quat>
x = d1;
y = d2;
z = d3;
return this;
}
public Quat rightMultiply(Quat quat)
{
public Quat rightMultiply(Quat quat) {
double d = s * quat.s - x * quat.x - y * quat.y - z * quat.z;
double d1 = s * quat.x + x * quat.s + y * quat.z - z * quat.y;
double d2 = s * quat.y - x * quat.z + y * quat.s + z * quat.x;
@@ -104,37 +91,32 @@ public class Quat implements Copyable<Quat>
x = d1;
y = d2;
z = d3;
return this;
}
public double mag()
{
public double mag() {
return Math.sqrt(x * x + y * y + z * z + s * s);
}
public Quat normalize()
{
public Quat normalize() {
double d = mag();
if(d != 0)
{
if (d != 0) {
d = 1 / d;
x *= d;
y *= d;
z *= d;
s *= d;
}
return this;
}
public Quat copy()
{
public Quat copy() {
return new Quat(this);
}
public void rotate(Vector3 vec)
{
public void rotate(Vector3 vec) {
double d = -x * vec.x - y * vec.y - z * vec.z;
double d1 = s * vec.x + y * vec.z - z * vec.y;
double d2 = s * vec.y - x * vec.z + z * vec.x;
@@ -144,14 +126,13 @@ public class Quat implements Copyable<Quat>
vec.z = d3 * s - d * z - d1 * y + d2 * x;
}
public String toString()
{
public String toString() {
MathContext cont = new MathContext(4, RoundingMode.HALF_UP);
return "Quat("+new BigDecimal(s, cont)+", "+new BigDecimal(x, cont)+", "+new BigDecimal(y, cont)+", "+new BigDecimal(z, cont)+")";
return "Quat(" + new BigDecimal(s, cont) + ", " + new BigDecimal(x, cont) + ", " + new BigDecimal(y, cont)
+ ", " + new BigDecimal(z, cont) + ")";
}
public Rotation rotation()
{
public Rotation rotation() {
return new Rotation(this);
}
}
@@ -1,18 +1,14 @@
package codechicken.lib.vec;
public class Rectangle4i
{
public class Rectangle4i {
public int x;
public int y;
public int w;
public int h;
public Rectangle4i()
{
}
public Rectangle4i(int x, int y, int w, int h)
{
public Rectangle4i() {}
public Rectangle4i(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
@@ -28,11 +24,11 @@ public class Rectangle4i
}
public int x2() {
return x+w-1;
return x + w - 1;
}
public int y2() {
return y+h-1;
return y + h - 1;
}
public void set(int x, int y, int w, int h) {
@@ -41,25 +37,23 @@ public class Rectangle4i
this.w = w;
this.h = h;
}
public Rectangle4i offset(int dx, int dy)
{
x+=dx;
y+=dy;
public Rectangle4i offset(int dx, int dy) {
x += dx;
y += dy;
return this;
}
@Deprecated
public Rectangle4i with(int px, int py)
{
public Rectangle4i with(int px, int py) {
return include(px, py);
}
public Rectangle4i include(int px, int py) {
if(px < x) expand(px-x, 0);
if(px >= x+w) expand(px-x-w+1, 0);
if(py < y) expand(0, py-y);
if(py >= y+h) expand(0, py-y-h+1);
if (px < x) expand(px - x, 0);
if (px >= x + w) expand(px - x - w + 1, 0);
if (py < y) expand(0, py - y);
if (py >= y + h) expand(0, py - y - h + 1);
return this;
}
@@ -69,32 +63,25 @@ public class Rectangle4i
}
public Rectangle4i expand(int px, int py) {
if(px > 0)
w+=px;
if (px > 0) w += px;
else {
x+=px;
w-=px;
x += px;
w -= px;
}
if(py > 0)
h+=py;
if (py > 0) h += py;
else {
y+=py;
h-=py;
y += py;
h -= py;
}
return this;
}
public boolean contains(int px, int py)
{
return x <= px && px < x+w && y <= py && py < y+h;
public boolean contains(int px, int py) {
return x <= px && px < x + w && y <= py && py < y + h;
}
public boolean intersects(Rectangle4i r)
{
return r.x+r.w > x &&
r.x < x+w &&
r.y+r.h > y &&
r.y < y+h;
public boolean intersects(Rectangle4i r) {
return r.x + r.w > x && r.x < x + w && r.y + r.h > y && r.y < y + h;
}
public int area() {
@@ -3,46 +3,42 @@ package codechicken.lib.vec;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class RedundantTransformation extends Transformation
{
public class RedundantTransformation extends Transformation {
@Override
public void apply(Vector3 vec){}
public void apply(Vector3 vec) {}
@Override
public void apply(Matrix4 mat){}
public void apply(Matrix4 mat) {}
@Override
public void applyN(Vector3 normal){}
public void applyN(Vector3 normal) {}
@Override
public Transformation at(Vector3 point)
{
public Transformation at(Vector3 point) {
return this;
}
@Override
@SideOnly(Side.CLIENT)
public void glApply(){}
public void glApply() {}
@Override
public Transformation inverse()
{
public Transformation inverse() {
return this;
}
@Override
public Transformation merge(Transformation next) {
return next;
}
@Override
public boolean isRedundant() {
return true;
}
@Override
public String toString()
{
public String toString() {
return "Nothing()";
}
}
Loaded 100 of 114 files, more files were not shown because too many files have changed in this diff. Show more