mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-12-25 17:32:35 +00:00
marble finish animation
This commit is contained in:
parent
0964fe53ca
commit
b9b111bf85
4 changed files with 125 additions and 61 deletions
|
|
@ -222,9 +222,8 @@ class CameraController extends Object {
|
|||
|
||||
if (this.finish) {
|
||||
// Make the camera spin around slowly
|
||||
CameraPitch = Util.lerp(this.level.finishPitch, 0.45,
|
||||
Util.clamp((this.level.timeState.currentAttemptTime - this.level.finishTime.currentAttemptTime) / 0.3, 0, 1));
|
||||
CameraYaw = this.level.finishYaw - (this.level.timeState.currentAttemptTime - this.level.finishTime.currentAttemptTime) / -1.2;
|
||||
CameraPitch = this.level.finishPitch;
|
||||
CameraYaw = this.level.finishYaw;
|
||||
}
|
||||
|
||||
if (!this.level.isWatching) {
|
||||
|
|
@ -236,7 +235,7 @@ class CameraController extends Object {
|
|||
CameraYaw = this.level.replay.currentPlaybackFrame.cameraYaw;
|
||||
}
|
||||
|
||||
var marblePosition = level.marble.getAbsPos().getPosition();
|
||||
var marblePosition = level.marble.collider.transform.getPosition();
|
||||
var up = new Vector(0, 0, 1);
|
||||
up.transform(orientationQuat.toMatrix());
|
||||
var directionVector = new Vector(1, 0, 0);
|
||||
|
|
|
|||
160
src/Marble.hx
160
src/Marble.hx
|
|
@ -265,6 +265,10 @@ class Marble extends GameObject {
|
|||
var helicopterSound:Channel;
|
||||
var playedSounds = [];
|
||||
|
||||
var finishAnimVelocity:Vector;
|
||||
var finishAnimPosition:Vector;
|
||||
var finishAnimTime:Float = 0;
|
||||
|
||||
public var mode:Mode = Play;
|
||||
|
||||
public var startPad:StartPad;
|
||||
|
|
@ -425,6 +429,7 @@ class Marble extends GameObject {
|
|||
this.isUltra = isUltra;
|
||||
|
||||
this.collider = new SphereCollisionEntity(cast this);
|
||||
this.collider.setTransform(this.getAbsPos());
|
||||
|
||||
this.addChild(marbleDts);
|
||||
|
||||
|
|
@ -512,7 +517,7 @@ class Marble extends GameObject {
|
|||
A = A.multiply(0.25);
|
||||
}
|
||||
for (obj in level.forceObjects) {
|
||||
var force = cast(obj, ForceObject).getForce(this.getAbsPos().getPosition());
|
||||
var force = cast(obj, ForceObject).getForce(this.collider.transform.getPosition());
|
||||
A = A.add(force.multiply(1 / _mass));
|
||||
}
|
||||
if (contacts.length != 0 && this.mode != Start) {
|
||||
|
|
@ -850,7 +855,7 @@ class Marble extends GameObject {
|
|||
function bounceEmitter(speed:Float, normal:Vector) {
|
||||
if (this.bounceEmitDelay == 0 && this._minBounceSpeed <= speed) {
|
||||
this.level.particleManager.createEmitter(bounceParticleOptions, this.bounceEmitterData,
|
||||
this.getAbsPos().getPosition().sub(normal.multiply(_radius)), null, new Vector(1, 1, 1).add(normal.multiply(-0.8)));
|
||||
this.collider.transform.getPosition().sub(normal.multiply(_radius)), null, new Vector(1, 1, 1).add(normal.multiply(-0.8)));
|
||||
this.bounceEmitDelay = 0.3;
|
||||
}
|
||||
}
|
||||
|
|
@ -911,15 +916,15 @@ class Marble extends GameObject {
|
|||
|
||||
function updateRollSound(time:TimeState, contactPct:Float, slipAmount:Float) {
|
||||
var rSpat = rollSound.getEffect(Spatialization);
|
||||
rSpat.position = this.getAbsPos().getPosition();
|
||||
rSpat.position = this.collider.transform.getPosition();
|
||||
|
||||
if (this.rollMegaSound != null) {
|
||||
var rmspat = this.rollMegaSound.getEffect(Spatialization);
|
||||
rmspat.position = this.getAbsPos().getPosition();
|
||||
rmspat.position = this.collider.transform.getPosition();
|
||||
}
|
||||
|
||||
var sSpat = slipSound.getEffect(Spatialization);
|
||||
sSpat.position = this.getAbsPos().getPosition();
|
||||
sSpat.position = this.collider.transform.getPosition();
|
||||
|
||||
var rollVel = bestContact != null ? this.velocity.sub(bestContact.velocity) : this.velocity;
|
||||
var scale = rollVel.length();
|
||||
|
|
@ -989,7 +994,9 @@ class Marble extends GameObject {
|
|||
position: position,
|
||||
t: deltaT,
|
||||
found: false,
|
||||
foundContacts: []
|
||||
foundContacts: [],
|
||||
lastContactPos: null,
|
||||
lastContactNormal: null
|
||||
};
|
||||
}
|
||||
var searchbox = new Bounds();
|
||||
|
|
@ -1109,6 +1116,7 @@ class Marble extends GameObject {
|
|||
finalT = collisionTime;
|
||||
currentFinalPos = position.add(relVel.multiply(finalT));
|
||||
found = true;
|
||||
lastContactPos = currentFinalPos.clone();
|
||||
// iterationFound = true;
|
||||
i += 3;
|
||||
// Debug.drawSphere(currentFinalPos, radius);
|
||||
|
|
@ -1319,7 +1327,9 @@ class Marble extends GameObject {
|
|||
position: position,
|
||||
t: finalT,
|
||||
found: found,
|
||||
foundContacts: testTriangles
|
||||
foundContacts: testTriangles,
|
||||
lastContactPos: lastContactPos,
|
||||
lastContactNormal: position.sub(lastContactPos).normalized(),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -1328,7 +1338,7 @@ class Marble extends GameObject {
|
|||
searchbox.addSpherePos(this.x, this.y, this.z, _radius);
|
||||
searchbox.addSpherePos(this.x + velocity.x * dt * 2, this.y + velocity.y * dt * 2, this.z + velocity.z * dt * 2, _radius);
|
||||
|
||||
var position = this.getAbsPos().getPosition();
|
||||
var position = this.collider.transform.getPosition();
|
||||
|
||||
var foundObjs = this.level.collisionWorld.boundingSearch(searchbox);
|
||||
// var foundObjs = this.contactEntities;
|
||||
|
|
@ -1618,7 +1628,7 @@ class Marble extends GameObject {
|
|||
|
||||
velocity.w = 0;
|
||||
|
||||
var pos = this.getAbsPos().getPosition();
|
||||
var pos = this.collider.transform.getPosition();
|
||||
this.prevPos = pos.clone();
|
||||
|
||||
var tdiff = timeStep;
|
||||
|
|
@ -1653,43 +1663,6 @@ class Marble extends GameObject {
|
|||
}
|
||||
}
|
||||
|
||||
// var intersectT = intersectData.t;
|
||||
// if (intersectData.found && intersectT > 0.001) {
|
||||
// var diff = timeStep - intersectT;
|
||||
// this.velocity = this.velocity.sub(A.multiply(diff));
|
||||
// this.omega = this.omega.sub(a.multiply(diff));
|
||||
// // var mo = new h3d.prim.Sphere();
|
||||
// // mo.addNormals();
|
||||
// // mo.scale(_radius);
|
||||
// // var mCol = new h3d.scene.Mesh(mo);
|
||||
// // mCol.setPosition(intersectData.position.x, intersectData.position.y, intersectData.position.z);
|
||||
// // this.level.scene.addChild(mCol);
|
||||
// timeStep = intersectT;
|
||||
// }
|
||||
|
||||
// var posAdd = this.velocity.multiply(timeStep);
|
||||
// var expectedPos = pos.add(posAdd);
|
||||
// var newPos = nudgeToContacts(expectedPos, _radius);
|
||||
|
||||
// if (mode == Start) {
|
||||
// var upVec = this.level.currentUp;
|
||||
// var startpadNormal = startPad.getAbsPos().up();
|
||||
// this.velocity = upVec.multiply(this.velocity.dot(upVec));
|
||||
// // Apply contact forces in startPad up direction if upVec is not startpad up, fixes the weird startpad shit in pinball wizard
|
||||
// if (upVec.dot(startpadNormal) < 0.95) {
|
||||
// for (contact in contacts) {
|
||||
// var normF = contact.normal.multiply(contact.normalForce);
|
||||
// var startpadF = startpadNormal.multiply(normF.dot(startpadNormal));
|
||||
// var upF = upVec.multiply(normF.dot(upVec));
|
||||
// this.velocity = this.velocity.add(startpadF.multiply(timeStep / 4));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (mode == Finish) {
|
||||
// this.velocity = this.velocity.multiply(0.925);
|
||||
// }
|
||||
|
||||
var rot = this.getRotationQuat();
|
||||
var quat = new Quat();
|
||||
quat.initRotation(omega.x * timeStep, omega.y * timeStep, omega.z * timeStep);
|
||||
|
|
@ -1858,6 +1831,11 @@ class Marble extends GameObject {
|
|||
|
||||
this.updateTeleporterState(timeState);
|
||||
|
||||
this.updateFinishAnimation(timeState.dt);
|
||||
if (this.mode == Finish) {
|
||||
this.setPosition(this.finishAnimPosition.x, this.finishAnimPosition.y, this.finishAnimPosition.z);
|
||||
}
|
||||
|
||||
this.trailEmitter();
|
||||
if (bounceEmitDelay > 0)
|
||||
bounceEmitDelay -= timeState.dt;
|
||||
|
|
@ -1867,6 +1845,81 @@ class Marble extends GameObject {
|
|||
// this.camera.target.load(this.getAbsPos().getPosition().toPoint());
|
||||
}
|
||||
|
||||
public function updateFinishAnimation(dt:Float) {
|
||||
if (this.mode == Finish) {
|
||||
var trans = @:privateAccess this.level.endPad.getAbsPos();
|
||||
var around = trans.getPosition();
|
||||
var forceEffect = trans.up();
|
||||
around = around.add(forceEffect);
|
||||
var offset = finishAnimPosition.sub(around);
|
||||
|
||||
static var animTimeAccumulator = 0.0;
|
||||
animTimeAccumulator += dt;
|
||||
while (animTimeAccumulator >= 1 / 60.0) {
|
||||
animTimeAccumulator -= (1 / 60.0);
|
||||
|
||||
finishAnimVelocity.scale(0.95);
|
||||
finishAnimVelocity = finishAnimVelocity.add(forceEffect.multiply(0.2));
|
||||
|
||||
var dist = offset.length();
|
||||
|
||||
finishAnimVelocity = finishAnimVelocity.sub(offset.multiply(0.35));
|
||||
|
||||
if (dist > 1.5) {
|
||||
var outward = offset.multiply(1 / dist);
|
||||
var outforce = outward.dot(finishAnimVelocity);
|
||||
if (outforce > 0) {
|
||||
finishAnimVelocity = finishAnimVelocity.sub(outward.multiply(outforce * 0.75));
|
||||
var noodles = offset.multiply(outforce * 0.5);
|
||||
noodles = finishAnimVelocity.sub(noodles);
|
||||
if (noodles.lengthSq() <= 0.1) {
|
||||
var cross = outward.cross(forceEffect);
|
||||
if (cross.lengthSq() <= 0.1) {
|
||||
noodles = trans.front().clone();
|
||||
} else {
|
||||
noodles = cross.normalized();
|
||||
}
|
||||
} else {
|
||||
noodles.normalize();
|
||||
}
|
||||
|
||||
finishAnimVelocity = finishAnimVelocity.add(noodles.multiply(outforce * 0.25));
|
||||
}
|
||||
}
|
||||
|
||||
var addVel = new Vector(Math.sin(finishAnimTime * 3), Math.sin(finishAnimTime * 3 + 2.45), Math.sin(finishAnimTime * 1.5 + 1.2));
|
||||
finishAnimVelocity = finishAnimVelocity.add(addVel.multiply(2.5 / 60.0));
|
||||
|
||||
var pos = finishAnimPosition.add(finishAnimVelocity.multiply(1 / 60.0));
|
||||
|
||||
var position = finishAnimPosition.clone();
|
||||
var velocity = pos.sub(finishAnimPosition);
|
||||
var time = 1.0;
|
||||
var i = 0;
|
||||
var totalTime = time;
|
||||
do {
|
||||
if (totalTime <= 1e-8)
|
||||
break;
|
||||
var tm = testMove(velocity, position, time, _radius, true);
|
||||
if (!tm.found)
|
||||
break;
|
||||
|
||||
i++;
|
||||
totalTime -= tm.t;
|
||||
time = totalTime;
|
||||
pos = tm.position;
|
||||
var norm = tm.lastContactNormal;
|
||||
var newAround = norm.multiply(1.5);
|
||||
newAround.scale(finishAnimVelocity.dot(norm));
|
||||
finishAnimVelocity = finishAnimVelocity.sub(newAround);
|
||||
} while (i < 4);
|
||||
|
||||
finishAnimPosition = pos;
|
||||
finishAnimTime += (1 / 60.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function updatePowerupStates(currentTime:Float, dt:Float) {
|
||||
if (currentTime - this.shockAbsorberEnableTime < 5) {
|
||||
this.shockabsorberSound.pause = false;
|
||||
|
|
@ -1977,6 +2030,20 @@ class Marble extends GameObject {
|
|||
}
|
||||
}
|
||||
|
||||
public function setMode(mode:Mode) {
|
||||
this.mode = mode;
|
||||
if (mode == Finish) {
|
||||
this.finishAnimPosition = this.collider.transform.getPosition().clone();
|
||||
this.finishAnimVelocity = this.velocity.clone();
|
||||
this.finishAnimTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public function setMarblePosition(x:Float, y:Float, z:Float) {
|
||||
this.collider.transform.setPosition(new Vector(x, y, z));
|
||||
this.setPosition(x, y, z);
|
||||
}
|
||||
|
||||
public override function reset() {
|
||||
this.velocity = new Vector();
|
||||
this.collider.velocity = new Vector();
|
||||
|
|
@ -1997,6 +2064,7 @@ class Marble extends GameObject {
|
|||
this.teleporting = false;
|
||||
this.teleportDisableTime = null;
|
||||
this.teleportEnableTime = null;
|
||||
this.finishAnimTime = 0;
|
||||
if (this._radius != this._prevRadius) {
|
||||
this._radius = this._prevRadius;
|
||||
this._marbleScale = this._renderScale = this._defaultScale;
|
||||
|
|
|
|||
|
|
@ -491,10 +491,7 @@ class MarbleWorld extends Scheduler {
|
|||
|
||||
var startquat = this.getStartPositionAndOrientation();
|
||||
|
||||
this.marble.setPosition(startquat.position.x, startquat.position.y, startquat.position.z + 0.727843);
|
||||
var oldtransform = this.marble.collider.transform.clone();
|
||||
oldtransform.setPosition(startquat.position);
|
||||
this.marble.collider.setTransform(oldtransform);
|
||||
this.marble.setMarblePosition(startquat.position.x, startquat.position.y, startquat.position.z + 0.727843);
|
||||
this.marble.reset();
|
||||
|
||||
var euler = startquat.quat.toEuler();
|
||||
|
|
@ -505,7 +502,7 @@ class MarbleWorld extends Scheduler {
|
|||
this.marble.camera.nextCameraYaw = euler.z + Math.PI / 2;
|
||||
this.marble.camera.oob = false;
|
||||
this.marble.camera.finish = false;
|
||||
this.marble.mode = Start;
|
||||
this.marble.setMode(Start);
|
||||
this.marble.startPad = cast startquat.pad;
|
||||
sky.follow = marble.camera;
|
||||
|
||||
|
|
@ -535,15 +532,15 @@ class MarbleWorld extends Scheduler {
|
|||
return; // We will update state manually
|
||||
if (this.timeState.currentAttemptTime < 0.5) {
|
||||
this.playGui.setCenterText('none');
|
||||
this.marble.mode = Start;
|
||||
this.marble.setMode(Start);
|
||||
}
|
||||
if ((this.timeState.currentAttemptTime >= 0.5) && (this.timeState.currentAttemptTime < 3.5)) {
|
||||
this.playGui.setCenterText('none');
|
||||
this.marble.mode = Start;
|
||||
this.marble.setMode(Start);
|
||||
}
|
||||
if (this.timeState.currentAttemptTime >= 3.5 && this.finishTime == null) {
|
||||
this.playGui.setCenterText('none');
|
||||
this.marble.mode = Play;
|
||||
this.marble.setMode(Play);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1412,7 +1409,7 @@ class MarbleWorld extends Scheduler {
|
|||
} else {
|
||||
this.endPad.spawnFirework(this.timeState);
|
||||
this.finishTime = this.timeState.clone();
|
||||
this.marble.mode = Finish;
|
||||
this.marble.setMode(Finish);
|
||||
this.marble.camera.finish = true;
|
||||
this.finishYaw = this.marble.camera.CameraYaw;
|
||||
this.finishPitch = this.marble.camera.CameraPitch;
|
||||
|
|
@ -1673,7 +1670,7 @@ class MarbleWorld extends Scheduler {
|
|||
// Determine where to spawn the marble
|
||||
var offset = new Vector(0, 0, 0.727843);
|
||||
var mpos = this.currentCheckpoint.getAbsPos().getPosition().add(offset);
|
||||
this.marble.setPosition(mpos.x, mpos.y, mpos.z);
|
||||
this.marble.setMarblePosition(mpos.x, mpos.y, mpos.z);
|
||||
marble.velocity.load(new Vector(0, 0, 0));
|
||||
marble.omega.load(new Vector(0, 0, 0));
|
||||
Console.log('Respawn:');
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ class RewindManager {
|
|||
|
||||
public function applyFrame(rf:RewindFrame) {
|
||||
level.timeState = rf.timeState.clone();
|
||||
level.marble.setPosition(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.velocity.set(rf.marbleVelocity.x, rf.marbleVelocity.y, rf.marbleVelocity.z);
|
||||
level.marble.omega.set(rf.marbleAngularVelocity.x, rf.marbleAngularVelocity.y, rf.marbleAngularVelocity.z);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue