speed up some octree crap

This commit is contained in:
RandomityGuy 2021-06-17 14:05:24 +05:30
parent 5a51c1ef75
commit 9f226a4f5d
10 changed files with 87 additions and 17 deletions

View file

@ -83,6 +83,7 @@ class DtsObject extends GameObject {
var lastSequenceKeyframes:Map<Sequence, Float> = new Map(); var lastSequenceKeyframes:Map<Sequence, Float> = new Map();
var graphNodes:Array<Object> = []; var graphNodes:Array<Object> = [];
var dirtyTransforms:Array<Bool> = [];
var useInstancing:Bool = true; var useInstancing:Bool = true;
var isTSStatic:Bool; var isTSStatic:Bool;
@ -302,6 +303,11 @@ class DtsObject extends GameObject {
this.boundingCollider = new BoxCollisionEntity(this.level.instanceManager.getObjectBounds(cast this), cast this); this.boundingCollider = new BoxCollisionEntity(this.level.instanceManager.getObjectBounds(cast this), cast this);
this.boundingCollider.setTransform(this.getTransform()); this.boundingCollider.setTransform(this.getTransform());
} }
this.dirtyTransforms = [];
for (i in 0...graphNodes.length) {
this.dirtyTransforms.push(true);
}
} }
function computeMaterials() { function computeMaterials() {
@ -570,6 +576,9 @@ class DtsObject extends GameObject {
super.setTransform(mat); super.setTransform(mat);
this.boundingCollider.setTransform(mat); this.boundingCollider.setTransform(mat);
this.level.collisionWorld.updateTransform(this.boundingCollider); this.level.collisionWorld.updateTransform(this.boundingCollider);
for (i in 0...this.dirtyTransforms.length) {
this.dirtyTransforms[i] = true;
}
} }
public function update(timeState:TimeState) { public function update(timeState:TimeState) {
@ -619,6 +628,7 @@ class DtsObject extends GameObject {
quat.normalize(); quat.normalize();
this.graphNodes[i].setRotationQuat(quat); this.graphNodes[i].setRotationQuat(quat);
this.dirtyTransforms[i] = true;
affectedCount++; affectedCount++;
// quaternions.push(quat); // quaternions.push(quat);
} else { } else {
@ -647,6 +657,7 @@ class DtsObject extends GameObject {
var v2 = new Vector(trans2.x, trans2.y, trans2.z); var v2 = new Vector(trans2.x, trans2.y, trans2.z);
var trans = Util.lerpThreeVectors(v1, v2, t); var trans = Util.lerpThreeVectors(v1, v2, t);
this.graphNodes[i].setPosition(trans.x, trans.y, trans.z); this.graphNodes[i].setPosition(trans.x, trans.y, trans.z);
this.dirtyTransforms[i] = true;
// translations.push(Util.lerpThreeVectors(v1, v2, t)); // translations.push(Util.lerpThreeVectors(v1, v2, t));
} else { } else {
@ -782,9 +793,14 @@ class DtsObject extends GameObject {
} }
for (i in 0...this.colliders.length) { for (i in 0...this.colliders.length) {
var absTform = this.graphNodes[this.colliders[i].userData].getAbsPos().clone(); if (this.dirtyTransforms[this.colliders[i].userData]) {
if (this.colliders[i] != null) var absTform = this.graphNodes[this.colliders[i].userData].getAbsPos().clone();
this.colliders[i].setTransform(absTform); if (this.colliders[i] != null)
this.colliders[i].setTransform(absTform);
}
}
for (i in 0...this.dirtyTransforms.length) {
this.dirtyTransforms[i] = false;
} }
} }

View file

@ -8,6 +8,7 @@ class GameObject extends Object {
public var identifier:String; public var identifier:String;
public var currentOpacity:Float = 1; public var currentOpacity:Float = 1;
public var isCollideable:Bool = false; public var isCollideable:Bool = false;
public var isBoundingBoxCollideable:Bool = true;
public function onMarbleContact(time:TimeState, ?contact:CollisionInfo) {} public function onMarbleContact(time:TimeState, ?contact:CollisionInfo) {}

View file

@ -52,7 +52,7 @@ class Main extends hxd.App {
override function init() { override function init() {
super.init(); super.init();
var ltr = File.getContent("data/missions/advanced/survival.mis"); var ltr = File.getContent("data/missions/advanced/airwalk.mis");
var mfp = new MisParser(ltr); var mfp = new MisParser(ltr);
var mis = mfp.parse(); var mis = mfp.parse();

View file

@ -1,5 +1,7 @@
package src; package src;
import h3d.col.Bounds;
import collision.CollisionEntity;
import shapes.StartPad; import shapes.StartPad;
import src.TimeState; import src.TimeState;
import src.ParticleSystem.ParticleEmitter; import src.ParticleSystem.ParticleEmitter;
@ -132,7 +134,9 @@ class Marble extends GameObject {
public var _mass:Float = 1; public var _mass:Float = 1;
var contacts:Array<CollisionInfo> = []; public var contacts:Array<CollisionInfo> = [];
public var contactEntities:Array<CollisionEntity> = [];
var queuedContacts:Array<CollisionInfo> = []; var queuedContacts:Array<CollisionInfo> = [];
public var heldPowerup:PowerUp; public var heldPowerup:PowerUp;
@ -189,6 +193,7 @@ class Marble extends GameObject {
this.forcefield.x = 1e8; this.forcefield.x = 1e8;
this.forcefield.y = 1e8; this.forcefield.y = 1e8;
this.forcefield.z = 1e8; this.forcefield.z = 1e8;
this.forcefield.isBoundingBoxCollideable = false;
level.addDtsObject(this.forcefield); level.addDtsObject(this.forcefield);
this.helicopter = new DtsObject(); this.helicopter = new DtsObject();
@ -196,6 +201,7 @@ class Marble extends GameObject {
this.helicopter.useInstancing = true; this.helicopter.useInstancing = true;
this.helicopter.identifier = "Helicopter"; this.helicopter.identifier = "Helicopter";
this.helicopter.showSequences = true; this.helicopter.showSequences = true;
this.helicopter.isBoundingBoxCollideable = false;
// this.addChild(this.helicopter); // this.addChild(this.helicopter);
this.helicopter.x = 1e8; this.helicopter.x = 1e8;
this.helicopter.y = 1e8; this.helicopter.y = 1e8;
@ -206,7 +212,8 @@ class Marble extends GameObject {
function findContacts(collisiomWorld:CollisionWorld, timeState:TimeState) { function findContacts(collisiomWorld:CollisionWorld, timeState:TimeState) {
this.contacts = queuedContacts; this.contacts = queuedContacts;
var c = collisiomWorld.sphereIntersection(this.collider, timeState); var c = collisiomWorld.sphereIntersection(this.collider, timeState);
contacts = contacts.concat(c); this.contactEntities = c.foundEntities;
contacts = contacts.concat(c.contacts);
} }
public function queueCollision(collisionInfo:CollisionInfo) { public function queueCollision(collisionInfo:CollisionInfo) {
@ -597,13 +604,13 @@ class Marble extends GameObject {
} }
function getIntersectionTime(dt:Float, velocity:Vector) { function getIntersectionTime(dt:Float, velocity:Vector) {
var expandedcollider = new SphereCollisionEntity(cast this); var searchbox = new Bounds();
searchbox.addSpherePos(this.x, this.y, this.z, _radius);
searchbox.addSpherePos(this.x + velocity.x * dt, this.y + velocity.y * dt, this.z + velocity.z * dt, _radius);
var position = this.getAbsPos().getPosition(); var position = this.getAbsPos().getPosition();
expandedcollider.transform = Matrix.T(position.x, position.y, position.z); var foundObjs = this.level.collisionWorld.boundingSearch(searchbox);
expandedcollider.radius = velocity.multiply(dt).length() + _radius;
var foundObjs = this.level.collisionWorld.radiusSearch(position, expandedcollider.radius);
function toDifPoint(vec:Vector) { function toDifPoint(vec:Vector) {
return new Point3F(vec.x, vec.y, vec.z); return new Point3F(vec.x, vec.y, vec.z);
@ -612,7 +619,7 @@ class Marble extends GameObject {
var intersectT = 10e8; var intersectT = 10e8;
for (obj in foundObjs) { for (obj in foundObjs) {
var radius = expandedcollider.radius; var radius = _radius;
var invMatrix = obj.transform.clone(); var invMatrix = obj.transform.clone();
invMatrix.invert(); invMatrix.invert();

View file

@ -569,7 +569,8 @@ class MarbleWorld extends Scheduler {
if (collider != null) if (collider != null)
this.collisionWorld.addEntity(collider); this.collisionWorld.addEntity(collider);
} }
this.collisionWorld.addEntity(obj.boundingCollider); if (obj.isBoundingBoxCollideable)
this.collisionWorld.addEntity(obj.boundingCollider);
} }
public function addMarble(marble:Marble) { public function addMarble(marble:Marble) {
@ -683,7 +684,8 @@ class MarbleWorld extends Scheduler {
} }
public function callCollisionHandlers(marble:Marble, timeState:TimeState) { public function callCollisionHandlers(marble:Marble, timeState:TimeState) {
var contacts = this.collisionWorld.radiusSearch(marble.getAbsPos().getPosition(), marble._radius); // var contacts = this.collisionWorld.radiusSearch(marble.getAbsPos().getPosition(), marble._radius);
var contacts = marble.contactEntities;
var newImmunity = []; var newImmunity = [];
var calledShapes = []; var calledShapes = [];
var inside = []; var inside = [];

View file

@ -43,6 +43,8 @@ class CollisionEntity implements IOctreeObject {
} }
public function setTransform(transform:Matrix) { public function setTransform(transform:Matrix) {
if (this.transform == transform)
return;
this.transform = transform; this.transform = transform;
generateBoundingBox(); generateBoundingBox();
} }

View file

@ -20,7 +20,7 @@ class CollisionWorld {
var radius = spherecollision.radius; var radius = spherecollision.radius;
var velocity = spherecollision.velocity; var velocity = spherecollision.velocity;
var searchdist = (velocity.length() * timeState.dt) + radius; var searchdist = (velocity.length() * timeState.dt) + radius;
var intersections = this.octree.radiusSearch(position, searchdist); // var intersections = this.octree.radiusSearch(position, searchdist);
var box = new Bounds(); var box = new Bounds();
box.xMin = position.x - radius; box.xMin = position.x - radius;
@ -29,12 +29,17 @@ class CollisionWorld {
box.xMax = position.x + radius; box.xMax = position.x + radius;
box.yMax = position.y + radius; box.yMax = position.y + radius;
box.zMax = position.z + radius; box.zMax = position.z + radius;
var intersections = this.octree.boundingSearch(box);
// var intersections = this.rtree.search([box.xMin, box.yMax, box.zMin], [box.xSize, box.ySize, box.zSize]);
var contacts = []; var contacts = [];
var foundEntities = [];
for (obj in intersections) { for (obj in intersections) {
var entity:CollisionEntity = cast obj; var entity:CollisionEntity = cast obj;
foundEntities.push(entity);
if (entity.go.isCollideable) { if (entity.go.isCollideable) {
contacts = contacts.concat(entity.sphereIntersection(spherecollision, timeState)); contacts = contacts.concat(entity.sphereIntersection(spherecollision, timeState));
} }
@ -46,7 +51,7 @@ class CollisionWorld {
contacts = contacts.concat(obj.sphereIntersection(spherecollision, timeState)); contacts = contacts.concat(obj.sphereIntersection(spherecollision, timeState));
} }
} }
return contacts; return {foundEntities: foundEntities, contacts: contacts};
} }
public function radiusSearch(center:Vector, radius:Float) { public function radiusSearch(center:Vector, radius:Float) {
@ -76,13 +81,26 @@ class CollisionWorld {
return contacts; return contacts;
} }
public function boundingSearch(bounds:Bounds) {
var contacts = this.octree.boundingSearch(bounds).map(x -> cast(x, CollisionEntity));
for (obj in dynamicEntities) {
if (obj.boundingBox.collide(bounds))
contacts.push(obj);
}
return contacts;
}
public function rayCast(rayStart:Vector, rayDirection:Vector) { public function rayCast(rayStart:Vector, rayDirection:Vector) {
return [];
return this.octree.raycast(rayStart, rayDirection); return this.octree.raycast(rayStart, rayDirection);
} }
public function addEntity(entity:CollisionEntity) { public function addEntity(entity:CollisionEntity) {
this.octree.insert(entity); this.octree.insert(entity);
this.entities.push(entity); this.entities.push(entity);
// this.rtree.insert([entity.boundingBox.xMin, entity.boundingBox.yMin, entity.boundingBox.zMin],
// [entity.boundingBox.xSize, entity.boundingBox.ySize, entity.boundingBox.zSize], entity);
} }
public function addMovingEntity(entity:CollisionEntity) { public function addMovingEntity(entity:CollisionEntity) {

View file

@ -131,6 +131,12 @@ class Octree {
return intersections; return intersections;
} }
public function boundingSearch(bounds:Bounds) {
var intersections = [];
this.root.boundingSearch(bounds, intersections);
return intersections;
}
public function radiusSearch(point:Vector, maximumDistance:Float) { public function radiusSearch(point:Vector, maximumDistance:Float) {
function getClosestPoint(box:Bounds, point:Vector) { function getClosestPoint(box:Bounds, point:Vector) {
var closest = new Vector(); var closest = new Vector();

View file

@ -185,6 +185,22 @@ class OctreeNode implements IOctreeElement {
} }
} }
public function boundingSearch(bounds:Bounds, intersections:Array<IOctreeElement>) {
var thisBounds = new Bounds();
thisBounds.setMin(this.min.toPoint());
thisBounds.xSize = thisBounds.ySize = thisBounds.zSize = this.size;
if (thisBounds.collide(bounds)) {
for (obj in this.objects) {
if (obj.boundingBox.collide(bounds))
intersections.push(obj);
}
if (octants != null) {
for (octant in this.octants)
octant.boundingSearch(bounds, intersections);
}
}
}
public function getClosestPoint(point:Vector) { public function getClosestPoint(point:Vector) {
var closest = new Vector(); var closest = new Vector();
if (this.min.x > point.x) if (this.min.x > point.x)

View file

@ -28,5 +28,7 @@ class TimeTravel extends PowerUp {
return true; return true;
} }
public function use(time:TimeState) {} public function use(time:TimeState) {
level.bonusTime += this.timeBonus;
}
} }