Skip to content

Commit

Permalink
Update entity
Browse files Browse the repository at this point in the history
  • Loading branch information
squid233 committed Aug 1, 2024
1 parent 61ab0f8 commit 98ad86c
Show file tree
Hide file tree
Showing 20 changed files with 250 additions and 215 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import freeworld.world.block.BlockType;
import freeworld.world.block.BlockTypes;
import freeworld.world.entity.EntityTypes;
import freeworld.world.entity.PlayerEntity;
import freeworld.world.entity.player.PlayerEntity;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import overrun.marshal.Unmarshal;
Expand Down Expand Up @@ -264,7 +264,7 @@ private void worldInput() {
if (!hitResult.missed() &&
glfw.getMouseButton(window, GLFW.MOUSE_BUTTON_LEFT) == GLFW.PRESS) {
Vector3i position = hitResult.position();
world.setBlockType(position.x(), position.y(), position.z(), BlockTypes.AIR);
world.setBlock(position.x(), position.y(), position.z(), BlockTypes.AIR);
blockDestroyTimer = 0;
}
}
Expand All @@ -278,9 +278,9 @@ private void worldInput() {
Vector3i axis = face.axis();
Vector3i position = hitResult.position();
Vector3i add = position.add(axis);
if (world.getBlockType(position.x(), position.y(), position.z()).replaceable() ||
world.getBlockType(add.x(), add.y(), add.z()).replaceable()) {
world.setBlockType(add.x(), add.y(), add.z(), type);
if (world.getBlock(position).replaceable() ||
world.getBlock(add).replaceable()) {
world.setBlock(add.x(), add.y(), add.z(), type);
}
}
blockPlaceTimer = 0;
Expand All @@ -296,7 +296,6 @@ private void worldInput() {

private void tick() {
if (world != null) {
camera.preUpdate();
if (screen == null) {
worldInput();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,46 +20,17 @@
* @since 0.1.0
*/
public final class Camera {
private Vector3d prevPosition = Vector3d.ZERO;
private Vector3d position = Vector3d.ZERO;
private Vector3d lerpPosition = Vector3d.ZERO;
private Vector2d rotation = Vector2d.ZERO;
private Vector3d eyePosition = Vector3d.ZERO;

public void moveToEntity(Entity entity) {
eyePosition = entity.eyePosition();
position = entity.position().add(0.0, eyePosition.y(), 0.0);
public void moveToEntity(Entity entity, double partialTick) {
position = entity.getCameraPos(partialTick);
rotation = entity.rotation();
}

public void preUpdate() {
prevPosition = position;
}

public void updateLerp(double partialTick) {
lerpPosition = prevPosition.lerp(position, partialTick);
}

public Matrix4f updateViewMatrix() {
return Matrix4f.translation((float) -eyePosition.x(), 0.0f, (float) -eyePosition.z())
.rotateX((float) -Math.toRadians(rotation.x()))
return Matrix4f.rotationX((float) -Math.toRadians(rotation.x()))
.rotateY((float) -Math.toRadians(rotation.y()))
.translate((float) -lerpPosition.x(), (float) -lerpPosition.y(), (float) -lerpPosition.z());
}

public Vector3d prevPosition() {
return prevPosition;
}

public Vector3d position() {
return position;
}

public Vector3d lerpPosition() {
return lerpPosition;
}

public Vector2d rotation() {
return rotation;
.translate((float) -position.x(), (float) -position.y(), (float) -position.z());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,24 @@
import freeworld.client.render.vertex.VertexLayouts;
import freeworld.client.render.world.WorldRenderer;
import freeworld.client.render.world.block.BlockRenderer;
import freeworld.client.render.world.entity.EntityRenderer;
import freeworld.client.render.world.entity.EntityRenderers;
import freeworld.client.world.chunk.ClientChunk;
import freeworld.math.Matrix4f;
import freeworld.math.Vector3i;
import freeworld.registry.Registries;
import freeworld.util.Direction;
import freeworld.util.Identifier;
import freeworld.util.Logging;
import freeworld.util.math.Lined;
import freeworld.world.World;
import freeworld.world.block.BlockHitResult;
import freeworld.world.entity.Entity;
import freeworld.world.entity.EntityType;
import org.slf4j.Logger;
import overrungl.opengl.GL10C;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* The game renderer.
Expand All @@ -61,6 +63,7 @@ public final class GameRenderer implements GLResource {
private BlockRenderer blockRenderer;
private WorldRenderer worldRenderer;
private BlockHitResult hitResult = new BlockHitResult(true, null, Vector3i.ZERO, Direction.SOUTH);
private Map<EntityType<?>, EntityRenderer<?>> rendererMap;

public GameRenderer(Freeworld client) {
this.client = client;
Expand Down Expand Up @@ -90,6 +93,8 @@ public void init(GLStateMgr gl) {

guiGraphics = new GuiGraphics(gl, this);
hudRenderer = new HudRenderer(this);

rendererMap = EntityRenderers.loadRenderers(client);
}

private void initBlockAtlas(GLStateMgr gl) {
Expand Down Expand Up @@ -151,8 +156,7 @@ private void renderWorld(GLStateMgr gl, double partialTick) {

final Camera camera = client.camera();
final Entity player = client.player();
camera.moveToEntity(player);
camera.updateLerp(partialTick);
camera.moveToEntity(player, partialTick);
RenderSystem.setProjectionViewMatrix(Matrix4f.setPerspective(
(float) Math.toRadians(70.0),
(float) client.framebufferWidth() / client.framebufferHeight(),
Expand All @@ -164,8 +168,7 @@ private void renderWorld(GLStateMgr gl, double partialTick) {
RenderSystem.useProgram(positionColorTexProgram);
RenderSystem.updateMatrices();

final List<ClientChunk> chunks = worldRenderer.renderingChunks(player);
worldRenderer.compileChunks(chunks);
worldRenderer.compileChunks(player);

hitResult = worldRenderer.selectBlock(player);

Expand All @@ -175,7 +178,7 @@ private void renderWorld(GLStateMgr gl, double partialTick) {
gl.setPolygonOffset(1.0f, 1.0f);
gl.setLineWidth(2.0f);
}
worldRenderer.renderChunks(gl, chunks);
worldRenderer.renderChunks(gl, player);
if (!hitResult.missed()) {
gl.disablePolygonOffsetFill();
gl.setLineWidth(1.0f);
Expand Down Expand Up @@ -203,17 +206,23 @@ private void renderWorld(GLStateMgr gl, double partialTick) {
private void renderWorldEntities(GLStateMgr gl, double partialTick) {
RenderSystem.useProgram(positionColorProgram);
RenderSystem.updateMatrices();
for (Entity entity : client.world().entities()) {
entity.interpolatePosition(partialTick);
var factory = EntityRenderers.registry().getById(Registries.ENTITY_TYPE.getId(entity.entityType()));
if (factory != null) {
factory.create(client).render(gl,
partialTick,
Matrix4f.translation(entity.interpolatedPosition().toVector3f())
.rotateY((float) Math.toRadians(entity.rotation().y())),
entity);
World.forInChunkRange(client.player(), WorldRenderer.RENDER_RADIUS, (x, y, z) -> {
for (Entity entity : client.world().getOrCreateChunk(x, y, z).entities()) {
var renderer = getEntityRenderer(entity);
if (renderer != null) {
renderer.render(gl,
partialTick,
Matrix4f.translation(entity.interpolatedPosition(partialTick).toVector3f())
.rotateY((float) Math.toRadians(entity.rotation().y())),
entity);
}
}
}
});
}

@SuppressWarnings("unchecked")
private <T extends Entity> EntityRenderer<T> getEntityRenderer(T entity) {
return (EntityRenderer<T>) rendererMap.get(entity.type());
}

private void renderHud(GLStateMgr gl, double partialTick) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,18 @@
public final class WorldRenderer implements GLResource, WorldListener {
private static final Logger logger = Logging.caller();
public static final int RENDER_RADIUS = 5;
private static int builtChunkCount = 0;
private final GameRenderer gameRenderer;
private final World world;
private final Scheduler scheduler = Schedulers.newParallel("WorldRenderer-Worker");
private final Pool<DefaultVertexBuilder> vertexBuilderPool = PoolBuilder
.from(Mono.fromSupplier(WorldRenderer::createVertexBuilder).subscribeOn(scheduler))
.buildPool();
@Deprecated
private final Map<Vector3i, ClientChunk> chunks = new HashMap<>(2048);
private final Disposable chunkGC;
private final Queue<Runnable> chunkGCQueue = new LinkedBlockingQueue<>();
@Deprecated
private Vector3i playerChunkPos = Vector3i.ZERO;

public WorldRenderer(GameRenderer gameRenderer, World world) {
Expand Down Expand Up @@ -84,22 +87,15 @@ private void uninstallChunks() {
}
}

public List<ClientChunk> renderingChunks(Entity player) {
final List<ClientChunk> chunks = new ArrayList<>(2048);
World.forInChunkRange(player, RENDER_RADIUS, (x, y, z) -> chunks.add(getChunkOrCreate(x, y, z)));
return chunks;
public void compileChunks(Entity player) {
World.forInChunkRange(player, RENDER_RADIUS, (x, y, z) -> getChunkOrCreate(x, y, z).compile());
}

public void compileChunks(List<ClientChunk> renderingChunks) {
for (ClientChunk chunk : renderingChunks) {
chunk.compile();
}
}

public void renderChunks(GLStateMgr gl, List<ClientChunk> renderingChunks) {
int builtChunkCount = 0;
public void renderChunks(GLStateMgr gl, Entity player) {
builtChunkCount = 0;
FrustumIntersection frustumIntersection = new FrustumIntersection(RenderSystem.projectionViewMatrix());
for (ClientChunk chunk : renderingChunks) {
World.forInChunkRange(player, RENDER_RADIUS, (x, y, z) -> {
ClientChunk chunk = getChunkOrCreate(x, y, z);
if (frustumIntersection.testAab(
chunk.fromX(),
chunk.fromY(),
Expand All @@ -114,10 +110,10 @@ public void renderChunks(GLStateMgr gl, List<ClientChunk> renderingChunks) {
}
chunk.render(gl);
}
}
});

Vector3d playerPos = gameRenderer.client().player().position();
Vector3i playerChunkPos = ChunkPos.absoluteToChunk(playerPos.toVector3iFloor());
Vector3i playerChunkPos = ChunkPos.toChunkPos(playerPos.toVector3iFloor());
if (!this.playerChunkPos.equals(playerChunkPos)) {
this.playerChunkPos = playerChunkPos;
uninstallChunks();
Expand Down Expand Up @@ -166,7 +162,7 @@ public BlockHitResult selectBlock(Entity player) {
final float vz = z + 0.5f - oz;
final float zSquared = vz * vz;
if ((xSquared + ySquared + zSquared) <= radiusSquared) {
final BlockType blockType = world.getBlockType(x, y, z);
final BlockType blockType = world.getBlock(x, y, z);
if (blockType.air()) {
continue;
}
Expand Down Expand Up @@ -207,20 +203,23 @@ public void onBlockChanged(int x, int y, int z) {
}
}

@Deprecated
private ClientChunk getChunk(int x, int y, int z) {
return chunks.get(new Vector3i(x, y, z));
}

@Deprecated
private ClientChunk getChunkOrCreate(int x, int y, int z) {
return chunks.computeIfAbsent(new Vector3i(x, y, z),
chunkPos -> new ClientChunk(world, this, chunkPos.x(), chunkPos.y(), chunkPos.z()));
}

@Deprecated
private ClientChunk getChunkByAbsolutePos(int x, int y, int z) {
return getChunk(
ChunkPos.absoluteToChunk(x),
ChunkPos.absoluteToChunk(y),
ChunkPos.absoluteToChunk(z)
ChunkPos.toChunkPos(x),
ChunkPos.toChunkPos(y),
ChunkPos.toChunkPos(z)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,17 @@ public static ChunkVertexData compile(
blockRenderer.renderBlockModel(
vertexBuilder,
model,
ChunkPos.relativeToAbsolute(cx, x),
ChunkPos.relativeToAbsolute(cy, y),
ChunkPos.relativeToAbsolute(cz, z),
ChunkPos.toBlockPosInWorld(cx, x),
ChunkPos.toBlockPosInWorld(cy, y),
ChunkPos.toBlockPosInWorld(cz, z),
direction -> {
Vector3i nPos = direction.axis().add(finalPos);
Vector3i abs = ChunkPos.relativeToAbsolute(chunkPos, nPos);
Vector3i abs = ChunkPos.toBlockPosInWorld(chunkPos, nPos);
final boolean shouldRender =
(chunk.isInBound(nPos.x(), nPos.y(), nPos.z()) &&
chunk.getBlockType(nPos.x(), nPos.y(), nPos.z()).hasSidedTransparency()) ||
(chunk.world().isBlockLoaded(abs.x(), abs.y(), abs.z()) &&
chunk.world().getBlockType(abs.x(), abs.y(), abs.z()).hasSidedTransparency()) ||
chunk.world().getBlock(abs).hasSidedTransparency()) ||
!chunk.world().isBlockLoaded(abs.x(), abs.y(), abs.z()) /* TODO: add method world::tryLoading() */;
return !shouldRender;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public CubeEntityRenderer(Freeworld client) {

@Override
public void render(GLStateMgr gl, double partialTick, Matrix4f positionMatrix, CubeEntity entity) {
RenderSystem.useProgram(client.gameRenderer().positionColorProgram());
RenderSystem.useProgram(context.gameRenderer().positionColorProgram());
Tessellator t = Tessellator.getInstance();
t.begin(GLDrawMode.TRIANGLES);
float x0 = -0.5f;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@
* @since 0.1.0
*/
public abstract class EntityRenderer<T extends Entity> {
protected final Freeworld client;
protected final Freeworld context;

protected EntityRenderer(Freeworld client) {
this.client = client;
protected EntityRenderer(Freeworld context) {
this.context = context;
}

public interface Factory<T extends Entity> {
EntityRenderer<T> create(Freeworld client);
EntityRenderer<T> create(Freeworld context);
}

public abstract void render(GLStateMgr gl, double partialTick, Matrix4f positionMatrix, T entity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,21 @@

package freeworld.client.render.world.entity;

import freeworld.registry.MappedRegistry;
import freeworld.registry.Registries;
import freeworld.registry.Registry;
import freeworld.util.Identifier;
import freeworld.client.Freeworld;
import freeworld.world.entity.Entity;
import freeworld.world.entity.EntityType;
import freeworld.world.entity.EntityTypes;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
* @author squid233
* @since 0.1.0
*/
public final class EntityRenderers {
private static final MappedRegistry<EntityRenderer.Factory<Entity>> REGISTRY = new MappedRegistry<>(Identifier.ofBuiltin("entity_renderer"));
private static final Map<EntityType<?>, EntityRenderer.Factory<?>> factoryMap = new HashMap<>();

private EntityRenderers() {
}
Expand All @@ -32,12 +33,13 @@ public static void bootstrap() {
register(EntityTypes.CUBE, CubeEntityRenderer::new);
}

@SuppressWarnings("unchecked")
public static <T extends Entity> void register(EntityType<T> entityType, EntityRenderer.Factory<T> renderer) {
Registry.register(REGISTRY, Registries.ENTITY_TYPE.getId(entityType), (EntityRenderer.Factory<Entity>) renderer);
factoryMap.put(entityType, renderer);
}

public static Registry<EntityRenderer.Factory<Entity>> registry() {
return REGISTRY;
public static Map<EntityType<?>, EntityRenderer<?>> loadRenderers(Freeworld context) {
final Map<EntityType<?>, EntityRenderer<?>> renderers = HashMap.newHashMap(factoryMap.size());
factoryMap.forEach((entityType, factory) -> renderers.put(entityType, factory.create(context)));
return Collections.unmodifiableMap(renderers);
}
}
Loading

0 comments on commit 98ad86c

Please sign in to comment.