Separated packet management to it's own thread, optimised the physics to only test bodies with mass, added 2D Noise, fixed pivot points

This commit is contained in:
Halbear 2026-08-26 16:33:02 +01:00
parent c9ef43a2a0
commit 5ea45890c8
47 changed files with 704 additions and 307 deletions

View file

@ -1,4 +1,4 @@
# Made in Blockbench 5.1.4
newmtl m_69683abb-0cbc-2632-be2c-1aa8a2ddc888
map_Kd cubetexture.png
newmtl m_b3ff62ec-245d-6ae0-3e07-f637264603d3
map_Kd cubetexture2.png
newmtl none

View file

@ -1,5 +1,5 @@
# Made in Blockbench 5.1.4
mtllib Cube.mtl
mtllib CollisionCube.mtl
o mesh
v 0.5 1 0.5
@ -10,37 +10,37 @@ v -0.5 1 0.5
v -0.5 1 -0.5
v -0.5 0 0.5
v -0.5 0 -0.5
vt 0.25 1
vt 0.3333333333333333 1
vt 0 1
vt 0 0.75
vt 0.25 0.75
vt 0.25 0.484375
vt 0.25 0.734375
vt 0 0.734375
vt 0 0.484375
vt 0.265625 0.75
vt 0.515625 0.75
vt 0.515625 1
vt 0.265625 1
vt 0.515625 0.484375
vt 0.515625 0.734375
vt 0.265625 0.734375
vt 0.265625 0.484375
vt 0.25 0.21875
vt 0.25 0.46875
vt 0 0.46875
vt 0 0.21875
vt 0.78125 1
vt 0.53125 1
vt 0.53125 0.75
vt 0.78125 0.75
vt 0 0.6666666666666667
vt 0.3333333333333333 0.6666666666666667
vt 0.3333333333333333 0.33333333333333337
vt 0.3333333333333333 0.6666666666666667
vt 0 0.6666666666666667
vt 0 0.33333333333333337
vt 0.3333333333333333 0.6666666666666667
vt 0.6666666666666666 0.6666666666666667
vt 0.6666666666666666 1
vt 0.3333333333333333 1
vt 0.6666666666666666 0.33333333333333337
vt 0.6666666666666666 0.6666666666666667
vt 0.3333333333333333 0.6666666666666667
vt 0.3333333333333333 0.33333333333333337
vt 0.3333333333333333 0
vt 0.3333333333333333 0.33333333333333337
vt 0 0.33333333333333337
vt 0 0
vt 1 1
vt 0.6666666666666666 1
vt 0.6666666666666666 0.6666666666666667
vt 1 0.6666666666666667
vn 1 0 0
vn -1 0 0
vn 0 1 0
vn 0 -1 0
vn 0 0 1
vn 0 0 -1
usemtl m_69683abb-0cbc-2632-be2c-1aa8a2ddc888
usemtl m_b3ff62ec-245d-6ae0-3e07-f637264603d3
f 2/1/1 1/2/1 3/3/1 4/4/1
f 7/5/2 5/6/2 6/7/2 8/8/2
f 5/9/3 1/10/3 2/11/3 6/12/3

Binary file not shown.

View file

@ -15,7 +15,7 @@
},
{
"ID": "Cube-mat-1",
"TexturePath": "resources\\models\\cube\\cubetexture.png",
"TexturePath": "resources\\models\\cube\\cubetexture2.png",
"NormalTexturePath": "",
"MetalRoughnessMap": "",
"DiffuseColour": {

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -13,8 +13,9 @@ import java.util.UUID;
public class Launcher {
@Parameter(names = "-server", description = "is this a server")
@Parameter(names = "-server", description = "toggle server/client")
private boolean Server = false;
public static void main(String[] args){
var Main = new Launcher();
var jCommander = JCommander.newBuilder().addObject(Main).build();

View file

@ -40,7 +40,7 @@ public class Server {
public static final Queue<Packet> OutGoingPacketQueue = new ConcurrentLinkedQueue<>();
public static final Queue<Packet> IncomingPacketQueue = new ConcurrentLinkedQueue<>();
public static void CollectIncomingPackets(){
public static synchronized void CollectIncomingPackets(){
ClientSession.GetClientSessionInstances().forEach((uuid, client)->{
client.CollectIncomingPackets(IncomingPacketQueue);
});
@ -53,14 +53,14 @@ public class Server {
});
}
public static void ProcessIncomingPackets(){
public static synchronized void ProcessIncomingPackets(){
Packet packet;
while((packet = IncomingPacketQueue.poll()) != null){
ServerSideNetworkUtils.ProcessClientPacket(packet);
}
}
public static void ProcessOutgoingPackets(){
public static synchronized void ProcessOutgoingPackets(){
Packet packet;
ClientSession.ProcessOutboundPackets();
while((packet = OutGoingPacketQueue.poll()) != null){

View file

@ -88,10 +88,10 @@ public class EngineConfig {
public RenderAPI RenderingAPI = RenderAPI.Vulkan;
public float MusicVolume = 0.0f;
public float SoundVolume = 0.0f;
public float WeaponVolume = 0.0f;
public float AmbientVolume = 0.0f;
public float MusicVolume = 0.5f;
public float SoundVolume = 0.5f;
public float WeaponVolume = 0.5f;
public float AmbientVolume = 0.5f;
public float PlayerOnline = 1.0f;

View file

@ -12,4 +12,5 @@ public interface IPhysicsController {
public String MeshID();
public void PhysicsTick(float DeltaTime, float TargetFrameRate);
public List<String> Collisions();
public boolean Static();
}

View file

@ -1,7 +1,7 @@
package net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.VisualisedCollisionActor;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.VisualisedCollisionActor3D;
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
import org.joml.Quaternionf;
import org.joml.Vector3f;
@ -25,6 +25,7 @@ public class ConvexMesh {
public static final Map<UUID, ConvexMesh> MeshRegistry = new HashMap<>();
public final List<Vector3f> LocalVertices = new ArrayList<>();
public final List<int[]> Triangles = new ArrayList<>();
public final List<Face> Faces = new ArrayList<>();
public final List<int[]> Edges = new ArrayList<>();
@ -112,10 +113,18 @@ public class ConvexMesh {
mesh.Faces.add(new Face(new int[]{0, 4, 7, 3}, new Vector3f(-1, 0, 0))); // -X
mesh.Faces.add(new Face(new int[]{1, 2, 6, 5}, new Vector3f( 1, 0, 0))); // +X
for(int i = 0; i < mesh.Faces.size(); i++){
ConvexMesh.Face face = mesh.Faces.get(i);
int[] Tri1 = new int[]{face.Indices[0],face.Indices[1],face.Indices[2]};
int[] Tri2 = new int[]{face.Indices[1],face.Indices[3],face.Indices[2]};
mesh.Triangles.add(Tri1);
mesh.Triangles.add(Tri2);
}
int[][] e = {{0,1},{1,2},{2,3},{3,0},{4,5},{5,6},{6,7},{7,4},{0,4},{1,5},{2,6},{3,7}};
mesh.Edges.addAll(Arrays.asList(e));
if(!PrimaryRuntime.IsServer && !RenderThread.Headless) {
PrimaryRuntime.GetEngineInstance().scene().AddActor(new VisualisedCollisionActor("VISUALISEDACTOR" + mesh.MeshID.toString(), mesh.Position, mesh.MeshID));
PrimaryRuntime.GetEngineInstance().scene().AddActor(new VisualisedCollisionActor3D("VISUALISEDACTOR" + mesh.MeshID.toString(), mesh.Position, mesh.MeshID));
}
return mesh;
}

View file

@ -3,7 +3,7 @@ package net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.IPhysicsController;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.WorldPhysicsManager;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
import org.joml.Vector3f;
@ -50,15 +50,15 @@ public class RigidPhysicsController implements IPhysicsController {
RigidBodyID = ActorID + "_RIGID_BODY";
RigidBody newRigidBody = new RigidBody(RigidBodyID,Shape,MassKG);
newRigidBody.SetRigidBoxInertia(0.5f,0.5f,0.5f);
newRigidBody.Position.set(Actor.Actors.get(ActorID).GetPosition());
newRigidBody.Rotation.set(Actor.Actors.get(ActorID).GetRotation());
newRigidBody.Position.set(Actor3D.Actors.get(ActorID).GetPosition());
newRigidBody.Rotation.set(Actor3D.Actors.get(ActorID).GetRotation());
newRigidBody.UpdateInertiaWorld();
WorldPhysicsManager.PhysicsObjects.put(ControllerID, this);
WorldPhysicsManager.ActiveControllers.add(ControllerID);
if(RigidBodyID != null && RigidBodyRegister.get(RigidBodyID) != null && ActorID != "NULL") {
RigidBody rigidBody = RigidBodyRegister.get(RigidBodyID);
if (Actor.Actors.get(ActorID) != null) {
Actor.Actors.get(ActorID).SetPivotOffset(new Vector3f(0, (rigidBody.shape.TopRightForward.y - rigidBody.shape.BottomLeftBack.y) / 2f, 0));
if (Actor3D.Actors.get(ActorID) != null) {
Actor3D.Actors.get(ActorID).SetPivotOffset(new Vector3f(0, (rigidBody.shape.TopRightForward.y - rigidBody.shape.BottomLeftBack.y) / 2f, 0));
}
}
return this;
@ -69,8 +69,8 @@ public class RigidPhysicsController implements IPhysicsController {
WorldPhysicsManager.PhysicsObjects.put(ControllerID, this);
WorldPhysicsManager.ActiveControllers.add(ControllerID);
if( rigidBody != null && ActorID != "NULL") {
if (Actor.Actors.get(ActorID) != null) {
Actor.Actors.get(ActorID).SetPivotOffset(new Vector3f(0, (rigidBody.shape.TopRightForward.y - rigidBody.shape.BottomLeftBack.y) / 2f, 0));
if (Actor3D.Actors.get(ActorID) != null) {
Actor3D.Actors.get(ActorID).SetPivotOffset(new Vector3f(0, (rigidBody.shape.TopRightForward.y - rigidBody.shape.BottomLeftBack.y) / 2f, 0));
}
}
return this;
@ -96,9 +96,11 @@ public class RigidPhysicsController implements IPhysicsController {
return RigidBodyID;
}
private RigidBody bodyCache = null;
@Override
public void PhysicsTick(float DeltaTime, float TargetFrameRate) {
Actor actor = Actor.Actors.get(ActorID);
Actor3D actor = Actor3D.Actors.get(ActorID);
if(!PrimaryRuntime.IsServer
&& ClientSideNetworkUtils.Connected
@ -113,10 +115,11 @@ public class RigidPhysicsController implements IPhysicsController {
if(RigidBodyID != null && RigidBodyRegister.get(RigidBodyID) != null && ActorID != "NULL") {
RigidBody rigidBody = RigidBodyRegister.get(RigidBodyID);
if(bodyCache == null) bodyCache = rigidBody;
rigidBody.Integrate(DeltaTime, new Vector3f(0,-1.8f,0));
if(Actor.Actors.get(ActorID) != null) {
Actor.Actors.get(ActorID).SetPosition(new Vector3f(rigidBody.Position));
if(ApplyRotation && Actor.Actors.get(ActorID) != null) Actor.Actors.get(ActorID).SetRotation(rigidBody.Rotation);
if(Actor3D.Actors.get(ActorID) != null) {
Actor3D.Actors.get(ActorID).SetPosition(new Vector3f(rigidBody.Position));
if(ApplyRotation && Actor3D.Actors.get(ActorID) != null) Actor3D.Actors.get(ActorID).SetRotation(rigidBody.Rotation);
}
}
/*
@ -144,4 +147,9 @@ public class RigidPhysicsController implements IPhysicsController {
return Collisions;
}
@Override
public boolean Static() {
return (bodyCache == null ? RigidBodyRegister.get(RigidBodyID) == null || RigidBodyRegister.get(RigidBodyID).MassKG == 0 : bodyCache.MassKG == 0);
}
}

View file

@ -3,7 +3,7 @@ package net.halbear.Terrain4J.EngineCore.Logic.Physics;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.*;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
import net.halbear.Terrain4J.EngineCore.Threads.InstancedPhysicsThread;
import org.joml.Vector2f;
@ -146,15 +146,15 @@ public class WorldPhysicsManager {
return false;
}
Actor actor = GetActorForRigidBody(body);
Actor3D actor = GetActorForRigidBody(body);
return actor != null
&& actor.IsServerSynced()
&& !actor.GetID().equals(ClientSideNetworkUtils.OwnedActorID);
}
public static Actor GetActorForRigidBody(RigidBody body) {
for (Actor actor : Actor.Actors.values()) {
public static Actor3D GetActorForRigidBody(RigidBody body) {
for (Actor3D actor : Actor3D.Actors.values()) {
if (!(actor.GetPhysicsController() instanceof RigidPhysicsController rigidPhysicsController)) {
continue;
}
@ -189,9 +189,8 @@ public class WorldPhysicsManager {
for (int i = 0; i < ActiveControllers.size(); i++) {
IPhysicsController controller = PhysicsObjects.get(ActiveControllers.get(i));
if(controller != null) {
controller.PhysicsTick(DeltaTime, TargetFrameTime);
}
if(controller == null || controller.Static()) continue;
controller.PhysicsTick(DeltaTime, TargetFrameTime);
}
SweepForTunneling();
@ -201,9 +200,8 @@ public class WorldPhysicsManager {
for (int i = 0; i < ActiveControllers.size(); i++) {
IPhysicsController controller = PhysicsObjects.get(ActiveControllers.get(i));
if(controller != null) {
controller.Collisions().clear();
}
if(controller == null || controller.Static()) continue;
controller.Collisions().clear();
}
}
@ -213,7 +211,7 @@ public class WorldPhysicsManager {
IPhysicsController controller = PhysicsObjects.get(ActiveControllers.get(i));
if(!(controller instanceof RigidPhysicsController rigidPhysicsController)) continue;
Actor actor = Actor.Actors.get(rigidPhysicsController.ActorID);
Actor3D actor = Actor3D.Actors.get(rigidPhysicsController.ActorID);
RigidBody body = RigidBody.RigidBodyRegister.get(rigidPhysicsController.RigidBodyID);
if(actor == null || body == null) continue;

View file

@ -21,7 +21,13 @@ import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.RigidPhysicsCont
import net.halbear.Terrain4J.EngineCore.Logic.Physics.WorldPhysicsManager;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.ModelLoader;
import net.halbear.Terrain4J.EngineCore.Main.Scene.*;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3DElement;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.PlayerActor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.VisualisedCollisionActor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.*;
import net.halbear.Terrain4J.EngineCore.Main.Util.Maths.Noise2D;
import net.halbear.Terrain4J.EngineCore.Main.Util.Maths.PermutationArray;
import net.halbear.Terrain4J.EngineCore.Profiling.CPUMonitor;
import net.halbear.Terrain4J.EngineCore.Profiling.GPUProfiler;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
@ -34,12 +40,12 @@ import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToS
import org.joml.Matrix4f;
import org.joml.Vector2f;
import org.joml.Vector3f;
import org.joml.Vector3i;
import org.lwjgl.openal.AL11;
import org.tinylog.Logger;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class GameCore implements GameLogic {
@ -71,6 +77,15 @@ public class GameCore implements GameLogic {
private Vector2f DeltaPos = new Vector2f(0,0);
private String PlayerActorID = "NULL";
public static Map<Vector3i, Boolean> getChunkMap() {
return ChunkMap;
}
public static void setChunkMap(Map<Vector3i, Boolean> chunkMap) {
ChunkMap.clear();
ChunkMap.putAll(chunkMap);
}
public Vector2f GetDeltaPos(){return DeltaPos;}
@Override
public void cleanup() {
@ -85,13 +100,13 @@ public class GameCore implements GameLogic {
CubeModelID = MelonaData.ID();
List<MaterialData> MelonaMat = ModelLoader.LoadMaterials("resources/models/cube/Cube_mat.json");
var CollisionVisualisationData = ModelLoader.LoadModel("resources/models/VisualCollision/CollisionCube.json");
VisualisedCollisionActor.CollisionCubeModelID = CollisionVisualisationData.ID();
VisualisedCollisionActor3D.CollisionCubeModelID = CollisionVisualisationData.ID();
List<MaterialData> CollisionVisualisationMat = ModelLoader.LoadMaterials("resources/models/VisualCollision/CollisionCube_mat.json");
List<MaterialData> materials = new ArrayList<>();
var Melona = ModelLoader.LoadModel("resources/models/melona/melona.json");
List<MaterialData> MelonaMaterial = ModelLoader.LoadMaterials("resources/models/melona/melona_mat.json");
PlayerActor.MelonaModelID = Melona.ID();
PlayerActor3D.MelonaModelID = Melona.ID();
MusketData = ModelLoader.LoadModel("resources/models/musket/musket.json");
List<MaterialData> MusketMat = ModelLoader.LoadMaterials("resources/models/musket/musket_mat.json");
@ -169,11 +184,8 @@ public class GameCore implements GameLogic {
ActorEditorComponents.get(i).UpdateAll();
}
if(PrimaryRuntime.IsServer) {
for (int x = -5; x < 6; x++) {
for (int y = -5; y < 6; y++) {
SpawnNewStaticActor(engineInstance, new Vector3f(x * 4f, -4 * (float) Math.random(), y * 4f), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1));
}
}
permutation.GeneratePermutationArray(5783904701859L);
GenerateChunk(new Vector3i(0, 0, 0), 16);
for(int i = 0; i < 20; i++){
SpawnNewActor(engineInstance, new Vector3f(-5 + (float)Math.random() * 10,10 + (float)Math.random() * 10, -5 + (float)Math.random() * 10), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1));
}
@ -188,6 +200,19 @@ public class GameCore implements GameLogic {
instance.scene().Reset();
}
private static final PermutationArray permutation = new PermutationArray();
private static final Map<Vector3i, Boolean> ChunkMap = new ConcurrentHashMap<>();
private void GenerateChunk(Vector3i Position, int ChunkSize){
for (int x = Position.x * ChunkSize; x < (Position.x + 1) * ChunkSize; x++) {
for (int y = Position.z * ChunkSize; y < (Position.z + 1) * ChunkSize; y++) {
SpawnNewStaticActor(PrimaryRuntime.GetEngineInstance(), new Vector3f(x , (int)(Math.floor(-2 + (float)(Noise2D.FractalNoise(x, y, 5, 10, 0.01, permutation)))), y), new Vector3f(0, 0, 0), new Vector3f(1, 1, 1));
}
}
ChunkMap.put(Position, true);
}
private static final Vector3f SpawnPosition = new Vector3f();
private static final Vector3f SpawnDirection = new Vector3f();
private static final Matrix4f rotationMatrix = new Matrix4f();
@ -206,11 +231,14 @@ public class GameCore implements GameLogic {
SpawnDirection.set(new Vector3f(Direction));
rotationMatrix.positiveZ(SpawnDirection).negate().mul(5);
SpawnPosition.add(SpawnDirection);
var Melona = new Actor("MelonaSpawned" + scene.GetActors().size(), CubeModelID, new Vector3f(SpawnPosition));
var Melona = new Actor3D("MelonaSpawned" + scene.GetActors().size(), CubeModelID, new Vector3f(SpawnPosition));
Logger.info("Spawning static cube actor [{}] with model ID [{}], with cached ID of [{}]", Melona.GetID(), Melona.GetModelID(),CubeModelID);
Melona.SetScale(4f);
Melona.CreatePhysicsController( ConvexMesh.Box(2.0f,2.0f,2.0f),0);
Melona.SetScale(1f);
ConvexMesh mesh = ConvexMesh.Box(0.5f,0.5f,0.5f);
Melona.CreatePhysicsController(mesh ,0);
Melona.SetPositionOffset(new Vector3f(0,0,0));
Melona.SetServerSynced(false);
scene.AddActor(Melona);
@ -227,18 +255,28 @@ public class GameCore implements GameLogic {
this.PlayerActorID = id;
}
public PlayerActor SpawnNetworkPlayer(EngineInstance engineInstance, UUID clientID){
public static List<PlayerActor3D> PlayerActors = new ArrayList<>();
public static void AddPlayerActor(PlayerActor3D playerActor) {
PlayerActors.add(playerActor);
}
public static void RemovePlayerActor(PlayerActor3D playerActor) {
PlayerActors.remove(playerActor);
}
public PlayerActor3D SpawnNetworkPlayer(EngineInstance engineInstance, UUID clientID){
var scene = engineInstance.scene();
String actorID = "Player_" + clientID;
PlayerActor player = new PlayerActor(
PlayerActor3D player = new PlayerActor3D(
"NULL",
actorID,
MusketData.ID(),
new Vector3f(0, 8f, 0)
).SetCameraOffset(new Vector3f(0, 1.85f, 0));
player.SetPositionOffset(new Vector3f(0.5f, 1.25f, -1.25f));
player.SetPositionOffset(new Vector3f(0.5f, 0.25f, -1.25f));
player.SetRotation(0, (float)Math.toRadians(180), 0);
player.CreatePhysicsController(ConvexMesh.Box(0.6f, 1.0f, 0.6f), 200f);
player.SetServerSynced(true);
@ -247,6 +285,7 @@ public class GameCore implements GameLogic {
RigidBody.RigidBodyRegister.get(physicsController.RigidBodyID).LockRotation();
scene.AddActor(player);
AddPlayerActor(player);
scene.NetworkedActors().add(player.GetID());
return player;
}
@ -259,7 +298,8 @@ public class GameCore implements GameLogic {
SpawnDirection.set(new Vector3f(Direction));
rotationMatrix.positiveZ(SpawnDirection).negate().mul(5);
SpawnPosition.add(SpawnDirection);
var Melona = new Actor("MelonaSpawned" + scene.GetActors().size(), CubeModelID, new Vector3f(SpawnPosition));
var Melona = new Actor3D("MelonaSpawned" + scene.GetActors().size(), CubeModelID, new Vector3f(SpawnPosition));
Melona.SetPivotOffset(new Vector3f(0,0f,0));
Melona.CreatePhysicsController( ConvexMesh.Box(0.5f,0.5f,0.5f),20);
Melona.SetServerSynced(true);
@ -281,7 +321,7 @@ public class GameCore implements GameLogic {
SpawnDirection.set(new Vector3f(Direction));
rotationMatrix.positiveZ(SpawnDirection).negate().mul(5);
SpawnPosition.add(SpawnDirection);
var Melona = new Actor("MelonaSpawned" + scene.GetActors().size(), CubeModelID, new Vector3f(SpawnPosition));
var Melona = new Actor3D("MelonaSpawned" + scene.GetActors().size(), CubeModelID, new Vector3f(SpawnPosition));
Melona.CreatePhysicsController( ConvexMesh.Box(0.75f,1.2f,0.5f),20);
scene.AddActor(Melona);
@ -295,6 +335,7 @@ public class GameCore implements GameLogic {
audioManager.SetAttenuationModel(AL11.AL_EXPONENT_DISTANCE);
audioManager.SetListener(new SoundListener(camera.GetPosition()));
engineInstance.scene().SetUpAudio(engineInstance, audioManager);
AudioInstance.ApplyUniversalVolume();
}
public void SwitchBGM(EngineInstance engineInstance, IScene scene, String path) {
AudioInstance bgm = scene.audioInstances().get("BGM");
@ -345,12 +386,12 @@ public class GameCore implements GameLogic {
PlayerActorID = ClientSideNetworkUtils.GetPlayerControlledActorID();
}
Actor player = Actor.Actors.get(PlayerActorID);
Actor3D player = Actor3D.Actors.get(PlayerActorID);
if(player != null){
player.TickUpdate();
}
for(Actor actor : engineInstance.scene().GetActors()) {
for(Actor3D actor : engineInstance.scene().GetActors()) {
if(actor != null
&& actor.IsServerSynced()
&& !actor.IsStaticRigidBody()
@ -391,8 +432,8 @@ public class GameCore implements GameLogic {
return;
}
Actor ownedActor = Actor.Actors.get(ClientSideNetworkUtils.GetPlayerControlledActorID());
if(!(ownedActor instanceof PlayerActor networkPlayer)) {
Actor3D ownedActor = Actor3D.Actors.get(ClientSideNetworkUtils.GetPlayerControlledActorID());
if(!(ownedActor instanceof PlayerActor3D networkPlayer)) {
return;
}
@ -413,8 +454,8 @@ public class GameCore implements GameLogic {
return;
}
Actor localActor = Actor.Actors.get(PlayerActorID);
if(!(localActor instanceof PlayerActor playerActor)) {
Actor3D localActor = Actor3D.Actors.get(PlayerActorID);
if(!(localActor instanceof PlayerActor3D playerActor)) {
return;
}
@ -468,12 +509,12 @@ public class GameCore implements GameLogic {
@Override
public void Update(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
if(!PrimaryRuntime.IsServer && !RenderThread.Headless) {
for (int i = 0; i < VisualisedCollisionActor.CollisionVisuals.size(); i++) {
VisualisedCollisionActor.CollisionVisuals.get(i).Update();
for (int i = 0; i < VisualisedCollisionActor3D.CollisionVisuals.size(); i++) {
VisualisedCollisionActor3D.CollisionVisuals.get(i).Update();
}
for(int i = 0; i < ActorElement.ElementNames.size(); i++){
if( ActorElement.ActorElementRegistry.get(ActorElement.ElementNames.get(i)) == null) continue;
ActorElement.ActorElementRegistry.get(ActorElement.ElementNames.get(i)).UpdateModelMatrix();
for(int i = 0; i < Actor3DElement.ElementNames.size(); i++){
if( Actor3DElement.ActorElementRegistry.get(Actor3DElement.ElementNames.get(i)) == null) continue;
Actor3DElement.ActorElementRegistry.get(Actor3DElement.ElementNames.get(i)).UpdateModelMatrix();
}
}
}
@ -486,20 +527,25 @@ public class GameCore implements GameLogic {
float PhysicsFrameTime = 1000f/PhysicsFramerate;
float DeltaTime = (float)FrameDiffNanoSeconds/(PhysicsFrameTime*1000000f);
if(PrimaryRuntime.IsServer){
if(UseLegacyNetworking) Server.LegacyCollectIncomingPackets(); else Server.CollectIncomingPackets();
if(UseLegacyNetworking) Server.LegacyProcessIncomingPackets(); else Server.ProcessIncomingPackets();
/* if(UseLegacyNetworking) Server.LegacyCollectIncomingPackets();
else*/ //Server.CollectIncomingPackets();
/*if(UseLegacyNetworking) Server.LegacyProcessIncomingPackets();
else*/ //Server.ProcessIncomingPackets();
WorldPhysicsManager.PhysicsTick2(DeltaTime, PhysicsFramerate);
PlayerActors.forEach(playerActor -> {
Vector3i ChunkPosition = new Vector3i((int)Math.floor(playerActor.GetPosition().x / 16), (int)Math.floor(playerActor.GetPosition().y / 16), (int)Math.floor(playerActor.GetPosition().z / 16));
if(!ChunkMap.containsKey(ChunkPosition))GenerateChunk(ChunkPosition, 16);
});
if(PrimaryRuntime.GetFastThread().Ticks(6) == 0) {
for(Actor actor : engineInstance.scene().GetActors()) {
if(actor.IsServerSynced() && !actor.IsStaticRigidBody()) {
ServerSideNetworkUtils.SendEntityUpdatePacket(actor);
}
}
// for(Actor3D actor : engineInstance.scene().GetActors()) {
// if(actor.IsServerSynced() && !actor.IsStaticRigidBody()) {
// ServerSideNetworkUtils.SendEntityUpdatePacket(actor);
// }
// }
}
if(UseLegacyNetworking) Server.LegacyProcessOutgoingPackets(); else Server.ProcessOutgoingPackets();
/*if(UseLegacyNetworking) Server.LegacyProcessOutgoingPackets();
else*/ //Server.ProcessOutgoingPackets();
} else {
ClientSideNetworkUtils.DecodePackets(engineInstance, this, engineInstance.scene());
if(!UseLegacyNetworking) ClientSideNetworkUtils.SendNIOPacketQueue();

View file

@ -1,22 +1,20 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene;
package net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.IPhysicsController;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.ConvexMesh;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.RigidBody;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.RigidPhysicsController;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel.ModelData;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import org.tinylog.Logger;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Actor{
public class Actor3D {
public enum PhysicsControllerType{
RigidBodySeparatingAxisTheory,
@ -25,23 +23,23 @@ public class Actor{
public float Health = 100f;
public static final Map<String, Actor> Actors = new HashMap<>();
public static final Map<String, Actor3D> Actors = new HashMap<>();
public static final List<String> ActorNames = new ArrayList<>();
protected final String ID;
protected String ModelID;
protected final Matrix4f ModelMatrix;
protected final Vector3f Position;
protected final Vector3f PositionOffset;
protected final Quaternionf Rotation;
protected Vector3f Scale;
public final String ID;
public String ModelID;
public final Matrix4f ModelMatrix;
public final Vector3f Position;
public final Vector3f PositionOffset;
public final Quaternionf Rotation;
public Vector3f Scale;
private IPhysicsController physicsController;
protected final Vector3f PivotOffset;
protected final Vector3f AdditionalPivotOffset;
protected final Vector3f TemporaryVector;
protected boolean ServerSynced = false;
protected boolean HasNetworkTarget = false;
protected final Vector3f NetworkTargetPosition = new Vector3f();
protected final Quaternionf NetworkTargetRotation = new Quaternionf();
public final Vector3f PivotOffset;
public final Vector3f AdditionalPivotOffset;
public final Vector3f TemporaryVector;
public boolean ServerSynced = false;
public boolean HasNetworkTarget = false;
public final Vector3f NetworkTargetPosition = new Vector3f();
public final Quaternionf NetworkTargetRotation = new Quaternionf();
public PhysicsControllerType PhysicsType = PhysicsControllerType.RigidBodySeparatingAxisTheory;
public void SetPhysicsType(PhysicsControllerType type){
@ -49,7 +47,7 @@ public class Actor{
}
public Actor(String ID, String ModelID, Vector3f Position){
public Actor3D(String ID, String ModelID, Vector3f Position){
this.ID = ID;
ActorNames.add(ID);
this.ModelID = ModelID;
@ -65,34 +63,36 @@ public class Actor{
Actors.put(ID,this);
}
public Actor SetPositionOffset(Vector3f PositionOffset){
public Actor3D SetPositionOffset(Vector3f PositionOffset){
this.PositionOffset.set(PositionOffset);
return this;
}
public Actor SetPositionOffset(float x, float y, float z){
public Actor3D SetPositionOffset(float x, float y, float z){
this.PositionOffset.set(x,y,z);
return this;
}
public Vector3f GetAditionalPivotOffset(){return AdditionalPivotOffset;}
public Actor SetAditionalPivotOffset(Vector3f offset){
public Actor3D SetAditionalPivotOffset(Vector3f offset){
AdditionalPivotOffset.set(offset);
UpdateModelMatrix();
return this;
}
public Vector3f GetPivotOffset(){return PivotOffset;}
public Actor SetPivotOffset(Vector3f offset){
public Actor3D SetPivotOffset(Vector3f offset){
PivotOffset.set(offset);
UpdateModelMatrix();
return this;
}
public void TickUpdate() {
}
public Actor SetServerSynced(boolean synced){
public Actor3D SetServerSynced(boolean synced){
this.ServerSynced = synced;
return this;
}
@ -103,7 +103,7 @@ public class Actor{
public boolean IsStaticRigidBody(){
RigidBody rigidBody = GetRigidBody();
return rigidBody != null && rigidBody.IsStatic;
return rigidBody != null && (rigidBody.IsStatic || rigidBody.MassKG == 0);
}
public void SetNetworkTarget(Vector3f position, Quaternionf rotation){
@ -136,39 +136,39 @@ public class Actor{
public IPhysicsController GetPhysicsController(){return physicsController;}
public Actor CreatePhysicsController(ConvexMesh mesh, float Mass){
public Actor3D CreatePhysicsController(ConvexMesh mesh, float Mass){
physicsController = new RigidPhysicsController(ID + "_RIGID_CONTROLLER", ID).CreateRigidBody(mesh, Mass);
return this;
}
public Actor ResetRotation(){
public Actor3D ResetRotation(){
Rotation.x = 0;
Rotation.y = 0;
Rotation.z = 0;
Rotation.w = 1.0f;
return this;
}
public Actor SetRotation(Quaternionf rot){
public Actor3D SetRotation(Quaternionf rot){
Rotation.set(rot);
UpdateModelMatrix();
return this;
}
public Actor SetRotMatrix(Vector3f rot){
public Actor3D SetRotMatrix(Vector3f rot){
Rotation.set(0,0,0,1.0f);
SetRotation(rot);
return this;
}
public Actor SetRotation(Vector3f rot){
public Actor3D SetRotation(Vector3f rot){
Rotation.rotateX(rot.x);
Rotation.rotateY(rot.y);
Rotation.rotateZ(rot.z);
UpdateModelMatrix();
return this;
}
public Actor SetRotation(float x, float y, float z){
public Actor3D SetRotation(float x, float y, float z){
Rotation.identity();
Rotation.rotateX(x);
Rotation.rotateY(y);
@ -176,17 +176,17 @@ public class Actor{
UpdateModelMatrix();
return this;
}
public Actor SetPosition(Vector3f position){
public Actor3D SetPosition(Vector3f position){
Position.set(position);
UpdateModelMatrix();
return this;
}
public Actor SetPosition(float x, float y, float z){
public Actor3D SetPosition(float x, float y, float z){
Position.set(x,y,z);
UpdateModelMatrix();
return this;
}
public Actor SetScale(float x, float y, float z){
public Actor3D SetScale(float x, float y, float z){
Scale.set(x,y,z);
UpdateModelMatrix();
return this;
@ -234,23 +234,28 @@ public class Actor{
return RigidBody.RigidBodyRegister.get(rigidPhysicsController.RigidBodyID);
}
public Actor SetScale(Vector3f Scale){
public Actor3D SetScale(Vector3f Scale){
this.Scale = new Vector3f(Scale);
UpdateModelMatrix();
return this;
}
public Actor SetScale(float Scale){
public Actor3D SetScale(float Scale){
this.Scale = new Vector3f(Scale,Scale,Scale);
UpdateModelMatrix();
return this;
}
public void UpdateModelMatrix(){
ModelMatrix.translateLocal(TemporaryVector.set(PivotOffset).add(AdditionalPivotOffset));
ModelMatrix.translationRotateScale(new Vector3f(Position), Rotation, Scale);
ModelMatrix.translate(PositionOffset);
ModelMatrix.translateLocal(TemporaryVector.negate());
TemporaryVector.set(PivotOffset).add(AdditionalPivotOffset);
ModelMatrix.identity()
.translate(Position)
.translate(TemporaryVector)
.rotate(Rotation)
.translate(TemporaryVector.negate())
.translate(PositionOffset)
.scale(Scale);
}

View file

@ -1,4 +1,4 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene;
package net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.IPhysicsController;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.ConvexMesh;
@ -11,9 +11,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ActorElement extends Actor {
public class Actor3DElement extends Actor3D {
public static Map<String, ActorElement> ActorElementRegistry = new HashMap<>();
public static Map<String, Actor3DElement> ActorElementRegistry = new HashMap<>();
public static List<String> ElementNames = new ArrayList<>();
private String ParentID = "NULL";
@ -21,7 +21,7 @@ public class ActorElement extends Actor {
public Vector3f RotationStrength = new Vector3f(1f,1f,1f);
public ActorElement(String ID, String ModelID, String ParentID, Vector3f PositionOffset){
public Actor3DElement(String ID, String ModelID, String ParentID, Vector3f PositionOffset){
super(ID,ModelID,PositionOffset);
ElementNames.add(ID);
this.ParentID = ParentID;
@ -36,33 +36,33 @@ public class ActorElement extends Actor {
public IPhysicsController GetPhysicsController(){return null;}
@Override
public Actor CreatePhysicsController(ConvexMesh mesh, float Mass){
public Actor3D CreatePhysicsController(ConvexMesh mesh, float Mass){
return this;
}
public Actor GenerateCollisionMesh(ModelData modelData) {
public Actor3D GenerateCollisionMesh(ModelData modelData) {
return this;
}
@Override
public Actor SetPosition(Vector3f position){
public Actor3D SetPosition(Vector3f position){
return this;
}
@Override
public Actor SetPosition(float x, float y, float z){
public Actor3D SetPosition(float x, float y, float z){
return this;
}
@Override
public Vector3f GetPosition(){
Actor Parent = Actor.Actors.get(ParentID);
Actor3D Parent = Actor3D.Actors.get(ParentID);
if(Parent == null) return null;
return new Vector3f(Parent.GetPosition()).add(PositionOffset);
}
@Override
public void UpdateModelMatrix(){
Actor Parent = Actor.Actors.get(ParentID);
Actor3D Parent = Actor3D.Actors.get(ParentID);
if(Parent == null) return;
ModelMatrix.translateLocal(TemporaryVector.set(PivotOffset).add(AdditionalPivotOffset));
ModelMatrix.translationRotateScale(new Vector3f(Parent.GetPosition()), new Quaternionf(Parent.GetRotation()), Scale);

View file

@ -0,0 +1,25 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
import org.joml.*;
public interface ActorPosition {
public double X();
public double Y();
public double Z();
public void X(double x);
public void Y(double y);
public void Z(double z);
public void AddX(double x);
public void AddY(double y);
public void AddZ(double z);
public Vector3f AsVector3f();
public Vector3d AsVector3d();
public Vector3i AsVector3i();
public Vector2f AsVector2f();
public Vector2i AsVector2i();
public Vector2d AsVector2d();
}

View file

@ -0,0 +1,72 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.IPhysicsController;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.ConvexMesh;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Vector3f;
public interface IActor {
public IActor SetPositionOffset(ActorPosition PositionOffset);
public IActor SetPositionOffset(float x, float y, float z);
public ActorPosition GetAditionalPivotOffset();
public IActor SetAditionalPivotOffset(Vector3f offset);
public ActorPosition GetPivotOffset();
public IActor SetPivotOffset(ActorPosition offset);
public void TickUpdate();
public IActor SetServerSynced(boolean synced);
public boolean IsServerSynced();
public boolean IsStaticRigidBody();
public void SetNetworkTarget(ActorPosition position, Quaternionf rotation);
public void InterpolateNetworkTarget(float alpha);
public ActorPosition GetPositionOffset();
public ActorPosition GetAdditionalPivotOffset();
public IPhysicsController GetPhysicsController();
public IActor CreatePhysicsController(ConvexMesh mesh, float Mass);
public IActor ResetRotation();
public IActor SetRotation(Quaternionf rot);
public IActor SetRotMatrix(Vector3f rot);
public IActor SetRotation(Vector3f rot);
public IActor SetRotation(float x, float y, float z);
public IActor SetPosition(Vector3f position);
public IActor SetPosition(float x, float y, float z);
public IActor SetScale(float x, float y, float z);
public void SetNewAngularVelocity(ActorPosition Velocity);
public void SetNewVelocity(ActorPosition Velocity);
public void SetNewRotation(Quaternionf Rotation);
public void SetNewPosition(ActorPosition Position);
public Actor3D SetScale(Vector3f Scale);
public Actor3D SetScale(float Scale);
public void UpdateModelMatrix();
public String GetID();
public String GetModelID();
public void SetModelID(String ModelID);
public Matrix4f GetModelMatrix();
public ActorPosition GetPosition();
public Quaternionf GetRotation();
public Vector3f GetScale();
}

View file

@ -0,0 +1,5 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
public interface IActorVisualController {
public RenderType getRenderType();
}

View file

@ -1,9 +1,9 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene;
package net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import org.joml.Vector3f;
public class ParticleActor extends Actor {
public class ParticleActor3D extends Actor3D {
private Vector3f Velocity;
private Vector3f RotatingAngles;
@ -11,7 +11,7 @@ public class ParticleActor extends Actor {
private int LifeTicks = 1000;
private float decelerationRate = 0.1f;
public ParticleActor(String ID, String ModelID, Vector3f Position, Vector3f RotatingAngles, float Rotation, Vector3f Velocity, float Deceleration, int LifeTicks){
public ParticleActor3D(String ID, String ModelID, Vector3f Position, Vector3f RotatingAngles, float Rotation, Vector3f Velocity, float Deceleration, int LifeTicks){
super(ID,ModelID,Position);
this.Angle = Rotation;
this.RotatingAngles = RotatingAngles;

View file

@ -1,30 +1,29 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene;
package net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.ConvexMesh;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.RigidBody;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.RigidPhysicsController;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Camera;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
import org.joml.Vector3f;
import org.tinylog.Logger;
import java.util.Objects;
public class PlayerActor extends Actor{
public class PlayerActor3D extends Actor3D {
public static String MelonaModelID = "melona";
public String AttachedCameraID;
public final Vector3f CameraOffset = new Vector3f(0,0,0);
Camera PlayerCam;
public Camera PlayerCam;
public PlayerActor(String AttachedCameraID, String ID, String ModelID, Vector3f Position) {
public PlayerActor3D(String AttachedCameraID, String ID, String ModelID, Vector3f Position) {
this.AttachedCameraID = AttachedCameraID;
PlayerCam = Camera.CameraRegistry.get(AttachedCameraID);
super(ID, ModelID, Position);
if(!ClientSideNetworkUtils.OwnsActor(ID) && !RenderThread.Headless && !PrimaryRuntime.IsServer){
ActorElement newMelona = new ActorElement("PlayerModel" + ID, MelonaModelID, ID,new Vector3f(0,0,0));
Actor3DElement newMelona = new Actor3DElement("PlayerModel" + ID, MelonaModelID, ID,new Vector3f(0,0,0));
newMelona.SetScale(1.3f);
newMelona.SetPositionOffset(0,-0.85f,0);
PrimaryRuntime.GetEngineInstance().scene().AddActor(newMelona);
@ -32,7 +31,7 @@ public class PlayerActor extends Actor{
}
@Override
public Actor CreatePhysicsController(ConvexMesh mesh, float Mass){
public Actor3D CreatePhysicsController(ConvexMesh mesh, float Mass){
super.CreatePhysicsController(mesh,Mass);
RigidPhysicsController controller = (RigidPhysicsController)GetPhysicsController();
controller.ApplyRotation = false;
@ -43,7 +42,7 @@ public class PlayerActor extends Actor{
return PlayerCam;
}
public PlayerActor AttachCamera(String cameraID){
public PlayerActor3D AttachCamera(String cameraID){
Camera camera = Camera.CameraRegistry.get(cameraID);
if(camera == null) {
Logger.warn("Could not attach camera [{}] to player actor [{}]", cameraID, GetID());
@ -57,7 +56,7 @@ public class PlayerActor extends Actor{
}
public PlayerActor SetCameraOffset(Vector3f Offset){
public PlayerActor3D SetCameraOffset(Vector3f Offset){
CameraOffset.set(Offset);
return this;
}

View file

@ -0,0 +1,7 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
public enum RenderType {
Mesh,
Sprite,
Billboard
}

View file

@ -1,4 +1,4 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene;
package net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.ConvexMesh;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
@ -9,11 +9,11 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class VisualisedCollisionActor extends Actor{
public static final List<VisualisedCollisionActor> CollisionVisuals = new ArrayList<>();
public class VisualisedCollisionActor3D extends Actor3D {
public static final List<VisualisedCollisionActor3D> CollisionVisuals = new ArrayList<>();
public static String CollisionCubeModelID;
final UUID LinkedMesh;
public VisualisedCollisionActor(String ID, Vector3f Position, UUID LinkedMesh) {
public VisualisedCollisionActor3D(String ID, Vector3f Position, UUID LinkedMesh) {
super(ID, CollisionCubeModelID, Position);
if(!PrimaryRuntime.IsServer && !RenderThread.Headless) {
this.LinkedMesh = LinkedMesh;
@ -28,7 +28,8 @@ public class VisualisedCollisionActor extends Actor{
if(mesh != null) {
SetScale(new Vector3f(mesh.hxhyhz).mul(2.01f));
SetPosition(new Vector3f(mesh.Position.x,mesh.Position.y,mesh.Position.z));
SetPositionOffset(new Vector3f(0,( mesh.GetWorldAABB().minY - mesh.GetWorldAABB().maxY)/2f,0));
SetPivotOffset(new Vector3f(0,0,0));
SetPositionOffset(new Vector3f(0,(( mesh.GetWorldAABB().minY - mesh.GetWorldAABB().maxY)/GetScale().y)/2f,0));
SetRotation(mesh.Orientation);
}
}

View file

@ -1,5 +1,6 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.Gimbal;
import org.joml.Vector3f;
@ -9,12 +10,12 @@ public class EditorActorComponent implements IMoveableActorComponent{
public static final HashMap<String, IMoveableActorComponent> EditorComponents = new HashMap<>();
public static int ActorComponentCount = 0;
private Gimbal ActorGimbal;
private Actor actor;
private Actor3D actor;
private Vector3f Position;
private Vector3f ActorDimensions;
private String ID = "ActorComponent";
public EditorActorComponent(Actor actor, Vector3f Position, Vector3f Dimensions){
public EditorActorComponent(Actor3D actor, Vector3f Position, Vector3f Dimensions){
ID = actor.GetID() + "_COMPONENT" + ActorComponentCount;
this.Position = new Vector3f(Position);
this.actor = actor;
@ -36,12 +37,12 @@ public class EditorActorComponent implements IMoveableActorComponent{
}
@Override
public Actor GetActor() {
public Actor3D GetActor() {
return actor;
}
@Override
public void SetActor(Actor actor) {
public void SetActor(Actor3D actor) {
this.actor = actor;
}

View file

@ -5,10 +5,8 @@ import imgui.ImGui;
import imgui.ImVec2;
import imgui.flag.ImGuiCol;
import imgui.flag.ImGuiWindowFlags;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIOverlay;
import net.halbear.Terrain4J.EngineCore.Main.Scene.IMoveableActorComponent;
import net.halbear.Terrain4J.EngineCore.Main.Util.Maths.T4Math;

View file

@ -1,12 +1,13 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.Gimbal;
import org.joml.Vector3f;
public interface IMoveableActorComponent {
public void UpdateAll();
public Actor GetActor();
public void SetActor(Actor actor);
public Actor3D GetActor();
public void SetActor(Actor3D actor);
public void AddPosition(Vector3f addedPos);
public void AddRotation(Vector3f addedRot);
public void AddScale(Vector3f addedScale);

View file

@ -1,9 +1,11 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.PlayerActor3D;
public interface IPlayerController {
public void SetPlayerControls(IPlayerInputEvents Controls);
public IPlayerInputEvents GetControls();
public void SetPlayerCamera(String camera);
public Camera GetPlayerCamera();
public void SwitchActor(PlayerActor newActor);
public void SwitchActor(PlayerActor3D newActor);
}

View file

@ -1,9 +1,9 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene;
import net.halbear.Terrain4J.EngineCore.Input.KeyboardInput;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.PlayerActor3D;
public interface IPlayerInputEvents {
void Input(KeyboardInput input, long FrameDiffNanoSeconds, PlayerActor playerActor, float MOVEMENT_SPEED, GameCore GameCore, IScene ParentScene);
void Input(KeyboardInput input, long FrameDiffNanoSeconds, PlayerActor3D playerActor, float MOVEMENT_SPEED, GameCore GameCore, IScene ParentScene);
}

View file

@ -5,6 +5,8 @@ import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.SkyBox;
import net.halbear.Terrain4J.EngineCore.Main.AudioInstance;
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.PlayerActor3D;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DynamicMesh.DynamicTerrainMesh;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Projection.Project3D;
@ -21,13 +23,13 @@ public interface IScene {
public void StartCameraTrack(String StartFrame, String EndFrame, int TickAmount);
public void SetActiveCameraFrame(String frameName);
public Camera GetCamera();
public void AddActor(Actor NewActor);
public List<Actor> GetActors();
public void AddActor(Actor3D NewActor);
public List<Actor3D> GetActors();
public Project3D GetProjection();
public void RemoveAllActors();
public Actor RemoveActor(Actor actor);
public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds, PlayerActor playerActor, float MOVEMENT_SPEED,GameCore parent);
public void GlobalInput(EngineInstance engineInstance, long FrameDiffNanoSeconds, PlayerActor playerActor, float MOVEMENT_SPEED,GameCore parent);
public Actor3D RemoveActor(Actor3D actor);
public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds, PlayerActor3D playerActor, float MOVEMENT_SPEED, GameCore parent);
public void GlobalInput(EngineInstance engineInstance, long FrameDiffNanoSeconds, PlayerActor3D playerActor, float MOVEMENT_SPEED, GameCore parent);
public void Update(EngineInstance engineInstance, long FrameDiffNanoSeconds);
public void UpdateFastThread(EngineInstance engineInstance, long FrameDiffNanoSeconds);
public void SecondUpdate(EngineInstance engineInstance);
@ -46,4 +48,5 @@ public interface IScene {
public Map<String, AudioInstance> audioInstances();
public void Reset();
public Queue<String> NetworkedActors();
public Queue<Actor3D> ChangedActors();
}

View file

@ -1,19 +1,15 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene.InputEvents;
import net.halbear.Terrain4J.EngineCore.Input.KeyboardInput;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.RigidBody;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.RigidPhysicsController;
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Main.Scene.*;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.Gimbal;
import org.joml.Vector3f;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.PlayerActor3D;
import static org.lwjgl.glfw.GLFW.*;
public class DebugCameraController implements IPlayerInputEvents {
@Override
public void Input(KeyboardInput input, long FrameDiffNanoSeconds, PlayerActor playerActor, float MOVEMENT_SPEED, GameCore GameCore, IScene ParentScene) {
public void Input(KeyboardInput input, long FrameDiffNanoSeconds, PlayerActor3D playerActor, float MOVEMENT_SPEED, GameCore GameCore, IScene ParentScene) {
Scene scene = (Scene)ParentScene;
float MovementDist = (float)(FrameDiffNanoSeconds / 1000000L) * MOVEMENT_SPEED;
Camera camera = scene.GetCamera();

View file

@ -1,28 +1,17 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene.InputEvents;
import net.halbear.Terrain4J.EngineCore.Display.Window;
import net.halbear.Terrain4J.EngineCore.Input.KeyboardInput;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.RigidBody;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.RigidPhysicsController;
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Main.Scene.*;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.Gimbal;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.PlayerActor3D;
import org.joml.Vector3f;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_1;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_2;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_3;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_A;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_D;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_F2;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_LEFT_CONTROL;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_M;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_S;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_SPACE;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_TAB;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_W;
public class PhysicsPlayerController implements IPlayerInputEvents {
@ -35,7 +24,7 @@ public class PhysicsPlayerController implements IPlayerInputEvents {
public void Input(
KeyboardInput input,
long frameDiffNanoseconds,
PlayerActor playerActor,
PlayerActor3D playerActor,
float movementSpeed,
GameCore gameCore,
IScene parentScene

View file

@ -2,6 +2,9 @@ package net.halbear.Terrain4J.EngineCore.Main.Scene;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.RigidBody;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.RigidPhysicsController;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3DElement;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.PlayerActor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.InputEvents.PhysicsPlayerController;
import org.joml.Quaternionf;
import org.joml.Vector3f;
@ -13,15 +16,15 @@ public class PlayerController implements IPlayerController{
public static Map<String, PlayerController> ControllerRegistry = new HashMap<>();
PlayerActor playerActor;
PlayerActor3D playerActor;
Vector3f Position;
Quaternionf Rotation;
Map<String, ActorElement> Elements = new HashMap<>();
Map<String, Actor3DElement> Elements = new HashMap<>();
IPlayerInputEvents InputEvents = new PhysicsPlayerController();
String PlayerCamera = "DebugCamera";
final String ID;
public PlayerController(PlayerActor Player, String ContollerID){
public PlayerController(PlayerActor3D Player, String ContollerID){
this.playerActor = Player;
if(Player.PlayerCam != null) {
@ -35,7 +38,7 @@ public class PlayerController implements IPlayerController{
ID = ContollerID;
ControllerRegistry.put(ContollerID,this);
}
public void SwitchActor(PlayerActor newActor){
public void SwitchActor(PlayerActor3D newActor){
if(newActor == null) return;
if(newActor.PlayerCam == null && newActor.AttachedCameraID != null) {
@ -44,7 +47,7 @@ public class PlayerController implements IPlayerController{
if(newActor.PlayerCam == null) return;
if(playerActor.PhysicsType == Actor.PhysicsControllerType.RigidBodySeparatingAxisTheory) {
if(playerActor.PhysicsType == Actor3D.PhysicsControllerType.RigidBodySeparatingAxisTheory) {
RigidPhysicsController physicsController = (RigidPhysicsController) playerActor.GetPhysicsController();
newActor.SetNewPosition(RigidBody.RigidBodyRegister.get(physicsController.RigidBodyID).Position);
newActor.SetNewRotation(RigidBody.RigidBodyRegister.get(physicsController.RigidBodyID).Rotation);
@ -56,7 +59,7 @@ public class PlayerController implements IPlayerController{
PlayerCamera = newActor.PlayerCam.GetID();
}
public PlayerController AddActorElement(ActorElement newActor){
public PlayerController AddActorElement(Actor3DElement newActor){
Elements.put(newActor.GetID(), newActor);
return this;
}

View file

@ -10,6 +10,8 @@ import net.halbear.Terrain4J.EngineCore.Logic.Rendering.SkyBox;
import net.halbear.Terrain4J.EngineCore.Main.AudioInstance;
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.PlayerActor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.GameChat;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.Gimbal;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.PerformanceOverlay;
@ -35,9 +37,10 @@ public class Scene implements IScene {
private static final float MOUSE_SENSITIVITY = 0.1f;
private static final float MOVEMENT_SPEED = 0.025f;
private final Map<String, Actor> Actors;
private final Map<String, Actor3D> Actors;
private final List<String> ActiveActors;
private final Queue<String> NetworkedActors = new ConcurrentLinkedQueue<>();
private final Queue<Actor3D> ChangedActors = new ConcurrentLinkedQueue<>();
private final Camera2D camera2D;
private final Map<String, Sprite> Sprites;
@ -63,9 +66,9 @@ public class Scene implements IScene {
public final int MaxJumps = 2;
public int GroundedGraceTicks = 0;
public final int MaxGroundedGraceTicks = 8;
public PlayerActor CurrentWeapon;
public PlayerActor Musket;
public PlayerActor Revolver;
public PlayerActor3D CurrentWeapon;
public PlayerActor3D Musket;
public PlayerActor3D Revolver;
public Item MusketItem;
public Item RevolverItem;
public Item CurrentItem;
@ -155,6 +158,7 @@ public class Scene implements IScene {
GUIReg.put("ChatLog",new GameChat());
ActiveGUIs.add("ChatLog");
}
}
public ISceneLightingManager GetLightingManager(){return lightingManager;}
@ -206,7 +210,7 @@ public class Scene implements IScene {
}
public void Reset(){
Actor actor;
Actor3D actor;
while((actor = Actors.get(NetworkedActors.poll())) != null) {
RemoveActor(actor);
}
@ -217,6 +221,11 @@ public class Scene implements IScene {
return NetworkedActors;
}
@Override
public Queue<Actor3D> ChangedActors() {
return ChangedActors;
}
public Map<String, CameraFrame> GetCameraFrameReg(){return CameraFrames;}
public CameraFrame GetCameraFrame(String Name){return CameraFrames.get(Name);}
public Scene AddCameraFrame(String Name, CameraFrame frame){
@ -243,7 +252,7 @@ public class Scene implements IScene {
CricketAmbience = new AudioInstance("resources/EngineResources/audio/sounds/CricketAmbience.ogg", "CricketAmbience", manager, false).SetAudioType(AudioType.AMBIENT);
}
public Camera GetCamera(){return camera;}
public void AddActor(Actor NewActor){
public void AddActor(Actor3D NewActor){
if(NewActor == null) return;
Actors.put(NewActor.GetID(), NewActor);
@ -252,8 +261,8 @@ public class Scene implements IScene {
ActiveActors.add(NewActor.GetID());
}
}
public List<Actor> GetActors(){
List<Actor> actors = new ArrayList<>();
public List<Actor3D> GetActors(){
List<Actor3D> actors = new ArrayList<>();
for(int i = 0; i < ActiveActors.size(); i++){
actors.add(Actors.get(ActiveActors.get(i)));
}
@ -261,21 +270,21 @@ public class Scene implements IScene {
}
public Project3D GetProjection(){return Projection;}
public void RemoveAllActors(){Actors.clear();}
public Actor RemoveActor(Actor actor){
public Actor3D RemoveActor(Actor3D actor){
if(actor == null) return null;
ActiveActors.remove(actor.GetID());
Actor.Actors.remove(actor.GetID());
Actor.ActorNames.remove(actor.GetID());
Actor3D.Actors.remove(actor.GetID());
Actor3D.ActorNames.remove(actor.GetID());
return Actors.remove(actor.GetID());
}
public void CreatePlayerController(PlayerActor CurrentActor){
public void CreatePlayerController(PlayerActor3D CurrentActor){
CurrentWeapon = CurrentActor;
playerController = new PlayerController(CurrentWeapon, "PLAYERCONTROLLER");
}
public void SetNetworkControlledPlayer(PlayerActor networkPlayer){
public void SetNetworkControlledPlayer(PlayerActor3D networkPlayer){
if(networkPlayer == null) return;
if(Musket != null && Musket != networkPlayer) {
@ -300,12 +309,18 @@ public class Scene implements IScene {
playerController.SetPlayerCamera(camera.GetID());
}
public void SetCurrentWeapon(PlayerActor Weapon) {this.CurrentWeapon = Weapon; }
public void SetCurrentWeapon(PlayerActor3D Weapon) {this.CurrentWeapon = Weapon; }
public int GUI_MODE = 1;
boolean InitialisedGun = false;
boolean AimingIn = false;
float AimingInPercent = 0;
Vector3f NotAiming = new Vector3f(0.5f, 0.35f, -1.25f);
Vector3f Aiming = new Vector3f(0f, 0.25f, -1.25f);
@Override
public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds,PlayerActor playerActor, float MOVEMENT_SPEED, GameCore parent) {
public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds, PlayerActor3D playerActor, float MOVEMENT_SPEED, GameCore parent) {
IScene scene = engineInstance.scene();
Window window = engineInstance.window();
@ -313,6 +328,13 @@ public class Scene implements IScene {
float MovementDist = (float)(FrameDiffNanoSeconds / 1000000L) * MOVEMENT_SPEED;
Camera camera = scene.GetCamera();
if(playerActor!= null)camera = Camera.GetCamera(playerActor.AttachedCameraID);
if(!InitialisedGun && playerActor != null){
playerActor.SetModelID(MusketItem.ModelID());
UpdateEntityModelID(playerActor.ID, MusketItem.ModelID());
CurrentItem= MusketItem;
GunCockSFX.Play();
InitialisedGun = true;
}
if(input.keySinglePress(GLFW_KEY_F3)){
GUI_MODE = (GUI_MODE + 1) % 2;
}
@ -352,11 +374,13 @@ public class Scene implements IScene {
}
MouseListener mouseListener = window.getMouseInput();
if(!parent.StartMenuActive && !StartMenu.ShowSettings && !StartMenu.ShowCredits ) {
if (mouseListener.isRightButtonPressed()) {
CurrentWeapon.SetPositionOffset(new Vector3f(0f, 1.15f, -1.25f));
} else {
CurrentWeapon.SetPositionOffset(new Vector3f(0.5f, 1.15f, -1.25f));
AimingIn = mouseListener.isRightButtonPressed();
if (AimingIn && AimingInPercent != 1.0f) {
AimingInPercent = Math.clamp(AimingInPercent + (FrameDiffNanoSeconds/1_000_000f)/160f, 0,1);
} else if (!AimingIn && AimingInPercent != 0.0f) {
AimingInPercent = Math.clamp(AimingInPercent - (FrameDiffNanoSeconds/1_000_000f)/160f, 0,1);
}
CurrentWeapon.SetPositionOffset(new Vector3f().set(NotAiming).lerp(Aiming, AimingInPercent));
if (mouseListener.isLeftButtonPressed()) {
if (CurrentItem != null && playerActor != null) {
long NewTime = System.nanoTime();
@ -398,7 +422,7 @@ public class Scene implements IScene {
}
@Override
public void GlobalInput(EngineInstance engineInstance, long FrameDiffNanoSeconds, PlayerActor playerActor, float MOVEMENT_SPEED, GameCore parent) {
public void GlobalInput(EngineInstance engineInstance, long FrameDiffNanoSeconds, PlayerActor3D playerActor, float MOVEMENT_SPEED, GameCore parent) {
IScene scene = engineInstance.scene();
Window window = engineInstance.window();

View file

@ -8,6 +8,8 @@ import net.halbear.Terrain4J.EngineCore.Logic.Rendering.SkyBox;
import net.halbear.Terrain4J.EngineCore.Main.AudioInstance;
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.PlayerActor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.StartMenu;
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DynamicMesh.DynamicTerrainMesh;
@ -81,12 +83,12 @@ public class Scene2D implements IScene{
}
@Override
public void AddActor(Actor NewActor) {
public void AddActor(Actor3D NewActor) {
}
@Override
public List<Actor> GetActors() {
public List<Actor3D> GetActors() {
return List.of();
}
@ -101,17 +103,17 @@ public class Scene2D implements IScene{
}
@Override
public Actor RemoveActor(Actor actor) {
public Actor3D RemoveActor(Actor3D actor) {
return null;
}
@Override
public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds, PlayerActor playerActor, float MOVEMENT_SPEED, GameCore parent) {
public void Input(EngineInstance engineInstance, long FrameDiffNanoSeconds, PlayerActor3D playerActor, float MOVEMENT_SPEED, GameCore parent) {
}
@Override
public void GlobalInput(EngineInstance engineInstance, long FrameDiffNanoSeconds, PlayerActor playerActor, float MOVEMENT_SPEED, GameCore parent) {
public void GlobalInput(EngineInstance engineInstance, long FrameDiffNanoSeconds, PlayerActor3D playerActor, float MOVEMENT_SPEED, GameCore parent) {
IScene scene = engineInstance.scene();
Window window = engineInstance.window();
@ -231,4 +233,9 @@ public class Scene2D implements IScene{
public Queue<String> NetworkedActors() {
return null;
}
@Override
public Queue<Actor3D> ChangedActors() {
return null;
}
}

View file

@ -0,0 +1,67 @@
package net.halbear.Terrain4J.EngineCore.Main.Util.Maths;
import org.joml.Vector2d;
public class Noise2D {
public static Vector2d GenGradientVector(int p)
{
int h = p & 3;
if (h == 0) return new Vector2d(1.0f, 1.0f);
else if (h == 1) return new Vector2d(-1.0f, 1.0f);
else if (h == 2) return new Vector2d(-1.0f, -1.0f);
else return new Vector2d(1.0f, -1.0f);
}
static double fade(double t)
{
return t * t * t * (t * (t * 6 - 15) + 10);
}
static double lerp(double t, double x, double y)
{
return x + t * (y - x);
}
public static double Noise2D(double x, double y, int[] permutation)
{
int X = (int)Math.floor(x) & 255;
int Y = (int)Math.floor(y) & 255;
double xd = x - Math.floor(x);
double yd = y - Math.floor(y);
Vector2d TR = new Vector2d(xd - 1.0, yd - 1.0);
Vector2d TL = new Vector2d(xd, yd - 1.0);
Vector2d BR = new Vector2d(xd - 1.0, yd);
Vector2d BL = new Vector2d(xd, yd);
int ValueTR = permutation[permutation[X + 1] + Y + 1];
int ValueTL = permutation[permutation[X] + Y + 1];
int ValueBR = permutation[permutation[X + 1] + Y];
int ValueBL = permutation[permutation[X] + Y];
double dTR = TR.dot(GenGradientVector(ValueTR));
double dTL = TL.dot(GenGradientVector(ValueTL));
double dBR = BR.dot(GenGradientVector(ValueBR));
double dBL = BL.dot(GenGradientVector(ValueBL));
double u = fade(xd); //perlin curve
double v = fade(yd);
return lerp(u,
lerp(v, dBL, dTL),
lerp(v, dBR, dTR)); //interpolate it all with the fade curve added
}
public static double FractalNoise(double x, double y, int Octaves, double amplitude, double frequency, PermutationArray permutation)
{
double FractalNoise = 0;
for (int octave = 0; octave < Octaves; octave++)
{
double Layer = amplitude * Noise2D(x * frequency, y * frequency,permutation.GetPermutation());
FractalNoise += Layer;
amplitude *= 0.5;
frequency *= 2.0;
}
return FractalNoise;
}
}

View file

@ -0,0 +1,33 @@
package net.halbear.Terrain4J.EngineCore.Main.Util.Maths;
import java.util.Random;
public class PermutationArray {
int[] permutation = new int[512];
public int[] GetPermutation()
{
return permutation;
}
public PermutationArray() { }
public void GeneratePermutationArray(long Seed)
{
Random rnd = new Random(Seed);
permutation = new int[512];
for (int i = 0; i < 256; i++)
{
permutation[i] = i;
}
for (int p = permutation.length - 1; p > 0; p--)
{
int index = (int)Math.round(rnd.nextDouble() * (p - 1));
int temp = permutation[p];
permutation[p] = permutation[index];
permutation[index] = temp;
}
for (int i = 0; i < 256; i++)
{
permutation[i + 256] = permutation[i];
}
}
}

View file

@ -3,8 +3,8 @@ package net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayTo
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
import net.halbear.Terrain4J.EngineCore.Main.Scene.ActorElement;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3DElement;
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments;
@ -411,13 +411,13 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
LongBuffer offsets = MemStack.mallocLong(1).put(0,0L);
LongBuffer vertexBuffer = MemStack.mallocLong(1);
IScene scene = instance.scene();
List<Actor> Actors = scene.GetActors();
List<Actor3D> Actors = scene.GetActors();
int ActorCount = Actors.size();
for(int i = 0; i < ActorCount; i++){
if(i < Actors.size()) {
var Actor = Actors.get(i);
if(Actor != null && Actor.GetPosition() != null) {
if(Actor instanceof ActorElement &&( !((ActorElement) Actor).RenderOnTopOfPlayer && ClientSideNetworkUtils.OwnsActor(((ActorElement) Actor).GetParentID()) || new Vector3f().set(Actor.GetPosition()).sub(instance.scene().GetCamera().GetPosition()).absolute().lengthSquared() < 4f)) continue;
if(Actor instanceof Actor3DElement &&( !((Actor3DElement) Actor).RenderOnTopOfPlayer && ClientSideNetworkUtils.OwnsActor(((Actor3DElement) Actor).GetParentID()) || new Vector3f().set(Actor.GetPosition()).sub(instance.scene().GetCamera().GetPosition()).absolute().lengthSquared() < 4f)) continue;
else {
VulkanModel model = modelsCache.GetModel(Actor.GetModelID());
List<VulkanMesh> VkMeshList = model.GetVkMeshList();

View file

@ -4,8 +4,8 @@ import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
import net.halbear.Terrain4J.EngineCore.Main.Scene.ActorElement;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3DElement;
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments;
@ -34,7 +34,6 @@ import java.nio.ByteBuffer;
import java.nio.LongBuffer;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import static org.lwjgl.vulkan.VK13.*;
@ -402,13 +401,13 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
LongBuffer offsets = MemStack.mallocLong(1).put(0,0L);
LongBuffer vertexBuffer = MemStack.mallocLong(1);
IScene scene = instance.scene();
List<Actor> Actors = scene.GetActors();
List<Actor3D> Actors = scene.GetActors();
int ActorCount = Actors.size();
for(int i = 0; i < ActorCount; i++){
if(i < Actors.size()) {
var Actor = Actors.get(i);
if(Actor != null) {
if(Actor instanceof ActorElement &&( !((ActorElement) Actor).RenderOnTopOfPlayer && ClientSideNetworkUtils.OwnsActor(((ActorElement) Actor).GetParentID())|| new Vector3f().set(Actor.GetPosition()).sub(instance.scene().GetCamera().GetPosition()).absolute().lengthSquared() < 4f)) continue;
if(Actor instanceof Actor3DElement &&( !((Actor3DElement) Actor).RenderOnTopOfPlayer && ClientSideNetworkUtils.OwnsActor(((Actor3DElement) Actor).GetParentID())|| new Vector3f().set(Actor.GetPosition()).sub(instance.scene().GetCamera().GetPosition()).absolute().lengthSquared() < 4f)) continue;
VulkanModel model = modelsCache.GetModel(Actor.GetModelID());
List<VulkanMesh> VkMeshList = model.GetVkMeshList();
int MeshCount = VkMeshList.size();

View file

@ -4,9 +4,9 @@ import net.halbear.Executable.Server;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
import net.halbear.Terrain4J.EngineCore.Main.Scene.PlayerActor;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.PlayerActor3D;
import net.halbear.Terrain4J.EngineCore.Threads.EngineThread;
import org.tinylog.Logger;
@ -63,7 +63,7 @@ public class ClientSession implements ServerConnection {
private final Queue<Packet> OutboundPacketQueue = new ConcurrentLinkedQueue<>();
public final ByteBuffer InBound = ByteBuffer.allocateDirect(1024 * 4);
public final Queue<ByteBuffer> OutBound = new ConcurrentLinkedQueue<>();
private final Map<String, Actor> NetworkOwnedActors = new ConcurrentHashMap<>();
private final Map<String, Actor3D> NetworkOwnedActors = new ConcurrentHashMap<>();
private final SocketChannel Channel;
private String ClientName;
private String IPAddress;
@ -175,7 +175,7 @@ public class ClientSession implements ServerConnection {
EngineInstance engineInstance = PrimaryRuntime.GetEngineInstance();
IScene scene = engineInstance.scene();
for(Actor actor : scene.GetActors()) {
for(Actor3D actor : scene.GetActors()) {
Packet actorPacket = CreateActorPacket(actor);
if(actorPacket != null) {
AddOutgoingPacket(actorPacket);
@ -185,7 +185,7 @@ public class ClientSession implements ServerConnection {
Server.ClientNames.forEach((client, name) -> AddOutgoingPacket(CreateUsernameUpdatePacket(client, name)));
GameCore gameCore = (GameCore) PrimaryRuntime.GetGameCore();
PlayerActor player = gameCore.SpawnNetworkPlayer(engineInstance, ClientUUID);
PlayerActor3D player = gameCore.SpawnNetworkPlayer(engineInstance, ClientUUID);
SetOwnedActorID(player.GetID());
@ -199,11 +199,12 @@ public class ClientSession implements ServerConnection {
SendPossessActorPacket(player.GetID());
Server.OutGoingPacketQueue.add(ServerSideNetworkUtils.CreateUsernameUpdatePacket(ClientUUID, ClientName));
Logger.debug("Queued possess packet for joining player's actor: " + player.GetID());
System.out.println("Validated new Connection, joining player: " + ClientName);
}
public void SetOwnedActorID(String ownedActorID){
if(Actor.Actors.containsKey(ownedActorID)) {
this.NetworkOwnedActors.put(ownedActorID, Actor.Actors.get(ownedActorID));
if(Actor3D.Actors.containsKey(ownedActorID)) {
this.NetworkOwnedActors.put(ownedActorID, Actor3D.Actors.get(ownedActorID));
}
}

View file

@ -13,6 +13,8 @@ import net.halbear.Terrain4J.EngineCore.Main.AudioInstance;
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.*;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.PlayerActor3D;
import net.halbear.Terrain4J.EngineCore.Threads.ClientConnectionThread;
import net.halbear.Terrain4J.EngineCore.Threads.NIO_ClientConnectionThread;
import org.joml.Quaternionf;
@ -109,7 +111,7 @@ public class ClientSideNetworkUtils {
public static String ServerMessage = "Offline";
public static String clientUUID = null;
public static UUID ClientUUID = null;
private static final Map<String, Actor> NetworkOwnedActors = new ConcurrentHashMap<>();
private static final Map<String, Actor3D> NetworkOwnedActors = new ConcurrentHashMap<>();
private static String PlayerControlledActorID = null;
@Deprecated
public static String OwnedActorID = "NULL";
@ -128,7 +130,7 @@ public class ClientSideNetworkUtils {
public static boolean IsReconnecting(){return Reconnect;}
public static Map<String, Actor> GetNetworkOwnedActors(){
public static Map<String, Actor3D> GetNetworkOwnedActors(){
return NetworkOwnedActors;
}
public static String GetPlayerControlledActorID(){
@ -142,9 +144,9 @@ public class ClientSideNetworkUtils {
}
private static boolean TryPossessActor(String actorID, GameCore gameCore, IScene scene){
Actor actor = Actor.Actors.get(actorID);
Actor3D actor = Actor3D.Actors.get(actorID);
if(!(actor instanceof PlayerActor playerActor)) {
if(!(actor instanceof PlayerActor3D playerActor)) {
PendingPossessActorID = actorID;
Logger.info("Possess actor [{}] is not created yet. Deferring possession.", actorID);
return false;
@ -240,7 +242,7 @@ public class ClientSideNetworkUtils {
Packet packet;
while((packet = IncomingPacketQueue.poll()) != null){
// Logger.debug("Packet: " + packet.PacketTypeByte);
Actor Target = Actor.Actors.get(packet.TargetID);
Actor3D Target = Actor3D.Actors.get(packet.TargetID);
Vector3f vector3f = new Vector3f();
String stringdata = "";
Quaternionf quaternionfdata = new Quaternionf();
@ -268,7 +270,7 @@ public class ClientSideNetworkUtils {
case Packet.PACKET_UPDATE_ANGULAR_VELOCITY:
Target.SetNewAngularVelocity(vector3f);
break;
case Packet.PACKET_CREATE_ACTOR: //"ACtorType:ModelID:x:y:z:rx:ry:rz:sx:sy:sz:hx:hy:hz:MassKG:vx:vy:vz:avx:avy:avz:posOffx:posOffy:posOffz:camOffx:camOffy:camOffz"
case Packet.PACKET_CREATE_ACTOR: //"ACtorType:ModelID:x:y:z:rx:ry:rz:sx:sy:sz:hx:hy:hz:MassKG:vx:vy:vz:avx:avy:avz:posOffx:posOffy:posOffz:camOffx:camOffy:camOffz:PivotX:PivotY:PivotZ"
try {
stringdata = Packet.DecodeAsString(packet.Data);
String[] Split = stringdata.split(":");
@ -334,16 +336,27 @@ public class ClientSideNetworkUtils {
);
}
Vector3f PivotOffset = new Vector3f(0, 0.0f, 0);
if(Split.length >= 30) {
CameraOffset.set(
Float.parseFloat(Split[28]),
Float.parseFloat(Split[29]),
Float.parseFloat(Split[30])
);
}
String actorType = Split[0];
String modelID = Split[1];
if (actorType.equals("PlayerActor")) {
Target = new PlayerActor("NULL", packet.TargetID, modelID, Position).SetCameraOffset(CameraOffset);
Target = new PlayerActor3D("NULL", packet.TargetID, modelID, Position).SetCameraOffset(CameraOffset);
Target.SetPositionOffset(PositionOffset);
} else {
Target = new Actor(packet.TargetID, modelID, Position);
Target = new Actor3D(packet.TargetID, modelID, Position);
Target.SetPositionOffset(PositionOffset);
}
Target.SetScale(Scale);
Target.SetPivotOffset(PivotOffset);
Target.CreatePhysicsController(ConvexMesh.Box(CollisionBox.x, CollisionBox.y, CollisionBox.z), MassKG);
Target.SetServerSynced(MassKG > 0.0f || actorType.equals("PlayerActor"));
@ -412,7 +425,7 @@ public class ClientSideNetworkUtils {
case Packet.PACKET_DESTROY_ACTOR:
GameChats.put(new GameChat(true, UUID.randomUUID(),"Destroying Actor " + packet.TargetID, Date.from(Instant.now())),"Server");
Logger.debug("Destroying Actor [{}]", packet.TargetID);
Actor actorToDestroy = Actor.Actors.get(packet.TargetID);
Actor3D actorToDestroy = Actor3D.Actors.get(packet.TargetID);
if(actorToDestroy != null) {
scene.RemoveActor(actorToDestroy);
} else {
@ -422,7 +435,7 @@ public class ClientSideNetworkUtils {
case Packet.PACKET_UPDATE_MODEL_ID:
Logger.debug("Rebound packet received for actor [{}]", packet.TargetID);
stringdata = Packet.DecodeAsString(packet.Data);
Actor actorToChangeModelID = Actor.Actors.get(packet.TargetID);
Actor3D actorToChangeModelID = Actor3D.Actors.get(packet.TargetID);
if(actorToChangeModelID != null) {
actorToChangeModelID.SetModelID(stringdata);
}
@ -535,7 +548,7 @@ public class ClientSideNetworkUtils {
OutGoingPacketQueue.add(namePacket);
}
public static void SendEntityUpdatePacket(Actor actor){
public static void SendEntityUpdatePacket(Actor3D actor){
Packet newOutgoingPacket = new Packet((byte)6);
newOutgoingPacket.SetTargetType((byte) 0);
RigidPhysicsController physicsController = (RigidPhysicsController) actor.GetPhysicsController();

View file

@ -4,8 +4,8 @@ import net.halbear.Executable.Server;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.RigidBody;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.RigidPhysicsController;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
import net.halbear.Terrain4J.EngineCore.Main.Scene.PlayerActor;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.PlayerActor3D;
import net.halbear.Terrain4J.EngineCore.Main.Util.Maths.T4Raycast;
import net.halbear.Terrain4J.EngineCore.Threads.ServerConnectionThread;
import org.joml.Quaternionf;
@ -40,7 +40,7 @@ public class ServerSideNetworkUtils {
if(sender == null) return;
//Logger.debug("Packet: " + packet.PacketTypeByte);
Actor Target = Actor.Actors.get(packet.TargetID);
Actor3D Target = Actor3D.Actors.get(packet.TargetID);
if(Target == null &&
(!BypassNullTargets.containsKey(packet.PacketTypeByte) || !BypassNullTargets.get(packet.PacketTypeByte))) {
@ -125,7 +125,7 @@ public class ServerSideNetworkUtils {
if(sender == null) return;
//Logger.debug("Packet: " + packet.PacketTypeByte);
Actor Target = Actor.Actors.get(packet.TargetID);
Actor3D Target = Actor3D.Actors.get(packet.TargetID);
if(Target == null &&
(!BypassNullTargets.containsKey(packet.PacketTypeByte) || !BypassNullTargets.get(packet.PacketTypeByte))) {
@ -227,7 +227,7 @@ public class ServerSideNetworkUtils {
private static void HandleFireWeapon(Packet packet){
Packet.DecodedFireRequest request = Packet.DecodeAsFireRequest(packet.Data);
Actor shooter = Actor.Actors.get(packet.TargetID);
Actor3D shooter = Actor3D.Actors.get(packet.TargetID);
String excludeBodyID = null;
if (shooter != null && shooter.GetPhysicsController() instanceof RigidPhysicsController rpc) {
excludeBodyID = rpc.RigidBodyID;
@ -242,7 +242,7 @@ public class ServerSideNetworkUtils {
resultPoint = hit.Point;
Vector3f impulse = new Vector3f(request.Direction).normalize().mul(request.Damage);
hit.Body.ApplyImpulse(impulse, hit.Point);
Actor hitActor = GetActorForRigidBody(hit.Body);
Actor3D hitActor = GetActorForRigidBody(hit.Body);
if (hitActor != null) hitActorID = hitActor.GetID();
} else {
resultPoint = new Vector3f(request.Direction).normalize().mul(request.MaxRange).add(request.Origin);
@ -263,7 +263,7 @@ public class ServerSideNetworkUtils {
return packet;
}
public static Packet CreateActorPacket(Actor actor){
public static Packet CreateActorPacket(Actor3D actor){
Packet newOutgoingPacket = new Packet(Packet.PACKET_CREATE_ACTOR);
newOutgoingPacket.SetTargetType((byte) 0);
@ -273,7 +273,7 @@ public class ServerSideNetworkUtils {
RigidBody rigidBody = RigidBody.RigidBodyRegister.get(physicsController.RigidBodyID);
if(rigidBody == null) return null;
String actorType = actor instanceof PlayerActor ? "PlayerActor" : "Actor";
String actorType = actor instanceof PlayerActor3D ? "PlayerActor" : "Actor";
StringBuilder OutgoingData = new StringBuilder(actorType)
.append(":")
.append(actor.GetModelID());
@ -288,9 +288,10 @@ public class ServerSideNetworkUtils {
Vector3f LinearVelocity = rigidBody.LinearVelocity;
Vector3f AngularVelocity = rigidBody.AngularVelocity;
Vector3f PositionOffset = actor.GetPositionOffset();
Vector3f PivotOffset = actor.GetPivotOffset();
Vector3f CameraOffset = new Vector3f();
if(actor instanceof PlayerActor playerActor) {
if(actor instanceof PlayerActor3D playerActor) {
CameraOffset.set(playerActor.CameraOffset);
}
@ -303,7 +304,8 @@ public class ServerSideNetworkUtils {
LinearVelocity.x, LinearVelocity.y, LinearVelocity.z,
AngularVelocity.x, AngularVelocity.y, AngularVelocity.z,
PositionOffset.x, PositionOffset.y, PositionOffset.z,
CameraOffset.x, CameraOffset.y, CameraOffset.z
CameraOffset.x, CameraOffset.y, CameraOffset.z,
PivotOffset.x, PivotOffset.y, PivotOffset.z
};
for(int i = 0; i < floats.length; i++){
@ -315,7 +317,7 @@ public class ServerSideNetworkUtils {
return newOutgoingPacket;
}
public static void BroadcastCreateActorPacket(Actor actor) {
public static void BroadcastCreateActorPacket(Actor3D actor) {
Packet newOutgoingPacket = CreateActorPacket(actor);
if(newOutgoingPacket != null)Server.OutGoingPacketQueue.add(newOutgoingPacket);
}
@ -357,7 +359,7 @@ public class ServerSideNetworkUtils {
Server.OutGoingPacketQueue.add(CreateDestroyActorPacket(actorID));
}
public static void SendEntityUpdatePacket(Actor actor){
public static void SendEntityUpdatePacket(Actor3D actor){
Packet newOutgoingPacket = new Packet((byte)6);
newOutgoingPacket.SetTargetType((byte) 0);
RigidPhysicsController physicsController = (RigidPhysicsController) actor.GetPhysicsController();

View file

@ -77,7 +77,7 @@ public class NIO_ClientConnectionThread implements ClientConnection {
ClientChannel.register(NetworkSelector, SelectionKey.OP_CONNECT);
while (ClientChannel.isOpen() && EngineThread.running) {
while (NetworkSelector.isOpen() && ClientChannel.isOpen() && EngineThread.running) {
NetworkSelector.select();
Iterator<SelectionKey> it = NetworkSelector.selectedKeys().iterator();
@ -101,7 +101,7 @@ public class NIO_ClientConnectionThread implements ClientConnection {
}
}
} catch (IOException e) {
System.err.println("Network client error: " + e.getMessage());
Logger.error("Network client error: " + e.getMessage());
Disconnect();
}
}

View file

@ -5,9 +5,9 @@ import net.halbear.Executable.Server;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
import net.halbear.Terrain4J.EngineCore.Main.Scene.PlayerActor;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.PlayerActor3D;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.Packet;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ServerConnection;
import org.tinylog.Logger;
@ -123,7 +123,7 @@ public class ServerConnectionThread implements Runnable, ServerConnection {
EngineInstance engineInstance = PrimaryRuntime.GetEngineInstance();
IScene scene = engineInstance.scene();
for(Actor actor : scene.GetActors()) {
for(Actor3D actor : scene.GetActors()) {
Packet actorPacket = CreateActorPacket(actor);
if(actorPacket != null) {
AddOutgoingPacket(actorPacket);
@ -133,7 +133,7 @@ public class ServerConnectionThread implements Runnable, ServerConnection {
Server.ClientNames.forEach((client, name) -> AddOutgoingPacket(CreateUsernameUpdatePacket(client, name)));
GameCore gameCore = (GameCore) PrimaryRuntime.GetGameCore();
PlayerActor player = gameCore.SpawnNetworkPlayer(engineInstance, ClientID);
PlayerActor3D player = gameCore.SpawnNetworkPlayer(engineInstance, ClientID);
SetOwnedActorID(player.GetID());
@ -213,7 +213,7 @@ public class ServerConnectionThread implements Runnable, ServerConnection {
if(OwnedActorID == null) return;
Logger.debug("Actor to destroy verified");
Actor actor = Actor.Actors.get(OwnedActorID);
Actor3D actor = Actor3D.Actors.get(OwnedActorID);
if(actor != null){
Logger.debug("Actor to destroy exists");
PrimaryRuntime.GetEngineInstance().scene().RemoveActor(actor);

View file

@ -3,8 +3,10 @@ package net.halbear.Terrain4J.EngineCore.Threads;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSession;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.IP_MODIFIER;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.NetworkingUtil;
import org.tinylog.Logger;
import java.io.IOException;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
@ -38,10 +40,11 @@ public class ServerMultiClientConnectionThread implements Runnable {
private Thread ConnectionThread;
static int ThreadNumbers =0;
private int ThreadNumber = 0;
public ServerMultiClientConnectionThread() throws IOException {
this.selector = Selector.open();
ConnectionThread = new Thread(this);
ThreadNumber = ThreadNumbers;
ConnectionThread.setName("Server NIO Connection Manager [" + ThreadNumbers++ + "]");
ConnectionThread.setDaemon(true);
}
@ -116,34 +119,47 @@ public class ServerMultiClientConnectionThread implements Runnable {
while (it.hasNext()) {
SelectionKey key = it.next();
it.remove();
boolean Disconnect = false;
if (!key.isValid()) continue;
ClientSession context = (ClientSession) key.attachment();
if (key.isReadable()) {
ClientSession context = (ClientSession) key.attachment();
SocketChannel channel = (SocketChannel) key.channel();
int bytesRead = channel.read(context.InBound);
if (bytesRead == -1) {
key.cancel();
channel.close();
} else {
context.ProcessIncomingPacket();
if (!Disconnect && key.isReadable()) {
try {
SocketChannel channel = (SocketChannel) key.channel();
int bytesRead = channel.read(context.InBound);
if (bytesRead == -1) {
key.cancel();
channel.close();
} else {
context.ProcessIncomingPacket();
}
} catch (SocketException e){
System.out.println("Client Disconnected ");
Disconnect = true;
}
}
if (key.isWritable()) {
ClientSession context = (ClientSession) key.attachment();
if (!Disconnect && key.isWritable()) {
try {
context.FlushOutboundData(key);
} catch (IOException e) {
key.cancel();
key.channel().close();
Disconnect = true;
}
}
if(Disconnect){
ClientSession.GetValidClientSessions().remove(context.GetClientUUID());
ClientSession.GetClientSessionInstances().remove(context.GetInstanceUUID());
context.CleanUp();
key.cancel();
key.channel().close();
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
System.out.print("Connection Manager" + ThreadNumber +" Crashed: " + e.getMessage());
Logger.error("Connection Manager" + ThreadNumber +" Crashed: " + e.getMessage());
}
}

View file

@ -0,0 +1,58 @@
package net.halbear.Terrain4J.EngineCore.Threads;
import net.halbear.Executable.Server;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
import net.halbear.Terrain4J.EngineCore.Logic.GameLogic;
import net.halbear.Terrain4J.EngineCore.Logic.Physics.WorldPhysicsManager;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor.Actor3D;
import net.halbear.Terrain4J.EngineCore.Profiling.CPUMonitor;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ServerSideNetworkUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ServerPacketThread extends EngineThread {
@Override
public void TickEvent(long nsTimeDiff){
if(PrimaryRuntime.GetEngineInstance() == null) return;
Server.CollectIncomingPackets();
Server.ProcessIncomingPackets();
for(Actor3D actor : PrimaryRuntime.GetEngineInstance().scene().GetActors()) {
if(actor.IsServerSynced() && !actor.IsStaticRigidBody()) {
ServerSideNetworkUtils.SendEntityUpdatePacket(actor);
}
}
Server.ProcessOutgoingPackets();
}
@Override
public void FrameEvent(long now, long InitialTime){
}
@Override
public void CycleEvent(){
}
@Override
public void SecondEvent(){
}
public void UpdateTickRateThreshold(){
CappedToTickRate = EngineConfig.getInstance().GetMainTickCap();
TickRate = 60;
if (CappedToTickRate){
TickThreshold = (double) 1000000000 / (double) TickRate;
} else{
TickThreshold = 0;
}
}
public ServerPacketThread(EngineInstance engineInstance, GameLogic appLogic){
super(engineInstance, appLogic, "Packet Thread");
UpdateTickRateThreshold();
}
}

View file

@ -1,6 +1,7 @@
package net.halbear.Terrain4J.EngineCore.Threads;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSession;
import net.halbear.Terrain4J.EngineCore.ServerNetworking.Packet;
import org.tinylog.Logger;
@ -14,25 +15,25 @@ import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicInteger;
public class ServerSelectorMasterThread implements Runnable {
public class ServerSelectorMasterThread extends VirtualEngineThread {
private static int PORT = 25565;
private static int TOTAL_THREADS = 9;
private static int CONNECTION_MANAGER_COUNT = TOTAL_THREADS - 1;
private static ServerMultiClientConnectionThread[] ConnectionManagers = new ServerMultiClientConnectionThread[CONNECTION_MANAGER_COUNT];
Selector MasterSelector;
AtomicInteger ManagerIterator;
Thread acceptThread;
ServerSocketChannel serverChannel;
VirtualEngineThread PendingProcessingThread;
ServerPacketThread PacketThread;
public ServerSelectorMasterThread() {
acceptThread = new Thread(this);
acceptThread.setDaemon(true);
super("Client Accepter");
}
@Override
public void run() {
try {
while (!acceptThread.isInterrupted() && EngineThread.running) {
while (!FetchThread().isInterrupted() && EngineThread.running) {
MasterSelector.select();
Iterator<SelectionKey> it = MasterSelector.selectedKeys().iterator();
@ -54,6 +55,8 @@ public class ServerSelectorMasterThread implements Runnable {
} } catch (IOException e) {
throw new RuntimeException(e);
}
PacketThread.KillThread();
PendingProcessingThread.KillThread();
}
public void Initialise() throws IOException {
@ -78,10 +81,13 @@ public class ServerSelectorMasterThread implements Runnable {
System.out.println("Server Master Thread started on port " + PORT + " with " + CONNECTION_MANAGER_COUNT + " connection managers.");
ManagerIterator = new AtomicInteger(0);
acceptThread.start();
StartThread();
VirtualEngineThread PendingProcessingThread = new VirtualEngineThread( "Terrain4J Server Pending Client Processing Thread");
PendingProcessingThread = new VirtualEngineThread( "Terrain4J Server Pending Client Processing Thread");
PendingProcessingThread.SetCycleEvent(ClientSession::QueryPendingClients);
PendingProcessingThread.StartThread();
PacketThread = new ServerPacketThread(PrimaryRuntime.GetEngineInstance(), PrimaryRuntime.GetGameCore());
PacketThread.StartThread();
}
}

View file

@ -1,5 +1,5 @@
#created new properties file
#Fri Aug 21 19:04:58 BST 2026
#Tue Aug 25 20:07:31 BST 2026
AlphaToCoverage=false
Debug_Shaders=false
DefaultTexturePath=resources/EngineResources/Texture/NoTexture.png
@ -28,11 +28,11 @@ frame_accuracy=0
main_thread_tickrate=120
master_tick_rate=240
server=false
server_ip=gameserver.halbear.net
server_ip=localhost
server_port=25566
throttle_accuracy=4000000
throttle_on_unfocus=false
user_display_name=The sigmarest of sigmas
user_display_name=TheSigma
vkValidated=true
vsync=false
z_far_plane=0.1f