diff --git a/src/main/java/com/minelittlepony/PonyConfig.java b/src/main/java/com/minelittlepony/PonyConfig.java index bff4f978..d0b5f161 100644 --- a/src/main/java/com/minelittlepony/PonyConfig.java +++ b/src/main/java/com/minelittlepony/PonyConfig.java @@ -22,6 +22,7 @@ public class PonyConfig extends SensibleConfig implements Exposable { @Expose public boolean showscale = true; @Expose public boolean fpsmagic = true; @Expose public boolean ponyskulls = true; + @Expose public boolean frustrum = true; public enum PonySettings implements Setting { SIZES, @@ -29,7 +30,8 @@ public class PonyConfig extends SensibleConfig implements Exposable { HD, SHOWSCALE, FPSMAGIC, - PONYSKULLS; + PONYSKULLS, + FRUSTRUM; } @Expose public boolean villagers = true; diff --git a/src/main/java/com/minelittlepony/pony/data/IPony.java b/src/main/java/com/minelittlepony/pony/data/IPony.java index b12b220c..ccc3f70c 100644 --- a/src/main/java/com/minelittlepony/pony/data/IPony.java +++ b/src/main/java/com/minelittlepony/pony/data/IPony.java @@ -3,6 +3,8 @@ package com.minelittlepony.pony.data; import net.minecraft.client.entity.AbstractClientPlayer; import net.minecraft.entity.EntityLivingBase; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.Vec3d; import com.minelittlepony.MineLittlePony; @@ -65,7 +67,6 @@ public interface IPony { /** * Gets the texture used for rendering this pony. - * @return */ ResourceLocation getTexture(); @@ -73,4 +74,14 @@ public interface IPony { * Gets the metadata associated with this pony's model texture. */ IPonyData getMetadata(); + + /** + * Gets the riding offset of this entity relative to its lowermost mount. + */ + Vec3d getAbsoluteRidingOffset(EntityLivingBase entity); + + /** + * Gets the actual bounding box of this entity as a pony. + */ + AxisAlignedBB getComputedBoundingBox(EntityLivingBase entity); } diff --git a/src/main/java/com/minelittlepony/pony/data/Pony.java b/src/main/java/com/minelittlepony/pony/data/Pony.java index ca067d75..47f05cb5 100644 --- a/src/main/java/com/minelittlepony/pony/data/Pony.java +++ b/src/main/java/com/minelittlepony/pony/data/Pony.java @@ -18,6 +18,7 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; @@ -162,6 +163,31 @@ public class Pony implements IPony { return render == null ? null : render.getEntityPony((EntityLivingBase)mount); } + @Override + public Vec3d getAbsoluteRidingOffset(EntityLivingBase entity) { + IPony ridingPony = getMountedPony(entity); + + if (ridingPony != null) { + EntityLivingBase ridee = (EntityLivingBase)entity.getRidingEntity(); + + Vec3d offset = ridingPony.getMetadata().getSize().getTranformation().getRiderOffset(); + return ridingPony.getAbsoluteRidingOffset(ridee).add(-offset.x / 4, offset.y / 5, -offset.z / 4); + } + + return entity.getPositionVector(); + } + + @Override + public AxisAlignedBB getComputedBoundingBox(EntityLivingBase entity) { + float scale = getMetadata().getSize().getScaleFactor(); + + Vec3d pos = getAbsoluteRidingOffset(entity); + + return new AxisAlignedBB( + - entity.width / 2, (entity.height * scale), -entity.width / 2, + entity.width / 2, 0, entity.width / 2).offset(pos); + } + @Override public String toString() { return MoreObjects.toStringHelper(this) diff --git a/src/main/java/com/minelittlepony/render/DebugBoundingBoxRenderer.java b/src/main/java/com/minelittlepony/render/DebugBoundingBoxRenderer.java new file mode 100644 index 00000000..d624d7e4 --- /dev/null +++ b/src/main/java/com/minelittlepony/render/DebugBoundingBoxRenderer.java @@ -0,0 +1,41 @@ +package com.minelittlepony.render; + +import net.minecraft.client.Minecraft; + +import net.minecraft.client.renderer.RenderGlobal; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.math.AxisAlignedBB; + +import com.minelittlepony.pony.data.IPony; + +import static net.minecraft.client.renderer.GlStateManager.*; + +public class DebugBoundingBoxRenderer { + + public static final DebugBoundingBoxRenderer instance = new DebugBoundingBoxRenderer(); + + private DebugBoundingBoxRenderer() { + } + + public void render(IPony pony, EntityLivingBase entity, float ticks) { + AxisAlignedBB boundingBox = pony.getComputedBoundingBox(entity); + + EntityPlayer player = Minecraft.getMinecraft().player; + double renderPosX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)ticks; + double renderPosY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double)ticks; + double renderPosZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)ticks; + + enableBlend(); + tryBlendFuncSeparate(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE, DestFactor.ZERO); + glLineWidth(2.0F); + disableTexture2D(); + depthMask(false); + + RenderGlobal.drawSelectionBoundingBox(boundingBox.grow(0.002D).offset(-renderPosX, -renderPosY, -renderPosZ), 1, 1, 1, 1); + + depthMask(true); + enableTexture2D(); + disableBlend(); + } +} diff --git a/src/main/java/com/minelittlepony/render/FrustrumCheck.java b/src/main/java/com/minelittlepony/render/FrustrumCheck.java new file mode 100644 index 00000000..175cf1a8 --- /dev/null +++ b/src/main/java/com/minelittlepony/render/FrustrumCheck.java @@ -0,0 +1,40 @@ +package com.minelittlepony.render; + +import net.minecraft.client.renderer.culling.ICamera; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.math.AxisAlignedBB; + +import com.minelittlepony.pony.data.IPony; + +public class FrustrumCheck implements ICamera { + + private T entity; + + private ICamera vanilla; + + private final RenderPony renderer; + + public FrustrumCheck(RenderPony render) { + renderer = render; + } + + public ICamera withCamera(T entity, ICamera vanillaFrustrum) { + this.entity = entity; + vanilla = vanillaFrustrum; + return this; + } + + @Override + public boolean isBoundingBoxInFrustum(AxisAlignedBB bounds) { + IPony pony = renderer.getPony(entity); + + AxisAlignedBB boundingBox = pony.getComputedBoundingBox(entity); + + return vanilla.isBoundingBoxInFrustum(boundingBox); + } + + @Override + public void setPosition(double x, double y, double z) { + vanilla.setPosition(x, y, z); + } +} diff --git a/src/main/java/com/minelittlepony/render/RenderPony.java b/src/main/java/com/minelittlepony/render/RenderPony.java index 2ed196b8..c5719c2d 100644 --- a/src/main/java/com/minelittlepony/render/RenderPony.java +++ b/src/main/java/com/minelittlepony/render/RenderPony.java @@ -8,6 +8,7 @@ import com.minelittlepony.pony.data.IPony; import com.minelittlepony.transform.PonyPosture; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.culling.ICamera; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; @@ -21,6 +22,8 @@ public class RenderPony { private IRenderPony renderer; + private FrustrumCheck frustrum = new FrustrumCheck<>(this); + public static void enableModelRenderProfile() { GlStateManager.enableBlend(); GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); @@ -35,6 +38,13 @@ public class RenderPony { this.renderer = renderer; } + public ICamera getFrustrum(T entity, ICamera vanilla) { + if (!MineLittlePony.getConfig().frustrum) { + return vanilla; + } + return frustrum.withCamera(entity, vanilla); + } + public void preRenderCallback(T entity, float ticks) { updateModel(entity); diff --git a/src/main/java/com/minelittlepony/render/RenderPonyMob.java b/src/main/java/com/minelittlepony/render/RenderPonyMob.java index cd885297..7fab92d0 100644 --- a/src/main/java/com/minelittlepony/render/RenderPonyMob.java +++ b/src/main/java/com/minelittlepony/render/RenderPonyMob.java @@ -13,6 +13,7 @@ import com.minelittlepony.render.layer.LayerPonyElytra; import com.voxelmodpack.hdskins.HDSkinManager; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.culling.ICamera; import net.minecraft.client.renderer.entity.RenderLiving; import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.layers.LayerArrow; @@ -53,7 +54,15 @@ public abstract class RenderPonyMob extends RenderLiving if (entity.isSneaking()) { yPosition -= 0.125D; } + super.doRender(entity, xPosition, yPosition, zPosition, yaw, ticks); + + DebugBoundingBoxRenderer.instance.render(renderPony.getPony(entity), entity, ticks); + } + + @Override + public boolean shouldRender(T entity, ICamera camera, double camX, double camY, double camZ) { + return super.shouldRender(entity, renderPony.getFrustrum(entity, camera), camX, camY, camZ); } @Override diff --git a/src/main/java/com/minelittlepony/transform/PonyTransformation.java b/src/main/java/com/minelittlepony/transform/PonyTransformation.java index b3b0777b..aec6e9e3 100644 --- a/src/main/java/com/minelittlepony/transform/PonyTransformation.java +++ b/src/main/java/com/minelittlepony/transform/PonyTransformation.java @@ -3,12 +3,14 @@ package com.minelittlepony.transform; import static net.minecraft.client.renderer.GlStateManager.scale; import static net.minecraft.client.renderer.GlStateManager.translate; +import net.minecraft.util.math.Vec3d; + import com.minelittlepony.model.BodyPart; import com.minelittlepony.model.capabilities.IModel; public enum PonyTransformation { - NORMAL { + NORMAL(0, 3, 0.5F) { @Override public void transform(IModel model, BodyPart part) { if (model.isCrouching()) translate(0, -0.2F, 0); @@ -23,13 +25,13 @@ public enum PonyTransformation { if (model.isCrouching()) translate(0, 0.1F, 0); break; case BACK: - translate(0, 3, 0.5F); + translateVec(riderOffset); break; default: } } }, - LARGE { + LARGE(0, 2.3F, 0.3F) { @Override public void transform(IModel model, BodyPart part) { if (model.isCrouching()) translate(0, -0.15F, 0); @@ -58,12 +60,12 @@ public enum PonyTransformation { scale(1.15F, 1.12F, 1.15F); break; case BACK: - translate(0, 2.3F, 0.3F); + translateVec(riderOffset); break; } } }, - FOAL { + FOAL(0, 4.5F, 0.6F) { @Override public void transform(IModel model, BodyPart part) { if (model.isCrouching()) translate(0, -0.3F, 0); @@ -86,13 +88,13 @@ public enum PonyTransformation { scale(1, 0.81F, 1); break; case BACK: - translate(0, 4.5F, 0.6F); + translateVec(riderOffset); break; default: } } }, - TALL { + TALL(0, 2F, 0.6F) { @Override public void transform(IModel model, BodyPart part) { if (model.isCrouching()) translate(0, -0.15F, 0); @@ -119,12 +121,12 @@ public enum PonyTransformation { if (model.isGoingFast()) translate(0, 0.05F, 0); break; case BACK: - translate(0, 2F, 0.6F); + translateVec(riderOffset); break; } } }, - YEARLING { + YEARLING(0, 4.3F, 0.6F) { @Override public void transform(IModel model, BodyPart part) { if (model.isCrouching()) translate(0, -0.15F, 0); @@ -152,15 +154,25 @@ public enum PonyTransformation { if (model.isGoingFast()) translate(0, 0.05F, 0); break; case BACK: - translate(0, 4.3F, 0.6F); + translateVec(riderOffset); break; } } }; + protected final Vec3d riderOffset; + PonyTransformation(float rX, float rY, float rZ) { + riderOffset = new Vec3d(rX, rY, rZ); + } + public static void translateVec(Vec3d offset) { + translate(offset.x, offset.y, offset.z); + } + public Vec3d getRiderOffset() { + return riderOffset; + } public abstract void transform(IModel model, BodyPart part); }