Added tilted panels. Currently they can only be created by editing the panels NBT data

This commit is contained in:
malte0811 2017-06-27 16:15:45 +02:00
parent cbac269e04
commit 15674f7ae3
7 changed files with 134 additions and 61 deletions

View file

@ -67,7 +67,7 @@ repositories {
}
dependencies {
deobfCompile "net.industrial-craft:industrialcraft-2:2.7.+:api"
compile "net.industrial-craft:industrialcraft-2:2.7.+"
deobfCompile "blusunrize:ImmersiveEngineering:0.11-+:deobf"
}

View file

@ -28,7 +28,6 @@ import malte0811.industrialWires.blocks.TileEntityIWBase;
import malte0811.industrialWires.controlpanel.*;
import malte0811.industrialWires.network.MessagePanelInteract;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
@ -227,25 +226,30 @@ public class TileEntityPanel extends TileEntityIWBase implements IDirectionalTil
@Nullable
public Pair<PanelComponent, RayTraceResult> getSelectedComponent(EntityPlayer player, Vec3d hit, boolean hitAbs) {
//TODO prvent clicking through the back of the panel
Matrix4 mat = components.getPanelTopTransform();
mat.invert();
PanelComponent retPc = null;
RayTraceResult retRay = null;
Vec3d playerPos = Minecraft.getMinecraft().player.getPositionVector().addVector(-pos.getX(), player.getEyeHeight() - pos.getY(), -pos.getZ());
Vec3d playerPosRelative = player.getPositionVector().addVector(-pos.getX(), player.getEyeHeight() - pos.getY(), -pos.getZ());
Vec3d playerPosTransformed = mat.apply(playerPosRelative);
for (PanelComponent pc : components) {
AxisAlignedBB box = pc.getBlockRelativeAABB();
if (box.maxY > box.minY) {
box = apply(mat, box.grow(.002));
box = box.grow(.002);
Vec3d hitVec = hitAbs ? hit.addVector(-pos.getX(), -pos.getY(), -pos.getZ()) : hit;
hitVec = hitVec.scale(2).subtract(playerPos);
RayTraceResult ray = box.calculateIntercept(playerPos, hitVec);
hitVec = hitVec.subtract(playerPosRelative.subtract(hitVec).scale(10));
RayTraceResult ray = box.calculateIntercept(playerPosTransformed, mat.apply(hitVec));
if (ray != null) {
if (retPc == null) {
ray.hitVec = ray.hitVec.subtract(pc.getX(), 0, pc.getY());
retPc = pc;
retRay = ray;
} else {
double oldDist = retRay.hitVec.subtract(playerPos).lengthSquared();
double newDist = ray.hitVec.subtract(playerPos).lengthSquared();
double oldDist = retRay.hitVec.subtract(playerPosRelative).lengthSquared();
double newDist = ray.hitVec.subtract(playerPosRelative).lengthSquared();
if (newDist < oldDist) {
ray.hitVec = ray.hitVec.subtract(pc.getX(), 0, pc.getY());
retPc = pc;
retRay = ray;
}
@ -261,12 +265,7 @@ public class TileEntityPanel extends TileEntityIWBase implements IDirectionalTil
if (world.isRemote) {
Pair<PanelComponent, RayTraceResult> pc = getSelectedComponent(player, new Vec3d(hitX, hitY, hitZ), false);
if (pc != null) {
Matrix4 inv = components.getPanelTopTransform();
inv.translate(pc.getLeft().getX(), 0, pc.getLeft().getY());
inv.invert();
Vec3d hitVec = inv.apply(pc.getRight().hitVec);
hitVec.subtract(pc.getLeft().getX(), 0, -pc.getLeft().getY());
IndustrialWires.packetHandler.sendToServer(new MessagePanelInteract(this, components.indexOf(pc.getKey()), hitVec));
IndustrialWires.packetHandler.sendToServer(new MessagePanelInteract(this, components.indexOf(pc.getKey()), pc.getRight().hitVec));
}
}
return true;

View file

@ -23,15 +23,19 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.EnumFacing;
import org.lwjgl.util.vector.Vector3f;
import javax.annotation.Nullable;
import java.util.Arrays;
import static org.lwjgl.util.vector.Vector3f.cross;
import static org.lwjgl.util.vector.Vector3f.sub;
public class RawQuad {
public final Vector3f[] vertices = new Vector3f[4];
public final EnumFacing facing;
public final TextureAtlasSprite tex;
public final float[] colorA;
public final Vector3f normal;
public final float[] uvs;
public final float[][] uvs;
public int light;
public RawQuad(Vector3f v0, Vector3f v1, Vector3f v2, Vector3f v3,
@ -43,6 +47,15 @@ public class RawQuad {
public RawQuad(Vector3f v0, Vector3f v1, Vector3f v2, Vector3f v3,
EnumFacing facing, TextureAtlasSprite tex, float[] colorA,
Vector3f normal, float[] uvs, int light) {
this(v0, v1, v2, v3, facing, tex, colorA, normal, new float[][]{
{uvs[0], uvs[1]}, {uvs[0], uvs[3]},
{uvs[2], uvs[3]}, {uvs[2], uvs[1]}
}, light);
}
public RawQuad(Vector3f v0, Vector3f v1, Vector3f v2, Vector3f v3,
EnumFacing facing, TextureAtlasSprite tex, float[] colorA,
@Nullable Vector3f normal, float[][] uvs, int light) {
vertices[0] = v0;
vertices[1] = v1;
vertices[2] = v2;
@ -55,7 +68,12 @@ public class RawQuad {
} else {
this.colorA = colorA;
}
this.normal = normal;
if (normal != null) {
this.normal = normal;
} else {
this.normal = cross(sub(v1, v3, null), sub(v2, v0, null), null);//TODO is this the right way around?
this.normal.normalise(this.normal);
}
this.uvs = uvs;
this.light = light;
}
@ -64,6 +82,6 @@ public class RawQuad {
Matrix4 matNormal = mat.copy().transpose();
matNormal.invert();
return new RawQuad(mat.apply(vertices[0]), mat.apply(vertices[1]), mat.apply(vertices[2]), mat.apply(vertices[3]),
facing, tex, colorA, matNormal.apply(normal), uvs);
facing, tex, colorA, matNormal.apply(normal), uvs, light);
}
}

View file

@ -66,7 +66,7 @@ public class RawModelFontRenderer extends FontRenderer {
Vector3f v3 = new Vector3f(posX + w, h0, posY);
v3.scale(scale);
RawQuad quad = new RawQuad(v0, v1, v2, v3,
EnumFacing.UP, sprite, colorA, new Vector3f(0, 1, 0),
EnumFacing.UP, sprite, colorA, normal,
new float[]{x, y, x + wt, y + ht});
if (transform!=null) {
quad = quad.apply(transform);

View file

@ -26,11 +26,12 @@ import malte0811.industrialWires.util.TriConsumer;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -158,20 +159,21 @@ public abstract class PanelComponent {
}
}
@SideOnly(Side.CLIENT)
public void renderBox(TileEntityPanel te) {
GlStateManager.pushMatrix();
GlStateManager.enableBlend();
GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
GlStateManager.glLineWidth(2.0F);
GlStateManager.disableTexture2D();
GlStateManager.depthMask(false);
double px = te.getPos().getX() - TileEntityRendererDispatcher.staticPlayerX;
double py = te.getPos().getY() - TileEntityRendererDispatcher.staticPlayerY;
double pz = te.getPos().getZ() - TileEntityRendererDispatcher.staticPlayerZ;
RenderGlobal.drawSelectionBoundingBox(te.apply(te.getComponents().getPanelTopTransform(), getBlockRelativeAABB()).grow(0.002).offset(px, py, pz),
te.getComponents().transformGLForTop(te.getPos());
RenderGlobal.drawSelectionBoundingBox(getBlockRelativeAABB().grow(0.002),
0.0F, 0.0F, 0.0F, 0.4F);
GlStateManager.depthMask(true);
GlStateManager.enableTexture2D();
GlStateManager.disableBlend();
GlStateManager.popMatrix();
}
public abstract void renderInGUI(GuiPanelCreator gui);

View file

@ -84,7 +84,7 @@ public final class PanelUtils {
Matrix4 m4Here = m4.copy().translate(pc.getX(), .0001, pc.getY());
List<RawQuad> compQuads = pc.getQuads();
for (RawQuad bq : compQuads) {
ret.add(bakeQuad(bq, m4Here, m4RotOnly, false));
ret.add(bakeQuad(bq, m4Here, m4RotOnly));
}
}
Matrix4 baseTrans = components.getPanelBaseTransform();
@ -94,50 +94,60 @@ public final class PanelUtils {
List<RawQuad> rawOut = new ArrayList<>();
//addTexturedBox(new Vector3f(0, 0, 0), new Vector3f(1, components.height, 1), rawOut, UV_FULL, PANEL_TEXTURE);
float vMax = 16 * components.height;
addQuad(rawOut, new Vector3f(0, components.height, 0), new Vector3f(0, components.height, 1),
new Vector3f(1, components.height, 1), new Vector3f(1, components.height, 0),
EnumFacing.UP, WHITE, PANEL_TEXTURE, UV_FULL, null, false);
addQuad(rawOut, new Vector3f(0, 0, 0), new Vector3f(1, 0, 0),
float maxHeight = components.getPanelMaxHeight();
float vMaxLower = 16 * components.height;
float vMaxUpper = 16 * maxHeight;
//TOP
rawOut.add(new RawQuad(new Vector3f(0, maxHeight, 0), new Vector3f(0, components.height, 1),
new Vector3f(1, components.height, 1), new Vector3f(1, maxHeight, 0),
EnumFacing.UP, PANEL_TEXTURE, WHITE, null, UV_FULL, -1));
//BOTTOM
rawOut.add(new RawQuad(new Vector3f(0, 0, 0), new Vector3f(1, 0, 0),
new Vector3f(1, 0, 1), new Vector3f(0, 0, 1),
EnumFacing.DOWN, WHITE, PANEL_TEXTURE, new float[]{0, 16, 16, 0}, null, false);
addQuad(rawOut, new Vector3f(0, 0, 0), new Vector3f(0, 0, 1),
new Vector3f(0, components.height, 1), new Vector3f(0, components.height, 0),
EnumFacing.WEST, WHITE, PANEL_TEXTURE, new float[]{0, vMax, 16, 0}, null, false);
addQuad(rawOut, new Vector3f(1, 0, 0), new Vector3f(1, components.height, 0),
EnumFacing.DOWN, PANEL_TEXTURE, WHITE, null, UV_FULL, -1));
//LEFT
rawOut.add(new RawQuad(new Vector3f(0, 0, 0), new Vector3f(0, 0, 1),
new Vector3f(0, components.height, 1), new Vector3f(0, maxHeight, 0),
EnumFacing.UP, PANEL_TEXTURE, WHITE, null, new float[][]{
{0, 0}, {0, 16},
{vMaxLower, 16}, {vMaxUpper, 0}
}, -1));
//RIGHT
rawOut.add(new RawQuad(new Vector3f(1, 0, 0), new Vector3f(1, maxHeight, 0),
new Vector3f(1, components.height, 1), new Vector3f(1, 0, 1),
EnumFacing.EAST, WHITE, PANEL_TEXTURE, new float[]{16, vMax, 0, 0}, null, false);
addQuad(rawOut, new Vector3f(1, 0, 0), new Vector3f(0, 0, 0),
new Vector3f(0, components.height, 0), new Vector3f(1, components.height, 0),
EnumFacing.NORTH, WHITE, PANEL_TEXTURE, new float[]{0, vMax, 16, 0}, null, false);
addQuad(rawOut, new Vector3f(0, 0, 1), new Vector3f(1, 0, 1),
EnumFacing.UP, PANEL_TEXTURE, WHITE, null, new float[][]{
{0, 0}, {vMaxUpper, 0},
{vMaxLower, 16}, {0, 16}
}, -1));
//BACK
rawOut.add(new RawQuad(new Vector3f(1, 0, 0), new Vector3f(0, 0, 0),
new Vector3f(0, maxHeight, 0), new Vector3f(1, maxHeight, 0),
EnumFacing.UP, PANEL_TEXTURE, WHITE, null, new float[]{0, 0, vMaxUpper, 16}, -1));
//FRONT
rawOut.add(new RawQuad(new Vector3f(0, 0, 1), new Vector3f(1, 0, 1),
new Vector3f(1, components.height, 1), new Vector3f(0, components.height, 1),
EnumFacing.SOUTH, WHITE, PANEL_TEXTURE, new float[]{0, vMax, 16, 0}, null, false);
EnumFacing.UP, PANEL_TEXTURE, WHITE, null, new float[]{0, 0, vMaxLower, 16}, -1));
for (RawQuad bq : rawOut) {
ret.add(bakeQuad(bq, baseTrans, baseNorm, bq.facing != EnumFacing.EAST && bq.facing != EnumFacing.UP));//flip south and west
ret.add(bakeQuad(bq, baseTrans, baseNorm));
}
return ret;
}
@SideOnly(Side.CLIENT)
public static BakedQuad bakeQuad(RawQuad raw, Matrix4 transform, Matrix4 transfNormal, boolean flip) {
public static BakedQuad bakeQuad(RawQuad raw, Matrix4 transform, Matrix4 transfNormal) {
VertexFormat format = DefaultVertexFormats.ITEM;
UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(format);
builder.setQuadOrientation(raw.facing);
builder.setTexture(raw.tex);
Vector3f[] vertices = raw.vertices;
float[] uvs = raw.uvs;
float[][] uvs = raw.uvs;
Vector3f normal = transfNormal.apply(raw.normal);
OBJModel.Normal faceNormal = new OBJModel.Normal(normal.x, normal.y, normal.z);
putVertexData(format, builder, transform.apply(vertices[0]), faceNormal, uvs[0], uvs[1], raw.tex,
raw.colorA);
putVertexData(format, builder, transform.apply(vertices[1]), faceNormal, uvs[flip ? 2 : 0], uvs[flip ? 1 : 3], raw.tex,
raw.colorA);
putVertexData(format, builder, transform.apply(vertices[2]), faceNormal, uvs[2], uvs[3], raw.tex,
raw.colorA);
putVertexData(format, builder, transform.apply(vertices[3]), faceNormal, uvs[flip ? 0 : 2], uvs[flip ? 3 : 1], raw.tex,
raw.colorA);
for (int i = 0; i < 4; i++) {
putVertexData(format, builder, transform.apply(vertices[i]), faceNormal, uvs[i][0], uvs[i][1], raw.tex,
raw.colorA);
}
BakedQuad ret = builder.build();
if (raw.light>0) {
ret = new SmartLightingQuadIW(ret, raw.light);

View file

@ -19,8 +19,14 @@
package malte0811.industrialWires.controlpanel;
import blusunrize.immersiveengineering.common.util.chickenbones.Matrix4;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.common.property.IUnlistedProperty;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.ArrayList;
@ -51,6 +57,7 @@ public class PropertyComponents implements IUnlistedProperty<PropertyComponents.
public EnumFacing facing = EnumFacing.NORTH;
public float height = .5F;
public EnumFacing top = EnumFacing.UP;
// as radians!
public float angle = 0;
public PanelRenderProperties() {
@ -74,14 +81,40 @@ public class PropertyComponents implements IUnlistedProperty<PropertyComponents.
}
public Matrix4 getPanelTopTransform() {
return getPanelBaseTransformUnrotated().translate(0, height, 0).rotate(angle, 1, 0, 0);
double centerOffset = -.5 * (1 / Math.cos(angle) - 1);
return getPanelBaseTransform().translate(0, height, 1)
.rotate(angle, 1, 0, 0).translate(0, 0, centerOffset - 1);
}
@SideOnly(Side.CLIENT)
public void transformGLForTop(BlockPos panelPos) {
double px = panelPos.getX() - TileEntityRendererDispatcher.staticPlayerX;
double py = panelPos.getY() - TileEntityRendererDispatcher.staticPlayerY;
double pz = panelPos.getZ() - TileEntityRendererDispatcher.staticPlayerZ;
GlStateManager.translate(px + .5, py + .5, pz + .5);
switch (top) {
case DOWN:
GlStateManager.rotate(180, 0, 0, 1);
case UP:
GlStateManager.rotate(-facing.getHorizontalAngle(), 0, 1, 0);
break;
case NORTH:
case SOUTH:
case WEST:
case EAST:
GlStateManager.rotate(90, 1, 0, 0);
GlStateManager.rotate(top.getHorizontalAngle(), 0, 0, 1);
break;
}
GlStateManager.translate(-.5, height - .5, -.5);
GlStateManager.rotate((float) (-angle * 180 / Math.PI), 1, 0, 0);
GlStateManager.translate(.5, 0, .5);
GlStateManager.rotate(180, 0, 1, 0);
double centerOffset = .5 * (1 / Math.cos(angle) - 1);
GlStateManager.translate(-.5, 0, -.5 - centerOffset);
}
public Matrix4 getPanelBaseTransform() {
return getPanelBaseTransformUnrotated().rotate(angle, 1, 0, 0);
}
public Matrix4 getPanelBaseTransformUnrotated() {
Matrix4 ret = new Matrix4();
ret.translate(.5, .5, .5);
switch (top) {
@ -103,14 +136,18 @@ public class PropertyComponents implements IUnlistedProperty<PropertyComponents.
}
public float getMaxHeight() {
float ret = 0;
float max = getPanelMaxHeight();
double centerOffset = .5 * (1 / Math.cos(angle) - 1);
for (PanelComponent pc : this) {
float hHere = pc.getHeight();
if (hHere > ret) {
ret = hHere;
AxisAlignedBB aabb = pc.getBlockRelativeAABB();
double y = angle > 0 ? aabb.minY : aabb.maxY;
float hComp = (float) (pc.getHeight() * Math.cos(angle));
float localPanelHeight = (float) (height + (1 - (y + centerOffset)) * Math.sin(angle));
if (hComp + localPanelHeight > max) {
max = hComp + localPanelHeight;
}
}
return ret + height;
return max;
}
public PanelRenderProperties copyOf() {
@ -120,9 +157,14 @@ public class PropertyComponents implements IUnlistedProperty<PropertyComponents.
}
ret.facing = facing;
ret.top = top;
ret.angle = angle;
return ret;
}
public float getPanelMaxHeight() {
return (float) (height + Math.tan(angle));
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@ -132,6 +174,7 @@ public class PropertyComponents implements IUnlistedProperty<PropertyComponents.
PanelRenderProperties that = (PanelRenderProperties) o;
if (Float.compare(that.height, height) != 0) return false;
if (Float.compare(that.angle, angle) != 0) return false;
if (facing != that.facing) return false;
return top == that.top;
}
@ -142,6 +185,7 @@ public class PropertyComponents implements IUnlistedProperty<PropertyComponents.
result = 31 * result + facing.hashCode();
result = 31 * result + (height != +0.0f ? Float.floatToIntBits(height) : 0);
result = 31 * result + top.hashCode();
result = 31 * result + (angle != +0.0f ? Float.floatToIntBits(angle) : 0);
return result;
}
}