mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-10-30 08:11:25 +00:00
optimize heap
This commit is contained in:
parent
8024bbf2c4
commit
4bc6e0b8fb
7 changed files with 80 additions and 223 deletions
162
src/Marble.hx
162
src/Marble.hx
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue