Skip to content

Commit

Permalink
Update ECS
Browse files Browse the repository at this point in the history
  • Loading branch information
squid233 committed Mar 17, 2024
1 parent a595c83 commit e204b1c
Show file tree
Hide file tree
Showing 15 changed files with 243 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import io.github.xenfork.freeworld.world.block.BlockTypes;
import io.github.xenfork.freeworld.world.entity.Entity;
import io.github.xenfork.freeworld.world.entity.EntityTypes;
import org.joml.Vector2d;
import org.slf4j.Logger;
import overrun.marshal.Unmarshal;
import overrungl.glfw.GLFW;
Expand Down Expand Up @@ -107,10 +108,10 @@ public void start() {
EntityTypes.bootstrap();
BuiltinRegistries.ENTITY_TYPE.freeze();

camera.setPosition(1.5, 16.0, 1.5);

world = new World("New world");
player = new Entity(world, UUID.randomUUID(), EntityTypes.PLAYER);
player.position().position().set(1.5, 16.0, 1.5);
world.entities.add(player);

initGL();
run();
Expand Down Expand Up @@ -141,14 +142,27 @@ private void onCursorPos(double x, double y) {
cursorDeltaX = x - cursorX;
cursorDeltaY = y - cursorY;
if (disableCursor) {
camera.rotate(-cursorDeltaY * MOUSE_SENSITIVITY, -cursorDeltaX * MOUSE_SENSITIVITY);
final double pitch = -cursorDeltaY * MOUSE_SENSITIVITY;
final double yaw = -cursorDeltaX * MOUSE_SENSITIVITY;
final Vector2d rotation = player.rotation().rotation();
final double updateX = Math.clamp(rotation.x() + pitch, -90.0, 90.0);
double updateY = rotation.y() + yaw;

if (updateY < 0.0) {
updateY += 360.0;
} else if (updateY >= 360.0) {
updateY -= 360.0;
}

rotation.set(updateX, updateY);
}
cursorX = x;
cursorY = y;
}

private void tick() {
camera.preUpdate();
world.tick();
final double speed = 0.5;
double xo = 0.0;
double yo = 0.0;
Expand All @@ -159,7 +173,7 @@ private void tick() {
if (glfw.getKey(window, GLFW.KEY_D) == GLFW.PRESS) xo += 1.0;
if (glfw.getKey(window, GLFW.KEY_LEFT_SHIFT) == GLFW.PRESS) yo -= 1.0;
if (glfw.getKey(window, GLFW.KEY_SPACE) == GLFW.PRESS) yo += 1.0;
camera.moveRelative(xo, yo, zo, speed);
player.velocity().velocity().set(xo, yo, zo).mul(speed);
}

private void initGL() {
Expand Down Expand Up @@ -227,6 +241,10 @@ public World world() {
return world;
}

public Entity player() {
return player;
}

public static Freeworld getInstance() {
return INSTANCE;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

package io.github.xenfork.freeworld.client.render;

import io.github.xenfork.freeworld.world.entity.Entity;
import io.github.xenfork.freeworld.world.entity.component.PositionComponent;
import io.github.xenfork.freeworld.world.entity.component.RotationXYComponent;
import io.github.xenfork.freeworld.world.entity.system.EntitySystem;
import org.joml.*;

import java.lang.Math;
Expand All @@ -25,42 +29,11 @@ public final class Camera {
private final Vector2d rotation = new Vector2d();
private final Matrix4f viewMatrix = new Matrix4f();

public void setPosition(double x, double y, double z) {
position.set(x, y, z);
}

public void move(double x, double y, double z) {
position.add(x, y, z);
}

public void moveRelative(double x, double y, double z, double speed) {
final double dest = x * x + z * z;
if (dest > 0.001) {
final double sqrt = Math.sqrt(dest);
final double invSqrt = 1.0 / sqrt;
final double yaw = Math.toRadians(rotation.y());

final double normalX = x * invSqrt * speed;
final double normalZ = z * invSqrt * speed;
final double sin = Math.sin(yaw);
final double cos = Math.cos(yaw);
position.x += normalX * cos + normalZ * sin;
position.z += normalZ * cos - normalX * sin;
public void moveToEntity(Entity entity) {
if (EntitySystem.filter(entity, PositionComponent.ID, RotationXYComponent.ID)) {
position.set(entity.position().position());
rotation.set(entity.rotation().rotation());
}
position.y += y * speed;
}

public void rotate(double pitch, double yaw) {
final double updateX = Math.clamp(rotation.x() + pitch, -90.0, 90.0);
double updateY = rotation.y() + yaw;

if (updateY < 0.0) {
updateY += 360.0;
} else if (updateY >= 360.0) {
updateY -= 360.0;
}

rotation.set(updateX, updateY);
}

public void preUpdate() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public void render(GLStateMgr gl, double partialTick) {
1000.0f
);
final Camera camera = client.camera();
camera.moveToEntity(client.player());
camera.updateLerp(partialTick);
camera.updateViewMatrix();
projectionView.mul(camera.viewMatrix());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* freeworld - 3D sandbox game
* Copyright (C) 2024 XenFork Union
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*/

package io.github.xenfork.freeworld.util;

import org.joml.Vector3d;

/**
* @author squid233
* @since 0.1.0
*/
public final class MathUtil {
private MathUtil() {
}

public static Vector3d moveRelative(double x, double y, double z, double yawDegrees, Vector3d dest) {
final double dst = x * x + z * z;
double moveX = 0.0;
double moveY = 0.0;
double moveZ = 0.0;
if (dst > 0.001) {
final double sqrt = Math.sqrt(dst);
final double invSqrt = 1.0 / sqrt;
final double yaw = Math.toRadians(yawDegrees);

final double normalX = x * invSqrt;
final double normalZ = z * invSqrt;
final double sin = Math.sin(yaw);
final double cos = Math.cos(yaw);
moveX += normalX * cos + normalZ * sin;
moveZ += normalZ * cos - normalX * sin;
}
moveY += y;
return dest.set(moveX, moveY, moveZ);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
package io.github.xenfork.freeworld.world;

import io.github.xenfork.freeworld.world.chunk.Chunk;
import io.github.xenfork.freeworld.world.entity.Entity;
import io.github.xenfork.freeworld.world.entity.system.MotionSystem;

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

/**
Expand All @@ -24,11 +27,17 @@ public final class World {
public final Chunk c2 = new Chunk(this, 0, 0, 1);
public final Chunk c3 = new Chunk(this, 1, 0, 1);
public final List<Chunk> chunks = List.of(c0, c1, c2, c3);
public final List<Entity> entities = new ArrayList<>();
public final MotionSystem motionSystem = new MotionSystem();

public World(String name) {
chunks.forEach(Chunk::generateTerrain);
}

public void tick() {
motionSystem.process(entities);
}

public Chunk createChunk(int x, int y, int z) {
return new Chunk(this, x, y, z);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@

package io.github.xenfork.freeworld.world.entity;

import io.github.xenfork.freeworld.core.Identifier;
import io.github.xenfork.freeworld.world.World;
import io.github.xenfork.freeworld.world.entity.component.EntityComponent;
import io.github.xenfork.freeworld.world.entity.component.PositionComponent;
import io.github.xenfork.freeworld.world.entity.component.VelocityComponent;
import io.github.xenfork.freeworld.world.entity.component.*;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;

/**
Expand All @@ -27,34 +27,45 @@ public final class Entity {
private final World world;
private final UUID uuid;
private final EntityType entityType;
private final Map<String, EntityComponent> componentMap = new HashMap<>();
private final Map<Identifier, EntityComponent> componentMap = new HashMap<>();

public Entity(World world, UUID uuid, EntityType entityType) {
this.world = world;
this.uuid = uuid;
this.entityType = entityType;
entityType.defaultComponents().forEach(this::addComponent);
for (var supplier : entityType.defaultComponents()) {
addComponent(supplier.get());
}
}

public void addComponent(EntityComponent component) {
final String name = component.componentName();
if (componentMap.containsKey(name)) {
Objects.requireNonNull(component);
final Identifier id = component.componentId();
if (componentMap.containsKey(id)) {
return;
}
componentMap.put(name, component);
componentMap.put(id, component);
}

@SuppressWarnings("unchecked")
public <T extends EntityComponent> T getComponent(String name) {
return (T) componentMap.get(name);
public <T extends EntityComponent> T getComponent(Identifier id) {
return (T) componentMap.get(id);
}

public boolean hasComponent(Identifier id) {
return componentMap.containsKey(id);
}

public PositionComponent position() {
return getComponent(PositionComponent.NAME);
return getComponent(PositionComponent.ID);
}

public RotationXYComponent rotation() {
return getComponent(RotationXYComponent.ID);
}

public VelocityComponent velocity() {
return getComponent(VelocityComponent.NAME);
return getComponent(VelocityComponent.ID);
}

public World world() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,21 @@
import io.github.xenfork.freeworld.world.entity.component.EntityComponent;

import java.util.List;
import java.util.function.Supplier;

/**
* @author squid233
* @since 0.1.0
*/
@SuppressWarnings("ClassCanBeRecord")
public final class EntityType {
private final List<EntityComponent> defaultComponents;
private final List<Supplier<EntityComponent>> defaultComponents;

public EntityType(List<EntityComponent> defaultComponents) {
public EntityType(List<Supplier<EntityComponent>> defaultComponents) {
this.defaultComponents = defaultComponents;
}

public List<EntityComponent> defaultComponents() {
public List<Supplier<EntityComponent>> defaultComponents() {
return defaultComponents;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import io.github.xenfork.freeworld.core.registry.BuiltinRegistries;
import io.github.xenfork.freeworld.core.registry.Registry;
import io.github.xenfork.freeworld.world.entity.component.PositionComponent;
import io.github.xenfork.freeworld.world.entity.component.RotationXYComponent;
import io.github.xenfork.freeworld.world.entity.component.VelocityComponent;

import java.util.List;
Expand All @@ -23,7 +24,15 @@
* @since 0.1.0
*/
public final class EntityTypes {
public static final EntityType PLAYER = register(0, "player", new EntityType(List.of(new PositionComponent(), new VelocityComponent())));
public static final EntityType PLAYER = register(0, "player",
new EntityType(List.of(
PositionComponent::new,
RotationXYComponent::new,
VelocityComponent::new
)));

private EntityTypes() {
}

private static EntityType register(int rawId, String name, EntityType entityType) {
return Registry.register(BuiltinRegistries.ENTITY_TYPE, Identifier.ofBuiltin(name), rawId, entityType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@

package io.github.xenfork.freeworld.world.entity.component;

import io.github.xenfork.freeworld.core.Identifier;

/**
* @author squid233
* @since 0.1.0
*/
public sealed interface EntityComponent permits
PositionComponent,
VelocityComponent {
public sealed interface EntityComponent permits PositionComponent, RotationXYComponent, VelocityComponent {
/**
* {@return a unique name of this component}
* {@return a unique identifier of this component}
*/
String componentName();
Identifier componentId();
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,22 @@

package io.github.xenfork.freeworld.world.entity.component;

import io.github.xenfork.freeworld.core.Identifier;
import org.joml.Vector3d;

/**
* @author squid233
* @since 0.1.0
*/
public record PositionComponent(Vector3d position) implements EntityComponent {
public static final String NAME = "position";
public static final Identifier ID = Identifier.ofBuiltin("position");

public PositionComponent() {
this(new Vector3d());
}

@Override
public String componentName() {
return NAME;
public Identifier componentId() {
return ID;
}
}
Loading

0 comments on commit e204b1c

Please sign in to comment.