mirror of
https://github.com/GTNewHorizons/CodeChickenCore.git
synced 2026-10-27 06:43:52 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d600169ac | ||
|
|
4e7eb37f3f | ||
|
|
22dfc1360e | ||
|
|
7bf5935f69 | ||
|
|
162de447d5 | ||
|
|
39ed6607a6 | ||
|
|
99b815c12e |
No files matched your search
@@ -0,0 +1,62 @@
|
||||
name: Report Bug
|
||||
description: "Report a bug."
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: "A bug/crash report with sufficient information and logs to reproduce and track down."
|
||||
- type: input
|
||||
id: discord
|
||||
attributes:
|
||||
label: Your GTNH Discord Username
|
||||
description: Leave empty if you don't have one, but this will make it harder to contact you if we need additional info.
|
||||
placeholder: "Example: Fake#1234"
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Mod Version
|
||||
description: "What version of the Mod are you using?"
|
||||
placeholder: "Example: 1.0.0"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: report
|
||||
attributes:
|
||||
label: Bug Report
|
||||
description: "Relevant information, as well as relevant logs attached such as `logs/fml-client-latest.log."
|
||||
placeholder: "Example: https://mclo.gs/ OR submit the file to github by dragging it to this textbox."
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: java
|
||||
attributes:
|
||||
label: Java Version
|
||||
description: What Java version are you using? It's worth mentioning that if you play on Java9+ you should try update to latest minor release (e.g. prefer Java 17.0.6 over 17.0.2) of that version.
|
||||
options:
|
||||
- Java 8
|
||||
- Java 9
|
||||
- Java 11
|
||||
- Java 17
|
||||
- Java 19
|
||||
- Java 20
|
||||
- Java 21
|
||||
- Other (Please Specify)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: modlist
|
||||
attributes:
|
||||
label: Mod List or GTNH Pack Version
|
||||
description: "List of mods, ideally a minimal reproducible set (can be retrieved from latest.log). If using GTNH please indicate pack version and any changed mods, not the entire modlist."
|
||||
placeholder: "List of mods or GTNH Pack version goes here"
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: final
|
||||
attributes:
|
||||
label: Final Checklist
|
||||
description: Certify that you read things
|
||||
options:
|
||||
- label: "I have searched the issues and haven't found a similar issue."
|
||||
required: true
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
name: Feature Request
|
||||
description: "Request a feature."
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: "Please use this form to request features. We ask you check if it was already requested though"
|
||||
- type: input
|
||||
id: discord
|
||||
attributes:
|
||||
label: Your GTNH Discord Username
|
||||
description: Leave empty if you don't have one, but this will make it harder to contact you if we need additional info.
|
||||
placeholder: "Example: Wumpus#1234"
|
||||
- type: textarea
|
||||
id: request
|
||||
attributes:
|
||||
label: Feature Request
|
||||
description: "Relevant information, as well as relevant images"
|
||||
placeholder: "Example: https://mclo.gs/ OR submit the file to github by dragging it to this textbox."
|
||||
validations:
|
||||
required: true
|
||||
- type: checkboxes
|
||||
id: final
|
||||
attributes:
|
||||
label: Final Checklist
|
||||
description: Certify that you read things
|
||||
options:
|
||||
- label: "I have searched the issues and haven't found a similar issue."
|
||||
required: true
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ pluginManagement {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.26'
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.30'
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package codechicken.core;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import net.minecraft.launchwrapper.Launch;
|
||||
|
||||
@@ -114,21 +114,18 @@ public class ClassDiscoverer {
|
||||
}
|
||||
|
||||
private void readFromZipFile(File file) throws IOException {
|
||||
FileInputStream fileinputstream = new FileInputStream(file);
|
||||
ZipInputStream zipinputstream = new ZipInputStream(fileinputstream);
|
||||
do {
|
||||
ZipEntry zipentry = zipinputstream.getNextEntry();
|
||||
if (zipentry == null) {
|
||||
break;
|
||||
try (ZipFile zipFile = new ZipFile(file)) {
|
||||
Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();
|
||||
while (zipEntries.hasMoreElements()) {
|
||||
ZipEntry zipentry = zipEntries.nextElement();
|
||||
String fullname = zipentry.getName().replace('\\', '/');
|
||||
int pos = fullname.lastIndexOf('/');
|
||||
String name = pos == -1 ? fullname : fullname.substring(pos + 1);
|
||||
if (!zipentry.isDirectory() && matcher.matches(name)) {
|
||||
checkAddClass(fullname);
|
||||
}
|
||||
}
|
||||
String fullname = zipentry.getName().replace('\\', '/');
|
||||
int pos = fullname.lastIndexOf('/');
|
||||
String name = pos == -1 ? fullname : fullname.substring(pos + 1);
|
||||
if (!zipentry.isDirectory() && matcher.matches(name)) {
|
||||
checkAddClass(fullname);
|
||||
}
|
||||
} while (true);
|
||||
fileinputstream.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void readFromDirectory(File directory, File basedirectory) {
|
||||
|
||||
@@ -23,11 +23,12 @@ import org.objectweb.asm.tree.InsnList;
|
||||
import org.objectweb.asm.tree.InsnNode;
|
||||
import org.objectweb.asm.tree.MethodInsnNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
import org.objectweb.asm.util.ASMifier;
|
||||
import org.objectweb.asm.util.Textifier;
|
||||
import org.objectweb.asm.util.TraceClassVisitor;
|
||||
|
||||
public class RedirectorTransformer implements IClassTransformer {
|
||||
import codechicken.core.launch.CodeChickenCorePlugin;
|
||||
|
||||
public class RedirectorTransformer implements IClassTransformer, Opcodes {
|
||||
|
||||
private static final boolean DUMP_CLASSES = Boolean.parseBoolean(System.getProperty("ccl.dumpClass", "false"));
|
||||
private static final String RenderStateClass = "codechicken/lib/render/CCRenderState";
|
||||
@@ -90,66 +91,63 @@ public class RedirectorTransformer implements IClassTransformer {
|
||||
cr.accept(cn, 0);
|
||||
boolean changed = false;
|
||||
|
||||
// spotless:off
|
||||
for (MethodNode mn : cn.methods) {
|
||||
for (AbstractInsnNode node : mn.instructions.toArray()) {
|
||||
if (node instanceof FieldInsnNode fNode) {
|
||||
if (node.getOpcode() == Opcodes.GETSTATIC && redirectedFields.contains(fNode.name)
|
||||
&& fNode.owner.equals(RenderStateClass)) {
|
||||
mn.instructions.insertBefore(
|
||||
fNode,
|
||||
new MethodInsnNode(
|
||||
Opcodes.INVOKESTATIC,
|
||||
fNode.owner,
|
||||
"instance",
|
||||
"()Lcodechicken/lib/render/CCRenderState;"));
|
||||
fNode.setOpcode(Opcodes.GETFIELD);
|
||||
if (node.getOpcode() == GETSTATIC && RenderStateClass.equals(fNode.owner) && redirectedFields.contains(fNode.name)) {
|
||||
mn.instructions.insertBefore(fNode,
|
||||
new MethodInsnNode(
|
||||
INVOKESTATIC,
|
||||
fNode.owner,
|
||||
"instance",
|
||||
"()Lcodechicken/lib/render/CCRenderState;",
|
||||
false));
|
||||
fNode.setOpcode(GETFIELD);
|
||||
changed = true;
|
||||
} else if (node.getOpcode() == Opcodes.PUTSTATIC
|
||||
&& (redirectedFields.contains(fNode.name) && fNode.owner.equals(RenderStateClass))) {
|
||||
InsnList beforePut = new InsnList();
|
||||
beforePut.add(
|
||||
new MethodInsnNode(
|
||||
Opcodes.INVOKESTATIC,
|
||||
fNode.owner,
|
||||
"instance",
|
||||
"()Lcodechicken/lib/render/CCRenderState;"));
|
||||
beforePut.add(new InsnNode(Opcodes.SWAP));
|
||||
mn.instructions.insertBefore(fNode, beforePut);
|
||||
fNode.setOpcode(Opcodes.PUTFIELD);
|
||||
changed = true;
|
||||
|
||||
}
|
||||
} else if (node.getOpcode() == PUTSTATIC && RenderStateClass.equals(fNode.owner) && redirectedFields.contains(fNode.name)) {
|
||||
InsnList list = new InsnList();
|
||||
list.add(new MethodInsnNode(
|
||||
INVOKESTATIC,
|
||||
fNode.owner,
|
||||
"instance",
|
||||
"()Lcodechicken/lib/render/CCRenderState;",
|
||||
false));
|
||||
list.add(new InsnNode(SWAP));
|
||||
mn.instructions.insertBefore(fNode, list);
|
||||
fNode.setOpcode(PUTFIELD);
|
||||
changed = true;
|
||||
}
|
||||
} else if (node instanceof MethodInsnNode mNode) {
|
||||
if (node.getOpcode() == Opcodes.INVOKESTATIC && redirectedSimpleMethods.contains(mNode.name)
|
||||
&& mNode.owner.equals(RenderStateClass)) {
|
||||
mn.instructions.insertBefore(
|
||||
mNode,
|
||||
new MethodInsnNode(
|
||||
Opcodes.INVOKESTATIC,
|
||||
mNode.owner,
|
||||
"instance",
|
||||
"()Lcodechicken/lib/render/CCRenderState;"));
|
||||
mNode.setOpcode(Opcodes.INVOKEVIRTUAL);
|
||||
if (node.getOpcode() == INVOKESTATIC && RenderStateClass.equals(mNode.owner) && redirectedSimpleMethods.contains(mNode.name)) {
|
||||
mn.instructions.insertBefore(mNode,
|
||||
new MethodInsnNode(
|
||||
INVOKESTATIC,
|
||||
mNode.owner,
|
||||
"instance",
|
||||
"()Lcodechicken/lib/render/CCRenderState;",
|
||||
false));
|
||||
mNode.setOpcode(INVOKEVIRTUAL);
|
||||
mNode.name = mNode.name + "Instance";
|
||||
changed = true;
|
||||
} else if (node.getOpcode() == Opcodes.INVOKEVIRTUAL && mNode.owner.equals(RenderStateClass)
|
||||
&& (redirectedSimpleMethods.contains(mNode.name)
|
||||
|| redirectedMethods.contains(mNode.name))) {
|
||||
// Handle mods that updated to previously new API
|
||||
mNode.name = mNode.name + "Instance";
|
||||
changed = true;
|
||||
}
|
||||
} else if (node.getOpcode() == INVOKEVIRTUAL && RenderStateClass.equals(mNode.owner)
|
||||
&& (redirectedSimpleMethods.contains(mNode.name) || redirectedMethods.contains(mNode.name))) {
|
||||
// Handle mods that updated to previously new API
|
||||
mNode.name = mNode.name + "Instance";
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// spotless:on
|
||||
|
||||
if (changed) {
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
|
||||
cn.accept(cw);
|
||||
final byte[] bytes = cw.toByteArray();
|
||||
if (DUMP_CLASSES) {
|
||||
saveTransformedClass(bytes, transformedName);
|
||||
saveTransformedClass(basicClass, transformedName + "_original");
|
||||
saveTransformedClass(basicClass, transformedName + "_PRE");
|
||||
saveTransformedClass(bytes, transformedName + "_POST");
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
@@ -158,13 +156,9 @@ public class RedirectorTransformer implements IClassTransformer {
|
||||
|
||||
private File outputDir = null;
|
||||
|
||||
private void saveTransformedClass(final byte[] data, final String transformedName) {
|
||||
if (!DUMP_CLASSES) {
|
||||
return;
|
||||
}
|
||||
|
||||
private void saveTransformedClass(final byte[] data, final String classname) {
|
||||
if (outputDir == null) {
|
||||
outputDir = new File(Launch.minecraftHome, "ASM_REDIRECTOR");
|
||||
outputDir = new File(Launch.minecraftHome, "ASM_CCL" + File.separatorChar + "REDIRECTOR");
|
||||
try {
|
||||
FileUtils.deleteDirectory(outputDir);
|
||||
} catch (IOException ignored) {}
|
||||
@@ -173,40 +167,34 @@ public class RedirectorTransformer implements IClassTransformer {
|
||||
outputDir.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
final String fileName = transformedName.replace('.', File.separatorChar);
|
||||
final String fileName = classname.replace('.', File.separatorChar);
|
||||
final File classFile = new File(outputDir, fileName + ".class");
|
||||
final File bytecodeFile = new File(outputDir, fileName + "_BYTE.txt");
|
||||
final File asmifiedFile = new File(outputDir, fileName + "_ASM.txt");
|
||||
final File outDir = classFile.getParentFile();
|
||||
if (!outDir.exists()) {
|
||||
// noinspection ResultOfMethodCallIgnored
|
||||
outDir.mkdirs();
|
||||
}
|
||||
if (classFile.exists()) {
|
||||
// noinspection ResultOfMethodCallIgnored
|
||||
classFile.delete();
|
||||
}
|
||||
try (final OutputStream output = Files.newOutputStream(classFile.toPath())) {
|
||||
output.write(data);
|
||||
CodeChickenCorePlugin.logger.info("Saved class (byte[]) to " + classFile.toPath());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
CodeChickenCorePlugin.logger.error("Could not save class (byte[]) " + classname);
|
||||
}
|
||||
if (bytecodeFile.exists()) {
|
||||
// noinspection ResultOfMethodCallIgnored
|
||||
bytecodeFile.delete();
|
||||
}
|
||||
try (final OutputStream output = Files.newOutputStream(bytecodeFile.toPath())) {
|
||||
final ClassReader classReader = new ClassReader(data);
|
||||
classReader.accept(new TraceClassVisitor(null, new Textifier(), new PrintWriter(output)), 0);
|
||||
CodeChickenCorePlugin.logger.info("Saved class (bytecode) to " + bytecodeFile.toPath());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (asmifiedFile.exists()) {
|
||||
asmifiedFile.delete();
|
||||
}
|
||||
try (final OutputStream output = Files.newOutputStream(asmifiedFile.toPath())) {
|
||||
final ClassReader classReader = new ClassReader(data);
|
||||
classReader.accept(new TraceClassVisitor(null, new ASMifier(), new PrintWriter(output)), 0);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
CodeChickenCorePlugin.logger.error("Could not save class (bytecode) " + classname);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,6 +162,11 @@ public class GuiDraw {
|
||||
}
|
||||
|
||||
public static void drawMultilineTip(FontRenderer font, int x, int y, List<String> list) {
|
||||
drawMultilineTip(font, x, y, list, 0xf0100010, 0xf0100010, 0x505000ff, 0x5028007F);
|
||||
}
|
||||
|
||||
public static void drawMultilineTip(FontRenderer font, int x, int y, List<String> list, int bgStart, int bgEnd,
|
||||
int borderStart, int borderEnd) {
|
||||
if (list.isEmpty()) return;
|
||||
|
||||
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
|
||||
@@ -189,7 +194,7 @@ public class GuiDraw {
|
||||
y = (int) MathHelper.clip(y, 8, displaySize().height - 8 - h);
|
||||
|
||||
gui.incZLevel(300);
|
||||
drawTooltipBox(x - 4, y - 4, w + 7, h + 7);
|
||||
drawTooltipBox(x - 4, y - 4, w + 7, h + 7, bgStart, bgEnd, borderStart, borderEnd);
|
||||
for (String s : list) {
|
||||
ITooltipLineHandler line = getTipLine(s);
|
||||
if (line != null) {
|
||||
@@ -210,18 +215,23 @@ public class GuiDraw {
|
||||
}
|
||||
|
||||
public static void drawTooltipBox(int x, int y, int w, int h) {
|
||||
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, y + 1, 1, h - 1, bg, bg);
|
||||
drawGradientRect(x + w, y + 1, 1, h - 1, bg, bg);
|
||||
int grad1 = 0x505000ff;
|
||||
int grad2 = 0x5028007F;
|
||||
drawGradientRect(x + 1, y + 2, 1, h - 3, grad1, grad2);
|
||||
drawGradientRect(x + w - 1, y + 2, 1, h - 3, grad1, grad2);
|
||||
drawTooltipBox(x, y, w, h, 0xf0100010, 0xf0100010, 0x505000ff, 0x5028007F);
|
||||
}
|
||||
|
||||
drawGradientRect(x + 1, y + 1, w - 1, 1, grad1, grad1);
|
||||
drawGradientRect(x + 1, y + h - 1, w - 1, 1, grad2, grad2);
|
||||
public static void drawTooltipBox(int x, int y, int w, int h, int bgStart, int bgEnd, int borderStart,
|
||||
int borderEnd) {
|
||||
// spotless:off
|
||||
// draw background
|
||||
drawGradientRect(x + 1, y, w - 1, 1, bgStart, bgStart); // top
|
||||
drawGradientRect(x + 1, y + h, w - 1, 1, bgEnd, bgEnd); // bottom
|
||||
drawGradientRect(x + 1, y + 1, w - 1, h - 1, bgStart, bgEnd); // center
|
||||
drawGradientRect(x, y + 1, 1, h - 1, bgStart, bgEnd); // left
|
||||
drawGradientRect(x + w, y + 1, 1, h - 1, bgStart, bgEnd); // right
|
||||
// draw inner border
|
||||
drawGradientRect(x + 1, y + 2, 1, h - 3, borderStart, borderEnd); // left
|
||||
drawGradientRect(x + w - 1, y + 2, 1, h - 3, borderStart, borderEnd); // right
|
||||
drawGradientRect(x + 1, y + 1, w - 1, 1, borderStart, borderStart); // top
|
||||
drawGradientRect(x + 1, y + h - 1, w - 1, 1, borderEnd, borderEnd); // bottom
|
||||
// spotless:on
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import static codechicken.lib.math.MathHelper.phi;
|
||||
import codechicken.lib.vec.Matrix4;
|
||||
import codechicken.lib.vec.Quat;
|
||||
import codechicken.lib.vec.Rotation;
|
||||
import codechicken.lib.vec.Scale;
|
||||
import codechicken.lib.vec.Vector3;
|
||||
|
||||
public class CCModelLibrary {
|
||||
@@ -82,7 +81,12 @@ public class CCModelLibrary {
|
||||
i++;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Matrix4 getRenderMatrix(Vector3 position, Rotation rotation, double scale) {
|
||||
return new Matrix4().translate(position).apply(new Scale(scale)).apply(rotation);
|
||||
return new Matrix4().translate(position).scale(scale).apply(rotation);
|
||||
}
|
||||
|
||||
public static Matrix4 getRenderMatrix(double posX, double posY, double posZ, Rotation rotation, double scale) {
|
||||
return new Matrix4().translate(posX, posY, posZ).scale(scale).apply(rotation);
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraft.util.MathHelper;
|
||||
import net.minecraftforge.client.IItemRenderer;
|
||||
import net.minecraftforge.client.MinecraftForgeClient;
|
||||
import net.minecraftforge.fluids.Fluid;
|
||||
@@ -26,87 +27,130 @@ import codechicken.lib.vec.Vector3;
|
||||
|
||||
public class RenderUtils {
|
||||
|
||||
static Vector3[] vectors = new Vector3[8];
|
||||
static RenderItem uniformRenderItem = new RenderItem() {
|
||||
|
||||
public boolean shouldBob() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
static RenderItem uniformRenderItem;
|
||||
static EntityItem entityItem;
|
||||
|
||||
static {
|
||||
for (int i = 0; i < vectors.length; i++) vectors[i] = new Vector3();
|
||||
uniformRenderItem = new RenderItem() {
|
||||
|
||||
public boolean shouldBob() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
uniformRenderItem.setRenderManager(RenderManager.instance);
|
||||
|
||||
entityItem = new EntityItem(null);
|
||||
entityItem.hoverStart = 0;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void renderFluidQuad(Vector3 point1, Vector3 point2, Vector3 point3, Vector3 point4, IIcon icon,
|
||||
double res) {
|
||||
// spotless:off
|
||||
renderFluidQuad(
|
||||
point2,
|
||||
vectors[0].set(point4).subtract(point1),
|
||||
vectors[1].set(point1).subtract(point2),
|
||||
icon,
|
||||
res);
|
||||
point2.x, point2.y, point2.z,
|
||||
point4.x - point1.x, point4.y - point1.y, point4.z - point1.z,
|
||||
point1.x - point2.x, point1.y - point2.y, point1.z - point2.z,
|
||||
icon, res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a tessellated quadrilateral bottom to top, left to right
|
||||
*
|
||||
*
|
||||
* @param base The bottom left corner of the quad
|
||||
* @param wide The bottom of the quad
|
||||
* @param high The left side of the quad
|
||||
* @param res Units per icon
|
||||
*/
|
||||
@Deprecated
|
||||
public static void renderFluidQuad(Vector3 base, Vector3 wide, Vector3 high, IIcon icon, double res) {
|
||||
Tessellator t = Tessellator.instance;
|
||||
renderFluidQuad(
|
||||
base.x, base.y, base.z,
|
||||
wide.x, wide.y, wide.z,
|
||||
wide.x, wide.y, wide.z,
|
||||
icon, res);
|
||||
}
|
||||
|
||||
double u1 = icon.getMinU();
|
||||
/**
|
||||
* Draws a tessellated quadrilateral bottom to top, left to right
|
||||
* <p>
|
||||
* base : The bottom left corner of the quad
|
||||
* <p>
|
||||
* wide : The bottom of the quad
|
||||
* <p>
|
||||
* high : The left side of the quad
|
||||
* <p>
|
||||
* res : Units per icon
|
||||
*/
|
||||
public static void renderFluidQuad(
|
||||
double baseX, double baseY, double baseZ,
|
||||
double wideX, double wideY, double wideZ,
|
||||
double highX, double highY, double highZ,
|
||||
IIcon icon, double res) {
|
||||
|
||||
Tessellator tessellator = Tessellator.instance;
|
||||
|
||||
double u = icon.getMinU();
|
||||
double du = icon.getMaxU() - icon.getMinU();
|
||||
double v2 = icon.getMaxV();
|
||||
double v = icon.getMinV();
|
||||
double dv = icon.getMaxV() - icon.getMinV();
|
||||
|
||||
double wlen = wide.mag();
|
||||
double hlen = high.mag();
|
||||
double wideLen = Math.sqrt(wideX * wideX + wideY * wideY + wideZ * wideZ);
|
||||
double highLen = Math.sqrt(highX * highX + highY * highY + highZ * highZ);
|
||||
|
||||
double x = 0;
|
||||
while (x < wlen) {
|
||||
double rx = wlen - x;
|
||||
while (x < wideLen) {
|
||||
double rx = wideLen - x;
|
||||
if (rx > res) rx = res;
|
||||
|
||||
double y = 0;
|
||||
while (y < hlen) {
|
||||
double ry = hlen - y;
|
||||
while (y < highLen) {
|
||||
double ry = highLen - 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);
|
||||
final double mult1 = x / wideLen;
|
||||
double dx1X = wideX * mult1;
|
||||
double dx1Y = wideY * mult1;
|
||||
double dx1Z = wideZ * mult1;
|
||||
|
||||
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);
|
||||
final double mult2 = (x + rx) / wideLen;
|
||||
double dx2X = wideX * mult2;
|
||||
double dx2Y = wideY * mult2;
|
||||
double dx2Z = wideZ * mult2;
|
||||
|
||||
final double mult3 = y / highLen;
|
||||
double dy1X = highX * mult3;
|
||||
double dy1Y = highY * mult3;
|
||||
double dy1Z = highZ * mult3;
|
||||
|
||||
final double mult4 = (y + ry) / highLen;
|
||||
double dy2X = highX * mult4;
|
||||
double dy2Y = highY * mult4;
|
||||
double dy2Z = highZ * mult4;
|
||||
|
||||
tessellator.addVertexWithUV(
|
||||
baseX + dx1X + dy2X,
|
||||
baseY + dx1Y + dy2Y,
|
||||
baseZ + dx1Z + dy2Z,
|
||||
u,
|
||||
v + ry / res * dv);
|
||||
tessellator.addVertexWithUV(
|
||||
baseX + dx1X + dy1X,
|
||||
baseY + dx1Y + dy1Y,
|
||||
baseZ + dx1Z + dy1Z,
|
||||
u,
|
||||
v);
|
||||
tessellator.addVertexWithUV(
|
||||
baseX + dx2X + dy1X,
|
||||
baseY + dx2Y + dy1Y,
|
||||
baseZ + dx2Z + dy1Z,
|
||||
u + rx / res * du,
|
||||
v);
|
||||
tessellator.addVertexWithUV(
|
||||
baseX + dx2X + dy2X,
|
||||
baseY + dx2Y + dy2Y,
|
||||
baseZ + dx2Z + dy2Z,
|
||||
u + rx / res * du,
|
||||
v + ry / res * dv);
|
||||
|
||||
y += ry;
|
||||
}
|
||||
@@ -115,132 +159,130 @@ public class RenderUtils {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
public static void translateToWorldCoords(Entity entity, float partialTicks) {
|
||||
double interpPosX = entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * partialTicks;
|
||||
double interpPosY = entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * partialTicks;
|
||||
double interpPosZ = entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * partialTicks;
|
||||
GL11.glTranslated(-interpPosX, -interpPosY, -interpPosZ);
|
||||
}
|
||||
|
||||
public static void drawCuboidOutline(Cuboid6 c) {
|
||||
Tessellator var2 = Tessellator.instance;
|
||||
var2.startDrawing(3);
|
||||
var2.addVertex(c.min.x, c.min.y, c.min.z);
|
||||
var2.addVertex(c.max.x, c.min.y, c.min.z);
|
||||
var2.addVertex(c.max.x, c.min.y, c.max.z);
|
||||
var2.addVertex(c.min.x, c.min.y, c.max.z);
|
||||
var2.addVertex(c.min.x, c.min.y, c.min.z);
|
||||
var2.draw();
|
||||
var2.startDrawing(3);
|
||||
var2.addVertex(c.min.x, c.max.y, c.min.z);
|
||||
var2.addVertex(c.max.x, c.max.y, c.min.z);
|
||||
var2.addVertex(c.max.x, c.max.y, c.max.z);
|
||||
var2.addVertex(c.min.x, c.max.y, c.max.z);
|
||||
var2.addVertex(c.min.x, c.max.y, c.min.z);
|
||||
var2.draw();
|
||||
var2.startDrawing(1);
|
||||
var2.addVertex(c.min.x, c.min.y, c.min.z);
|
||||
var2.addVertex(c.min.x, c.max.y, c.min.z);
|
||||
var2.addVertex(c.max.x, c.min.y, c.min.z);
|
||||
var2.addVertex(c.max.x, c.max.y, c.min.z);
|
||||
var2.addVertex(c.max.x, c.min.y, c.max.z);
|
||||
var2.addVertex(c.max.x, c.max.y, c.max.z);
|
||||
var2.addVertex(c.min.x, c.min.y, c.max.z);
|
||||
var2.addVertex(c.min.x, c.max.y, c.max.z);
|
||||
var2.draw();
|
||||
Tessellator tess = Tessellator.instance;
|
||||
tess.startDrawing(3);
|
||||
tess.addVertex(c.min.x, c.min.y, c.min.z);
|
||||
tess.addVertex(c.max.x, c.min.y, c.min.z);
|
||||
tess.addVertex(c.max.x, c.min.y, c.max.z);
|
||||
tess.addVertex(c.min.x, c.min.y, c.max.z);
|
||||
tess.addVertex(c.min.x, c.min.y, c.min.z);
|
||||
tess.draw();
|
||||
tess.startDrawing(3);
|
||||
tess.addVertex(c.min.x, c.max.y, c.min.z);
|
||||
tess.addVertex(c.max.x, c.max.y, c.min.z);
|
||||
tess.addVertex(c.max.x, c.max.y, c.max.z);
|
||||
tess.addVertex(c.min.x, c.max.y, c.max.z);
|
||||
tess.addVertex(c.min.x, c.max.y, c.min.z);
|
||||
tess.draw();
|
||||
tess.startDrawing(1);
|
||||
tess.addVertex(c.min.x, c.min.y, c.min.z);
|
||||
tess.addVertex(c.min.x, c.max.y, c.min.z);
|
||||
tess.addVertex(c.max.x, c.min.y, c.min.z);
|
||||
tess.addVertex(c.max.x, c.max.y, c.min.z);
|
||||
tess.addVertex(c.max.x, c.min.y, c.max.z);
|
||||
tess.addVertex(c.max.x, c.max.y, c.max.z);
|
||||
tess.addVertex(c.min.x, c.min.y, c.max.z);
|
||||
tess.addVertex(c.min.x, c.max.y, c.max.z);
|
||||
tess.draw();
|
||||
}
|
||||
|
||||
public static void renderFluidCuboid(CCRenderState state, 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.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.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.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),
|
||||
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.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);
|
||||
renderFluidCuboid(bound, tex, res);
|
||||
}
|
||||
|
||||
public static void renderFluidCuboid(Cuboid6 bound, IIcon tex, double res) {
|
||||
renderFluidCuboid(CCRenderState.instance(), bound, tex, res);
|
||||
final double minX = bound.min.x;
|
||||
final double minY = bound.min.y;
|
||||
final double minZ = bound.min.z;
|
||||
final double maxX = bound.max.x;
|
||||
final double maxY = bound.max.y;
|
||||
final double maxZ = bound.max.z;
|
||||
renderFluidQuad( // bottom
|
||||
minX, minY, minZ,
|
||||
maxX - minX, 0, 0,
|
||||
0, 0, maxZ - minZ,
|
||||
tex, res);
|
||||
renderFluidQuad( // top
|
||||
minX, maxY, minZ,
|
||||
0, 0, maxZ - minZ,
|
||||
maxX - minX, 0, 0,
|
||||
tex, res);
|
||||
renderFluidQuad( // -x
|
||||
minX, maxY, minZ,
|
||||
0, minY - maxY, 0,
|
||||
0, 0, maxZ - minZ,
|
||||
tex, res);
|
||||
renderFluidQuad( // +x
|
||||
maxX, maxY, maxZ,
|
||||
0, minY - maxY, 0,
|
||||
0, 0, minZ - maxZ,
|
||||
tex, res);
|
||||
renderFluidQuad( // -z
|
||||
maxX, maxY, minZ,
|
||||
0, minY - maxY, 0,
|
||||
minX - maxX, 0, 0,
|
||||
tex, res);
|
||||
renderFluidQuad( // +z
|
||||
minX, maxY, maxZ,
|
||||
0, minY - maxY, 0,
|
||||
maxX - minX, 0, 0,
|
||||
tex, res);
|
||||
}
|
||||
// spotless:on
|
||||
|
||||
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;
|
||||
final double minX = x - 0.009;
|
||||
final double maxX = x + 1.009;
|
||||
final double minY = y - 0.009;
|
||||
final double maxY = y + 1.009;
|
||||
final double minZ = z - 0.009;
|
||||
final double maxZ = z + 1.009;
|
||||
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);
|
||||
tessellator.addVertexWithUV(minX, minY, minZ, tx1, ty1);
|
||||
tessellator.addVertexWithUV(maxX, minY, minZ, tx2, ty1);
|
||||
tessellator.addVertexWithUV(maxX, minY, maxZ, tx2, ty2);
|
||||
tessellator.addVertexWithUV(minX, minY, maxZ, tx1, ty2);
|
||||
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);
|
||||
tessellator.addVertexWithUV(maxX, maxY, minZ, tx2, ty1);
|
||||
tessellator.addVertexWithUV(minX, maxY, minZ, tx1, ty1);
|
||||
tessellator.addVertexWithUV(minX, maxY, maxZ, tx1, ty2);
|
||||
tessellator.addVertexWithUV(maxX, maxY, maxZ, tx2, ty2);
|
||||
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);
|
||||
tessellator.addVertexWithUV(minX, maxY, minZ, tx2, ty1);
|
||||
tessellator.addVertexWithUV(maxX, maxY, minZ, tx1, ty1);
|
||||
tessellator.addVertexWithUV(maxX, minY, minZ, tx1, ty2);
|
||||
tessellator.addVertexWithUV(minX, minY, minZ, tx2, ty2);
|
||||
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);
|
||||
tessellator.addVertexWithUV(maxX, maxY, maxZ, tx2, ty1);
|
||||
tessellator.addVertexWithUV(minX, maxY, maxZ, tx1, ty1);
|
||||
tessellator.addVertexWithUV(minX, minY, maxZ, tx1, ty2);
|
||||
tessellator.addVertexWithUV(maxX, minY, maxZ, tx2, ty2);
|
||||
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);
|
||||
tessellator.addVertexWithUV(minX, maxY, maxZ, tx2, ty1);
|
||||
tessellator.addVertexWithUV(minX, maxY, minZ, tx1, ty1);
|
||||
tessellator.addVertexWithUV(minX, minY, minZ, tx1, ty2);
|
||||
tessellator.addVertexWithUV(minX, minY, maxZ, tx2, ty2);
|
||||
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);
|
||||
tessellator.addVertexWithUV(maxX, maxY, minZ, tx2, ty1);
|
||||
tessellator.addVertexWithUV(maxX, maxY, maxZ, tx1, ty1);
|
||||
tessellator.addVertexWithUV(maxX, minY, maxZ, tx1, ty2);
|
||||
tessellator.addVertexWithUV(maxX, minY, minZ, tx2, ty2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -276,66 +318,76 @@ public class RenderUtils {
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
}
|
||||
|
||||
public static double fluidDensityToAlpha(double density) {
|
||||
return Math.pow(density, 0.4);
|
||||
public static double fluidDensityToAlpha(double d) {
|
||||
return Math.pow(d, 0.4);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* to fillRate/bound.height. If the fluid is a gas, it will render the full box with an alpha equal to fillRate.
|
||||
* Warning, bound will be mutated if the fluid is a liquid
|
||||
*
|
||||
* @param stack The fluid to render.
|
||||
* @param bound The box within which the fluid is contained.
|
||||
* @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.
|
||||
*
|
||||
* @param stack The fluid to render.
|
||||
* @param bound The bounding box within which the fluid is contained.
|
||||
* @param fillRate The volume of fluid / the capacity of the tank. This is a double between 0 and 1.
|
||||
* @param res The resolution to render at.
|
||||
*/
|
||||
public static void renderFluidCuboid(CCRenderState state, FluidStack stack, Cuboid6 bound, double density,
|
||||
public static void renderFluidCuboid(CCRenderState state, FluidStack stack, Cuboid6 bound, double fillRate,
|
||||
double res) {
|
||||
if (!shouldRenderFluid(stack)) return;
|
||||
|
||||
fillRate = MathHelper.clamp_double(fillRate, 0d, 1d);
|
||||
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(fillRate) * 255);
|
||||
} else {
|
||||
bound.max.y = bound.min.y + (bound.max.y - bound.min.y) * fillRate;
|
||||
}
|
||||
|
||||
IIcon tex = prepareFluidRender(state, stack, alpha);
|
||||
state.startDrawingInstance();
|
||||
renderFluidCuboid(state, bound, tex, res);
|
||||
renderFluidCuboid(bound, tex, res);
|
||||
state.drawInstance();
|
||||
postFluidRender();
|
||||
}
|
||||
|
||||
public static void renderFluidCuboid(FluidStack stack, Cuboid6 bound, double density, double res) {
|
||||
renderFluidCuboid(CCRenderState.instance(), stack, bound, density, res);
|
||||
/**
|
||||
* Renders a fluid within a bounding box. If the fluid is a liquid it will render as a normal tank with height equal
|
||||
* to fillRate/bound.height. If the fluid is a gas, it will render the full box with an alpha equal to fillRate.
|
||||
* Warning, bound will be mutated if the fluid is a liquid
|
||||
*
|
||||
* @param stack The fluid to render.
|
||||
* @param bound The bounding box within which the fluid is contained.
|
||||
* @param fillRate The volume of fluid / the capacity of the tank. This is a double between 0 and 1.
|
||||
* @param res The resolution to render at.
|
||||
*/
|
||||
public static void renderFluidCuboid(FluidStack stack, Cuboid6 bound, double fillRate, double res) {
|
||||
renderFluidCuboid(CCRenderState.instance(), stack, bound, fillRate, res);
|
||||
}
|
||||
|
||||
public static void renderFluidGauge(CCRenderState state, FluidStack stack, Rectangle4i rect, double density,
|
||||
public static void renderFluidGauge(CCRenderState state, FluidStack stack, Rectangle4i rect, double fillRate,
|
||||
double res) {
|
||||
if (!shouldRenderFluid(stack)) return;
|
||||
|
||||
fillRate = MathHelper.clamp_double(fillRate, 0d, 1d);
|
||||
int alpha = 255;
|
||||
if (stack.getFluid().isGaseous()) alpha = (int) (fluidDensityToAlpha(density) * 255);
|
||||
else {
|
||||
int height = (int) (rect.h * density);
|
||||
if (stack.getFluid().isGaseous()) {
|
||||
alpha = (int) (fluidDensityToAlpha(fillRate) * 255);
|
||||
} else {
|
||||
int height = (int) (rect.h * fillRate);
|
||||
rect.y += rect.h - height;
|
||||
rect.h = height;
|
||||
}
|
||||
|
||||
IIcon tex = prepareFluidRender(state, stack, alpha);
|
||||
state.startDrawingInstance();
|
||||
renderFluidQuad(
|
||||
new Vector3(rect.x, rect.y + rect.h, 0),
|
||||
new Vector3(rect.w, 0, 0),
|
||||
new Vector3(0, -rect.h, 0),
|
||||
tex,
|
||||
res);
|
||||
renderFluidQuad(rect.x, rect.y + rect.h, 0, rect.w, 0, 0, 0, -rect.h, 0, tex, res);
|
||||
state.drawInstance();
|
||||
postFluidRender();
|
||||
}
|
||||
|
||||
public static void renderFluidGauge(FluidStack stack, Rectangle4i rect, double density, double res) {
|
||||
renderFluidGauge(CCRenderState.instance(), stack, rect, density, res);
|
||||
public static void renderFluidGauge(FluidStack stack, Rectangle4i rect, double fillRate, double res) {
|
||||
renderFluidGauge(CCRenderState.instance(), stack, rect, fillRate, res);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -347,7 +399,7 @@ 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) {
|
||||
|
||||
@@ -19,7 +19,10 @@ public class Matrix4 extends Transformation implements Copyable<Matrix4> {
|
||||
.asDoubleBuffer();
|
||||
|
||||
// m<row><column>
|
||||
public double m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33;
|
||||
public double m00, m01, m02, m03;
|
||||
public double m10, m11, m12, m13;
|
||||
public double m20, m21, m22, m23;
|
||||
public double m30, m31, m32, m33;
|
||||
|
||||
public Matrix4() {
|
||||
m00 = m11 = m22 = m33 = 1;
|
||||
@@ -65,6 +68,15 @@ public class Matrix4 extends Transformation implements Copyable<Matrix4> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Matrix4 translate(double x, double y, double z) {
|
||||
m03 += m00 * x + m01 * y + m02 * z;
|
||||
m13 += m10 * x + m11 * y + m12 * z;
|
||||
m23 += m20 * x + m21 * y + m22 * z;
|
||||
m33 += m30 * x + m31 * y + m32 * z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Matrix4 scale(Vector3 vec) {
|
||||
m00 *= vec.x;
|
||||
m10 *= vec.x;
|
||||
@@ -82,6 +94,22 @@ public class Matrix4 extends Transformation implements Copyable<Matrix4> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Matrix4 scale(double scale) {
|
||||
m00 *= scale;
|
||||
m10 *= scale;
|
||||
m20 *= scale;
|
||||
m30 *= scale;
|
||||
m01 *= scale;
|
||||
m11 *= scale;
|
||||
m21 *= scale;
|
||||
m31 *= scale;
|
||||
m02 *= scale;
|
||||
m12 *= scale;
|
||||
m22 *= scale;
|
||||
m32 *= scale;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Matrix4 rotate(double angle, Vector3 axis) {
|
||||
double c = Math.cos(angle);
|
||||
double s = Math.sin(angle);
|
||||
|
||||
@@ -29,10 +29,10 @@ public class Vector3 implements Copyable<Vector3> {
|
||||
|
||||
public Vector3() {}
|
||||
|
||||
public Vector3(double d, double d1, double d2) {
|
||||
x = d;
|
||||
y = d1;
|
||||
z = d2;
|
||||
public Vector3(double x, double y, double z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public Vector3(Vector3 vec) {
|
||||
@@ -398,7 +398,7 @@ public class Vector3 implements Copyable<Vector3> {
|
||||
|
||||
/**
|
||||
* Equals method with tolerance
|
||||
*
|
||||
*
|
||||
* @return true if this is equal to v within +-1E-5
|
||||
*/
|
||||
public boolean equalsT(Vector3 v) {
|
||||
|
||||
Reference in new issue
Block a user