optimize heap

This commit is contained in:
RandomityGuy 2023-10-02 13:56:47 +05:30
parent 8024bbf2c4
commit 4bc6e0b8fb
7 changed files with 80 additions and 223 deletions

View file

@ -863,9 +863,6 @@ class Marble extends GameObject {
testTriangles.push({
v: [v0, v, v2],
n: surfaceNormal,
edge: surf.edgeData != null ? surf.edgeData[Math.floor(i / 3)] : 0,
concavity: surface.edgeConcavities != null ? surface.edgeConcavities.slice(Math.floor(i / 3),
Math.floor(i / 3) + 3) : [false, false, false],
});
// Time until collision with the plane
@ -1110,166 +1107,9 @@ class Marble extends GameObject {
};
}
function getIntersectionTime(dt:Float, velocity:Vector) {
var searchbox = new Bounds();
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 foundObjs = this.level.collisionWorld.boundingSearch(searchbox);
// var foundObjs = this.contactEntities;
function toDifPoint(vec:Vector) {
return new Point3F(vec.x, vec.y, vec.z);
}
var maxIntersectDist = 0.0;
var contactNorm = new Vector();
var contactPt = null;
var traceinfo = new TraceInfo();
traceinfo.resetTrace(position.clone(), position.add(velocity.multiply(dt)), this._radius);
var foundTriangles = [];
for (obj in foundObjs) {
var radius = _radius;
var invMatrix = @:privateAccess obj.invTransform;
if (obj.go is PathedInterior)
invMatrix = obj.transform.getInverse();
var localpos = position.clone();
localpos.transform(invMatrix);
var relLocalVel = velocity.sub(obj.velocity);
relLocalVel.transform3x3(invMatrix);
var boundThing = new Bounds();
boundThing.addSpherePos(localpos.x, localpos.y, localpos.z, radius * 1.1);
boundThing.addSpherePos(localpos.x + relLocalVel.x * dt * 2, localpos.y + relLocalVel.y * dt * 2, localpos.z + relLocalVel.z * dt * 2,
radius * 1.1);
var surfaces = obj.bvh == null ? obj.octree.boundingSearch(boundThing).map(x -> cast x) : obj.bvh.boundingSearch(boundThing);
var tform = obj.transform.clone();
var relVelocity = velocity.sub(obj.velocity);
// tform.setPosition(tform.getPosition().add(velDir.multiply(_radius)));
// tform.setPosition(tform.getPosition().add(obj.velocity.multiply(dt)));
var contacts = [];
for (surf in surfaces) {
var surface:CollisionSurface = cast surf;
var i = 0;
while (i < surface.indices.length) {
var v0 = surface.points[surface.indices[i]].transformed(tform);
var v = surface.points[surface.indices[i + 1]].transformed(tform);
var v2 = surface.points[surface.indices[i + 2]].transformed(tform);
var surfacenormal = surface.normals[surface.indices[i]].transformed3x3(obj.transform);
foundTriangles.push(v0);
foundTriangles.push(v);
foundTriangles.push(v2);
// foundTriangles.push(surfacenormal);
traceinfo.resetTrace(position.clone(), position.add(relVelocity.multiply(dt)), this._radius);
traceinfo.traceSphereTriangle(v2, v, v0);
if (traceinfo.collision) {
var tcolpos = traceinfo.getTraceEndpoint();
var closest = Collision.ClosestPtPointTriangle(tcolpos, _radius, v2.add(obj.velocity.multiply(traceinfo.t)),
v.add(obj.velocity.multiply(traceinfo.t)), v0.add(obj.velocity.multiply(traceinfo.t)), surfacenormal);
if (closest != null) {
var dist = tcolpos.sub(closest);
var distlen = dist.length();
if (maxIntersectDist < distlen && distlen < _radius) {
maxIntersectDist = distlen;
contactNorm = dist.normalized();
contactPt = closest;
}
}
}
// var closest = Collision.IntersectTriangleCapsule(position, position.add(relVelocity.multiply(dt)), _radius, v0, v, v2, surfacenormal);
// var closest = Collision.IntersectTriangleSphere(v0, v, v2, surfacenormal, position, radius);
// if (closest != null) {
// This is some ballpark approximation, very bruh
// var radiusDir = relVelocity.normalized().multiply(radius);
// var t = (-position.add(radiusDir).dot(surfacenormal) + v0.dot(surfacenormal)) / relVelocity.dot(surfacenormal);
// var pt = position.add(radiusDir).add(relVelocity.multiply(t));
// if (Collision.PointInTriangle(pt, v0, v, v2)) {
// if (t > 0 && t < intersectT) {
// intersectT = t;
// }
// }
// }
i += 3;
}
}
}
if (maxIntersectDist > 0) {
var finalPos = contactPt.add(contactNorm.multiply(_radius));
// Nudge the finalPos to the surface of the object
var chull = new ConvexHull(foundTriangles);
var sph = new collision.gjk.Sphere();
sph.position = finalPos;
sph.radius = _radius;
var pt = GJK.gjk(sph, chull).epa;
while (pt != null) {
if (pt.lengthSq() < 0.0001) {
break;
}
trace('Separating Vector Len: ${pt.length()}');
finalPos = finalPos.sub(pt);
sph.position = finalPos;
pt = GJK.gjk(sph, chull).epa;
}
// if (pt != null) {
// finalPos = finalPos.sub(pt);
// sph.position = finalPos;
// pt = GJK.gjk(sph, chull);
// if (pt != null) {
// trace("?????");
// }
// trace('Separating Vector Len: ${pt.length()}');
// }
// var colpos = finalPos;
// var msh = new h3d.prim.Sphere();
// var prim = new h3d.scene.Mesh(msh);
// msh.addNormals();
// prim.setTransform(Matrix.T(colpos.x, colpos.y, colpos.z));
// prim.setScale(this._radius);
// this.level.scene.addChild(prim);
var intersectT = finalPos.sub(position).length() / velocity.length();
return intersectT;
}
return 10e8;
}
function nudgeToContacts(position:Vector, radius:Float, foundContacts:Array<{
v:Array<Vector>,
n:Vector,
edge:Int,
concavity:Array<Bool>
n:Vector
}>) {
var it = 0;
var concernedContacts = foundContacts; // PathedInteriors have their own nudge logic

View file

@ -1275,8 +1275,8 @@ class MarbleWorld extends Scheduler {
for (surface in chull.surfaces) {
var i = 0;
while (i < surface.indices.length) {
var surfaceN = surface.normals[surface.indices[i]].transformed3x3(chullinvT);
var v1 = surface.points[surface.indices[i]].transformed(chull.transform);
var surfaceN = surface.getNormal(surface.indices[i]).transformed3x3(chullinvT);
var v1 = surface.getPoint(surface.indices[i]).transformed(chull.transform);
var surfaceD = -surfaceN.dot(v1);
if (surfaceN.dot(padUp.multiply(-10)) < 0) {
@ -1284,8 +1284,8 @@ class MarbleWorld extends Scheduler {
if (dist >= 0 && dist < 5) {
var intersectT = -(checkBoundsCenter.dot(surfaceN.toPoint()) + surfaceD) / (padUp.dot(surfaceN));
var intersectP = checkBoundsCenter.add(padUp.multiply(intersectT).toPoint()).toVector();
if (Collision.PointInTriangle(intersectP, v1, surface.points[surface.indices[i + 1]].transformed(chull.transform),
surface.points[surface.indices[i + 2]].transformed(chull.transform))) {
if (Collision.PointInTriangle(intersectP, v1, surface.getPoint(surface.indices[i + 1]).transformed(chull.transform),
surface.getPoint(surface.indices[i + 2]).transformed(chull.transform))) {
found = true;
break;
}

View file

@ -144,7 +144,7 @@ class Collision {
return res;
}
public static function TriangleSphereIntersection(A:Vector, B:Vector, C:Vector, N:Vector, P:Vector, r:Float, edgeData:Int, edgeConcavities:Array<Bool>) {
public static function TriangleSphereIntersection(A:Vector, B:Vector, C:Vector, N:Vector, P:Vector, r:Float) {
var res:ITSResult = {
result: false,
point: null,
@ -356,7 +356,7 @@ class Collision {
return res;
}
public static function PointInTriangle(point:Vector, v0:Vector, v1:Vector, v2:Vector):Bool {
public static inline function PointInTriangle(point:Vector, v0:Vector, v1:Vector, v2:Vector):Bool {
var u = v1.sub(v0);
var v = v2.sub(v0);
var w = point.sub(v0);

View file

@ -38,8 +38,6 @@ class CollisionEntity implements IOctreeObject implements IBVHObject {
public var userData:Int;
public var fastTransform:Bool = false;
public var difEdgeMap:Map<Int, dif.Edge>;
var _transformKey:Int = 0;
var _dbgEntity:h3d.scene.Mesh;
@ -216,28 +214,9 @@ class CollisionEntity implements IOctreeObject implements IBVHObject {
var v = verts.v2;
var v2 = verts.v3;
// var e1e2 = hashEdge(surface.originalIndices[i], surface.originalIndices[i + 1]);
// var e2e3 = hashEdge(surface.originalIndices[i + 1], surface.originalIndices[i + 2]);
// var e1e3 = hashEdge(surface.originalIndices[i], surface.originalIndices[i + 3]);
// var edgeData = 0;
// if (this.difEdgeMap.exists(e1e2)) {
// edgeData |= 1;
// }
// if (this.difEdgeMap.exists(e2e3)) {
// edgeData |= 2;
// }
// if (this.difEdgeMap.exists(e1e3)) {
// edgeData |= 4;
// }
var edgeData = surface.edgeData[Math.floor(i / 3)];
var edgeConcavities = surface.edgeConcavities.slice(Math.floor(i / 3), Math.floor(i / 3) + 3);
var surfacenormal = verts.n; // surface.normals[surface.indices[i]].transformed3x3(transform).normalized();
var res = Collision.TriangleSphereIntersection(v0, v, v2, surfacenormal, position, radius, edgeData, edgeConcavities);
var res = Collision.TriangleSphereIntersection(v0, v, v2, surfacenormal, position, radius);
var closest = res.point;
// var closest = Collision.ClosestPtPointTriangle(position, radius, v0, v, v2, surfacenormal);
if (closest != null) {

View file

@ -60,7 +60,9 @@ class CollisionHull extends CollisionEntity {
super.addSurface(surface);
if (hull == null)
hull = new ConvexHull([]);
hull.vertices = hull.vertices.concat(surface.points);
for (i in 0...(Std.int(surface.points.length / 3))) {
hull.vertices.push(new Vector(surface.points[i * 3], surface.points[i * 3 + 1], surface.points[i * 3 + 2]));
}
if (surface.points.length != 0) {
this.force = surface.force;
this.friction = surface.friction;

View file

@ -10,20 +10,18 @@ class CollisionSurface implements IOctreeObject implements IBVHObject {
public var priority:Int;
public var position:Int;
public var boundingBox:Bounds;
public var points:Array<Vector>;
public var normals:Array<Vector>;
public var points:Array<Float>;
public var normals:Array<Float>;
public var indices:Array<Int>;
public var friction:Float = 1;
public var restitution:Float = 1;
public var force:Float = 0;
public var edgeData:Array<Int>;
public var edgeConcavities:Array<Bool>;
public var originalIndices:Array<Int>;
public var originalSurfaceIndex:Int;
public var transformKeys:Array<Int>;
var _transformedPoints:Array<Vector>;
var _transformedNormals:Array<Vector>;
var _transformedPoints:Array<Float>;
var _transformedNormals:Array<Float>;
public function new() {}
@ -33,15 +31,21 @@ class CollisionSurface implements IOctreeObject implements IBVHObject {
public function generateNormals() {
var i = 0;
normals = [for (n in points) null];
normals = [for (n in points) 0.0];
while (i < indices.length) {
var p1 = points[indices[i]].clone();
var p2 = points[indices[i + 1]].clone();
var p3 = points[indices[i + 2]].clone();
var p1 = getPoint(indices[i]);
var p2 = getPoint(indices[i + 1]);
var p3 = getPoint(indices[i + 2]);
var n = p2.sub(p1).cross(p3.sub(p1)).normalized().multiply(-1);
normals[indices[i]] = n;
normals[indices[i + 1]] = n;
normals[indices[i + 2]] = n;
normals[indices[i] * 3] = n.x;
normals[indices[i] * 3 + 1] = n.y;
normals[indices[i] * 3 + 2] = n.z;
normals[indices[i + 1] * 3] = n.x;
normals[indices[i + 1] * 3 + 1] = n.y;
normals[indices[i + 1] * 3 + 2] = n.z;
normals[indices[i + 2] * 3] = n.x;
normals[indices[i + 2] * 3 + 1] = n.y;
normals[indices[i + 2] * 3 + 2] = n.z;
i += 3;
}
}
@ -55,7 +59,8 @@ class CollisionSurface implements IOctreeObject implements IBVHObject {
boundingBox.yMax = -10e8;
boundingBox.zMax = -10e8;
for (point in points) {
for (i in 0...Std.int(points.length / 3)) {
var point = getPoint(i);
if (point.x > boundingBox.xMax) {
boundingBox.xMax = point.x;
}
@ -82,14 +87,34 @@ class CollisionSurface implements IOctreeObject implements IBVHObject {
this.priority = priority;
}
inline public function getPoint(idx:Int) {
return new Vector(points[idx * 3], points[idx * 3 + 1], points[idx * 3 + 2]);
}
inline public function getNormal(idx:Int) {
return new Vector(normals[idx * 3], normals[idx * 3 + 1], normals[idx * 3 + 2]);
}
inline public function addPoint(x:Float, y:Float, z:Float) {
points.push(x);
points.push(y);
points.push(z);
}
inline public function addNormal(x:Float, y:Float, z:Float) {
normals.push(x);
normals.push(y);
normals.push(z);
}
public function rayCast(rayOrigin:Vector, rayDirection:Vector):Array<RayIntersectionData> {
var intersections = [];
var i = 0;
while (i < indices.length) {
var p1 = points[indices[i]].clone();
var p2 = points[indices[i + 1]].clone();
var p3 = points[indices[i + 2]].clone();
var n = normals[indices[i]].clone();
var p1 = getPoint(indices[i]);
var p2 = getPoint(indices[i + 1]);
var p3 = getPoint(indices[i + 2]);
var n = getNormal(indices[i]);
var d = -p1.dot(n);
var t = -(rayOrigin.dot(n) + d) / (rayDirection.dot(n));
@ -107,7 +132,8 @@ class CollisionSurface implements IOctreeObject implements IBVHObject {
var furthestDistance:Float = Math.NEGATIVE_INFINITY;
var furthestVertex:Vector = new Vector();
for (v in points) {
for (i in 0...Std.int(points.length / 3)) {
var v = getPoint(i);
var v2 = v.transformed(transform);
var distance:Float = v2.dot(direction);
if (distance > furthestDistance) {
@ -132,23 +158,35 @@ class CollisionSurface implements IOctreeObject implements IBVHObject {
var p2 = indices[idx + 1];
var p3 = indices[idx + 2];
if (transformKeys[p1] != key) {
_transformedPoints[p1] = points[p1].transformed(tform);
_transformedNormals[p1] = normals[p1].transformed3x3(invtform).normalized();
var pt = getPoint(p1).transformed(tform);
_transformedPoints[p1 * 3] = pt.x;
_transformedPoints[p1 * 3 + 1] = pt.y;
_transformedPoints[p1 * 3 + 2] = pt.z;
var pn = getNormal(p1).transformed3x3(invtform).normalized();
_transformedNormals[p1 * 3] = pn.x;
_transformedNormals[p1 * 3 + 1] = pn.y;
_transformedNormals[p1 * 3 + 2] = pn.z;
transformKeys[p1] = key;
}
if (transformKeys[p2] != key) {
_transformedPoints[p2] = points[p2].transformed(tform);
var pt = getPoint(p2).transformed(tform);
_transformedPoints[p2 * 3] = pt.x;
_transformedPoints[p2 * 3 + 1] = pt.y;
_transformedPoints[p2 * 3 + 2] = pt.z;
transformKeys[p2] = key;
}
if (transformKeys[p3] != key) {
_transformedPoints[p3] = points[p3].transformed(tform);
var pt = getPoint(p3).transformed(tform);
_transformedPoints[p3 * 3] = pt.x;
_transformedPoints[p3 * 3 + 1] = pt.y;
_transformedPoints[p3 * 3 + 2] = pt.z;
transformKeys[p3] = key;
}
return {
v1: _transformedPoints[p1],
v2: _transformedPoints[p2],
v3: _transformedPoints[p3],
n: _transformedNormals[p1]
v1: new Vector(_transformedPoints[p1 * 3], _transformedPoints[p1 * 3 + 1], _transformedPoints[p1 * 3 + 2]),
v2: new Vector(_transformedPoints[p2 * 3], _transformedPoints[p2 * 3 + 1], _transformedPoints[p2 * 3 + 2]),
v3: new Vector(_transformedPoints[p3 * 3], _transformedPoints[p3 * 3 + 1], _transformedPoints[p3 * 3 + 2]),
n: new Vector(_transformedNormals[p1 * 3], _transformedNormals[p1 * 3 + 1], _transformedNormals[p1 * 3 + 2])
};
}
@ -158,8 +196,6 @@ class CollisionSurface implements IOctreeObject implements IBVHObject {
indices = null;
_transformedPoints = null;
_transformedNormals = null;
edgeData = null;
edgeConcavities = null;
originalIndices = null;
}
}

View file

@ -40,9 +40,9 @@ class RewindFrame {
timeState:TimeState
};
public function new() {}
inline public function new() {}
public function clone() {
public inline function clone() {
var c = new RewindFrame();
c.timeState = timeState.clone();
c.marblePosition = marblePosition.clone();
@ -85,7 +85,7 @@ class RewindFrame {
return c;
}
public function serialize(rm:RewindManager) {
public inline function serialize(rm:RewindManager) {
var bb = new BytesOutput();
var framesize = 0;
framesize += 32; // timeState
@ -231,7 +231,7 @@ class RewindFrame {
return bb.getBytes();
}
public function deserialize(rm:RewindManager, br:haxe.io.BytesInput) {
public inline function deserialize(rm:RewindManager, br:haxe.io.BytesInput) {
marblePosition = new Vector();
marbleOrientation = new Quat();
marbleVelocity = new Vector();