mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-04 03:16:24 +01:00
Lines are hard
- Add BoundingBoxComponent for drawing entity bounding boxes. - Render lines with a wireframe material. - Add viewport size and default line width uniforms.
This commit is contained in:
parent
c5687ccf43
commit
cdfe144131
8 changed files with 203 additions and 3 deletions
|
@ -7,11 +7,12 @@ import com.jozufozu.flywheel.api.event.RenderContext;
|
|||
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
|
||||
import com.jozufozu.flywheel.lib.math.MatrixMath;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class FrameUniforms implements UniformProvider {
|
||||
public static final int SIZE = 220;
|
||||
public static final int SIZE = 232;
|
||||
|
||||
private RenderContext context;
|
||||
|
||||
|
@ -51,10 +52,17 @@ public class FrameUniforms implements UniformProvider {
|
|||
writeVec3(ptr + 176, lookVector.x, lookVector.y, lookVector.z);
|
||||
|
||||
writeVec2(ptr + 192, camera.getXRot(), camera.getYRot());
|
||||
var window = Minecraft.getInstance()
|
||||
.getWindow();
|
||||
|
||||
MemoryUtil.memPutInt(ptr + 200, getConstantAmbientLightFlag(context));
|
||||
writeVec2(ptr + 200, window.getWidth(), window.getHeight());
|
||||
|
||||
writeTime(ptr + 204);
|
||||
// default line width: net.minecraft.client.renderer.RenderStateShard.LineStateShard
|
||||
MemoryUtil.memPutFloat(ptr + 208, Math.max(2.5F, (float) window.getWidth() / 1920.0F * 2.5F));
|
||||
|
||||
MemoryUtil.memPutInt(ptr + 212, getConstantAmbientLightFlag(context));
|
||||
|
||||
writeTime(ptr + 216);
|
||||
}
|
||||
|
||||
private void writeTime(long ptr) {
|
||||
|
|
|
@ -10,6 +10,8 @@ public final class StandardMaterialShaders {
|
|||
Flywheel.rl("material/default.vert"),
|
||||
Flywheel.rl("material/default.frag")));
|
||||
|
||||
public static final MaterialShaders WIREFRAME = MaterialShaders.REGISTRY.registerAndGet(new SimpleMaterialShaders(Flywheel.rl("material/wireframe.vert"), Flywheel.rl("material/wireframe.frag")));
|
||||
|
||||
private StandardMaterialShaders() {
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ public abstract class AbstractEntityVisual<T extends Entity> extends AbstractVis
|
|||
protected final EntityVisibilityTester visibilityTester;
|
||||
protected final ShadowComponent shadow;
|
||||
protected final FireComponent fire;
|
||||
protected final BoundingBoxComponent boundingBox;
|
||||
|
||||
public AbstractEntityVisual(VisualizationContext ctx, T entity) {
|
||||
super(ctx, entity.level());
|
||||
|
@ -42,6 +43,7 @@ public abstract class AbstractEntityVisual<T extends Entity> extends AbstractVis
|
|||
visibilityTester = new EntityVisibilityTester(entity, ctx.renderOrigin(), 1.5f);
|
||||
shadow = new ShadowComponent(ctx, entity);
|
||||
fire = new FireComponent(ctx, entity);
|
||||
boundingBox = new BoundingBoxComponent(ctx, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -96,5 +98,6 @@ public abstract class AbstractEntityVisual<T extends Entity> extends AbstractVis
|
|||
protected void _delete() {
|
||||
shadow.delete();
|
||||
fire.delete();
|
||||
boundingBox.delete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
package com.jozufozu.flywheel.lib.visual;
|
||||
|
||||
import org.joml.Vector4f;
|
||||
import org.joml.Vector4fc;
|
||||
|
||||
import com.jozufozu.flywheel.api.material.Material;
|
||||
import com.jozufozu.flywheel.api.model.Model;
|
||||
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
|
||||
import com.jozufozu.flywheel.api.visual.VisualFrameContext;
|
||||
import com.jozufozu.flywheel.api.visualization.VisualizationContext;
|
||||
import com.jozufozu.flywheel.lib.instance.InstanceTypes;
|
||||
import com.jozufozu.flywheel.lib.instance.TransformedInstance;
|
||||
import com.jozufozu.flywheel.lib.material.SimpleMaterial;
|
||||
import com.jozufozu.flywheel.lib.material.StandardMaterialShaders;
|
||||
import com.jozufozu.flywheel.lib.math.MoreMath;
|
||||
import com.jozufozu.flywheel.lib.model.QuadMesh;
|
||||
import com.jozufozu.flywheel.lib.model.SingleMeshModel;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
|
||||
public class BoundingBoxComponent {
|
||||
private static final Material MATERIAL = SimpleMaterial.builder()
|
||||
.shaders(StandardMaterialShaders.WIREFRAME)
|
||||
.backfaceCulling(false)
|
||||
.build();
|
||||
private static final Model MODEL = new SingleMeshModel(BoundingBoxMesh.INSTANCE, MATERIAL);
|
||||
|
||||
private final VisualizationContext context;
|
||||
private final Entity entity;
|
||||
|
||||
private boolean showEyeBox;
|
||||
|
||||
private final InstanceRecycler<TransformedInstance> recycler;
|
||||
|
||||
public BoundingBoxComponent(VisualizationContext context, Entity entity) {
|
||||
this.context = context;
|
||||
this.entity = entity;
|
||||
this.showEyeBox = entity instanceof LivingEntity;
|
||||
|
||||
this.recycler = new InstanceRecycler<>(this::createInstance);
|
||||
}
|
||||
|
||||
private TransformedInstance createInstance() {
|
||||
TransformedInstance instance = context.instancerProvider()
|
||||
.instancer(InstanceTypes.TRANSFORMED, MODEL)
|
||||
.createInstance();
|
||||
instance.setBlockLight(LightTexture.block(LightTexture.FULL_BLOCK));
|
||||
instance.setChanged();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void showEyeBox(boolean renderEyeBox) {
|
||||
this.showEyeBox = renderEyeBox;
|
||||
}
|
||||
|
||||
public void beginFrame(VisualFrameContext context) {
|
||||
recycler.resetCount();
|
||||
|
||||
var shouldRenderHitBoxes = Minecraft.getInstance()
|
||||
.getEntityRenderDispatcher()
|
||||
.shouldRenderHitBoxes();
|
||||
if (shouldRenderHitBoxes && !entity.isInvisible() && !Minecraft.getInstance()
|
||||
.showOnlyReducedInfo()) {
|
||||
double entityX = Mth.lerp(context.partialTick(), entity.xOld, entity.getX());
|
||||
double entityY = Mth.lerp(context.partialTick(), entity.yOld, entity.getY());
|
||||
double entityZ = Mth.lerp(context.partialTick(), entity.zOld, entity.getZ());
|
||||
|
||||
var bbWidth = entity.getBbWidth();
|
||||
var bbHeight = entity.getBbHeight();
|
||||
var bbWidthHalf = bbWidth * 0.5;
|
||||
recycler.get()
|
||||
.loadIdentity()
|
||||
.translate(entityX - bbWidthHalf, entityY, entityZ - bbWidthHalf)
|
||||
.scale(bbWidth, bbHeight, bbWidth)
|
||||
.setChanged();
|
||||
|
||||
// TODO: multipart entities and view vectors
|
||||
|
||||
if (showEyeBox) {
|
||||
recycler.get()
|
||||
.loadIdentity()
|
||||
.translate(entityX - bbWidthHalf, entityY + entity.getEyeHeight() - 0.01, entityZ - bbWidthHalf)
|
||||
.scale(bbWidth, 0.02f, bbWidth)
|
||||
.setColor(255, 0, 0)
|
||||
.setChanged();
|
||||
}
|
||||
}
|
||||
|
||||
recycler.discardExtra();
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
recycler.delete();
|
||||
}
|
||||
|
||||
private static class BoundingBoxMesh implements QuadMesh {
|
||||
private static final BoundingBoxMesh INSTANCE = new BoundingBoxMesh();
|
||||
private static final Vector4fc BOUNDING_SPHERE = new Vector4f(0.5f, 0.5f, 0.5f, MoreMath.SQRT_3_OVER_2);
|
||||
|
||||
private BoundingBoxMesh() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int vertexCount() {
|
||||
return 24;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(MutableVertexList vertexList) {
|
||||
// very cursed, maybe we should use vanilla ModelParts instead?
|
||||
writeVertex(vertexList, 0, 0, 0, 0, 0, 0);
|
||||
writeVertex(vertexList, 1, 1, 0, 0, 1, 0);
|
||||
writeVertex(vertexList, 2, 1, 1, 0, 1, 1);
|
||||
writeVertex(vertexList, 3, 0, 1, 0, 0, 1);
|
||||
|
||||
writeVertex(vertexList, 4, 0, 0, 1, 0, 0);
|
||||
writeVertex(vertexList, 5, 0, 0, 0, 1, 0);
|
||||
writeVertex(vertexList, 6, 0, 1, 0, 1, 1);
|
||||
writeVertex(vertexList, 7, 0, 1, 1, 0, 1);
|
||||
|
||||
writeVertex(vertexList, 8, 0, 1, 0, 0, 0);
|
||||
writeVertex(vertexList, 9, 1, 1, 0, 1, 0);
|
||||
writeVertex(vertexList, 10, 1, 1, 1, 1, 1);
|
||||
writeVertex(vertexList, 11, 0, 1, 1, 0, 1);
|
||||
|
||||
writeVertex(vertexList, 12, 1, 0, 1, 0, 0);
|
||||
writeVertex(vertexList, 13, 0, 0, 1, 1, 0);
|
||||
writeVertex(vertexList, 14, 0, 1, 1, 1, 1);
|
||||
writeVertex(vertexList, 15, 1, 1, 1, 0, 1);
|
||||
|
||||
writeVertex(vertexList, 16, 1, 0, 0, 0, 0);
|
||||
writeVertex(vertexList, 17, 1, 0, 1, 1, 0);
|
||||
writeVertex(vertexList, 18, 1, 1, 1, 1, 1);
|
||||
writeVertex(vertexList, 19, 1, 1, 0, 0, 1);
|
||||
|
||||
writeVertex(vertexList, 20, 0, 0, 0, 0, 0);
|
||||
writeVertex(vertexList, 21, 1, 0, 0, 1, 0);
|
||||
writeVertex(vertexList, 22, 1, 0, 1, 1, 1);
|
||||
writeVertex(vertexList, 23, 0, 0, 1, 0, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector4fc boundingSphere() {
|
||||
return BOUNDING_SPHERE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
}
|
||||
|
||||
private static void writeVertex(MutableVertexList vertexList, int i, float x, float y, float z, float u, float v) {
|
||||
vertexList.x(i, x);
|
||||
vertexList.y(i, y);
|
||||
vertexList.z(i, z);
|
||||
vertexList.r(i, 1);
|
||||
vertexList.g(i, 1);
|
||||
vertexList.b(i, 1);
|
||||
vertexList.u(i, u);
|
||||
vertexList.v(i, v);
|
||||
vertexList.light(i, LightTexture.FULL_BRIGHT);
|
||||
vertexList.normalX(i, 0);
|
||||
vertexList.normalY(i, 1);
|
||||
vertexList.normalZ(i, 0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -111,6 +111,7 @@ public class MinecartVisual<T extends AbstractMinecart> extends AbstractEntityVi
|
|||
public void beginFrame(VisualFrameContext context) {
|
||||
shadow.beginFrame(context);
|
||||
fire.beginFrame(context);
|
||||
boundingBox.beginFrame(context);
|
||||
|
||||
if (!isVisible(context.frustum())) {
|
||||
return;
|
||||
|
|
|
@ -15,6 +15,10 @@ layout(std140) uniform _FlwFrameUniforms {
|
|||
vec4 flw_cameraPos;
|
||||
vec4 flw_cameraLook;
|
||||
vec2 flw_cameraRot;
|
||||
|
||||
vec2 flw_viewportSize;
|
||||
float flw_defaultLineWidth;
|
||||
|
||||
uint flw_constantAmbientLight;
|
||||
|
||||
uint flw_ticks;
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
void flw_materialFragment() {
|
||||
float closestEdge = min(flw_vertexTexCoord.s, min(flw_vertexTexCoord.t, min(1. - flw_vertexTexCoord.s, 1. - flw_vertexTexCoord.t)));
|
||||
|
||||
// multiply by fwidth to get the width of the edge in screen space
|
||||
if (flw_defaultLineWidth * fwidth(closestEdge) < closestEdge) {
|
||||
discard;
|
||||
}
|
||||
|
||||
flw_fragColor = flw_vertexColor;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
void flw_materialVertex() {
|
||||
}
|
Loading…
Reference in a new issue