optimize heap

This commit is contained in:
RandomityGuy 2023-10-02 13:56:47 +05:30
parent a9b9ed1a98
commit 63781f1532
10 changed files with 92 additions and 288 deletions

View file

@ -62,12 +62,16 @@ class Debug {
}
public static function drawTriangle(p1:Vector, p2:Vector, p3:Vector) {
if (!drawBounds)
return;
_triangles.push(p3.toPoint());
_triangles.push(p2.toPoint());
_triangles.push(p1.toPoint());
}
public static function drawSphere(centre:Vector, radius:Float) {
if (!drawBounds)
return;
_spheres.push({position: centre.clone(), radius: radius});
}
}

View file

@ -342,8 +342,6 @@ class DifBuilder {
colliderSurface.normals = [];
colliderSurface.indices = [];
colliderSurface.transformKeys = [];
colliderSurface.edgeData = [];
colliderSurface.edgeConcavities = [];
colliderSurface.originalIndices = [];
colliderSurface.originalSurfaceIndex = surfaceindex;
for (k in (surface.windingStart + 2)...(surface.windingStart + surface.windingCount)) {
@ -414,12 +412,12 @@ class DifBuilder {
colliderSurface.restitution = minfo.restitution;
colliderSurface.force = minfo.force != null ? minfo.force : 0;
}
colliderSurface.points.push(new Vector(-p1.x, p1.y, p1.z));
colliderSurface.points.push(new Vector(-p2.x, p2.y, p2.z));
colliderSurface.points.push(new Vector(-p3.x, p3.y, p3.z));
colliderSurface.normals.push(new Vector(-normal.x, normal.y, normal.z));
colliderSurface.normals.push(new Vector(-normal.x, normal.y, normal.z));
colliderSurface.normals.push(new Vector(-normal.x, normal.y, normal.z));
colliderSurface.addPoint(-p1.x, p1.y, p1.z);
colliderSurface.addPoint(-p2.x, p2.y, p2.z);
colliderSurface.addPoint(-p3.x, p3.y, p3.z);
colliderSurface.addNormal(-normal.x, normal.y, normal.z);
colliderSurface.addNormal(-normal.x, normal.y, normal.z);
colliderSurface.addNormal(-normal.x, normal.y, normal.z);
colliderSurface.indices.push(colliderSurface.indices.length);
colliderSurface.indices.push(colliderSurface.indices.length);
colliderSurface.indices.push(colliderSurface.indices.length);
@ -565,49 +563,6 @@ class DifBuilder {
return vec;
}
for (colliderSurface in colliderSurfaces) {
var i = 0;
while (i < colliderSurface.indices.length) {
var e1e2 = hashEdge(colliderSurface.originalIndices[i], colliderSurface.originalIndices[i + 1]);
var e2e3 = hashEdge(colliderSurface.originalIndices[i + 1], colliderSurface.originalIndices[i + 2]);
var e1e3 = hashEdge(colliderSurface.originalIndices[i], colliderSurface.originalIndices[i + 2]);
var edgeData = 0;
if (difEdges.exists(e1e2)) {
// if (getEdgeDot(difEdges[e1e2]) < Math.cos(Math.PI / 12)) {
edgeData |= 1;
// }
colliderSurface.edgeConcavities.push(getEdgeConcavity(difEdges[e1e2]));
// colliderSurface.edgeNormals.push(getEdgeNormal(difEdges[e1e2]));
} else {
colliderSurface.edgeConcavities.push(false);
// colliderSurface.edgeNormals.push(new Vector(0, 0, 0));
}
if (difEdges.exists(e2e3)) {
// if (getEdgeDot(difEdges[e2e3]) < Math.cos(Math.PI / 12)) {
edgeData |= 2;
// }
colliderSurface.edgeConcavities.push(getEdgeConcavity(difEdges[e2e3]));
// colliderSurface.edgeNormals.push(getEdgeNormal(difEdges[e2e3]));
// colliderSurface.edgeDots.push(dot);
} else {
colliderSurface.edgeConcavities.push(false);
// colliderSurface.edgeNormals.push(new Vector(0, 0, 0));
}
if (difEdges.exists(e1e3)) {
// if (getEdgeDot(difEdges[e1e3]) < Math.cos(Math.PI / 12)) {
edgeData |= 4;
// }
colliderSurface.edgeConcavities.push(getEdgeConcavity(difEdges[e1e3]));
// colliderSurface.edgeNormals.push(getEdgeNormal(difEdges[e1e3]));
// colliderSurface.edgeDots.push(dot);
} else {
colliderSurface.edgeConcavities.push(false);
// colliderSurface.edgeNormals.push(new Vector(0, 0, 0));
}
colliderSurface.edgeData.push(edgeData);
i += 3;
}
}
for (vtex => buckets in vertexBuckets) {
for (i in 0...buckets.length) {
var bucket = buckets[i];
@ -635,7 +590,6 @@ class DifBuilder {
mats.set(value.texture, [value]);
}
}
collider.difEdgeMap = difEdges;
collider.finalize();
itr.collider = collider;
function canFindTex(tex:String) {

View file

@ -545,8 +545,6 @@ class DtsObject extends GameObject {
hs.normals = [];
hs.indices = [];
hs.transformKeys = [];
hs.edgeConcavities = [];
hs.edgeData = [];
var material = this.dts.matNames[primitive.matIndex & TSDrawPrimitive.MaterialMask];
if (dtsMaterials.exists(material) && !this.isTSStatic) {
@ -570,11 +568,11 @@ class DtsObject extends GameObject {
for (index in [i1, i2, i3]) {
var vertex = vertices[index];
hs.points.push(new Vector(vertex.x, vertex.y, vertex.z));
hs.addPoint(vertex.x, vertex.y, vertex.z);
hs.transformKeys.push(0);
var normal = vertexNormals[index];
hs.normals.push(new Vector(normal.x, normal.y, normal.z));
hs.addNormal(normal.x, normal.y, normal.z);
}
hs.indices.push(hs.indices.length);
@ -590,15 +588,6 @@ class DtsObject extends GameObject {
// chull.finalize();
// hulls.push(chull);
}
for (colliderSurface in ent.surfaces) {
var i = 0;
while (i < colliderSurface.indices.length) {
var edgeData = 0;
colliderSurface.edgeConcavities.push(false);
colliderSurface.edgeData.push(edgeData);
i += 3;
}
}
ent.generateBoundingBox();
ent.finalize();
return hulls;

View file

@ -1071,9 +1071,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
@ -1317,166 +1314,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

@ -1471,8 +1471,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) {
@ -1480,8 +1480,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

@ -39,8 +39,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;
@ -205,28 +203,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

@ -51,9 +51,9 @@ class RewindFrame {
checkpointBlast:Float
};
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();
@ -108,7 +108,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
@ -254,7 +254,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();