Physics, toggle the collision mesh preview with F2, collision is hella buggy
This commit is contained in:
parent
6b51c9b680
commit
c02b9ed2ca
104 changed files with 1401 additions and 1720 deletions
|
|
@ -1,6 +1,7 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Logic.Collision;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.primitives.AABBf;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
|
@ -10,41 +11,77 @@ import java.util.Map;
|
|||
public class CollisionManager {
|
||||
public static Map<String,CollisionMesh> CollisionMeshes = new HashMap<>();
|
||||
public static Map<String,List<String>> CollisionChunks = new HashMap<>();
|
||||
public static List<String> AlwaysCheckMeshes = new ArrayList<>();
|
||||
public static int ChunkWidth = 64;
|
||||
|
||||
public static void AddNewMesh(CollisionMesh mesh){
|
||||
CollisionMeshes.put(mesh.ID, mesh);
|
||||
Vector3f WorldPos = new Vector3f(mesh.WorldPosition).div(ChunkWidth);
|
||||
WorldPos.x = (int)Math.floor(WorldPos.x);
|
||||
WorldPos.y = (int)Math.floor(WorldPos.y);
|
||||
WorldPos.z = (int)Math.floor(WorldPos.z);
|
||||
String ChunkPosition = WorldPos.x + ":" + WorldPos.y + ":" + WorldPos.z;
|
||||
if(!CollisionChunks.containsKey(ChunkPosition)){
|
||||
List<String> newStrList = new ArrayList<>();
|
||||
CollisionChunks.put(ChunkPosition, newStrList);
|
||||
AABBf Bounds = mesh.GetVoxelCollider();
|
||||
if(Bounds != null) {
|
||||
Vector3f LowestPoints = new Vector3f(Bounds.minX, Bounds.minY, Bounds.minZ).div(ChunkWidth);
|
||||
LowestPoints.x = (int) Math.floor(LowestPoints.x);
|
||||
LowestPoints.y = (int) Math.floor(LowestPoints.y);
|
||||
LowestPoints.z = (int) Math.floor(LowestPoints.z);
|
||||
Vector3f LargestPoints = new Vector3f(Bounds.maxX, Bounds.maxY, Bounds.maxZ).div(ChunkWidth);
|
||||
LargestPoints.x = (int) Math.ceil(LargestPoints.x);
|
||||
LargestPoints.y = (int) Math.ceil(LargestPoints.y);
|
||||
LargestPoints.z = (int) Math.ceil(LargestPoints.z);
|
||||
for (int x = (int) LowestPoints.x; x < LargestPoints.x + 1; x++) {
|
||||
for (int y = (int) LowestPoints.y; y < LargestPoints.y + 1; y++) {
|
||||
for (int z = (int) LowestPoints.z; z < LargestPoints.z + 1; z++) {
|
||||
String ChunkPosition = x + ":" + y + ":" + z;
|
||||
if (!CollisionChunks.containsKey(ChunkPosition)) {
|
||||
List<String> newStrList = new ArrayList<>();
|
||||
CollisionChunks.put(ChunkPosition, newStrList);
|
||||
}
|
||||
CollisionChunks.get(ChunkPosition).add(mesh.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else{
|
||||
AlwaysCheckMeshes.add(mesh.ID);
|
||||
}
|
||||
CollisionChunks.get(ChunkPosition).add(mesh.ID);
|
||||
}
|
||||
|
||||
public static List<String> GetCollisionMeshesAtChunk(String Chunk){
|
||||
return CollisionChunks.get(Chunk) == null ? new ArrayList<>() : CollisionChunks.get(Chunk);
|
||||
}
|
||||
|
||||
public static List<CollisionMesh> GetAllCollisionMeshes(){return CollisionMeshes.values().stream().toList();}
|
||||
|
||||
public static void UpdateCollisionChunks(){
|
||||
public static synchronized void UpdateCollisionChunks(){
|
||||
Map<String,List<String>> newMap = new HashMap<>();
|
||||
List<CollisionMesh> meshes = GetAllCollisionMeshes();
|
||||
List<String> AlwaysShowMesh = new ArrayList<>();
|
||||
for(int i = 0; i < meshes.size(); i++){
|
||||
Vector3f WorldPos = new Vector3f(meshes.get(i).WorldPosition).div(ChunkWidth);
|
||||
WorldPos.x = (int)Math.floor(WorldPos.x);
|
||||
WorldPos.y = (int)Math.floor(WorldPos.y);
|
||||
WorldPos.z = (int)Math.floor(WorldPos.z);
|
||||
String ChunkPosition = WorldPos.x + ":" + WorldPos.y + ":" + WorldPos.z;
|
||||
if(!newMap.containsKey(ChunkPosition)){
|
||||
List<String> newStrList = new ArrayList<>();
|
||||
newMap.put(ChunkPosition, newStrList);
|
||||
CollisionMesh mesh = meshes.get(i);
|
||||
AABBf Bounds = mesh.GetVoxelCollider();
|
||||
if(Bounds != null) {
|
||||
Vector3f LowestPoints = new Vector3f(Bounds.minX, Bounds.minY, Bounds.minZ).div(ChunkWidth);
|
||||
LowestPoints.x = (int) Math.floor(LowestPoints.x);
|
||||
LowestPoints.y = (int) Math.floor(LowestPoints.y);
|
||||
LowestPoints.z = (int) Math.floor(LowestPoints.z);
|
||||
Vector3f LargestPoints = new Vector3f(Bounds.maxX, Bounds.maxY, Bounds.maxZ).div(ChunkWidth);
|
||||
LargestPoints.x = (int) Math.ceil(LargestPoints.x);
|
||||
LargestPoints.y = (int) Math.ceil(LargestPoints.y);
|
||||
LargestPoints.z = (int) Math.ceil(LargestPoints.z);
|
||||
for (int x = (int) LowestPoints.x; x < LargestPoints.x + 1; x++) {
|
||||
for (int y = (int) LowestPoints.y; y < LargestPoints.y + 1; y++) {
|
||||
for (int z = (int) LowestPoints.z; z < LargestPoints.z + 1; z++) {
|
||||
String ChunkPosition = x + ":" + y + ":" + z;
|
||||
if (!CollisionChunks.containsKey(ChunkPosition)) {
|
||||
List<String> newStrList = new ArrayList<>();
|
||||
CollisionChunks.put(ChunkPosition, newStrList);
|
||||
}
|
||||
CollisionChunks.get(ChunkPosition).add(mesh.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else{
|
||||
AlwaysShowMesh.add(mesh.ID);
|
||||
}
|
||||
newMap.get(ChunkPosition).add(meshes.get(i).ID);
|
||||
|
||||
}
|
||||
CollisionChunks.clear();
|
||||
CollisionChunks.putAll(newMap);
|
||||
AlwaysCheckMeshes = (AlwaysShowMesh);
|
||||
CollisionChunks = (newMap);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,37 +1,57 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Logic.Collision;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Util.Maths.T4Math;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VertexBufferStructure;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.MeshData;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.VulkanMesh;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.VulkanModel;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Util.VulkanUtils;
|
||||
import org.joml.Intersectionf;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
import org.joml.primitives.AABBf;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
import java.util.*;
|
||||
|
||||
public class CollisionMesh {
|
||||
public final List<CollisionPoly> Polygons;
|
||||
public Vector3f TopLeftFront = new Vector3f(0,0,0);
|
||||
public Vector3f BottomRightBack = new Vector3f(0,0,0);
|
||||
public Vector3f TopRightFront = new Vector3f(0,0,0);
|
||||
public Vector3f BottomLeftBack = new Vector3f(0,0,0);
|
||||
public Vector3f WorldPosition = new Vector3f(0,0,0);
|
||||
public Quaternionf Rotation;
|
||||
public Vector3f Scale;
|
||||
public Quaternionf Rotation = new Quaternionf();
|
||||
public Vector3f Scale = new Vector3f(1f,1f,1f);
|
||||
public final String ID;
|
||||
public CollisionMesh(String ID){
|
||||
public final String ParentID;
|
||||
public AABBf Voxel;
|
||||
|
||||
public CollisionMesh(String ID, String ActorID){
|
||||
this.ID = ID;
|
||||
if(ActorID != "NULL") {
|
||||
Scale = new Vector3f(Actor.Actors.get(ActorID).GetScale());
|
||||
Rotation = new Quaternionf(Actor.Actors.get(ActorID).GetRotation());
|
||||
}
|
||||
ParentID = ActorID;
|
||||
Polygons = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void RegisterMesh(){
|
||||
CollisionManager.AddNewMesh(this);
|
||||
}
|
||||
|
||||
public AABBf GetVoxelCollider(){
|
||||
if(TopRightFront == null || BottomLeftBack == null) return null;
|
||||
if(Voxel == null){
|
||||
Vector3f TLF = new Vector3f(TopRightFront);
|
||||
Vector3f BRB = new Vector3f(BottomLeftBack);
|
||||
TLF = TLF.mul(Scale).rotate(Rotation).add(WorldPosition);
|
||||
BRB = BRB.mul(Scale).rotate(Rotation).add(WorldPosition);
|
||||
AABBf ThisVoxel = new AABBf(BRB,TLF);
|
||||
this.Voxel = ThisVoxel;
|
||||
}
|
||||
return Voxel;
|
||||
}
|
||||
|
||||
public CollisionMesh SetWorldPosition(Vector3f newPos){
|
||||
this.WorldPosition = new Vector3f(newPos);
|
||||
return this;
|
||||
|
|
@ -107,37 +127,71 @@ public class CollisionMesh {
|
|||
}
|
||||
|
||||
public void CheckAABbounds(Vector3f v1, Vector3f v2, Vector3f v3){
|
||||
float Bottom = Math.min(Math.min(v3.y, v1.y), Math.min(v3.y, v2.y));
|
||||
float Left = Math.min(Math.min(v3.x, v1.x), Math.min(v3.x, v2.x));
|
||||
float back = Math.min(Math.min(v3.z, v1.z), Math.min(v3.z, v2.z));
|
||||
float Top = Math.max(Math.max(v3.y, v1.y), Math.max(v3.y, v2.y));
|
||||
float Right = Math.max(Math.max(v3.x, v1.x), Math.max(v3.x, v2.x));
|
||||
float Front = Math.max(Math.max(v3.z, v1.z), Math.max(v3.z, v2.z));
|
||||
TopLeftFront.x = Math.min(TopLeftFront.x, Left);
|
||||
TopLeftFront.y = Math.max(TopLeftFront.y, Top);
|
||||
TopLeftFront.z = Math.max(TopLeftFront.z, Front);
|
||||
BottomRightBack.x = Math.max(BottomRightBack.x, Right);
|
||||
BottomRightBack.y = Math.min(BottomRightBack.y, Bottom);
|
||||
BottomRightBack.z = Math.min(BottomRightBack.z, back);
|
||||
float localMinX = Math.min(v1.x, Math.min(v2.x, v3.x));
|
||||
float localMinY = Math.min(v1.y, Math.min(v2.y, v3.y));
|
||||
float localMinZ = Math.min(v1.z, Math.min(v2.z, v3.z));
|
||||
float localMaxX = Math.max(v1.x, Math.max(v2.x, v3.x));
|
||||
float localMaxY = Math.max(v1.y, Math.max(v2.y, v3.y));
|
||||
float localMaxZ = Math.max(v1.z, Math.max(v2.z, v3.z));
|
||||
TopRightFront.x = Math.max(TopRightFront.x, localMaxX);
|
||||
TopRightFront.y = Math.max(TopRightFront.y, localMaxY);
|
||||
TopRightFront.z = Math.max(TopRightFront.z, localMaxZ);
|
||||
BottomLeftBack.x = Math.min(BottomLeftBack.x, localMinX);
|
||||
BottomLeftBack.y = Math.min(BottomLeftBack.y, localMinY);
|
||||
BottomLeftBack.z = Math.min(BottomLeftBack.z, localMinZ);
|
||||
}
|
||||
|
||||
public void AddNewCollisionPoly(Vector3f v1, Vector3f v2, Vector3f v3){
|
||||
// if(Actor.Actors.get(ParentID) != null) {
|
||||
// PhysicsController physicsController = Actor.Actors.get(ParentID).GetPhysicsController();
|
||||
// if (physicsController != null) {
|
||||
// physicsController.AddCollisionSensor(v1);
|
||||
// physicsController.AddCollisionSensor(v2);
|
||||
// physicsController.AddCollisionSensor(v3);
|
||||
// }
|
||||
// }
|
||||
CollisionPoly newPoly = new CollisionPoly(v1,v2,v3,new Vector3f(0,0,0));
|
||||
newPoly.CalculateCentre();
|
||||
Polygons.add(newPoly);
|
||||
CheckAABbounds(v1,v2,v3);
|
||||
}
|
||||
|
||||
public boolean CheckAABBCollisionAgainstAABB(Vector3f inTopLeftFront, Vector3f inBottomRightBack){
|
||||
AABBf OtherVoxel = new AABBf(inBottomRightBack,inTopLeftFront);
|
||||
Vector3f TLF = new Vector3f(TopRightFront);
|
||||
Vector3f BRB = new Vector3f(BottomLeftBack);
|
||||
TLF = TLF.mul(Scale).rotate(Rotation).add(WorldPosition);
|
||||
BRB = BRB.mul(Scale).rotate(Rotation).add(WorldPosition);
|
||||
AABBf ThisVoxel = new AABBf(BRB,TLF);
|
||||
this.Voxel = ThisVoxel;
|
||||
return ThisVoxel.intersectsAABB(OtherVoxel);
|
||||
}
|
||||
|
||||
public boolean CheckAABBCollisionAgainstAABB(AABBf OtherVoxel){
|
||||
Vector3f TLF = new Vector3f(TopRightFront);
|
||||
Vector3f BRB = new Vector3f(BottomLeftBack);
|
||||
TLF = TLF.mul(Scale).rotate(Rotation).add(WorldPosition);
|
||||
BRB = BRB.mul(Scale).rotate(Rotation).add(WorldPosition);
|
||||
AABBf ThisVoxel = new AABBf(BRB,TLF);
|
||||
this.Voxel = ThisVoxel;
|
||||
return ThisVoxel.intersectsAABB(OtherVoxel);
|
||||
}
|
||||
|
||||
public boolean CheckAABCollision(Vector3f Origin, Vector3f Sensor){
|
||||
Vector3f LineDirection = new Vector3f(Sensor).sub(Origin);
|
||||
Vector2f Result = new Vector2f();
|
||||
return Intersectionf.intersectRayAab(Origin, LineDirection,BottomRightBack,TopLeftFront,Result) && Result.x <= 1.0f && Result.y >= 0.0f;
|
||||
Vector3f TLF = new Vector3f(TopRightFront);
|
||||
Vector3f BRB = new Vector3f(BottomLeftBack);
|
||||
TLF = TLF.mul(Scale).rotate(Rotation).add(WorldPosition);
|
||||
BRB = BRB.mul(Scale).rotate(Rotation).add(WorldPosition);
|
||||
AABBf ThisVoxel = new AABBf(BRB,TLF);
|
||||
return Intersectionf.intersectRayAab(Origin, LineDirection,BRB,TLF,Result) && Result.x <= 1.0f && Result.y >= 0.0f;
|
||||
}
|
||||
|
||||
public boolean SimpleCheckCollision(Vector3f Origin, Vector3f Sensor){
|
||||
Vector3f LineDirection = new Vector3f(Sensor).sub(Origin);
|
||||
Vector2f Result = new Vector2f(0,0);
|
||||
if(Intersectionf.intersectRayAab(Origin, LineDirection,BottomRightBack,TopLeftFront,Result) && Result.x <= 1.0f && Result.y >= 0.0f){
|
||||
if(Intersectionf.intersectRayAab(Origin, LineDirection, BottomLeftBack, TopRightFront,Result) && Result.x <= 1.0f && Result.y >= 0.0f){
|
||||
for(int i = 0; i < Polygons.size(); i++){
|
||||
CollisionPoly polygon = Polygons.get(i);
|
||||
if(T4Math.Math3D.DoesLineCollideWithPoly(Origin,Sensor,new Vector3f[]{polygon.v1(),polygon.v2(),polygon.v3()})){
|
||||
|
|
@ -151,18 +205,20 @@ public class CollisionMesh {
|
|||
public CollisionPoly[] GetAllPolygons(){
|
||||
int Rows = Polygons.size();
|
||||
CollisionPoly[] PolygonArr = new CollisionPoly[Rows * 3];
|
||||
Vector3f PivotOffset = Actor.Actors.get(ParentID) != null ? new Vector3f(Actor.Actors.get(ParentID).GetPivotOffset()).add(Actor.Actors.get(ParentID).GetAditionalPivotOffset()) : new Vector3f(0,0,0);
|
||||
for(int row = 0; row < Rows; row++){
|
||||
PolygonArr[row] = Polygons.get(row).TransformScale(Scale).TransformRotation(Rotation).TransformPosition(WorldPosition);
|
||||
PolygonArr[row] = Polygons.get(row).TransformScale(Scale).TransformPosition(PivotOffset).TransformRotation(Rotation).TransformPosition(PivotOffset.negate()).TransformPosition(WorldPosition);
|
||||
}
|
||||
return PolygonArr;
|
||||
}
|
||||
|
||||
public Vector3f[] GetAllVertices(){
|
||||
int Rows = Polygons.size();
|
||||
Vector3f PivotOffset = Actor.Actors.get(ParentID) != null ? new Vector3f(Actor.Actors.get(ParentID).GetPivotOffset()).add(Actor.Actors.get(ParentID).GetAditionalPivotOffset()) : new Vector3f(0,0,0);
|
||||
Vector3f[] Vertices = new Vector3f[Rows * 3];
|
||||
for(int row = 0; row < Rows; row++){
|
||||
int StartPos = row * 3;
|
||||
CollisionPoly poly = Polygons.get(row).TransformScale(Scale).TransformRotation(Rotation).TransformPosition(WorldPosition);
|
||||
CollisionPoly poly = Polygons.get(row).TransformScale(Scale).TransformPosition(PivotOffset).TransformRotation(Rotation).TransformPosition(PivotOffset.negate()).TransformPosition(WorldPosition);
|
||||
Vertices[StartPos] = new Vector3f(poly.v1().x,poly.v1().y,poly.v1().z);
|
||||
Vertices[StartPos + 1] = new Vector3f(poly.v2().x,poly.v2().y,poly.v2().z);
|
||||
Vertices[StartPos + 2] = new Vector3f(poly.v3().x,poly.v3().y,poly.v3().z);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Logic.Physics;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Collision.CollisionPoly;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
public record CollisionSensor(Vector3f Offset, String ActorID) {
|
||||
public CollisionSensor TransformRotation(Quaternionf quaternionf){
|
||||
if(quaternionf == null ) return this;
|
||||
Vector3f newV1 = new Vector3f(Offset);
|
||||
newV1.rotate(quaternionf);
|
||||
CollisionSensor newPoly = new CollisionSensor(newV1,ActorID);
|
||||
return newPoly;
|
||||
}
|
||||
public CollisionSensor TransformScale(Vector3f Scale){
|
||||
if(Scale == null ) return this;
|
||||
Vector3f newV1 = new Vector3f(Offset);
|
||||
newV1.mul(Scale);
|
||||
CollisionSensor newPoly = new CollisionSensor(newV1,ActorID);
|
||||
return newPoly;
|
||||
}
|
||||
public CollisionSensor TransformPosition(Vector3f Position){
|
||||
if(Position == null ) return this;
|
||||
Vector3f newV1 = new Vector3f(Offset);
|
||||
newV1.add(Position);
|
||||
CollisionSensor newPoly = new CollisionSensor(newV1,ActorID);
|
||||
return newPoly;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Logic.Physics;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Collision.CollisionManager;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Collision.CollisionMesh;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Collision.CollisionPoly;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Util.Maths.T4Math;
|
||||
import org.joml.Vector3f;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static net.halbear.Terrain4J.EngineCore.Logic.Collision.CollisionManager.ChunkWidth;
|
||||
|
||||
public class PhysicsController {
|
||||
|
||||
public List<CollisionSensor> collisionSensors;
|
||||
public Vector3f Velocities = new Vector3f(0,0,0);
|
||||
public Vector3f WeightBalance = new Vector3f(0,0,0);
|
||||
public float MassKG = 10.0f;
|
||||
public Vector3f TerminalVelocitiesMS = new Vector3f(36f,6.6f,36f);
|
||||
public Vector3f Drag = new Vector3f(0.2f,0.2f,0.2f);
|
||||
public Vector3f DragCoefficients = new Vector3f(0.1f,0.1f,0.1f);
|
||||
public Vector3f CrossSectionAreas = new Vector3f(1.8f * 0.9f, 0.6f * 0.9f, 1.8f * 0.6f);
|
||||
public Vector3f WeightDistribution = new Vector3f(2.0f,5.0f,7.0f);
|
||||
public float FallingAcceleration = 0.0f;
|
||||
public float Bounciness = 0.3f;
|
||||
String CurrentChunkPosition = "NULL";
|
||||
|
||||
public void CalculateDragCoefficients(){
|
||||
Vector3f dragCoefficients = WorldPhysicsManager.CalculateDragFromTerminalVelocities(TerminalVelocitiesMS,MassKG,CrossSectionAreas);
|
||||
this.DragCoefficients = new Vector3f(dragCoefficients);
|
||||
}
|
||||
public void CalculateDrag(){
|
||||
Vector3f drag = WorldPhysicsManager.CalculateRealDrag(Velocities,DragCoefficients,CrossSectionAreas);
|
||||
this.Drag = new Vector3f(drag);
|
||||
}
|
||||
public void CalculateFallSpeed(){
|
||||
FallingAcceleration = WorldPhysicsManager.CalculateGravityForce(MassKG, Drag);
|
||||
}
|
||||
|
||||
public final String ID;
|
||||
public final String ParentID;
|
||||
|
||||
public PhysicsController(String ActorID){
|
||||
collisionSensors = new ArrayList<>();
|
||||
ID = ActorID + "_PHYSICS_CONTROLLER";
|
||||
ParentID = ActorID;
|
||||
WorldPhysicsManager.PhysicsObjects.put(ID, this);
|
||||
WorldPhysicsManager.ActiveControllers.add(ID);
|
||||
Actor actor = Actor.Actors.get(ParentID);
|
||||
Vector3f WorldPos = new Vector3f(actor.GetPosition()).div(ChunkWidth);
|
||||
WorldPos.x = (int)Math.floor(WorldPos.x);
|
||||
WorldPos.y = (int)Math.floor(WorldPos.y);
|
||||
WorldPos.z = (int)Math.floor(WorldPos.z);
|
||||
CurrentChunkPosition = WorldPos.x + ":" + WorldPos.y + ":" + WorldPos.z;
|
||||
CalculateDragCoefficients();
|
||||
}
|
||||
|
||||
public PhysicsController AddCollisionSensor(Vector3f RelativeOffset){
|
||||
collisionSensors.add(new CollisionSensor(RelativeOffset, ParentID));
|
||||
return this;
|
||||
}
|
||||
|
||||
public void PhysicsTick(float DeltaTime, float TargetFrameRate){
|
||||
Actor actor = Actor.Actors.get(ParentID);
|
||||
Vector3f Position = new Vector3f(actor.GetPosition());
|
||||
Vector3f NextPosition = new Vector3f(Position);
|
||||
Vector3f Velocity = new Vector3f(Velocities);
|
||||
Velocity = Velocity.mul(DeltaTime);
|
||||
NextPosition.add(Velocity);
|
||||
boolean ValidMovement = true;
|
||||
CalculateDrag();
|
||||
CalculateFallSpeed();
|
||||
Velocities.y -= (FallingAcceleration/(TargetFrameRate*2)) * DeltaTime;
|
||||
Velocities = Velocities.mul((1f - (WorldPhysicsManager.Drag * (DeltaTime))),1f,(1f - (WorldPhysicsManager.Drag * (DeltaTime))));
|
||||
if(collisionSensors != null && !collisionSensors.isEmpty()) {
|
||||
// Vector3f WorldPos = new Vector3f(NextPosition).div(ChunkWidth);
|
||||
// WorldPos.x = (int) Math.floor(WorldPos.x);
|
||||
// WorldPos.y = (int) Math.floor(WorldPos.y);
|
||||
// WorldPos.z = (int) Math.floor(WorldPos.z);
|
||||
// String NextChunkPosition = WorldPos.x + ":" + WorldPos.y + ":" + WorldPos.z;
|
||||
// List<String> CollisionMeshesToCycleThrough = new ArrayList<>(CollisionManager.AlwaysCheckMeshes);
|
||||
// CollisionMeshesToCycleThrough.addAll(CollisionManager.GetCollisionMeshesAtChunk(NextChunkPosition));
|
||||
// if (!NextChunkPosition.equals(CurrentChunkPosition)) {
|
||||
// CollisionMeshesToCycleThrough.addAll(CollisionManager.GetCollisionMeshesAtChunk(CurrentChunkPosition));
|
||||
// CurrentChunkPosition = NextChunkPosition;
|
||||
// }
|
||||
// Logger.debug(CollisionMeshesToCycleThrough.size());
|
||||
List<CollisionMesh> CollisionMeshesToCycleThrough = CollisionManager.GetAllCollisionMeshes();
|
||||
//Logger.debug("Collision Mesh Count [{}]",CollisionMeshesToCycleThrough.size());
|
||||
Vector3f PivotOffset = Actor.Actors.get(ParentID) != null ? new Vector3f(Actor.Actors.get(ParentID).GetPivotOffset()).add(Actor.Actors.get(ParentID).GetAditionalPivotOffset()) : new Vector3f(0,0,0);
|
||||
List<CollisionSensor> CollidingSensors = new ArrayList<>();
|
||||
for (int j = 0; j < collisionSensors.size(); j++) {
|
||||
CollidingSensors.add(collisionSensors.get(j).TransformScale(actor.GetScale()).TransformPosition(PivotOffset).TransformRotation(actor.GetRotation()).TransformPosition(PivotOffset.negate()).TransformPosition(NextPosition));
|
||||
}
|
||||
if(CollidingSensors.size() > 0){
|
||||
for(int i = 0; i < CollisionMeshesToCycleThrough.size(); i++){
|
||||
CollisionMesh collisionMesh = CollisionMeshesToCycleThrough.get(i);
|
||||
if(collisionMesh != null && !Objects.equals(collisionMesh.ID, actor.GetCollisionMesh().ID) && collisionMesh.CheckAABBCollisionAgainstAABB(collisionMesh.GetVoxelCollider())) {
|
||||
CollisionPoly[] polygons = collisionMesh.GetAllPolygons();
|
||||
for(int j = 0; j < polygons.length; j++){
|
||||
CollisionPoly poly = polygons[j];
|
||||
if(poly != null) {
|
||||
for (int k = 0; k < CollidingSensors.size(); k++) {
|
||||
Vector3f CollisionPoint = T4Math.Math3D.LineCollisionPointWithPoly(NextPosition, CollidingSensors.get(k).Offset(), new Vector3f[]{poly.v1(), poly.v2(), poly.v3()});
|
||||
if (CollisionPoint != null) {
|
||||
Vector3f subtraction = new Vector3f(NextPosition).sub(CollisionPoint);
|
||||
if(Math.abs(subtraction.x) > 0.1f && Math.abs(subtraction.z) > 0.1f) {
|
||||
NextPosition.sub(new Vector3f(NextPosition).sub(CollisionPoint));
|
||||
} else {
|
||||
NextPosition.sub(0,new Vector3f(NextPosition).sub(CollisionPoint).y,0);
|
||||
}
|
||||
Velocities.y = -Velocities.y * Bounciness;
|
||||
if(Math.abs(Velocities.y) < 0.05f) Velocities.y = 0;
|
||||
ValidMovement = false;
|
||||
}
|
||||
if(!ValidMovement)break;
|
||||
}
|
||||
}
|
||||
if(!ValidMovement)break;
|
||||
}
|
||||
}
|
||||
if(!ValidMovement)break;
|
||||
}
|
||||
}
|
||||
}
|
||||
actor.SetPosition(NextPosition);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Logic.Physics;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class WorldPhysicsManager {
|
||||
public static float GravityMS = 9.8f;
|
||||
public static float AirResistance = 0.5f;
|
||||
public static float Drag = 0.02f;
|
||||
public static float AirDensityKGM3 = 1.225f;
|
||||
|
||||
public static Vector3f CalculateRealDrag(Vector3f Velocity, Vector3f DragCoefficients, Vector3f CrossSectionAreas){
|
||||
float XDrag = 0.5f * (AirDensityKGM3 * Velocity.x * Velocity.x * DragCoefficients.x * CrossSectionAreas.x);
|
||||
float YDrag = 0.5f * (AirDensityKGM3 * Velocity.y * Velocity.y * DragCoefficients.y * CrossSectionAreas.y);
|
||||
float ZDrag = 0.5f * (AirDensityKGM3 * Velocity.z * Velocity.z * DragCoefficients.z * CrossSectionAreas.z);
|
||||
return new Vector3f(XDrag,YDrag,ZDrag);
|
||||
}
|
||||
|
||||
public static float CalculateGravityForce(float Mass, Vector3f Drag){
|
||||
return ((Mass * GravityMS) - Drag.y)/Mass;
|
||||
}
|
||||
|
||||
public static Vector3f CalculateDragFromTerminalVelocities(Vector3f TerminalVelocities, float Mass, Vector3f CrossSectionAreas){
|
||||
float Cdx = (2 * Mass * GravityMS) / (AirDensityKGM3 * TerminalVelocities.x * TerminalVelocities.x * CrossSectionAreas.x);
|
||||
float Cdy = (2 * Mass * GravityMS) / (AirDensityKGM3 * TerminalVelocities.y * TerminalVelocities.y * CrossSectionAreas.y);
|
||||
float Cdz = (2 * Mass * GravityMS) / (AirDensityKGM3 * TerminalVelocities.z * TerminalVelocities.z * CrossSectionAreas.z);
|
||||
return new Vector3f(Cdx, Cdy, Cdz);
|
||||
}
|
||||
|
||||
public static final Map<String, PhysicsController> PhysicsObjects = new HashMap<>();
|
||||
public static List<String> ActiveControllers = new ArrayList<>();
|
||||
|
||||
public static void PhysicsTick(float DeltaTime, float TargetFrameTime){
|
||||
for(int i = 0; i < ActiveControllers.size(); i++){
|
||||
PhysicsObjects.get(ActiveControllers.get(i)).PhysicsTick(DeltaTime, TargetFrameTime);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -12,11 +12,13 @@ import net.halbear.Terrain4J.EngineCore.Audio.SoundListener;
|
|||
import net.halbear.Terrain4J.EngineCore.Display.Window;
|
||||
import net.halbear.Terrain4J.EngineCore.Input.KeyboardInput;
|
||||
import net.halbear.Terrain4J.EngineCore.Input.MouseListener;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Collision.CollisionManager;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Collision.CollisionMesh;
|
||||
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.InitData;
|
||||
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.GUIs.Gimbal;
|
||||
|
|
@ -78,14 +80,32 @@ public class GameCore implements GameLogic {
|
|||
MelonaData = ModelLoader.LoadModel("resources/models/melona/melona.json");
|
||||
List<MaterialData> MelonaDataMat = ModelLoader.LoadMaterials("resources/models/melona/melona_mat.json");
|
||||
var Melona = new Actor("Melona", MelonaData.ID(), new Vector3f(0,0f,-5f)).SetRotation(0,(float)Math.toRadians(180),0);
|
||||
CollisionMesh mesh = new CollisionMesh("Super Collision Mesh");
|
||||
mesh.AddNewCollisionPoly(new Vector3f(-100,-5,0),new Vector3f(-100,-5,-100),new Vector3f(0,-5,-100));
|
||||
mesh.AddNewCollisionPoly(new Vector3f(0,-5,0),new Vector3f(0,-5,-100),new Vector3f(-100,-5,0));
|
||||
Melona.CreatePhysicsController();
|
||||
Melona.GetPhysicsController()
|
||||
.AddCollisionSensor(new Vector3f(0,0,0))
|
||||
.AddCollisionSensor(new Vector3f(0,1.8f,0))
|
||||
.AddCollisionSensor(new Vector3f(0.5f,0,0))
|
||||
.AddCollisionSensor(new Vector3f(-0.5f,0,0))
|
||||
.AddCollisionSensor(new Vector3f(0.5f,1.8f,0))
|
||||
.AddCollisionSensor(new Vector3f(-5f,1.8f,0))
|
||||
.AddCollisionSensor(new Vector3f(0.5f,1.8f,0.5f))
|
||||
.AddCollisionSensor(new Vector3f(-0.5f,1.8f,0.5f))
|
||||
.AddCollisionSensor(new Vector3f(-0.5f,1.8f,-0.5f))
|
||||
.AddCollisionSensor(new Vector3f(0.5f,1.8f,-0.5f))
|
||||
.AddCollisionSensor(new Vector3f(0f,1.8f,0.5f))
|
||||
.AddCollisionSensor(new Vector3f(-0f,1.8f,-0.5f))
|
||||
.AddCollisionSensor(new Vector3f(-0f,0f,-0.5f))
|
||||
.AddCollisionSensor(new Vector3f(0f,0f,0.5f));
|
||||
|
||||
CollisionMesh mesh = new CollisionMesh("Super Collision Mesh","NULL");
|
||||
mesh.AddNewCollisionPoly(new Vector3f(-100,-5,100),new Vector3f(-100,-5.5f,-100),new Vector3f(100,-6,-100));
|
||||
mesh.AddNewCollisionPoly(new Vector3f(100,-5.5f,100),new Vector3f(100,-6,-100),new Vector3f(-100,-5,100));
|
||||
try {
|
||||
Melona.GenerateCollisionMesh(MelonaData);
|
||||
} catch(IOException e){
|
||||
Logger.error("Could Not Generate Collison Mesh [{}]",e);
|
||||
}
|
||||
mesh.RegisterMesh();
|
||||
scene.AddActor(Melona);
|
||||
ActorEditorComponents.add(new EditorActorComponent(Melona,new Vector3f(0,0f,-5f),new Vector3f(1.0f,1.8f,1.0f)));
|
||||
CubeActors.forEach(scene::AddActor);
|
||||
|
|
@ -127,7 +147,26 @@ public class GameCore implements GameLogic {
|
|||
|
||||
public void SpawnNewActorEditorComponent(EngineInstance engineInstance){
|
||||
var scene = engineInstance.scene();
|
||||
var Melona = new Actor("Melona" + scene.GetActors().size(), MelonaData.ID(), new Vector3f(scene.GetCamera().GetPosition())).SetRotation(new Vector3f(scene.GetCamera().GetRotation()));
|
||||
Camera camera = scene.GetCamera().CloneCamera();
|
||||
camera.MoveForward(5);
|
||||
var Melona = new Actor("MelonaSpawned" + scene.GetActors().size(), MelonaData.ID(), new Vector3f(camera.GetPosition()));
|
||||
camera = null;
|
||||
Melona.CreatePhysicsController();
|
||||
Melona.GetPhysicsController()
|
||||
.AddCollisionSensor(new Vector3f(0,0,0))
|
||||
.AddCollisionSensor(new Vector3f(0,1.8f,0))
|
||||
.AddCollisionSensor(new Vector3f(0.5f,0,0))
|
||||
.AddCollisionSensor(new Vector3f(-0.5f,0,0))
|
||||
.AddCollisionSensor(new Vector3f(0.5f,1.8f,0))
|
||||
.AddCollisionSensor(new Vector3f(-5f,1.8f,0))
|
||||
.AddCollisionSensor(new Vector3f(0.5f,1.8f,0.5f))
|
||||
.AddCollisionSensor(new Vector3f(-0.5f,1.8f,0.5f))
|
||||
.AddCollisionSensor(new Vector3f(-0.5f,1.8f,-0.5f))
|
||||
.AddCollisionSensor(new Vector3f(0.5f,1.8f,-0.5f))
|
||||
.AddCollisionSensor(new Vector3f(0f,1.8f,0.5f))
|
||||
.AddCollisionSensor(new Vector3f(-0f,1.8f,-0.5f))
|
||||
.AddCollisionSensor(new Vector3f(-0f,0f,-0.5f))
|
||||
.AddCollisionSensor(new Vector3f(0f,0f,0.5f));
|
||||
try {
|
||||
Melona.GenerateCollisionMesh(MelonaData);
|
||||
} catch(IOException e){
|
||||
|
|
@ -196,7 +235,7 @@ public class GameCore implements GameLogic {
|
|||
KeyboardInput input = window.getKeyboardInput();
|
||||
float MovementDist = (float)(FrameDiffNanoSeconds / 1000000L) * MOVEMENT_SPEED;
|
||||
Camera camera = scene.GetCamera();
|
||||
if(input.keyPressed(GLFW_KEY_F3)){
|
||||
if(input.keySinglePress(GLFW_KEY_F3)){
|
||||
GUI_MODE = (GUI_MODE + 1) % 2;
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_1)) {
|
||||
|
|
@ -208,6 +247,14 @@ public class GameCore implements GameLogic {
|
|||
if(input.keyPressed(GLFW_KEY_3)) {
|
||||
Gimbal.universalType = Gimbal.GimbalType.Rotate;
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_TAB)){
|
||||
for(int i = 0; i < ActorEditorComponents.size(); i++){
|
||||
ActorEditorComponents.get(i).UpdateAll();
|
||||
}
|
||||
}
|
||||
if(input.keySinglePress(GLFW_KEY_F2)) {
|
||||
EngineConfig.getInstance().SetRenderCollisionMesh(!EngineConfig.getInstance().RenderCollisionMeshes());
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_W)){
|
||||
camera.MoveForward(MovementDist);
|
||||
}
|
||||
|
|
@ -269,10 +316,18 @@ public class GameCore implements GameLogic {
|
|||
|
||||
@Override
|
||||
public void Update(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void UpdateFastThread(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||
float PhysicsFramerate = 24f;
|
||||
float PhysicsFrameTime = 1000f/PhysicsFramerate;
|
||||
float DeltaTime = (float)FrameDiffNanoSeconds/(PhysicsFrameTime*1000000f);
|
||||
if(PrimaryRuntime.GetFastThread().Ticks(20)==0){
|
||||
//CollisionManager.UpdateCollisionChunks();
|
||||
}
|
||||
WorldPhysicsManager.PhysicsTick(DeltaTime, PhysicsFramerate);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1,14 +1,19 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Main.Scene;
|
||||
|
||||
import imgui.extension.imguizmo.flag.Mode;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Collision.CollisionMesh;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Physics.PhysicsController;
|
||||
import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Actor{
|
||||
public static final Map<String, Actor> Actors = new HashMap<>();
|
||||
private final String ID;
|
||||
private final String ModelID;
|
||||
private final Matrix4f ModelMatrix;
|
||||
|
|
@ -16,6 +21,10 @@ public class Actor{
|
|||
private final Quaternionf Rotation;
|
||||
private CollisionMesh collisionMesh;
|
||||
private Vector3f Scale;
|
||||
private PhysicsController physicsController;
|
||||
private final Vector3f PivotOffset;
|
||||
private final Vector3f AdditionalPivotOffset;
|
||||
private final Vector3f TemporaryVector;
|
||||
|
||||
public CollisionMesh GetCollisionMesh(){
|
||||
return collisionMesh;
|
||||
|
|
@ -25,15 +34,41 @@ public class Actor{
|
|||
this.ID = ID;
|
||||
this.ModelID = ModelID;
|
||||
this.Position = Position;
|
||||
TemporaryVector = new Vector3f();
|
||||
PivotOffset = new Vector3f();
|
||||
AdditionalPivotOffset = new Vector3f();
|
||||
Scale = new Vector3f(1f,1f,1f);
|
||||
Rotation = new Quaternionf();
|
||||
ModelMatrix = new Matrix4f();
|
||||
UpdateModelMatrix();
|
||||
Actors.put(ID,this);
|
||||
}
|
||||
|
||||
public Vector3f GetAditionalPivotOffset(){return AdditionalPivotOffset;}
|
||||
|
||||
public Actor SetAditionalPivotOffset(Vector3f offset){
|
||||
AdditionalPivotOffset.set(offset);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector3f GetPivotOffset(){return PivotOffset;}
|
||||
|
||||
public Actor SetPivotOffset(Vector3f offset){
|
||||
PivotOffset.set(offset);
|
||||
return this;
|
||||
}
|
||||
|
||||
public PhysicsController GetPhysicsController(){return physicsController;}
|
||||
|
||||
public Actor CreatePhysicsController(){
|
||||
physicsController = new PhysicsController(ID);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Actor GenerateCollisionMesh(ModelData modelData) throws IOException {
|
||||
collisionMesh = new CollisionMesh(ID + "_COLLISION_MESH");
|
||||
collisionMesh = new CollisionMesh(ID + "_COLLISION_MESH", ID);
|
||||
collisionMesh.GenerateCollisionMeshFromVulkanModel(modelData);
|
||||
collisionMesh.RegisterMesh();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -59,7 +94,12 @@ public class Actor{
|
|||
UpdateModelMatrix();
|
||||
return this;
|
||||
}
|
||||
|
||||
public Actor SetPosition(Vector3f position){
|
||||
Position.set(position);
|
||||
UpdateModelMatrix();
|
||||
if(collisionMesh != null)collisionMesh.SetWorldPosition(Position);
|
||||
return this;
|
||||
}
|
||||
public Actor SetPosition(float x, float y, float z){
|
||||
Position.x = x;
|
||||
Position.y = y;
|
||||
|
|
@ -83,7 +123,10 @@ public class Actor{
|
|||
}
|
||||
|
||||
public void UpdateModelMatrix(){
|
||||
ModelMatrix.translateLocal(TemporaryVector.set(PivotOffset).add(AdditionalPivotOffset));
|
||||
ModelMatrix.translationRotateScale(Position, Rotation, Scale);
|
||||
ModelMatrix.translateLocal(TemporaryVector.negate());
|
||||
|
||||
}
|
||||
|
||||
public String GetID(){return ID;}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,18 @@ public class Camera {
|
|||
private final Matrix4f ViewMatrix;
|
||||
private float FOV = (float) (60 * EngineConfig.DegToRad);
|
||||
private boolean Sprint;
|
||||
int i = 0;
|
||||
|
||||
public Camera CloneCamera(){
|
||||
Camera NewCam = new Camera();
|
||||
NewCam.SetPosition(Position.x, Position.y, Position.z);
|
||||
NewCam.SetRotation(Rotation.x, Rotation.y, Rotation.z);
|
||||
NewCam.Right.set(new Vector3f(Right));
|
||||
NewCam.Up.set(new Vector3f(Up));
|
||||
NewCam.SetFOVrad(FOV);
|
||||
NewCam.Sprint = Sprint;
|
||||
NewCam.ViewMatrix.set(new Matrix4f(ViewMatrix));
|
||||
return NewCam;
|
||||
}
|
||||
|
||||
public Camera(){
|
||||
Direction = new Vector3f();
|
||||
|
|
@ -24,6 +35,12 @@ public class Camera {
|
|||
ViewMatrix = new Matrix4f();
|
||||
}
|
||||
|
||||
public Camera SetFOVrad(float FOVradians){
|
||||
FOV = FOVradians;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Camera SetFOV(float FOVdegrees){
|
||||
FOV = (float) (FOVdegrees * EngineConfig.DegToRad);
|
||||
return this;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,10 @@ package net.halbear.Terrain4J.EngineCore.Main.Scene;
|
|||
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.Gimbal;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
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;
|
||||
|
|
@ -19,8 +22,12 @@ public class EditorActorComponent implements IMoveableActorComponent{
|
|||
ActorGimbal = new Gimbal(Position, new Vector3f(1.0f,1.0f,1.0f),this).SetID(ID);
|
||||
ActorComponentCount++;
|
||||
UpdateAll();
|
||||
EditorComponents.put(actor.GetID() + "_COMPONENT",this);
|
||||
}
|
||||
|
||||
public IMoveableActorComponent GetEditorComponent(String ActorID){
|
||||
return EditorComponents.get(ActorID + "_COMPONENT");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void UpdateAll() {
|
||||
|
|
@ -30,7 +37,7 @@ public class EditorActorComponent implements IMoveableActorComponent{
|
|||
actor.GetCollisionMesh().SetRotationTransform(actor.GetRotation());
|
||||
actor.GetCollisionMesh().SetScaleTransform(actor.GetScale());
|
||||
}
|
||||
ActorGimbal.SetPosition(new Vector3f(Position.x, Position.y + ActorDimensions.y/2, Position.z));
|
||||
ActorGimbal.SetPosition(new Vector3f(Position.x, Position.y, Position.z).add(actor.GetPivotOffset()).add(actor.GetAditionalPivotOffset()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -45,8 +52,8 @@ public class EditorActorComponent implements IMoveableActorComponent{
|
|||
|
||||
@Override
|
||||
public void AddPosition(Vector3f addedPos) {
|
||||
Vector3f Pos = actor.GetPosition();
|
||||
actor.SetPosition(Pos.x + addedPos.x, Pos.y + addedPos.y, Pos.z + addedPos.z);
|
||||
Vector3f Pos = Position;
|
||||
actor.GetPosition().set(Pos.x + addedPos.x, Pos.y + addedPos.y, Pos.z + addedPos.z);
|
||||
Position = new Vector3f(actor.GetPosition());
|
||||
UpdateAll();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ public class Gimbal implements GUIOverlay {
|
|||
drawList.addLine(v1.x, v1.y, v2.x, v2.y, colour, 1f);
|
||||
drawList.addLine(v2.x, v2.y, v3.x, v3.y, colour, 1f);
|
||||
drawList.addLine(v3.x, v3.y, v1.x, v1.y, colour, 1f);
|
||||
colour = ImGui.getColorU32(0.0f, 0.4f, 1.0f, 0.3f);
|
||||
colour = ImGui.getColorU32(0.0f, 0.4f, 1.0f, 0.1f);
|
||||
drawList.addTriangleFilled(
|
||||
new ImVec2(v1.x,v1.y),
|
||||
new ImVec2(v2.x,v2.y),
|
||||
|
|
|
|||
|
|
@ -28,6 +28,17 @@ public class T4Math {
|
|||
public static class Math3D {
|
||||
public static float epsilon = 1e-6f;
|
||||
|
||||
|
||||
|
||||
public static boolean TestAabbAabb(
|
||||
float minX1, float minY1, float minZ1, float maxX1, float maxY1, float maxZ1,
|
||||
float minX2, float minY2, float minZ2, float maxX2, float maxY2, float maxZ2) {
|
||||
|
||||
return minX1 <= maxX2 && maxX1 >= minX2 &&
|
||||
minY1 <= maxY2 && maxY1 >= minY2 &&
|
||||
minZ1 <= maxZ2 && maxZ1 >= minZ2;
|
||||
}
|
||||
|
||||
public static boolean DoesLineCollideWithPoly(Vector3f Origin, Vector3f Point, Vector3f[] Vertices){
|
||||
Vector3f LineDirection = new Vector3f(Point).sub(Origin);
|
||||
float Test = Intersectionf.intersectRayTriangle(Origin,LineDirection,
|
||||
|
|
@ -35,36 +46,14 @@ public class T4Math {
|
|||
return(Test >= 0.0f && Test <= 1.0f);
|
||||
}
|
||||
|
||||
public static boolean ComplexLinePolyCollisionCheck(Vector3f Origin, Vector3f Point, Vector3f[] Vertices){
|
||||
public static Vector3f LineCollisionPointWithPolyRelative(Vector3f Origin, Vector3f Point, Vector3f[] Vertices){
|
||||
Vector3f LineDirection = new Vector3f(Point).sub(Origin);
|
||||
float Test = Intersectionf.intersectRayTriangle(Origin,LineDirection,
|
||||
Vertices[0],Vertices[1],Vertices[2], epsilon);
|
||||
if(Test >= 0.0f && Test <= 1.0f) return true;
|
||||
|
||||
Vector3f edge1 = new Vector3f(Vertices[1]).sub(Vertices[0]);
|
||||
Vector3f edge2 = new Vector3f(Vertices[2]).sub(Vertices[0]);
|
||||
Vector3f normal = new Vector3f(edge1).cross(edge2).normalize();
|
||||
Vector3f pAFromV0 = new Vector3f(Origin).sub(Vertices[0]);
|
||||
Vector3f pBFromV0 = new Vector3f(Point).sub(Vertices[0]);
|
||||
boolean pAOnPlane = Math.abs(pAFromV0.dot(normal)) < epsilon;
|
||||
boolean pBOnPlane = Math.abs(pBFromV0.dot(normal)) < epsilon;
|
||||
|
||||
if (pAOnPlane && pBOnPlane) {
|
||||
if (Intersectionf.testPointInTriangle(Origin.x,Origin.y,Origin.z,
|
||||
Vertices[0].x,Vertices[0].y,Vertices[0].z,
|
||||
Vertices[1].x,Vertices[1].y,Vertices[1].z,
|
||||
Vertices[2].x,Vertices[2].y,Vertices[2].z) ||
|
||||
Intersectionf.testPointInTriangle(Point.x,Point.y,Point.z,
|
||||
Vertices[0].x,Vertices[0].y,Vertices[0].z,
|
||||
Vertices[1].x,Vertices[1].y,Vertices[1].z,
|
||||
Vertices[2].x,Vertices[2].y,Vertices[2].z)) {
|
||||
return true;
|
||||
}
|
||||
if (Intersectionf.testLineSegmentTriangle(Origin, Point, Vertices[0], Vertices[1],Vertices[2], epsilon)){
|
||||
return true;
|
||||
}
|
||||
if (Test >= 0.0f && Test <= 1.0f) {
|
||||
return new Vector3f(LineDirection).mul(Test);
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Vector3f LineCollisionPointWithPoly(Vector3f Origin, Vector3f Point, Vector3f[] Vertices){
|
||||
|
|
@ -128,10 +117,41 @@ public class T4Math {
|
|||
float ndcX = clipSpacePos.x / clipSpacePos.w;
|
||||
float ndcY = clipSpacePos.y / clipSpacePos.w;
|
||||
float ndcZ = clipSpacePos.z / clipSpacePos.w;
|
||||
if (ndcZ < -1.0f || ndcZ > 1.0f) return null;
|
||||
float screenX = ((ndcX + 1.0f) / 2.0f) * windowWidth;
|
||||
float screenY = ((1.0f - ndcY) / 2.0f) * windowHeight;
|
||||
return new Vector3f(screenX, screenY, ndcZ);
|
||||
}
|
||||
|
||||
public static boolean ComplexLinePolyCollisionCheck(Vector3f Origin, Vector3f Point, Vector3f[] Vertices){
|
||||
Vector3f LineDirection = new Vector3f(Point).sub(Origin);
|
||||
float Test = Intersectionf.intersectRayTriangle(Origin,LineDirection,
|
||||
Vertices[0],Vertices[1],Vertices[2], epsilon);
|
||||
if(Test >= 0.0f && Test <= 1.0f) return true;
|
||||
|
||||
Vector3f edge1 = new Vector3f(Vertices[1]).sub(Vertices[0]);
|
||||
Vector3f edge2 = new Vector3f(Vertices[2]).sub(Vertices[0]);
|
||||
Vector3f normal = new Vector3f(edge1).cross(edge2).normalize();
|
||||
Vector3f pAFromV0 = new Vector3f(Origin).sub(Vertices[0]);
|
||||
Vector3f pBFromV0 = new Vector3f(Point).sub(Vertices[0]);
|
||||
boolean pAOnPlane = Math.abs(pAFromV0.dot(normal)) < epsilon;
|
||||
boolean pBOnPlane = Math.abs(pBFromV0.dot(normal)) < epsilon;
|
||||
|
||||
if (pAOnPlane && pBOnPlane) {
|
||||
if (Intersectionf.testPointInTriangle(Origin.x,Origin.y,Origin.z,
|
||||
Vertices[0].x,Vertices[0].y,Vertices[0].z,
|
||||
Vertices[1].x,Vertices[1].y,Vertices[1].z,
|
||||
Vertices[2].x,Vertices[2].y,Vertices[2].z) ||
|
||||
Intersectionf.testPointInTriangle(Point.x,Point.y,Point.z,
|
||||
Vertices[0].x,Vertices[0].y,Vertices[0].z,
|
||||
Vertices[1].x,Vertices[1].y,Vertices[1].z,
|
||||
Vertices[2].x,Vertices[2].y,Vertices[2].z)) {
|
||||
return true;
|
||||
}
|
||||
if (Intersectionf.testLineSegmentTriangle(Origin, Point, Vertices[0], Vertices[1],Vertices[2], epsilon)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import org.tinylog.Logger;
|
|||
|
||||
public class FastTickThread extends EngineThread {
|
||||
|
||||
private int Ticks = 0;
|
||||
|
||||
public FastTickThread(EngineInstance engineInstance, GameLogic appLogic){
|
||||
super(engineInstance, appLogic, "Fast");
|
||||
UpdateTickRateThreshold();
|
||||
|
|
@ -17,6 +19,14 @@ public class FastTickThread extends EngineThread {
|
|||
public void TickEvent(long nsTimeDiff){
|
||||
gameLogic.UpdateFastThread(PrimaryRuntime.GetEngineInstance(), nsTimeDiff);
|
||||
}
|
||||
|
||||
public int Ticks(int TickThreshold){
|
||||
int TickCount = Ticks;
|
||||
Ticks++;
|
||||
if(Ticks >= TickThreshold) Ticks = 0;
|
||||
return TickCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void FrameEvent(long now, long InitialTime){
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue