mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-10-30 08:11:25 +00:00
some optimization
This commit is contained in:
parent
99ae6ecf65
commit
aa85fc2faa
6 changed files with 224 additions and 106 deletions
|
|
@ -1062,7 +1062,7 @@ class Marble extends GameObject {
|
|||
searchbox.addSpherePos(position.x + velocity.x * deltaT, position.y + velocity.y * deltaT, position.z + velocity.z * deltaT, _radius);
|
||||
|
||||
var foundObjs = this.collisionWorld.boundingSearch(searchbox);
|
||||
foundObjs.push(this.collisionWorld.staticWorld);
|
||||
// foundObjs.push(this.collisionWorld.staticWorld);
|
||||
|
||||
var finalT = deltaT;
|
||||
var found = false;
|
||||
|
|
@ -1151,7 +1151,7 @@ class Marble extends GameObject {
|
|||
// var v = surface.points[surface.indices[i + 1]].transformed(obj.transform);
|
||||
// var v2 = surface.points[surface.indices[i + 2]].transformed(obj.transform);
|
||||
|
||||
var triangleVerts = [v0, v, v2];
|
||||
// var triangleVerts = [v0, v, v2];
|
||||
|
||||
var surfaceNormal = new Vector(verts.nx, verts.ny,
|
||||
verts.nz); // surface.normals[surface.indices[i]].transformed3x3(obj.transform).normalized();
|
||||
|
|
@ -1166,8 +1166,8 @@ class Marble extends GameObject {
|
|||
}
|
||||
|
||||
testTriangles.push({
|
||||
v: [v0, v, v2],
|
||||
n: surfaceNormal,
|
||||
v: [v0.clone(), v.clone(), v2.clone()],
|
||||
n: surfaceNormal.clone(),
|
||||
});
|
||||
|
||||
// Time until collision with the plane
|
||||
|
|
@ -1190,7 +1190,9 @@ class Marble extends GameObject {
|
|||
}
|
||||
// We *might* be colliding with an edge
|
||||
|
||||
var lastVert = v2;
|
||||
var triangleVerts = [v0.clone(), v.clone(), v2.clone()];
|
||||
|
||||
var lastVert = v2.clone();
|
||||
|
||||
var radSq = radius * radius;
|
||||
for (iter in 0...3) {
|
||||
|
|
@ -1211,7 +1213,7 @@ class Marble extends GameObject {
|
|||
|
||||
// If it's not quadratic or has no solution, ignore this edge.
|
||||
if (a == 0.0 || discriminant < 0.0) {
|
||||
lastVert = thisVert;
|
||||
lastVert.load(thisVert);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1231,7 +1233,7 @@ class Marble extends GameObject {
|
|||
|
||||
// If the collision doesn't happen on this time step, ignore this edge.
|
||||
if (edgeCollisionTime2 <= 0.0001 || finalT <= edgeCollisionTime) {
|
||||
lastVert = thisVert;
|
||||
lastVert.load(thisVert);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1245,7 +1247,7 @@ class Marble extends GameObject {
|
|||
|
||||
// If the collision happens outside the boundaries of the edge, ignore this edge.
|
||||
if (-radius > distanceAlongEdge || edgeLen + radius < distanceAlongEdge) {
|
||||
lastVert = thisVert;
|
||||
lastVert.load(thisVert);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1309,14 +1311,14 @@ class Marble extends GameObject {
|
|||
|
||||
// We still need to check the other corner ...
|
||||
// Build one last quadratic equation to solve for the collision time
|
||||
posVertDiff = position.sub(lastVert);
|
||||
var posVertDiff = position.sub(lastVert);
|
||||
b = 2 * posVertDiff.dot(relVel);
|
||||
c = posVertDiff.lengthSq() - radSq;
|
||||
discriminant = b * b - (4 * a * c);
|
||||
|
||||
// If it's not quadratic or has no solution, then skip this corner
|
||||
if (a == 0.0 || discriminant < 0.0) {
|
||||
lastVert = thisVert;
|
||||
lastVert.load(thisVert);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1335,7 +1337,7 @@ class Marble extends GameObject {
|
|||
}
|
||||
|
||||
if (edgeCollisionTime2 <= 0.0001 || finalT <= edgeCollisionTime) {
|
||||
lastVert = thisVert;
|
||||
lastVert.load(thisVert);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1343,7 +1345,7 @@ class Marble extends GameObject {
|
|||
edgeCollisionTime = 0;
|
||||
|
||||
if (edgeCollisionTime < 0.000001) {
|
||||
lastVert = thisVert;
|
||||
lastVert.load(thisVert);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1351,7 +1353,7 @@ class Marble extends GameObject {
|
|||
currentFinalPos = position.add(relVel.multiply(finalT));
|
||||
// Debug.drawSphere(currentFinalPos, radius);
|
||||
|
||||
lastVert = thisVert;
|
||||
lastVert.load(thisVert);
|
||||
found = true;
|
||||
// iterationFound = true;
|
||||
}
|
||||
|
|
@ -1415,7 +1417,7 @@ class Marble extends GameObject {
|
|||
// Nudge to the surface of the contact plane
|
||||
Debug.drawTriangle(testTri.v[0], testTri.v[1], testTri.v[2]);
|
||||
Debug.drawSphere(position, radius);
|
||||
position = position.add(separatingDistance.multiply(radius - distToContactPlane - 0.005));
|
||||
position.load(position.add(separatingDistance.multiply(radius - distToContactPlane - 0.005)));
|
||||
resolved++;
|
||||
}
|
||||
}
|
||||
|
|
@ -1446,7 +1448,7 @@ class Marble extends GameObject {
|
|||
var dist = marblePosition.distance(position);
|
||||
if (dist < radius + marble.radius + 0.001) {
|
||||
var separatingDistance = position.sub(marblePosition).normalized();
|
||||
position = position.add(separatingDistance.multiply(radius + marble.radius + 0.001 - dist));
|
||||
position.load(position.add(separatingDistance.multiply(radius + marble.radius + 0.001 - dist)));
|
||||
}
|
||||
}
|
||||
return position;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package src;
|
||||
|
||||
import net.MarblePredictionStore;
|
||||
import net.MarblePredictionStore.MarblePrediction;
|
||||
import net.MarbleUpdateQueue;
|
||||
import haxe.Exception;
|
||||
import net.NetPacket.MarbleUpdatePacket;
|
||||
|
|
@ -103,6 +105,7 @@ import modes.NullMode;
|
|||
import modes.GameMode.GameModeFactory;
|
||||
import src.Renderer;
|
||||
import src.Analytics;
|
||||
import src.Debug;
|
||||
|
||||
class MarbleWorld extends Scheduler {
|
||||
public var collisionWorld:CollisionWorld;
|
||||
|
|
@ -204,6 +207,7 @@ class MarbleWorld extends Scheduler {
|
|||
var maxPredictionTicks:Int = 16;
|
||||
|
||||
var clientMarbles:Map<GameConnection, Marble> = [];
|
||||
var predictions:MarblePredictionStore;
|
||||
|
||||
public var lastMoves:MarbleUpdateQueue;
|
||||
|
||||
|
|
@ -246,6 +250,7 @@ class MarbleWorld extends Scheduler {
|
|||
isRecording = false;
|
||||
isWatching = false;
|
||||
lastMoves = new MarbleUpdateQueue();
|
||||
predictions = new MarblePredictionStore();
|
||||
}
|
||||
|
||||
// Set the network RNG for hunt
|
||||
|
|
@ -768,10 +773,10 @@ class MarbleWorld extends Scheduler {
|
|||
var tmat = Matrix.T(interiorPosition.x, interiorPosition.y, interiorPosition.z);
|
||||
mat.multiply(mat, tmat);
|
||||
|
||||
if (hasCollision)
|
||||
this.collisionWorld.addStaticInterior(interior.collider, mat);
|
||||
// if (hasCollision)
|
||||
// this.collisionWorld.addStaticInterior(interior.collider, mat);
|
||||
|
||||
interior.isCollideable = false;
|
||||
interior.isCollideable = hasCollision;
|
||||
interior.setTransform(mat);
|
||||
onFinish();
|
||||
});
|
||||
|
|
@ -890,7 +895,7 @@ class MarbleWorld extends Scheduler {
|
|||
public function addInterior(obj:InteriorObject, onFinish:Void->Void) {
|
||||
this.interiors.push(obj);
|
||||
obj.init(cast this, () -> {
|
||||
// this.collisionWorld.addEntity(obj.collider);
|
||||
this.collisionWorld.addEntity(obj.collider);
|
||||
if (obj.useInstancing)
|
||||
this.instanceManager.addObject(obj);
|
||||
else
|
||||
|
|
@ -1033,9 +1038,12 @@ class MarbleWorld extends Scheduler {
|
|||
}
|
||||
|
||||
public function applyReceivedMoves() {
|
||||
var needsPrediction = 0;
|
||||
if (!lastMoves.ourMoveApplied) {
|
||||
var ourMove = lastMoves.myMarbleUpdate;
|
||||
if (ourMove != null) {
|
||||
var ourMoveStruct = Net.clientConnection.moveManager.acknowledgeMove(ourMove.move.id, timeState);
|
||||
lastMoves.ourMoveApplied = true;
|
||||
for (client => arr in lastMoves.otherMarbleUpdates) {
|
||||
var lastMove = null;
|
||||
while (arr.length > 0) {
|
||||
|
|
@ -1047,27 +1055,61 @@ class MarbleWorld extends Scheduler {
|
|||
}
|
||||
}
|
||||
if (lastMove != null) {
|
||||
if (ourMove.serverTicks == lastMove.serverTicks)
|
||||
// if (ourMove.serverTicks == lastMove.serverTicks) {
|
||||
if (ourMoveStruct != null) {
|
||||
var otherPred = predictions.retrieveState(clientMarbles[Net.clientIdMap[client]], ourMoveStruct.timeState.ticks);
|
||||
if (otherPred != null) {
|
||||
if (otherPred.getError(lastMove) > 0.001) {
|
||||
// trace('Prediction error: ${otherPred.getError(lastMove)}');
|
||||
trace('Desync for tick ${ourMoveStruct.timeState.ticks}');
|
||||
clientMarbles[Net.clientIdMap[client]].unpackUpdate(lastMove);
|
||||
needsPrediction |= 1 << client;
|
||||
arr.insert(0, lastMove);
|
||||
}
|
||||
} else {
|
||||
trace('Desync for tick ${ourMoveStruct.timeState.ticks}');
|
||||
clientMarbles[Net.clientIdMap[client]].unpackUpdate(lastMove);
|
||||
needsPrediction |= 1 << client;
|
||||
arr.insert(0, lastMove);
|
||||
}
|
||||
} else {
|
||||
trace('Desync in General');
|
||||
clientMarbles[Net.clientIdMap[client]].unpackUpdate(lastMove);
|
||||
arr.insert(0, lastMove);
|
||||
needsPrediction |= 1 << client;
|
||||
arr.insert(0, lastMove);
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
marble.unpackUpdate(ourMove);
|
||||
if (ourMoveStruct != null) {
|
||||
var ourPred = predictions.retrieveState(marble, ourMoveStruct.timeState.ticks);
|
||||
if (ourPred != null) {
|
||||
if (ourPred.getError(ourMove) > 0.001) {
|
||||
trace('Desync for tick ${ourMoveStruct.timeState.ticks}');
|
||||
marble.unpackUpdate(ourMove);
|
||||
needsPrediction |= 1 << Net.clientId;
|
||||
}
|
||||
} else {
|
||||
trace('Desync for tick ${ourMoveStruct.timeState.ticks}');
|
||||
marble.unpackUpdate(ourMove);
|
||||
needsPrediction |= 1 << Net.clientId;
|
||||
}
|
||||
} else {
|
||||
trace('Desync in General');
|
||||
marble.unpackUpdate(ourMove);
|
||||
needsPrediction |= 1 << Net.clientId;
|
||||
}
|
||||
}
|
||||
}
|
||||
return needsPrediction;
|
||||
}
|
||||
|
||||
public function applyClientPrediction() {
|
||||
public function applyClientPrediction(marbleNeedsPrediction:Int) {
|
||||
// First acknowledge the marble's last move so we can get that over with
|
||||
var ourLastMove = lastMoves.myMarbleUpdate;
|
||||
if (ourLastMove == null)
|
||||
return;
|
||||
if (ourLastMove == null || marbleNeedsPrediction == 0)
|
||||
return -1;
|
||||
var ackLag = @:privateAccess Net.clientConnection.moveManager.queuedMoves.length;
|
||||
var mvStored = null;
|
||||
if (!lastMoves.ourMoveApplied)
|
||||
mvStored = Net.clientConnection.moveManager.acknowledgeMove(ourLastMove.move.id, timeState);
|
||||
else
|
||||
return;
|
||||
|
||||
var ourLastMoveTime = ourLastMove.serverTicks;
|
||||
|
||||
|
|
@ -1076,97 +1118,87 @@ class MarbleWorld extends Scheduler {
|
|||
var qm = ourQueuedMoves[0];
|
||||
var advanceTimeState = qm != null ? qm.timeState.clone() : timeState.clone();
|
||||
advanceTimeState.dt = 0.032;
|
||||
advanceTimeState.ticks = ourLastMoveTime;
|
||||
|
||||
if (qm != null) {
|
||||
var mvs = qm.powerupStates.copy();
|
||||
for (pw in marble.level.powerUps) {
|
||||
pw.lastPickUpTime = mvs.shift();
|
||||
if (marbleNeedsPrediction & (1 << Net.clientId) > 0) {
|
||||
if (qm != null) {
|
||||
var mvs = qm.powerupStates.copy();
|
||||
for (pw in marble.level.powerUps) {
|
||||
pw.lastPickUpTime = mvs.shift();
|
||||
}
|
||||
@:privateAccess marble.helicopterEnableTime = qm.helicopterState;
|
||||
@:privateAccess marble.megaMarbleEnableTime = qm.megaState;
|
||||
marble.blastAmount = qm.blastAmt;
|
||||
}
|
||||
@:privateAccess marble.helicopterEnableTime = qm.helicopterState;
|
||||
@:privateAccess marble.megaMarbleEnableTime = qm.megaState;
|
||||
marble.blastAmount = qm.blastAmt;
|
||||
}
|
||||
|
||||
ackLag = ourQueuedMoves.length;
|
||||
|
||||
// Tick the remaining moves (ours)
|
||||
if (!lastMoves.ourMoveApplied) {
|
||||
@:privateAccess this.marble.isNetUpdate = true;
|
||||
var totalTicksToDo = ourQueuedMoves.length;
|
||||
var endTick = ourLastMoveTime + totalTicksToDo;
|
||||
var currentTick = ourLastMoveTime;
|
||||
//- Std.int(ourLastMove.moveQueueSize - @:privateAccess Net.clientConnection.moveManager.ackRTT); // - Std.int((@:privateAccess Net.clientConnection.moveManager.ackRTT)) - offset;
|
||||
@:privateAccess this.marble.isNetUpdate = true;
|
||||
var totalTicksToDo = ourQueuedMoves.length;
|
||||
var endTick = ourLastMoveTime + totalTicksToDo;
|
||||
var currentTick = ourLastMoveTime;
|
||||
//- Std.int(ourLastMove.moveQueueSize - @:privateAccess Net.clientConnection.moveManager.ackRTT); // - Std.int((@:privateAccess Net.clientConnection.moveManager.ackRTT)) - offset;
|
||||
|
||||
var marblesToTick = new Map();
|
||||
var marblesToTick = new Map();
|
||||
|
||||
for (client => arr in lastMoves.otherMarbleUpdates) {
|
||||
if (arr.length > 0) {
|
||||
var m = arr[0];
|
||||
if (m.serverTicks == ourLastMoveTime) {
|
||||
var marbleToUpdate = clientMarbles[Net.clientIdMap[client]];
|
||||
Debug.drawSphere(@:privateAccess marbleToUpdate.newPos, marbleToUpdate._radius);
|
||||
m.calculationTicks = ourQueuedMoves.length; // ourQueuedMoves.length;
|
||||
for (client => arr in lastMoves.otherMarbleUpdates) {
|
||||
if (marbleNeedsPrediction & (1 << client) > 0 && arr.length > 0) {
|
||||
var m = arr[0];
|
||||
// if (m.serverTicks == ourLastMoveTime) {
|
||||
var marbleToUpdate = clientMarbles[Net.clientIdMap[client]];
|
||||
Debug.drawSphere(@:privateAccess marbleToUpdate.newPos, marbleToUpdate._radius);
|
||||
if (marbleNeedsPrediction & (1 << Net.clientId) > 0)
|
||||
m.calculationTicks = ourQueuedMoves.length; // ourQueuedMoves.length;
|
||||
else
|
||||
m.calculationTicks = ourQueuedMoves.length;
|
||||
// - Std.int((@:privateAccess Net.clientConnection.moveManager.ackRTT - ourLastMove.moveQueueSize) / 2);
|
||||
|
||||
// - Std.int((@:privateAccess Net.clientConnection.moveManager.ackRTT - ourLastMove.moveQueueSize) / 2);
|
||||
marblesToTick.set(client, m);
|
||||
arr.shift();
|
||||
}
|
||||
}
|
||||
marblesToTick.set(client, m);
|
||||
arr.shift();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
Debug.drawSphere(@:privateAccess this.marble.newPos, this.marble._radius);
|
||||
// var syncTickStates = new Map();
|
||||
Debug.drawSphere(@:privateAccess this.marble.newPos, this.marble._radius);
|
||||
// var syncTickStates = new Map();
|
||||
|
||||
for (move in ourQueuedMoves) {
|
||||
var m = move.move;
|
||||
// Debug.drawSphere(@:privateAccess this.marble.newPos, this.marble._radius);
|
||||
for (move in ourQueuedMoves) {
|
||||
var m = move.move;
|
||||
// Debug.drawSphere(@:privateAccess this.marble.newPos, this.marble._radius);
|
||||
if (marbleNeedsPrediction & (1 << Net.clientId) > 0) {
|
||||
this.marble.heldPowerup = move.powerup;
|
||||
@:privateAccess this.marble.moveMotionDir = move.motionDir;
|
||||
@:privateAccess this.marble.advancePhysics(advanceTimeState, m, this.collisionWorld, this.pathedInteriors);
|
||||
// var collidings = @:privateAccess this.marble.contactEntities.filter(x -> x is SphereCollisionEntity);
|
||||
advanceTimeState.currentAttemptTime += 0.032;
|
||||
|
||||
for (client => m in marblesToTick) {
|
||||
if (m.calculationTicks > 0) {
|
||||
var marbleToUpdate = clientMarbles[Net.clientIdMap[client]];
|
||||
// Debug.drawSphere(@:privateAccess marbleToUpdate.newPos, marbleToUpdate._radius);
|
||||
|
||||
var beforePos = @:privateAccess marbleToUpdate.newPos.clone();
|
||||
var mv = m.move.move;
|
||||
@:privateAccess marbleToUpdate.isNetUpdate = true;
|
||||
@:privateAccess marbleToUpdate.moveMotionDir = m.move.motionDir;
|
||||
@:privateAccess marbleToUpdate.advancePhysics(advanceTimeState, mv, this.collisionWorld, this.pathedInteriors);
|
||||
@:privateAccess marbleToUpdate.isNetUpdate = false;
|
||||
m.calculationTicks--;
|
||||
|
||||
var afterPos = @:privateAccess marbleToUpdate.newPos;
|
||||
}
|
||||
}
|
||||
currentTick++;
|
||||
this.predictions.storeState(this.marble, move.timeState.ticks);
|
||||
}
|
||||
// var collidings = @:privateAccess this.marble.contactEntities.filter(x -> x is SphereCollisionEntity);
|
||||
|
||||
// for (marble => state in syncTickStates) {
|
||||
// marble.restoreState(state);
|
||||
// }
|
||||
for (client => m in marblesToTick) {
|
||||
if (m.calculationTicks > 0) {
|
||||
var marbleToUpdate = clientMarbles[Net.clientIdMap[client]];
|
||||
// Debug.drawSphere(@:privateAccess marbleToUpdate.newPos, marbleToUpdate._radius);
|
||||
|
||||
// for (client => m in marblesToTick) {
|
||||
// if (m.calculationTicks >= 0) {
|
||||
// var marbleToUpdate = clientMarbles[Net.clientIdMap[client]];
|
||||
|
||||
// while (m.calculationTicks > 0) {
|
||||
// var mv = m.move.move;
|
||||
// @:privateAccess marbleToUpdate.isNetUpdate = true;
|
||||
// @:privateAccess marbleToUpdate.moveMotionDir = m.move.motionDir;
|
||||
// @:privateAccess marbleToUpdate.advancePhysics(advanceTimeState, mv, this.collisionWorld, this.pathedInteriors);
|
||||
// @:privateAccess marbleToUpdate.isNetUpdate = false;
|
||||
// m.calculationTicks--;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
lastMoves.ourMoveApplied = true;
|
||||
@:privateAccess this.marble.isNetUpdate = false;
|
||||
var mv = m.move.move;
|
||||
@:privateAccess marbleToUpdate.isNetUpdate = true;
|
||||
@:privateAccess marbleToUpdate.moveMotionDir = m.move.motionDir;
|
||||
@:privateAccess marbleToUpdate.advancePhysics(advanceTimeState, mv, this.collisionWorld, this.pathedInteriors);
|
||||
this.predictions.storeState(marbleToUpdate, move.timeState.ticks);
|
||||
@:privateAccess marbleToUpdate.isNetUpdate = false;
|
||||
m.calculationTicks--;
|
||||
}
|
||||
}
|
||||
advanceTimeState.currentAttemptTime += 0.032;
|
||||
advanceTimeState.ticks++;
|
||||
currentTick++;
|
||||
}
|
||||
|
||||
lastMoves.ourMoveApplied = true;
|
||||
@:privateAccess this.marble.isNetUpdate = false;
|
||||
return advanceTimeState.ticks;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function rollback(t:Float) {
|
||||
|
|
@ -1355,10 +1387,11 @@ class MarbleWorld extends Scheduler {
|
|||
tickAccumulator += timeState.dt;
|
||||
while (tickAccumulator >= 0.032) {
|
||||
// Apply the server side ticks
|
||||
var lastPredTick = -1;
|
||||
if (Net.isClient) {
|
||||
applyReceivedMoves();
|
||||
var marbleNeedsTicking = applyReceivedMoves();
|
||||
// Catch up
|
||||
applyClientPrediction();
|
||||
lastPredTick = applyClientPrediction(marbleNeedsTicking);
|
||||
}
|
||||
|
||||
// Do the clientside prediction sim
|
||||
|
|
@ -1371,6 +1404,10 @@ class MarbleWorld extends Scheduler {
|
|||
for (client => marble in clientMarbles) {
|
||||
otherMoves.push(marble.updateServer(fixedDt, collisionWorld, pathedInteriors));
|
||||
}
|
||||
this.predictions.storeState(marble, myMove.timeState.ticks);
|
||||
for (client => marble in clientMarbles) {
|
||||
this.predictions.storeState(marble, myMove.timeState.ticks);
|
||||
}
|
||||
if (Net.isHost) {
|
||||
for (client => othermarble in clientMarbles) { // Oh no!
|
||||
var mv = otherMoves.shift();
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class CollisionWorld {
|
|||
}
|
||||
}
|
||||
|
||||
contacts = contacts.concat(this.staticWorld.sphereIntersection(spherecollision, timeState));
|
||||
// contacts = contacts.concat(this.staticWorld.sphereIntersection(spherecollision, timeState));
|
||||
|
||||
var dynSearch = dynamicOctree.boundingSearch(box).map(x -> cast(x, CollisionEntity));
|
||||
for (obj in dynSearch) {
|
||||
|
|
|
|||
62
src/net/MarblePredictionStore.hx
Normal file
62
src/net/MarblePredictionStore.hx
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
package net;
|
||||
|
||||
import net.NetPacket.MarbleUpdatePacket;
|
||||
import net.NetPacket.MarbleMovePacket;
|
||||
import src.TimeState;
|
||||
import src.Marble;
|
||||
import h3d.Vector;
|
||||
|
||||
@:publicFields
|
||||
class MarblePrediction {
|
||||
var tick:Int;
|
||||
var position:Vector;
|
||||
var velocity:Vector;
|
||||
var omega:Vector;
|
||||
|
||||
public function new(marble:Marble, tick:Int) {
|
||||
this.tick = tick;
|
||||
position = @:privateAccess marble.newPos.clone();
|
||||
velocity = @:privateAccess marble.velocity.clone();
|
||||
omega = @:privateAccess marble.omega.clone();
|
||||
}
|
||||
|
||||
public inline function getError(p:MarbleUpdatePacket) {
|
||||
var subs = position.sub(p.position).lengthSq() + velocity.sub(p.velocity).lengthSq() + omega.sub(p.omega).lengthSq();
|
||||
return subs;
|
||||
}
|
||||
}
|
||||
|
||||
class MarblePredictionStore {
|
||||
var predictions:Map<Marble, Array<MarblePrediction>>;
|
||||
|
||||
public function new() {
|
||||
predictions = [];
|
||||
}
|
||||
|
||||
public function storeState(marble:Marble, tick:Int) {
|
||||
var state = new MarblePrediction(marble, tick);
|
||||
if (predictions.exists(marble)) {
|
||||
var arr = predictions[marble];
|
||||
while (arr.length != 0 && arr[0].tick >= tick)
|
||||
arr.shift();
|
||||
arr.push(state);
|
||||
} else {
|
||||
predictions.set(marble, [state]);
|
||||
}
|
||||
}
|
||||
|
||||
public function retrieveState(marble:Marble, tick:Int) {
|
||||
if (predictions.exists(marble)) {
|
||||
var arr = predictions[marble];
|
||||
while (arr.length != 0 && arr[0].tick < tick)
|
||||
arr.shift();
|
||||
if (arr.length == 0)
|
||||
return null;
|
||||
var p = arr[0];
|
||||
if (p.tick == tick)
|
||||
return p;
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package net;
|
||||
|
||||
import net.NetPacket.MarbleUpdatePacket;
|
||||
import shapes.PowerUp;
|
||||
import net.NetPacket.MarbleMovePacket;
|
||||
import src.TimeState;
|
||||
|
|
@ -199,4 +200,20 @@ class MoveManager {
|
|||
lastAckMoveId = m;
|
||||
return mv;
|
||||
}
|
||||
|
||||
public function getMoveForTick(m:Int) {
|
||||
if (m <= lastAckMoveId)
|
||||
return null;
|
||||
if (m == 65535 || m == -1)
|
||||
return null;
|
||||
if (queuedMoves.length == 0)
|
||||
return null;
|
||||
for (i in 0...queuedMoves.length) {
|
||||
if (queuedMoves[i].id == m)
|
||||
return queuedMoves[i];
|
||||
if (queuedMoves[i].id > m)
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ class Net {
|
|||
isHost = true;
|
||||
isClient = false;
|
||||
clientId = 0;
|
||||
masterWs = new WebSocket("ws://localhost:8080");
|
||||
masterWs = new WebSocket("ws://192.168.1.2:8080");
|
||||
|
||||
masterWs.onmessage = (m) -> {
|
||||
switch (m) {
|
||||
|
|
@ -97,7 +97,7 @@ class Net {
|
|||
}
|
||||
|
||||
public static function joinServer(connectedCb:() -> Void) {
|
||||
masterWs = new WebSocket("ws://localhost:8080");
|
||||
masterWs = new WebSocket("ws://192.168.1.2:8080");
|
||||
masterWs.onopen = () -> {
|
||||
client = new RTCPeerConnection(["stun:stun.l.google.com:19302"], "0.0.0.0");
|
||||
var candidates = [];
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue