undo mbp port

This commit is contained in:
RandomityGuy 2023-01-07 23:19:47 +05:30
parent 295901f951
commit 0523bb946b
5 changed files with 342 additions and 247 deletions

View file

@ -1294,6 +1294,11 @@ class Marble extends GameObject {
var a = retf[1]; var a = retf[1];
this.velocity = this.velocity.add(A.multiply(timeStep)); this.velocity = this.velocity.add(A.multiply(timeStep));
this.omega = this.omega.add(a.multiply(timeStep)); this.omega = this.omega.add(a.multiply(timeStep));
if (this.mode == Start) {
// Bruh...
this.velocity.y = 0;
this.velocity.x = 0;
}
stoppedPaths = this.velocityCancel(timeState.currentAttemptTime, timeStep, isCentered, true, stoppedPaths, pathedInteriors); stoppedPaths = this.velocityCancel(timeState.currentAttemptTime, timeStep, isCentered, true, stoppedPaths, pathedInteriors);
this._totalTime += timeStep; this._totalTime += timeStep;
if (contacts.length != 0) { if (contacts.length != 0) {
@ -1367,30 +1372,6 @@ class Marble extends GameObject {
} }
} }
var pos = this.getAbsPos().getPosition();
this.prevPos = pos.clone();
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 newPos = pos.add(this.velocity.multiply(timeStep));
newPos = nudgeToContacts(newPos, _radius);
var rot = this.getRotationQuat(); var rot = this.getRotationQuat();
var quat = new Quat(); var quat = new Quat();
quat.initRotation(omega.x * timeStep, omega.y * timeStep, omega.z * timeStep); quat.initRotation(omega.x * timeStep, omega.y * timeStep, omega.z * timeStep);

View file

@ -971,16 +971,11 @@ class MarbleWorld extends Scheduler {
if (timeTravelSound == null) { if (timeTravelSound == null) {
var ttsnd = ResourceLoader.getResource("data/sound/timetravelactive.wav", ResourceLoader.getAudio, this.soundResources); var ttsnd = ResourceLoader.getResource("data/sound/timetravelactive.wav", ResourceLoader.getAudio, this.soundResources);
timeTravelSound = AudioManager.playSound(ttsnd, null, true); timeTravelSound = AudioManager.playSound(ttsnd, null, true);
if (alarmSound != null)
alarmSound.pause = true;
} }
} else { } else {
if (timeTravelSound != null) { if (timeTravelSound != null) {
timeTravelSound.stop(); timeTravelSound.stop();
timeTravelSound = null; timeTravelSound = null;
if (alarmSound != null)
alarmSound.pause = false;
} }
if (this.timeState.currentAttemptTime >= 3.5) if (this.timeState.currentAttemptTime >= 3.5)
this.timeState.gameplayClock += dt; this.timeState.gameplayClock += dt;
@ -1063,8 +1058,6 @@ class MarbleWorld extends Scheduler {
val = Util.getKeyForButton(Settings.controlsSettings.powerup); val = Util.getKeyForButton(Settings.controlsSettings.powerup);
if (funcdata[1] == "freelook") if (funcdata[1] == "freelook")
val = Util.getKeyForButton(Settings.controlsSettings.freelook); val = Util.getKeyForButton(Settings.controlsSettings.freelook);
if (funcdata[1] == "useblast")
val = Util.getKeyForButton(Settings.controlsSettings.blast);
} }
start = val.length + pos; start = val.length + pos;
text = pre + val + post; text = pre + val + post;

View file

@ -1,5 +1,6 @@
package collision; package collision;
import h3d.Vector;
import h3d.col.Bounds; import h3d.col.Bounds;
interface IBVHObject { interface IBVHObject {
@ -17,9 +18,7 @@ class BVHNode<T:IBVHObject> {
var bounds:Bounds; var bounds:Bounds;
var object:T; var object:T;
public function new(bounds:Bounds) { public function new() {}
this.bounds = bounds.clone();
surfaceArea = this.bounds.xSize * this.bounds.ySize + this.bounds.xSize * this.bounds.zSize + this.bounds.ySize * this.bounds.zSize;
} }
class BVHTree<T:IBVHObject> { class BVHTree<T:IBVHObject> {
@ -39,17 +38,14 @@ class BVHNode<T:IBVHObject> {
return; return;
} }
public function split() { invalidNodes.push(node);
// Splitting first time }
// Calculate the centroids of all objects
var objs = objects.map(x -> {
x.generateBoundingBox();
return {obj: x, centroid: x.boundingBox.getCenter()};
}); });
for (node in invalidNodes) { for (node in invalidNodes) {
this.remove(node); this.remove(node);
this.add(node.object); this.add(node.object);
} }
}
public function add(entity:T) { public function add(entity:T) {
// Enlarged AABB // Enlarged AABB
@ -66,43 +62,90 @@ class BVHNode<T:IBVHObject> {
return newNode; return newNode;
} }
// Make the child nodes // Find the best sibling for the new leaf
var leftBounds = new Bounds(); var bestSibling = this.root;
var rightBounds = new Bounds(); var bestCostBox = this.root.bounds.clone();
for (o in leftObjs) bestCostBox.add(aabb);
leftBounds.add(o.boundingBox); var bestCost = bestCostBox.xSize * bestCostBox.ySize + bestCostBox.xSize * bestCostBox.zSize + bestCostBox.ySize * bestCostBox.zSize;
for (o in rightObjs) var q = [{p1: this.root, p2: 0.0}];
rightBounds.add(o.boundingBox);
left = new BVHNode(leftBounds);
right = new BVHNode(rightBounds);
left.objects = leftObjs;
right.objects = rightObjs;
this.objects = intersectObjs;
this.objectBounds = new Bounds();
for (o in intersectObjs)
this.objectBounds.add(o.boundingBox);
left.split(); while (q.length != 0) {
right.split(); var front = q.shift();
var current = front.p1;
var inheritedCost = front.p2;
var combined = current.bounds.clone();
combined.add(aabb);
var directCost = combined.xSize * combined.ySize + combined.xSize * combined.zSize + combined.ySize * combined.zSize;
var costForCurrent = directCost + inheritedCost;
if (costForCurrent < bestCost) {
bestCost = costForCurrent;
bestSibling = current;
} }
public function boundingSearch(searchbox:Bounds) { inheritedCost += directCost
if (this.bounds.containsBounds(searchbox) || this.bounds.collide(searchbox)) { - (current.bounds.xSize * current.bounds.ySize + current.bounds.xSize * current.bounds.zSize + current.bounds.ySize * current.bounds.zSize);
var intersects = [];
if (this.left != null && this.right != null) { var aabbCost = aabb.xSize * aabb.ySize + aabb.xSize * aabb.zSize + aabb.ySize * aabb.zSize;
intersects = intersects.concat(this.left.boundingSearch(searchbox)); var lowerBoundCost = aabbCost + inheritedCost;
intersects = intersects.concat(this.right.boundingSearch(searchbox)); if (lowerBoundCost < bestCost) {
} if (!current.isLeaf) {
if (this.objectBounds.collide(searchbox) || this.objectBounds.containsBounds(searchbox)) { if (current.child1 != null)
for (o in this.objects) { q.push({p1: current.child1, p2: inheritedCost});
if (o.boundingBox.containsBounds(searchbox) || o.boundingBox.collide(searchbox)) if (current.child2 != null)
intersects.push(o); q.push({p1: current.child2, p2: inheritedCost});
} }
} }
return intersects; }
// Create a new parent
var oldParent = bestSibling.parent;
var newParent = new BVHNode();
newParent.id = this.nodeId++;
newParent.parent = oldParent;
newParent.bounds = bestSibling.bounds.clone();
newParent.bounds.add(aabb);
newParent.isLeaf = false;
if (oldParent != null) {
if (oldParent.child1 == bestSibling) {
oldParent.child1 = newParent;
} else { } else {
return []; oldParent.child2 = newParent;
} }
newParent.child1 = bestSibling;
newParent.child2 = newNode;
bestSibling.parent = newParent;
newNode.parent = newParent;
} else {
newParent.child1 = bestSibling;
newParent.child2 = newNode;
bestSibling.parent = newParent;
newNode.parent = newParent;
this.root = newParent;
}
// Walk back up the tree refitting ancestors' AABB and applying rotations
var ancestor = newNode.parent;
while (ancestor != null) {
var child1 = ancestor.child1;
var child2 = ancestor.child2;
ancestor.bounds = new Bounds();
if (child1 != null)
ancestor.bounds.add(child1.bounds);
if (child2 != null)
ancestor.bounds.add(child2.bounds);
this.rotate(ancestor);
ancestor = ancestor.parent;
}
return newNode;
} }
function reset() { function reset() {
@ -144,10 +187,24 @@ class BVHNode<T:IBVHObject> {
} else { } else {
parent.parent.child2 = sibling; parent.parent.child2 = sibling;
} }
}
return intersects;
} else { } else {
return []; this.root = sibling;
sibling.parent = null;
}
var ancestor = sibling.parent;
while (ancestor != null) {
var child1 = ancestor.child1;
var child2 = ancestor.child2;
ancestor.bounds = child1.bounds.clone();
ancestor.bounds.add(child2.bounds);
ancestor = ancestor.parent;
}
} else {
if (this.root == node) {
this.root = null;
}
} }
} }
@ -158,29 +215,104 @@ class BVHNode<T:IBVHObject> {
var parent = node.parent; var parent = node.parent;
var sibling = parent.child1 == node ? parent.child2 : parent.child1; var sibling = parent.child1 == node ? parent.child2 : parent.child1;
var costDiffs = []; var costDiffs = [];
var nodeArea = node.bounds.xSize * node.bounds.ySize + node.bounds.zSize * node.bounds.ySize var nodeArea = node.bounds.xSize * node.bounds.ySize + node.bounds.zSize * node.bounds.ySize + node.bounds.xSize * node.bounds.zSize;
+ node.bounds.xSize * node.bounds.zSize;
class BVHTree { var ch1 = sibling.bounds.clone();
public var bounds:Bounds; ch1.add(node.child1.bounds);
costDiffs.push(ch1.xSize * ch1.ySize + ch1.zSize * ch1.ySize + ch1.xSize * ch1.zSize - nodeArea);
var ch2 = sibling.bounds.clone();
ch2.add(node.child2.bounds);
costDiffs.push(ch2.xSize * ch2.ySize + ch2.zSize * ch2.ySize + ch2.xSize * ch2.zSize - nodeArea);
var surfaces:Array<CollisionSurface> = []; if (!sibling.isLeaf) {
var siblingArea = sibling.bounds.xSize * sibling.bounds.ySize + sibling.bounds.zSize * sibling.bounds.ySize
var root:BVHNode; + sibling.bounds.xSize * sibling.bounds.zSize;
if (sibling.child1 != null) {
public function new(bounds:Bounds) { var ch3 = node.bounds.clone();
this.bounds = bounds.clone(); ch3.add(sibling.child1.bounds);
costDiffs.push(ch3.xSize * ch3.ySize + ch3.zSize * ch3.ySize + ch3.xSize * ch3.zSize - siblingArea);
}
if (sibling.child2 != null) {
var ch4 = node.bounds.clone();
ch4.add(sibling.child2.bounds);
costDiffs.push(ch4.xSize * ch4.ySize + ch4.zSize * ch4.ySize + ch4.xSize * ch4.zSize - siblingArea);
}
} }
public function insert(surf:CollisionSurface) { var bestDiffIndex = 0;
surfaces.push(surf); for (i in 1...costDiffs.length) {
if (costDiffs[i] < costDiffs[bestDiffIndex]) {
bestDiffIndex = i;
}
} }
public function build() { if (costDiffs[bestDiffIndex] < 0.0) {
root = new BVHNode(bounds); switch (bestDiffIndex) {
// Add all children case 0:
root.objects = this.surfaces; if (parent.child1 == sibling) {
root.split(); parent.child1 = node.child2;
} else {
parent.child2 = node.child2;
}
if (node.child2 != null) {
node.child2.parent = parent;
}
node.child2 = sibling;
sibling.parent = node;
node.bounds = sibling.bounds.clone();
if (node.child1 != null) {
node.bounds.add(node.child1.bounds);
}
case 1:
if (parent.child1 == sibling) {
parent.child1 = node.child1;
} else {
parent.child2 = node.child1;
}
if (node.child1 != null) {
node.child1.parent = parent;
}
node.child1 = sibling;
sibling.parent = node;
node.bounds = sibling.bounds.clone();
if (node.child2 != null) {
node.bounds.add(node.child2.bounds);
}
case 2:
if (parent.child1 == node) {
parent.child1 = sibling.child2;
} else {
parent.child2 = sibling.child2;
}
if (sibling.child2 != null) {
sibling.child2.parent = parent;
}
sibling.child2 = node;
node.parent = sibling;
sibling.bounds = node.bounds.clone();
if (sibling.child2 != null) {
sibling.bounds.add(sibling.child2.bounds);
}
case 3:
if (parent.child1 == node) {
parent.child1 = sibling.child1;
} else {
parent.child2 = sibling.child1;
}
if (sibling.child1 != null) {
sibling.child1.parent = parent;
}
sibling.child1 = node;
node.parent = sibling;
sibling.bounds = node.bounds.clone();
if (sibling.child1 != null) {
sibling.bounds.add(sibling.child1.bounds);
}
}
}
} }
public function boundingSearch(searchbox:Bounds) { public function boundingSearch(searchbox:Bounds) {

View file

@ -58,11 +58,11 @@ class CollisionEntity implements IOctreeObject implements IBVHObject {
// Generates the bvh // Generates the bvh
public function finalize() { public function finalize() {
this.generateBoundingBox(); this.generateBoundingBox();
this.bvh = new BVHTree(this.boundingBox); this.bvh = new BVHTree();
for (surface in this.surfaces) { for (surface in this.surfaces) {
this.bvh.insert(surface); this.bvh.add(surface);
} }
this.bvh.build(); // this.bvh.build();
} }
public function setTransform(transform:Matrix) { public function setTransform(transform:Matrix) {

View file

@ -9,7 +9,6 @@ import src.MarbleGame;
@:publicFields @:publicFields
class GuiImage extends GuiControl { class GuiImage extends GuiControl {
var bmp:Bitmap; var bmp:Bitmap;
var bmpFlow:Flow;
public var pressedAction:GuiControl->Void = null; public var pressedAction:GuiControl->Void = null;
@ -25,22 +24,15 @@ class GuiImage extends GuiControl {
// bmp.scaleY = renderRect.extent.y / bmp.tile.height; // bmp.scaleY = renderRect.extent.y / bmp.tile.height;
bmp.width = renderRect.extent.x; bmp.width = renderRect.extent.x;
bmp.height = renderRect.extent.y; bmp.height = renderRect.extent.y;
if (doClipping) { if (scene2d.contains(bmp)) {
bmpFlow.maxWidth = Std.int(hittestRect.extent.x); scene2d.removeChild(bmp); // Refresh "layer"
bmpFlow.maxHeight = Std.int(hittestRect.extent.y);
} }
if (scene2d.contains(obj)) { scene2d.addChild(bmp);
scene2d.removeChild(obj); // Refresh "layer"
}
scene2d.addChild(obj);
super.render(scene2d); super.render(scene2d);
} }
public override function dispose() { public override function dispose() {
super.dispose(); super.dispose();
if (this.doClipping) {
bmpFlow.remove();
} else
this.bmp.remove(); this.bmp.remove();
} }
@ -53,9 +45,6 @@ class GuiImage extends GuiControl {
public override function onRemove() { public override function onRemove() {
super.onRemove(); super.onRemove();
if (MarbleGame.canvas.scene2d.contains(bmpFlow)) {
MarbleGame.canvas.scene2d.removeChild(bmpFlow); // Refresh "layer"
}
if (MarbleGame.canvas.scene2d.contains(bmp)) { if (MarbleGame.canvas.scene2d.contains(bmp)) {
MarbleGame.canvas.scene2d.removeChild(bmp); // Refresh "layer" MarbleGame.canvas.scene2d.removeChild(bmp); // Refresh "layer"
} }