mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2026-04-27 21:21:41 +00:00
slightly faster raycasts
This commit is contained in:
parent
82ceb35251
commit
6f0b5857e4
11 changed files with 38 additions and 22 deletions
|
|
@ -6,7 +6,7 @@ import h3d.col.Bounds;
|
||||||
interface IBVHObject {
|
interface IBVHObject {
|
||||||
var boundingBox:Bounds;
|
var boundingBox:Bounds;
|
||||||
var key:Int;
|
var key:Int;
|
||||||
function rayCast(rayOrigin:Vector, rayDirection:Vector, results:Array<octree.IOctreeObject.RayIntersectionData>):Void;
|
function rayCast(rayOrigin:Vector, rayDirection:Vector, results:Array<octree.IOctreeObject.RayIntersectionData>, bestT:Float):Float;
|
||||||
}
|
}
|
||||||
|
|
||||||
@:generic
|
@:generic
|
||||||
|
|
@ -463,7 +463,7 @@ class BVHTree<T:IBVHObject> {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rayCast(origin:Vector, direction:Vector) {
|
public function rayCast(origin:Vector, direction:Vector, bestT:Float) {
|
||||||
var res = [];
|
var res = [];
|
||||||
if (this.root == null)
|
if (this.root == null)
|
||||||
return res;
|
return res;
|
||||||
|
|
@ -476,7 +476,7 @@ class BVHTree<T:IBVHObject> {
|
||||||
var currentnode = this.nodes[current];
|
var currentnode = this.nodes[current];
|
||||||
if (currentnode.collideRay(ray)) {
|
if (currentnode.collideRay(ray)) {
|
||||||
if (currentnode.isLeaf) {
|
if (currentnode.isLeaf) {
|
||||||
currentnode.object.rayCast(origin, direction, res);
|
bestT = currentnode.object.rayCast(origin, direction, res, bestT);
|
||||||
} else {
|
} else {
|
||||||
if (currentnode.child1 != -1)
|
if (currentnode.child1 != -1)
|
||||||
q.push(currentnode.child1);
|
q.push(currentnode.child1);
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,9 @@ class BoxCollisionEntity extends CollisionEntity implements IBVHObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function rayCast(rayOrigin:Vector, rayDirection:Vector, results:Array<octree.IOctreeObject.RayIntersectionData>) {
|
public override function rayCast(rayOrigin:Vector, rayDirection:Vector, results:Array<octree.IOctreeObject.RayIntersectionData>, bestT:Float) {
|
||||||
// TEMP cause bruh
|
// TEMP cause bruh
|
||||||
|
return Math.POSITIVE_INFINITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState) {
|
public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState) {
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ class CollisionEntity implements IOctreeObject implements IBVHObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rayCast(rayOrigin:Vector, rayDirection:Vector, results:Array<RayIntersectionData>) {
|
public function rayCast(rayOrigin:Vector, rayDirection:Vector, results:Array<RayIntersectionData>, bestT:Float) {
|
||||||
var invMatrix = invTransform;
|
var invMatrix = invTransform;
|
||||||
var invTPos = invMatrix.clone();
|
var invTPos = invMatrix.clone();
|
||||||
invTPos.transpose();
|
invTPos.transpose();
|
||||||
|
|
@ -159,13 +159,17 @@ class CollisionEntity implements IOctreeObject implements IBVHObject {
|
||||||
// }
|
// }
|
||||||
// return intersections; // iData;
|
// return intersections; // iData;
|
||||||
// } else {
|
// } else {
|
||||||
var intersections = grid.rayCast(rStart, rDir); // this.bvh.rayCast(rStart, rDir);
|
var intersections = grid.rayCast(rStart, rDir, bestT); // this.bvh.rayCast(rStart, rDir);
|
||||||
for (i in intersections) {
|
for (i in intersections) {
|
||||||
i.point.transform(transform);
|
i.point.transform(transform);
|
||||||
i.normal.transform3x3(invTPos);
|
i.normal.transform3x3(invTPos);
|
||||||
i.normal.normalize();
|
i.normal.normalize();
|
||||||
results.push(i);
|
if (i.t < bestT) {
|
||||||
|
bestT = i.t;
|
||||||
|
results.push(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return bestT;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ class CollisionSurface implements IOctreeObject implements IBVHObject {
|
||||||
normals.push(z);
|
normals.push(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rayCast(rayOrigin:Vector, rayDirection:Vector, intersections:Array<RayIntersectionData>) {
|
public function rayCast(rayOrigin:Vector, rayDirection:Vector, intersections:Array<RayIntersectionData>, bestT:Float) {
|
||||||
var i = 0;
|
var i = 0;
|
||||||
while (i < indices.length) {
|
while (i < indices.length) {
|
||||||
var p1 = getPoint(indices[i]);
|
var p1 = getPoint(indices[i]);
|
||||||
|
|
@ -152,10 +152,19 @@ class CollisionSurface implements IOctreeObject implements IBVHObject {
|
||||||
var ip = rayOrigin.add(rayDirection.multiply(t));
|
var ip = rayOrigin.add(rayDirection.multiply(t));
|
||||||
ip.w = 1;
|
ip.w = 1;
|
||||||
if (t >= 0 && Collision.PointInTriangle(ip, p1, p2, p3)) {
|
if (t >= 0 && Collision.PointInTriangle(ip, p1, p2, p3)) {
|
||||||
intersections.push({point: ip, normal: n, object: cast this});
|
if (t < bestT) {
|
||||||
|
bestT = t;
|
||||||
|
intersections.push({
|
||||||
|
point: ip,
|
||||||
|
normal: n,
|
||||||
|
object: cast this,
|
||||||
|
t: t
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
i += 3;
|
i += 3;
|
||||||
}
|
}
|
||||||
|
return bestT;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function support(direction:Vector, transform:Matrix) {
|
public function support(direction:Vector, transform:Matrix) {
|
||||||
|
|
|
||||||
|
|
@ -139,12 +139,12 @@ class CollisionWorld {
|
||||||
var results = [];
|
var results = [];
|
||||||
for (obj in objs) {
|
for (obj in objs) {
|
||||||
var oo = cast(obj, CollisionEntity);
|
var oo = cast(obj, CollisionEntity);
|
||||||
oo.rayCast(rayStart, rayDirection, results);
|
oo.rayCast(rayStart, rayDirection, results, rayLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (obj in dynObjs) {
|
for (obj in dynObjs) {
|
||||||
var oo = cast(obj, CollisionEntity);
|
var oo = cast(obj, CollisionEntity);
|
||||||
oo.rayCast(rayStart, rayDirection, results);
|
oo.rayCast(rayStart, rayDirection, results, rayLength);
|
||||||
}
|
}
|
||||||
// results = results.concat(this.staticWorld.rayCast(rayStart, rayDirection));
|
// results = results.concat(this.staticWorld.rayCast(rayStart, rayDirection));
|
||||||
return results;
|
return results;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ class Grid {
|
||||||
|
|
||||||
public var cellSize:Vector; // The dimensions of one cell
|
public var cellSize:Vector; // The dimensions of one cell
|
||||||
|
|
||||||
static var CELL_SIZE = 16;
|
static var CELL_SIZE = 24;
|
||||||
|
|
||||||
public var CELL_DIV = new Vector(CELL_SIZE, CELL_SIZE); // split the bounds into cells of dimensions 1/16th of the corresponding dimensions of the bounds
|
public var CELL_DIV = new Vector(CELL_SIZE, CELL_SIZE); // split the bounds into cells of dimensions 1/16th of the corresponding dimensions of the bounds
|
||||||
|
|
||||||
|
|
@ -124,7 +124,7 @@ class Grid {
|
||||||
return elegantPair(elegantPair(x, y), z);
|
return elegantPair(elegantPair(x, y), z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rayCast(origin:Vector, direction:Vector) {
|
public function rayCast(origin:Vector, direction:Vector, bestT:Float) {
|
||||||
var cell = origin.sub(this.bounds.getMin().toVector());
|
var cell = origin.sub(this.bounds.getMin().toVector());
|
||||||
cell.x /= this.cellSize.x;
|
cell.x /= this.cellSize.x;
|
||||||
cell.y /= this.cellSize.y;
|
cell.y /= this.cellSize.y;
|
||||||
|
|
@ -175,7 +175,7 @@ class Grid {
|
||||||
if (surf.key == searchKey)
|
if (surf.key == searchKey)
|
||||||
continue;
|
continue;
|
||||||
surf.key = searchKey;
|
surf.key = searchKey;
|
||||||
surf.rayCast(origin, direction, results);
|
bestT = surf.rayCast(origin, direction, results, bestT);
|
||||||
}
|
}
|
||||||
if (tmax.x < tmax.y) {
|
if (tmax.x < tmax.y) {
|
||||||
X = X + stepX;
|
X = X + stepX;
|
||||||
|
|
|
||||||
|
|
@ -69,8 +69,9 @@ class SphereCollisionEntity extends CollisionEntity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function rayCast(rayOrigin:Vector, rayDirection:Vector, results:Array<octree.IOctreeObject.RayIntersectionData>) {
|
public override function rayCast(rayOrigin:Vector, rayDirection:Vector, results:Array<octree.IOctreeObject.RayIntersectionData>, bestT:Float) {
|
||||||
// TEMP cause bruh
|
// TEMP cause bruh
|
||||||
|
return Math.POSITIVE_INFINITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState) {
|
public override function sphereIntersection(collisionEntity:SphereCollisionEntity, timeState:TimeState) {
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ class GemSpawnPoint implements IOctreeObject {
|
||||||
this.priority = priority;
|
this.priority = priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function rayCast(rayOrigin:Vector, rayDirection:Vector, resultSet:Array<RayIntersectionData>) {
|
public function rayCast(rayOrigin:Vector, rayDirection:Vector, resultSet:Array<RayIntersectionData>, bestT:Float):Float {
|
||||||
throw new haxe.exceptions.NotImplementedException(); // Not applicable
|
throw new haxe.exceptions.NotImplementedException(); // Not applicable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,10 @@ class RayIntersectionData {
|
||||||
var point:Vector;
|
var point:Vector;
|
||||||
var normal:Vector;
|
var normal:Vector;
|
||||||
var object:IOctreeObject;
|
var object:IOctreeObject;
|
||||||
|
var t:Float;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IOctreeObject extends IOctreeElement {
|
interface IOctreeObject extends IOctreeElement {
|
||||||
var boundingBox:Bounds;
|
var boundingBox:Bounds;
|
||||||
function rayCast(rayOrigin:Vector, rayDirection:Vector, resultSet:Array<RayIntersectionData>):Void;
|
function rayCast(rayOrigin:Vector, rayDirection:Vector, resultSet:Array<RayIntersectionData>, bestT:Float):Float;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -153,9 +153,9 @@ class Octree {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a list of all objects that intersect with the given ray, sorted by distance. */
|
/** Returns a list of all objects that intersect with the given ray, sorted by distance. */
|
||||||
public function raycast(rayOrigin:Vector, rayDirection:Vector) {
|
public function raycast(rayOrigin:Vector, rayDirection:Vector, bestT:Float) {
|
||||||
var intersections:Array<OctreeIntersection> = [];
|
var intersections:Array<OctreeIntersection> = [];
|
||||||
this.root.raycast(rayOrigin, rayDirection, intersections);
|
this.root.raycast(rayOrigin, rayDirection, intersections, bestT);
|
||||||
intersections.sort((a, b) -> (a.distance == b.distance) ? 0 : (a.distance > b.distance ? 1 : -1));
|
intersections.sort((a, b) -> (a.distance == b.distance) ? 0 : (a.distance > b.distance ? 1 : -1));
|
||||||
return intersections;
|
return intersections;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ class OctreeNode implements IOctreeElement {
|
||||||
return maxmin;
|
return maxmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function raycast(rayOrigin:Vector, rayDirection:Vector, intersections:Array<OctreeIntersection>) {
|
public function raycast(rayOrigin:Vector, rayDirection:Vector, intersections:Array<OctreeIntersection>, bestT:Float) {
|
||||||
var ray = Ray.fromValues(rayOrigin.x, rayOrigin.y, rayOrigin.z, rayDirection.x, rayDirection.y, rayDirection.z);
|
var ray = Ray.fromValues(rayOrigin.x, rayOrigin.y, rayOrigin.z, rayDirection.x, rayDirection.y, rayDirection.z);
|
||||||
// Construct the loose bounding box of this node (2x in size, with the regular bounding box in the center)
|
// Construct the loose bounding box of this node (2x in size, with the regular bounding box in the center)
|
||||||
|
|
||||||
|
|
@ -201,7 +201,7 @@ class OctreeNode implements IOctreeElement {
|
||||||
|
|
||||||
for (obj in this.objects) {
|
for (obj in this.objects) {
|
||||||
var iSecs = [];
|
var iSecs = [];
|
||||||
obj.rayCast(rayOrigin, rayDirection, iSecs);
|
obj.rayCast(rayOrigin, rayDirection, iSecs, bestT);
|
||||||
for (intersection in iSecs) {
|
for (intersection in iSecs) {
|
||||||
var intersectionData = new OctreeIntersection();
|
var intersectionData = new OctreeIntersection();
|
||||||
intersectionData.distance = rayOrigin.distance(intersection.point);
|
intersectionData.distance = rayOrigin.distance(intersection.point);
|
||||||
|
|
@ -215,7 +215,7 @@ class OctreeNode implements IOctreeElement {
|
||||||
if (this.octants != null) {
|
if (this.octants != null) {
|
||||||
for (i in 0...8) {
|
for (i in 0...8) {
|
||||||
var octant = this.octants[i];
|
var octant = this.octants[i];
|
||||||
octant.raycast(rayOrigin, rayDirection, intersections);
|
octant.raycast(rayOrigin, rayDirection, intersections, bestT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue