mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2026-04-27 13:11:42 +00:00
fix rewind hogging all the memory when not on vsync
This commit is contained in:
parent
2ee42a2291
commit
6c20de1b8a
2 changed files with 111 additions and 89 deletions
|
|
@ -11,25 +11,44 @@ import src.TimeState;
|
||||||
import src.DtsObject;
|
import src.DtsObject;
|
||||||
import shapes.Gem;
|
import shapes.Gem;
|
||||||
|
|
||||||
|
@:publicFields
|
||||||
|
class RewindMPState {
|
||||||
|
var currentTime:Float;
|
||||||
|
var targetTime:Float;
|
||||||
|
var stoppedPosition:Vector;
|
||||||
|
var prevPosition:Vector;
|
||||||
|
var position:Vector;
|
||||||
|
var velocity:Vector;
|
||||||
|
|
||||||
|
public function new() {}
|
||||||
|
|
||||||
|
public function clone() {
|
||||||
|
var c = new RewindMPState();
|
||||||
|
c.currentTime = currentTime;
|
||||||
|
c.targetTime = targetTime;
|
||||||
|
c.stoppedPosition = stoppedPosition != null ? stoppedPosition.clone() : null;
|
||||||
|
c.prevPosition = prevPosition.clone();
|
||||||
|
c.position = position.clone();
|
||||||
|
c.velocity = velocity.clone();
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@:publicFields
|
@:publicFields
|
||||||
class RewindFrame {
|
class RewindFrame {
|
||||||
var timeState:TimeState;
|
var timeState:TimeState;
|
||||||
|
var rewindAccumulator:Float;
|
||||||
var marbleColliderTransform:Matrix;
|
var marbleColliderTransform:Matrix;
|
||||||
var marblePrevPosition:Vector;
|
var marblePrevPosition:Vector;
|
||||||
var marbleNextPosition:Vector;
|
var marbleNextPosition:Vector;
|
||||||
var marblePhysicsAccmulator:Float;
|
var marblePhysicsAccmulator:Float;
|
||||||
var marbleOrientation:Quat;
|
var marbleOrientation:Quat;
|
||||||
|
var marblePrevOrientation:Quat;
|
||||||
var marbleVelocity:Vector;
|
var marbleVelocity:Vector;
|
||||||
var marbleAngularVelocity:Vector;
|
var marbleAngularVelocity:Vector;
|
||||||
var marblePowerup:PowerUp;
|
var marblePowerup:PowerUp;
|
||||||
var bonusTime:Float;
|
var bonusTime:Float;
|
||||||
var mpStates:Array<{
|
var mpStates:Array<RewindMPState>;
|
||||||
curState:PIState,
|
|
||||||
stopped:Bool,
|
|
||||||
stoppedPosition:Vector,
|
|
||||||
prevPosition:Vector,
|
|
||||||
position:Vector,
|
|
||||||
}>;
|
|
||||||
var gemCount:Int;
|
var gemCount:Int;
|
||||||
var gemStates:Array<Bool>;
|
var gemStates:Array<Bool>;
|
||||||
var powerupStates:Array<Float>;
|
var powerupStates:Array<Float>;
|
||||||
|
|
@ -58,11 +77,13 @@ class RewindFrame {
|
||||||
public function clone() {
|
public function clone() {
|
||||||
var c = new RewindFrame();
|
var c = new RewindFrame();
|
||||||
c.timeState = timeState.clone();
|
c.timeState = timeState.clone();
|
||||||
|
c.rewindAccumulator = rewindAccumulator;
|
||||||
c.marbleColliderTransform = marbleColliderTransform.clone();
|
c.marbleColliderTransform = marbleColliderTransform.clone();
|
||||||
c.marblePrevPosition = marblePrevPosition.clone();
|
c.marblePrevPosition = marblePrevPosition.clone();
|
||||||
c.marbleNextPosition = marbleNextPosition.clone();
|
c.marbleNextPosition = marbleNextPosition.clone();
|
||||||
c.marblePhysicsAccmulator = marblePhysicsAccmulator;
|
c.marblePhysicsAccmulator = marblePhysicsAccmulator;
|
||||||
c.marbleOrientation = marbleOrientation.clone();
|
c.marbleOrientation = marbleOrientation.clone();
|
||||||
|
c.marblePrevOrientation = marblePrevOrientation.clone();
|
||||||
c.marbleVelocity = marbleVelocity.clone();
|
c.marbleVelocity = marbleVelocity.clone();
|
||||||
c.marbleAngularVelocity = marbleAngularVelocity.clone();
|
c.marbleAngularVelocity = marbleAngularVelocity.clone();
|
||||||
c.marblePowerup = marblePowerup;
|
c.marblePowerup = marblePowerup;
|
||||||
|
|
@ -74,20 +95,7 @@ class RewindFrame {
|
||||||
c.activePowerupStates = activePowerupStates.copy();
|
c.activePowerupStates = activePowerupStates.copy();
|
||||||
c.currentUp = currentUp.clone();
|
c.currentUp = currentUp.clone();
|
||||||
c.lastContactNormal = lastContactNormal.clone();
|
c.lastContactNormal = lastContactNormal.clone();
|
||||||
c.mpStates = [];
|
c.mpStates = mpStates.copy();
|
||||||
for (s in mpStates) {
|
|
||||||
c.mpStates.push({
|
|
||||||
curState: {
|
|
||||||
currentTime: s.curState.currentTime,
|
|
||||||
targetTime: s.curState.targetTime,
|
|
||||||
velocity: s.curState.velocity.clone(),
|
|
||||||
},
|
|
||||||
stopped: s.stopped,
|
|
||||||
position: s.position.clone(),
|
|
||||||
prevPosition: s.prevPosition.clone(),
|
|
||||||
stoppedPosition: s.stoppedPosition != null ? s.stoppedPosition.clone() : null,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
c.trapdoorStates = [];
|
c.trapdoorStates = [];
|
||||||
for (s in trapdoorStates) {
|
for (s in trapdoorStates) {
|
||||||
c.trapdoorStates.push({
|
c.trapdoorStates.push({
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package rewind;
|
package rewind;
|
||||||
|
|
||||||
|
import rewind.RewindFrame.RewindMPState;
|
||||||
import shapes.AbstractBumper;
|
import shapes.AbstractBumper;
|
||||||
import shapes.PowerUp;
|
import shapes.PowerUp;
|
||||||
import src.MarbleWorld;
|
import src.MarbleWorld;
|
||||||
|
|
@ -13,87 +14,93 @@ class RewindManager {
|
||||||
|
|
||||||
public var timeScale:Float = 1;
|
public var timeScale:Float = 1;
|
||||||
|
|
||||||
|
var timeAccumulator:Float = 0.0;
|
||||||
|
var saveResolution:Float = 0.032;
|
||||||
|
|
||||||
public function new(level:MarbleWorld) {
|
public function new(level:MarbleWorld) {
|
||||||
this.level = level;
|
this.level = level;
|
||||||
this.timeScale = Settings.optionsSettings.rewindTimescale;
|
this.timeScale = Settings.optionsSettings.rewindTimescale;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function recordFrame() {
|
public function recordFrame() {
|
||||||
var rf = new RewindFrame();
|
timeAccumulator += level.timeState.dt;
|
||||||
rf.timeState = level.timeState.clone();
|
while (timeAccumulator >= saveResolution) {
|
||||||
rf.marbleColliderTransform = level.marble.collider.transform.clone();
|
timeAccumulator -= saveResolution;
|
||||||
rf.marblePrevPosition = @:privateAccess level.marble.oldPos.clone();
|
var rf = new RewindFrame();
|
||||||
rf.marbleNextPosition = @:privateAccess level.marble.newPos.clone();
|
rf.timeState = level.timeState.clone();
|
||||||
rf.marbleOrientation = @:privateAccess level.marble.prevRot.clone();
|
rf.marbleColliderTransform = level.marble.collider.transform.clone();
|
||||||
rf.marblePhysicsAccmulator = @:privateAccess level.marble.physicsAccumulator;
|
rf.marblePrevPosition = @:privateAccess level.marble.oldPos.clone();
|
||||||
rf.marbleVelocity = level.marble.velocity.clone();
|
rf.marbleNextPosition = @:privateAccess level.marble.newPos.clone();
|
||||||
rf.marbleAngularVelocity = level.marble.omega.clone();
|
rf.marbleOrientation = @:privateAccess level.marble.getRotationQuat().clone();
|
||||||
rf.marblePowerup = level.marble.heldPowerup;
|
rf.marblePrevOrientation = @:privateAccess level.marble.prevRot.clone();
|
||||||
rf.bonusTime = level.bonusTime;
|
rf.marblePhysicsAccmulator = @:privateAccess level.marble.physicsAccumulator;
|
||||||
rf.gemCount = level.gemCount;
|
rf.marbleVelocity = level.marble.velocity.clone();
|
||||||
rf.gemStates = level.gems.map(x -> x.pickedUp);
|
rf.marbleAngularVelocity = level.marble.omega.clone();
|
||||||
rf.activePowerupStates = [@:privateAccess level.marble.helicopterEnableTime, @:privateAccess level.marble.megaMarbleEnableTime];
|
rf.marblePowerup = level.marble.heldPowerup;
|
||||||
rf.currentUp = level.currentUp.clone();
|
rf.bonusTime = level.bonusTime;
|
||||||
rf.lastContactNormal = level.marble.lastContactNormal.clone();
|
rf.gemCount = level.gemCount;
|
||||||
rf.mpStates = level.pathedInteriors.map(x -> {
|
rf.gemStates = level.gems.map(x -> x.pickedUp);
|
||||||
return {
|
rf.activePowerupStates = [@:privateAccess level.marble.helicopterEnableTime, @:privateAccess level.marble.megaMarbleEnableTime];
|
||||||
curState: {
|
rf.currentUp = level.currentUp.clone();
|
||||||
currentTime: x.currentTime,
|
rf.lastContactNormal = level.marble.lastContactNormal.clone();
|
||||||
targetTime: x.targetTime,
|
rf.mpStates = level.pathedInteriors.map(x -> {
|
||||||
velocity: x.velocity.clone(),
|
var mpstate = new RewindMPState();
|
||||||
},
|
mpstate.currentTime = x.currentTime;
|
||||||
stopped: @:privateAccess x.stopped,
|
mpstate.targetTime = x.targetTime;
|
||||||
position: @:privateAccess x.position.clone(),
|
mpstate.velocity = x.velocity.clone();
|
||||||
prevPosition: @:privateAccess x.prevPosition.clone(),
|
mpstate.stoppedPosition = @:privateAccess x.stopped ? @:privateAccess x.stoppedPosition.clone() : null;
|
||||||
stoppedPosition: @:privateAccess x.stoppedPosition != null ? @:privateAccess x.stoppedPosition.clone() : null,
|
mpstate.position = @:privateAccess x.position.clone();
|
||||||
}
|
mpstate.prevPosition = @:privateAccess x.prevPosition.clone();
|
||||||
});
|
return mpstate;
|
||||||
rf.powerupStates = [];
|
});
|
||||||
rf.landMineStates = [];
|
rf.powerupStates = [];
|
||||||
rf.trapdoorStates = [];
|
rf.landMineStates = [];
|
||||||
for (dts in level.dtsObjects) {
|
rf.trapdoorStates = [];
|
||||||
if (dts is PowerUp) {
|
for (dts in level.dtsObjects) {
|
||||||
var pow:PowerUp = cast dts;
|
if (dts is PowerUp) {
|
||||||
rf.powerupStates.push(pow.lastPickUpTime);
|
var pow:PowerUp = cast dts;
|
||||||
}
|
rf.powerupStates.push(pow.lastPickUpTime);
|
||||||
if (dts is Trapdoor) {
|
}
|
||||||
var td:Trapdoor = cast dts;
|
if (dts is Trapdoor) {
|
||||||
rf.trapdoorStates.push({
|
var td:Trapdoor = cast dts;
|
||||||
lastCompletion: td.lastCompletion,
|
rf.trapdoorStates.push({
|
||||||
lastDirection: td.lastDirection,
|
lastCompletion: td.lastCompletion,
|
||||||
lastContactTime: td.lastContactTime
|
lastDirection: td.lastDirection,
|
||||||
});
|
lastContactTime: td.lastContactTime
|
||||||
}
|
});
|
||||||
if (dts is AbstractBumper) {
|
}
|
||||||
var ab:AbstractBumper = cast dts;
|
if (dts is AbstractBumper) {
|
||||||
rf.powerupStates.push(ab.lastContactTime);
|
var ab:AbstractBumper = cast dts;
|
||||||
|
rf.powerupStates.push(ab.lastContactTime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
rf.blastAmt = level.blastAmount;
|
||||||
|
rf.oobState = {
|
||||||
|
oob: level.outOfBounds,
|
||||||
|
timeState: level.outOfBoundsTime != null ? level.outOfBoundsTime.clone() : null
|
||||||
|
};
|
||||||
|
rf.checkpointState = {
|
||||||
|
currentCheckpoint: @:privateAccess level.currentCheckpoint,
|
||||||
|
currentCheckpointTrigger: @:privateAccess level.currentCheckpointTrigger,
|
||||||
|
checkpointBlast: @:privateAccess level.cheeckpointBlast,
|
||||||
|
checkpointCollectedGems: @:privateAccess level.checkpointCollectedGems.copy(),
|
||||||
|
checkpointHeldPowerup: @:privateAccess level.checkpointHeldPowerup,
|
||||||
|
};
|
||||||
|
rf.modeState = level.gameMode.getRewindState();
|
||||||
|
frames.push(rf);
|
||||||
}
|
}
|
||||||
rf.blastAmt = level.blastAmount;
|
|
||||||
rf.oobState = {
|
|
||||||
oob: level.outOfBounds,
|
|
||||||
timeState: level.outOfBoundsTime != null ? level.outOfBoundsTime.clone() : null
|
|
||||||
};
|
|
||||||
rf.checkpointState = {
|
|
||||||
currentCheckpoint: @:privateAccess level.currentCheckpoint,
|
|
||||||
currentCheckpointTrigger: @:privateAccess level.currentCheckpointTrigger,
|
|
||||||
checkpointBlast: @:privateAccess level.cheeckpointBlast,
|
|
||||||
checkpointCollectedGems: @:privateAccess level.checkpointCollectedGems.copy(),
|
|
||||||
checkpointHeldPowerup: @:privateAccess level.checkpointHeldPowerup,
|
|
||||||
};
|
|
||||||
rf.modeState = level.gameMode.getRewindState();
|
|
||||||
frames.push(rf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyFrame(rf:RewindFrame) {
|
public function applyFrame(rf:RewindFrame) {
|
||||||
|
timeAccumulator = rf.rewindAccumulator;
|
||||||
level.timeState = rf.timeState.clone();
|
level.timeState = rf.timeState.clone();
|
||||||
@:privateAccess level.marble.oldPos.load(rf.marblePrevPosition);
|
@:privateAccess level.marble.oldPos.load(rf.marblePrevPosition);
|
||||||
@:privateAccess level.marble.newPos.load(rf.marbleNextPosition);
|
@:privateAccess level.marble.newPos.load(rf.marbleNextPosition);
|
||||||
@:privateAccess level.marble.collider.transform.load(rf.marbleColliderTransform);
|
@:privateAccess level.marble.collider.transform.load(rf.marbleColliderTransform);
|
||||||
@:privateAccess level.marble.physicsAccumulator = rf.marblePhysicsAccmulator;
|
@:privateAccess level.marble.physicsAccumulator = rf.marblePhysicsAccmulator;
|
||||||
@:privateAccess level.marble.prevRot.load(rf.marbleOrientation);
|
@:privateAccess level.marble.prevRot.load(rf.marblePrevOrientation);
|
||||||
// level.marble.setMarblePosition(rf.marblePosition.x, rf.marblePosition.y, rf.marblePosition.z);
|
// level.marble.setMarblePosition(rf.marblePosition.x, rf.marblePosition.y, rf.marblePosition.z);
|
||||||
// level.marble.setRotationQuat(rf.marbleOrientation.clone());
|
level.marble.setRotationQuat(rf.marbleOrientation.clone());
|
||||||
level.marble.velocity.load(rf.marbleVelocity);
|
level.marble.velocity.load(rf.marbleVelocity);
|
||||||
level.marble.omega.load(rf.marbleAngularVelocity);
|
level.marble.omega.load(rf.marbleAngularVelocity);
|
||||||
|
|
||||||
|
|
@ -136,13 +143,19 @@ class RewindManager {
|
||||||
level.currentUp.load(rf.currentUp);
|
level.currentUp.load(rf.currentUp);
|
||||||
level.marble.lastContactNormal.load(rf.lastContactNormal);
|
level.marble.lastContactNormal.load(rf.lastContactNormal);
|
||||||
for (i in 0...rf.mpStates.length) {
|
for (i in 0...rf.mpStates.length) {
|
||||||
level.pathedInteriors[i].currentTime = rf.mpStates[i].curState.currentTime;
|
level.pathedInteriors[i].currentTime = rf.mpStates[i].currentTime;
|
||||||
level.pathedInteriors[i].targetTime = rf.mpStates[i].curState.targetTime;
|
level.pathedInteriors[i].targetTime = rf.mpStates[i].targetTime;
|
||||||
level.pathedInteriors[i].velocity.load(rf.mpStates[i].curState.velocity);
|
level.pathedInteriors[i].velocity.load(rf.mpStates[i].velocity);
|
||||||
@:privateAccess level.pathedInteriors[i].stopped = rf.mpStates[i].stopped;
|
@:privateAccess level.pathedInteriors[i].stopped = rf.mpStates[i].stoppedPosition != null;
|
||||||
@:privateAccess level.pathedInteriors[i].position.load(rf.mpStates[i].position);
|
@:privateAccess level.pathedInteriors[i].position.load(rf.mpStates[i].position);
|
||||||
@:privateAccess level.pathedInteriors[i].prevPosition.load(rf.mpStates[i].prevPosition);
|
@:privateAccess level.pathedInteriors[i].prevPosition.load(rf.mpStates[i].prevPosition);
|
||||||
@:privateAccess level.pathedInteriors[i].stoppedPosition = rf.mpStates[i].stoppedPosition;
|
@:privateAccess level.pathedInteriors[i].stoppedPosition = rf.mpStates[i].stoppedPosition;
|
||||||
|
if (level.pathedInteriors[i].isCollideable) {
|
||||||
|
var tform = level.pathedInteriors[i].getAbsPos().clone();
|
||||||
|
tform.setPosition(rf.mpStates[i].position);
|
||||||
|
@:privateAccess level.pathedInteriors[i].collider.setTransform(tform);
|
||||||
|
level.collisionWorld.updateTransform(@:privateAccess level.pathedInteriors[i].collider);
|
||||||
|
}
|
||||||
// level.pathedInteriors[i].setTransform(level.pathedInteriors[i].getTransform());
|
// level.pathedInteriors[i].setTransform(level.pathedInteriors[i].getTransform());
|
||||||
}
|
}
|
||||||
var pstates = rf.powerupStates.copy();
|
var pstates = rf.powerupStates.copy();
|
||||||
|
|
@ -209,5 +222,6 @@ class RewindManager {
|
||||||
|
|
||||||
public function clear() {
|
public function clear() {
|
||||||
frames = [];
|
frames = [];
|
||||||
|
timeAccumulator = 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue