Physics corrections
This commit is contained in:
parent
2b0344630e
commit
eb09963e3a
17 changed files with 1126 additions and 899 deletions
1725
LastSession.t4jlog
1725
LastSession.t4jlog
File diff suppressed because it is too large
Load diff
1
resources/models/cube/Cube.bbmodel
Normal file
1
resources/models/cube/Cube.bbmodel
Normal file
File diff suppressed because one or more lines are too long
0
resources/models/cube/Cube.colmesh
Normal file
0
resources/models/cube/Cube.colmesh
Normal file
BIN
resources/models/cube/Cube.idx
Normal file
BIN
resources/models/cube/Cube.idx
Normal file
Binary file not shown.
15
resources/models/cube/Cube.json
Normal file
15
resources/models/cube/Cube.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"ID": "Cube",
|
||||
"Meshes": [
|
||||
{
|
||||
"ID": "mesh_0",
|
||||
"MaterialID": "Cube-mat-1",
|
||||
"OffsetVertex": 0,
|
||||
"VertexSize": 1344,
|
||||
"OffsetIndex": 0,
|
||||
"IndexSize": 144
|
||||
}
|
||||
],
|
||||
"VertexPath": "resources/models/cube/Cube.vtx",
|
||||
"IndexPath": "resources/models/cube/Cube.idx"
|
||||
}
|
||||
4
resources/models/cube/Cube.mtl
Normal file
4
resources/models/cube/Cube.mtl
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# Made in Blockbench 5.1.4
|
||||
newmtl m_69683abb-0cbc-2632-be2c-1aa8a2ddc888
|
||||
map_Kd cubetexture.png
|
||||
newmtl none
|
||||
49
resources/models/cube/Cube.obj
Normal file
49
resources/models/cube/Cube.obj
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
# Made in Blockbench 5.1.4
|
||||
mtllib Cube.mtl
|
||||
|
||||
o mesh
|
||||
v 0.5 0.75 0.5
|
||||
v 0.5 0.75 -0.5
|
||||
v 0.5 -0.25 0.5
|
||||
v 0.5 -0.25 -0.5
|
||||
v -0.5 0.75 0.5
|
||||
v -0.5 0.75 -0.5
|
||||
v -0.5 -0.25 0.5
|
||||
v -0.5 -0.25 -0.5
|
||||
vt 0.25 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
|
||||
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
|
||||
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
|
||||
f 4/13/4 3/14/4 7/15/4 8/16/4
|
||||
f 3/17/5 1/18/5 5/19/5 7/20/5
|
||||
f 6/21/6 2/22/6 4/23/6 8/24/6
|
||||
BIN
resources/models/cube/Cube.vtx
Normal file
BIN
resources/models/cube/Cube.vtx
Normal file
Binary file not shown.
44
resources/models/cube/Cube_mat.json
Normal file
44
resources/models/cube/Cube_mat.json
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
[
|
||||
{
|
||||
"ID": "Cube-mat-0",
|
||||
"TexturePath": "",
|
||||
"NormalTexturePath": "",
|
||||
"MetalRoughnessMap": "",
|
||||
"DiffuseColour": {
|
||||
"X": 0.6,
|
||||
"Y": 0.6,
|
||||
"Z": 0.6,
|
||||
"W": 1.0
|
||||
},
|
||||
"Roughness": 0.0,
|
||||
"Metallic": 0.0
|
||||
},
|
||||
{
|
||||
"ID": "Cube-mat-1",
|
||||
"TexturePath": "resources\\models\\cube\\cubetexture.png",
|
||||
"NormalTexturePath": "",
|
||||
"MetalRoughnessMap": "",
|
||||
"DiffuseColour": {
|
||||
"X": 0.6,
|
||||
"Y": 0.6,
|
||||
"Z": 0.6,
|
||||
"W": 1.0
|
||||
},
|
||||
"Roughness": 0.0,
|
||||
"Metallic": 0.0
|
||||
},
|
||||
{
|
||||
"ID": "Cube-mat-2",
|
||||
"TexturePath": "",
|
||||
"NormalTexturePath": "",
|
||||
"MetalRoughnessMap": "",
|
||||
"DiffuseColour": {
|
||||
"X": 0.6,
|
||||
"Y": 0.6,
|
||||
"Z": 0.6,
|
||||
"W": 1.0
|
||||
},
|
||||
"Roughness": 0.0,
|
||||
"Metallic": 0.0
|
||||
}
|
||||
]
|
||||
BIN
resources/models/cube/cubetexture.png
Normal file
BIN
resources/models/cube/cubetexture.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
|
|
@ -29,7 +29,7 @@ public class RigidBody {
|
|||
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 = 1f;
|
||||
public float Bounciness = 0.3f;
|
||||
|
||||
public final Vector3f LinearVelocity = new Vector3f();
|
||||
public final Vector3f AngularVelocity = new Vector3f();
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import org.joml.Vector3f;
|
|||
//Resolves the Separating Axis Theorem Test into reaction forces in impulses and position correction
|
||||
public class RigidCollision {
|
||||
private static final float CORRECTION_THRESHOLD = 1.0f; //how much it gets corrected positionally per physics step
|
||||
private static final float SLOP = 0.001f; // amount of overlap can happen before collision gets corrected
|
||||
private static final float SLOP = 0.000f; // amount of overlap can happen before collision gets corrected
|
||||
|
||||
public synchronized static void ResolveCollision(RigidBody body1, RigidBody body2, SeparatingAxisTheoremTester.CollisionResult collisionResult){
|
||||
Vector3f Normal = collisionResult.Normal;
|
||||
|
|
@ -43,6 +43,9 @@ public class RigidCollision {
|
|||
float j = -(1 + Restitution) * VelocityAlongNormal / InverseMassSum;
|
||||
Impulse.set(normal).mul(j);
|
||||
|
||||
body1.LinearVelocity.mul(-1,body1.LinearVelocity.y < 0 ? 1 : -1,-1).mul(body1.Bounciness,body1.LinearVelocity.y < 0 ? 1 : body1.Bounciness,body1.Bounciness);
|
||||
body2.LinearVelocity.mul(-1,body1.LinearVelocity.y < 0 ? 1 : -1,-1).mul(body1.Bounciness,body1.LinearVelocity.y < 0 ? 1 : body1.Bounciness,body1.Bounciness);
|
||||
|
||||
body1.ApplyImpulse(NegatedImpulse.set(Impulse).negate(), Point);
|
||||
|
||||
body2.ApplyImpulse(Impulse,Point);
|
||||
|
|
|
|||
|
|
@ -25,9 +25,17 @@ public class RigidPhysicsController implements IPhysicsController {
|
|||
public final List<String> Collisions = new ArrayList<>();
|
||||
|
||||
public static RigidBody Ground = new RigidBody("FLOOR",ConvexMesh.Box(100,100f,100),0);
|
||||
public static RigidBody Wall = new RigidBody("WALL",ConvexMesh.Box(100,100f,10),0);
|
||||
public static RigidBody Wall2 = new RigidBody("WALL2",ConvexMesh.Box(100,100f,10),0);
|
||||
public static RigidBody Wall3 = new RigidBody("WALL3",ConvexMesh.Box(10,100f,100),0);
|
||||
public static RigidBody Wall4 = new RigidBody("WALL4",ConvexMesh.Box(10,100f,100),0);
|
||||
|
||||
static {
|
||||
Ground.Position.set(0,-100f,0);
|
||||
Wall.Position.set(0,0f,-60f);
|
||||
Wall2.Position.set(0,0f,60f);
|
||||
Wall3.Position.set(-60f,0f,0);
|
||||
Wall4.Position.set(60f,0f,0);
|
||||
}
|
||||
|
||||
public String RigidBodyID = "NULL";
|
||||
|
|
@ -49,6 +57,12 @@ public class RigidPhysicsController implements IPhysicsController {
|
|||
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));
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -56,6 +70,11 @@ public class RigidPhysicsController implements IPhysicsController {
|
|||
RigidBodyID = rigidBody.GetID();
|
||||
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));
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -77,7 +96,7 @@ public class RigidPhysicsController implements IPhysicsController {
|
|||
@Override
|
||||
public void PhysicsTick(float DeltaTime, float TargetFrameRate) {
|
||||
DeltaTime/=10f;
|
||||
if(DeltaTime >0.1f) DeltaTime = 0.1f;
|
||||
// if(DeltaTime >0.1f) DeltaTime = 0.1f;
|
||||
if(RigidBodyID != null && RigidBodyRegister.get(RigidBodyID) != null && ActorID != "NULL") {
|
||||
RigidBody rigidBody = RigidBodyRegister.get(RigidBodyID);
|
||||
rigidBody.Integrate(DeltaTime, new Vector3f(0,-1.8f,0));
|
||||
|
|
@ -91,7 +110,6 @@ public class RigidPhysicsController implements IPhysicsController {
|
|||
}
|
||||
}
|
||||
if(Actor.Actors.get(ActorID) != null) {
|
||||
Actor.Actors.get(ActorID).SetPivotOffset(new Vector3f(0,(rigidBody.shape.TopRightForward.y - rigidBody.shape.BottomLeftBack.y)/2f,0));
|
||||
Actor.Actors.get(ActorID).SetPosition(new Vector3f(rigidBody.Position));
|
||||
Actor.Actors.get(ActorID).SetRotation(rigidBody.Rotation);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,12 +36,12 @@ public class SeparatingAxisTheoremTester {
|
|||
public final List<Contact> Contacts = new ArrayList<>();
|
||||
}
|
||||
//as much as i'd like to multithread the fuck out of this, im putting it as synchronised so it doesn't get messy, and so memory management is smoother, i want to minimize the amount of Vectors creating during loops
|
||||
public synchronized static CollisionResult TestCollision(ConvexMesh Mesh1, ConvexMesh Mesh2){
|
||||
public static CollisionResult TestCollision(ConvexMesh Mesh1, ConvexMesh Mesh2){
|
||||
float BestOverlap = Float.MAX_VALUE;
|
||||
Vector3f BestAxis = null;
|
||||
ConvexMesh.Face BestFace =null;
|
||||
ConvexMesh BestFaceOwner = null;
|
||||
|
||||
if(Mesh1 == null || Mesh2 == null) return null;
|
||||
for(ConvexMesh.Face face : Mesh1.Faces){
|
||||
Vector3f Axis = Mesh1.WorldFaceNormal(face);
|
||||
Float Overlap = AxisOverlap(Mesh1,Mesh2,Axis);
|
||||
|
|
@ -147,14 +147,14 @@ public class SeparatingAxisTheoremTester {
|
|||
return result;
|
||||
}
|
||||
|
||||
private synchronized static Float AxisOverlap(ConvexMesh mesh1, ConvexMesh mesh2, Vector3f axis) {
|
||||
private static Float AxisOverlap(ConvexMesh mesh1, ConvexMesh mesh2, Vector3f axis) {
|
||||
float[] Range1 = ProjectOntoAxis(mesh1, axis);
|
||||
float[] Range2 = ProjectOntoAxis(mesh2, axis);
|
||||
float Overlap = Math.min(Range1[1],Range2[1]) - Math.max(Range1[0],Range2[0]);
|
||||
return (Overlap < 0) ? null : Overlap;
|
||||
}
|
||||
|
||||
private synchronized static float[] ProjectOntoAxis(ConvexMesh mesh, Vector3f axis){
|
||||
private static float[] ProjectOntoAxis(ConvexMesh mesh, Vector3f axis){
|
||||
float minimum = Float.MAX_VALUE, maximum = -Float.MAX_VALUE;
|
||||
for(int i = 0; i < mesh.LocalVertices.size(); i++){
|
||||
float distance = mesh.WorldVertex(i).dot(axis);
|
||||
|
|
@ -164,14 +164,14 @@ public class SeparatingAxisTheoremTester {
|
|||
return new float[]{minimum,maximum};
|
||||
}
|
||||
|
||||
private synchronized static Vector3f MeshCenter(ConvexMesh mesh){
|
||||
private static Vector3f MeshCenter(ConvexMesh mesh){
|
||||
Vector3f Center = new Vector3f();
|
||||
for(int i = 0; i < mesh.LocalVertices.size(); i++) Center.add(mesh.WorldVertex(i));
|
||||
Center.div(mesh.LocalVertices.size());
|
||||
return Center;
|
||||
}
|
||||
|
||||
private synchronized static ConvexMesh.Face FindIncidentFace(ConvexMesh mesh, Vector3f ReferenceNormal){
|
||||
private static ConvexMesh.Face FindIncidentFace(ConvexMesh mesh, Vector3f ReferenceNormal){
|
||||
ConvexMesh.Face Best = null;
|
||||
float BestDot = Float.MAX_VALUE;
|
||||
for(ConvexMesh.Face face : mesh.Faces){
|
||||
|
|
@ -184,7 +184,7 @@ public class SeparatingAxisTheoremTester {
|
|||
return Best;
|
||||
}
|
||||
|
||||
private synchronized static List<Vector3f> ClipPolygonAgainstFace(List<Vector3f> Incident, List<Vector3f> ReferencePoly, Vector3f ReferenceNormal){
|
||||
private static List<Vector3f> ClipPolygonAgainstFace(List<Vector3f> Incident, List<Vector3f> ReferencePoly, Vector3f ReferenceNormal){
|
||||
List<Vector3f> Output = new ArrayList<>(Incident);
|
||||
int Count = ReferencePoly.size();
|
||||
for(int i = 0; i < Count; i++){
|
||||
|
|
@ -215,7 +215,7 @@ public class SeparatingAxisTheoremTester {
|
|||
return Output;
|
||||
}
|
||||
|
||||
private synchronized static Vector3f IntersectEdge(Vector3f Vertex1, Vector3f Vertex2, Vector3f Normal, float Offset) {
|
||||
private static Vector3f IntersectEdge(Vector3f Vertex1, Vector3f Vertex2, Vector3f Normal, float Offset) {
|
||||
Vector3f Distance = new Vector3f(Vertex2).sub(Vertex1);
|
||||
float Denominator = Normal.dot(Distance);
|
||||
float t = (Math.abs(Denominator) < T4Math.Math3D.epsilon) ? 0 : (Offset - Normal.dot(Vertex1)) / Denominator;
|
||||
|
|
@ -223,7 +223,7 @@ public class SeparatingAxisTheoremTester {
|
|||
}
|
||||
|
||||
|
||||
private synchronized static Vector3f[] ClosestPointsSegment2(Vector3f p1, Vector3f q1, Vector3f p2, Vector3f q2) {
|
||||
private static Vector3f[] ClosestPointsSegment2(Vector3f p1, Vector3f q1, Vector3f p2, Vector3f q2) {
|
||||
Vector3f d1 = new Vector3f(q1).sub(p1);
|
||||
Vector3f d2 = new Vector3f(q2).sub(p2);
|
||||
Vector3f r = new Vector3f(p1).sub(p2);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Logic.Physics;
|
||||
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||
import net.halbear.Terrain4J.EngineCore.Threads.PhysicsThread;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
|
@ -21,11 +22,20 @@ public class WorldPhysicsManager {
|
|||
public static float FixedTimeStep = 1f / 60f;
|
||||
public static int MaxSubStepsPerFrame = 8;
|
||||
private static float Accumulator = 0f;
|
||||
private static boolean SingleThread = false;
|
||||
private static List<PhysicsThread> physicsThreads = new ArrayList<>();
|
||||
|
||||
public static void SteppedPhysicsTick(float DeltaTime, float TargetFrameTime){
|
||||
int ThreadsNeeded = (int)Math.floor(ActiveControllers.size()/100f);
|
||||
SingleThread = ThreadsNeeded <= 1;
|
||||
if(EngineConfig.getInstance().IsEngineThrottled()) return;
|
||||
DeltaTime *= EngineConfig.getInstance().PhysicsSpeed();
|
||||
|
||||
/* if(!SingleThread && ThreadsNeeded > physicsThreads.size()) {
|
||||
while(ThreadsNeeded > physicsThreads.size()) {
|
||||
int Index = physicsThreads.size();
|
||||
physicsThreads.add(new PhysicsThread("PhysThread"+Index, Index, ThreadsNeeded).StartThread());
|
||||
}
|
||||
} else if(SingleThread){*/
|
||||
Accumulator += DeltaTime;
|
||||
float maxAccumulated = FixedTimeStep * MaxSubStepsPerFrame;
|
||||
if (Accumulator > maxAccumulated) Accumulator = maxAccumulated;
|
||||
|
|
@ -45,6 +55,7 @@ public class WorldPhysicsManager {
|
|||
for (int i = 0; i < ActiveControllers.size(); i++) {
|
||||
PhysicsObjects.get(ActiveControllers.get(i)).Collisions().clear();
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
public static void PhysicsTick(float DeltaTime, float TargetFrameTime){
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ import net.halbear.Terrain4J.EngineCore.Logic.GameLogic;
|
|||
import net.halbear.Terrain4J.EngineCore.Logic.InitData;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Physics.LegacyPhysicsController;
|
||||
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.Logic.Physics.WorldPhysicsManager;
|
||||
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.ModelLoader;
|
||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.*;
|
||||
|
|
@ -76,8 +78,8 @@ public class GameCore implements GameLogic {
|
|||
public InitData Initialise(EngineInstance engineInstance) {
|
||||
IScene scene = engineInstance.scene();
|
||||
List<ModelData> models = new ArrayList<>();
|
||||
MelonaData = ModelLoader.LoadModel("resources/models/melona/melona.json");
|
||||
List<MaterialData> MelonaDataMat = ModelLoader.LoadMaterials("resources/models/melona/melona_mat.json");
|
||||
MelonaData = ModelLoader.LoadModel("resources/models/cube/Cube.json");
|
||||
List<MaterialData> MelonaDataMat = ModelLoader.LoadMaterials("resources/models/cube/Cube_mat.json");
|
||||
var Melona = new Actor("Melona", MelonaData.ID(), new Vector3f(0,0f,-5f)).SetRotation(0,(float)Math.toRadians(180),0);
|
||||
Melona.CreatePhysicsController(LegacyPhysicsController.CollisionType.Sensor);
|
||||
/* Melona.GetPhysicsController()
|
||||
|
|
@ -166,7 +168,9 @@ public class GameCore implements GameLogic {
|
|||
SpawnPosition.add(SpawnDirection);
|
||||
var Melona = new Actor("MelonaSpawned" + scene.GetActors().size(), MelonaData.ID(), new Vector3f(SpawnPosition));
|
||||
|
||||
Melona.CreatePhysicsController( ConvexMesh.Box(0.75f,1,0.5f),20);
|
||||
Melona.CreatePhysicsController( ConvexMesh.Box(0.5f,0.5f,0.5f),20);
|
||||
RigidPhysicsController physicsController = (RigidPhysicsController) Melona.GetPhysicsController();
|
||||
RigidBody.RigidBodyRegister.get(physicsController.RigidBodyID).LinearVelocity.set(0,0,-20f -(40f * (float)Math.random()));
|
||||
scene.AddActor(Melona);
|
||||
}
|
||||
|
||||
|
|
@ -245,7 +249,7 @@ public class GameCore implements GameLogic {
|
|||
float MovementDist = (float)(FrameDiffNanoSeconds / 1000000L) * MOVEMENT_SPEED;
|
||||
Camera camera = scene.GetCamera();
|
||||
if(input.keyPressed(GLFW_KEY_ENTER)) {
|
||||
SpawnNewActor(engineInstance, new Vector3f( (float)(2 * Math.random()),20 + (float)(10 * Math.random()), (float)(2 * Math.random())),new Vector3f(-1f + (float)(2 * Math.random()),-1f + (float)(2 * Math.random()),-1f + (float)(2 * Math.random())),new Vector3f((float)Math.random(),(float)Math.random(),(float)Math.random()));
|
||||
SpawnNewActor(engineInstance, new Vector3f( (float)(5 * Math.random()),20 + (float)(10 * Math.random()), (float)(5 * Math.random())),new Vector3f(-1f + (float)(2 * Math.random()),-1f + (float)(2 * Math.random()),-1f + (float)(2 * Math.random())),new Vector3f((float)Math.random(),(float)Math.random(),(float)Math.random()));
|
||||
}
|
||||
if(input.keyPressed(GLFW_KEY_1)) {
|
||||
Gimbal.universalType = Gimbal.GimbalType.Move;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
package net.halbear.Terrain4J.EngineCore.Threads;
|
||||
|
||||
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 org.tinylog.Logger;
|
||||
|
||||
import static net.halbear.Terrain4J.EngineCore.Logic.Physics.WorldPhysicsManager.ActiveControllers;
|
||||
import static net.halbear.Terrain4J.EngineCore.Logic.Physics.WorldPhysicsManager.PhysicsObjects;
|
||||
|
||||
public class PhysicsThread implements Runnable{
|
||||
public static boolean running = true;
|
||||
public final Thread EngineThread;
|
||||
public static float FixedTimeStep = 1f / 60f;
|
||||
public static int PhysicsTick = 0;
|
||||
public static int MaxSubStepsPerFrame = 8;
|
||||
public int Frames = 0;
|
||||
public int TickFrames = 0;
|
||||
private static float Accumulator = 0f;
|
||||
public String ThreadName;
|
||||
public int Index;
|
||||
public int Total;
|
||||
|
||||
public Thread FetchThread(){
|
||||
return EngineThread;
|
||||
}
|
||||
|
||||
public PhysicsThread StartThread(){
|
||||
EngineThread.start();
|
||||
return this;
|
||||
}
|
||||
|
||||
public PhysicsThread(String ThreadName, int Index, int TotalCount){
|
||||
this.ThreadName = ThreadName;
|
||||
Logger.debug("Starting {} Thread",ThreadName);
|
||||
EngineThread = new Thread(this);
|
||||
EngineThread.setName("Terrain4J "+ThreadName+" Engine Thread");
|
||||
this.Index = Index;
|
||||
this.Total = TotalCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long InitialTime = System.nanoTime();
|
||||
long updateTime = InitialTime;
|
||||
double[] FrameTimes = new double[]{0,0,0,0};
|
||||
while(FastTickThread.running && (Index/Total) * ActiveControllers.size() < ActiveControllers.size()){
|
||||
long now = System.nanoTime();
|
||||
TickFrames++;
|
||||
long nsTimeDiff = now - updateTime;
|
||||
updateTime = now;
|
||||
float PhysicsFramerate = 24f;
|
||||
float PhysicsFrameTime = 1000f/PhysicsFramerate;
|
||||
float DeltaTime = (float)nsTimeDiff/(PhysicsFrameTime*1000000f);
|
||||
SteppedPhysicsTickMultiThreaded(DeltaTime, 60,Index,Total);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SteppedPhysicsTickMultiThreaded(float DeltaTime, float TargetFrameTime, int Index, int Total){
|
||||
Accumulator += DeltaTime;
|
||||
float maxAccumulated = FixedTimeStep * MaxSubStepsPerFrame;
|
||||
if (Accumulator > maxAccumulated) Accumulator = maxAccumulated;
|
||||
|
||||
int stepsRun = 0;
|
||||
|
||||
while (Accumulator >= FixedTimeStep && stepsRun < MaxSubStepsPerFrame) {
|
||||
PhysicsTick++;
|
||||
for (int i = (Index/Total) * ActiveControllers.size(); i < Math.min((Index + 1/Total) * ActiveControllers.size(),ActiveControllers.size()); i++) {
|
||||
if (PhysicsObjects.get(ActiveControllers.get(i)) != null) {
|
||||
PhysicsObjects.get(ActiveControllers.get(i)).PhysicsTick(FixedTimeStep, TargetFrameTime);
|
||||
}
|
||||
}
|
||||
Accumulator -= FixedTimeStep;
|
||||
stepsRun++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue