mirror of
https://github.com/RandomityGuy/MBHaxe.git
synced 2025-10-30 08:11:25 +00:00
performance improvement
This commit is contained in:
parent
b6eafc57b7
commit
9aafd8b541
14 changed files with 164 additions and 88 deletions
|
|
@ -26,6 +26,8 @@ class MeshBatchInfo {
|
|||
var meshbatch:MeshBatch;
|
||||
var transparencymeshbatch:MeshBatch;
|
||||
var mesh:Mesh;
|
||||
var dtsShader:DtsTexture;
|
||||
var glowPassDtsShader:DtsTexture;
|
||||
|
||||
public function new() {}
|
||||
}
|
||||
|
|
@ -81,7 +83,7 @@ class InstanceManager {
|
|||
var opaqueinstances = visibleinstances.filter(x -> x.gameObject.currentOpacity == 1);
|
||||
minfo.meshbatch.begin(opaqueinstances.length);
|
||||
for (instance in opaqueinstances) { // Draw the opaque shit first
|
||||
var dtsShader = minfo.meshbatch.material.mainPass.getShader(DtsTexture);
|
||||
var dtsShader = minfo.dtsShader; // minfo.meshbatch.material.mainPass.getShader(DtsTexture);
|
||||
var subOpacity = 1.0;
|
||||
if (dtsShader != null) {
|
||||
if (instance.gameObject.animateSubObjectOpacities) {
|
||||
|
|
@ -112,7 +114,7 @@ class InstanceManager {
|
|||
// handle the glow pass too
|
||||
var glowPass = minfo.meshbatch.material.getPass("glow");
|
||||
if (glowPass != null) {
|
||||
dtsShader = glowPass.getShader(DtsTexture);
|
||||
dtsShader = minfo.glowPassDtsShader;
|
||||
if (dtsShader != null)
|
||||
dtsShader.currentOpacity = instance.gameObject.currentOpacity * subOpacity;
|
||||
}
|
||||
|
|
@ -124,7 +126,7 @@ class InstanceManager {
|
|||
var transparentinstances = visibleinstances.filter(x -> x.gameObject.currentOpacity != 1 && x.gameObject.currentOpacity != 0); // Filter out all zero opacity things too
|
||||
minfo.transparencymeshbatch.begin(transparentinstances.length);
|
||||
for (instance in transparentinstances) { // Non opaque shit
|
||||
var dtsShader = minfo.transparencymeshbatch.material.mainPass.getShader(DtsTexture);
|
||||
var dtsShader = minfo.dtsShader;
|
||||
if (dtsShader != null) {
|
||||
dtsShader.currentOpacity = instance.gameObject.currentOpacity;
|
||||
}
|
||||
|
|
@ -218,6 +220,8 @@ class InstanceManager {
|
|||
for (shader in addshaders)
|
||||
gpass.addShader(shader);
|
||||
|
||||
minfo.glowPassDtsShader = gpass.getShader(DtsTexture);
|
||||
|
||||
minfo.meshbatch.material.addPass(gpass);
|
||||
}
|
||||
var refractPass = mat.getPass("refract");
|
||||
|
|
@ -279,6 +283,7 @@ class InstanceManager {
|
|||
|
||||
minfo.meshbatch.material.addPass(gpass);
|
||||
}
|
||||
minfo.dtsShader = minfo.meshbatch.material.mainPass.getShader(DtsTexture);
|
||||
// var dtsshader = mat.mainPass.getShader(DtsTexture);
|
||||
// if (dtsshader != null) {
|
||||
// minfo.meshbatch.material.mainPass.removeShader(minfo.meshbatch.material.textureShader);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package src;
|
||||
|
||||
import collision.CollisionPool;
|
||||
import net.NetPacket.MarbleNetFlags;
|
||||
import net.BitStream.OutputBitStream;
|
||||
import net.ClientConnection;
|
||||
|
|
@ -532,9 +533,10 @@ class Marble extends GameObject {
|
|||
matWorker.run();
|
||||
}
|
||||
|
||||
function findContacts(collisiomWorld:CollisionWorld, timeState:TimeState) {
|
||||
function findContacts(collisionWorld:CollisionWorld, timeState:TimeState) {
|
||||
this.contacts = queuedContacts;
|
||||
var c = collisiomWorld.sphereIntersection(this.collider, timeState);
|
||||
CollisionPool.clear();
|
||||
var c = collisionWorld.sphereIntersection(this.collider, timeState);
|
||||
this.contactEntities = c.foundEntities;
|
||||
contacts = contacts.concat(c.contacts);
|
||||
}
|
||||
|
|
@ -1763,7 +1765,7 @@ class Marble extends GameObject {
|
|||
if (this.controllable && this.mode != Finish && !MarbleGame.instance.paused && !this.level.isWatching && !this.level.isReplayingMovement) {
|
||||
if (Net.isClient) {
|
||||
var axis = getMarbleAxis()[1];
|
||||
move = Net.clientConnection.moveManager.recordMove(cast this, axis, timeState);
|
||||
move = Net.clientConnection.recordMove(cast this, axis, timeState);
|
||||
} else if (Net.isHost) {
|
||||
var axis = getMarbleAxis()[1];
|
||||
var innerMove = recordMove();
|
||||
|
|
@ -1772,7 +1774,7 @@ class Marble extends GameObject {
|
|||
}
|
||||
var moveId = 65535;
|
||||
if (!this.controllable && this.connection != null && Net.isHost) {
|
||||
var nextMove = this.connection.moveManager.getNextMove();
|
||||
var nextMove = this.connection.getNextMove();
|
||||
// trace('Moves left: ${@:privateAccess this.connection.moveManager.queuedMoves.length}');
|
||||
if (nextMove == null) {
|
||||
var axis = getMarbleAxis()[1];
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package src;
|
||||
|
||||
import collision.CollisionPool;
|
||||
import net.GemPredictionStore;
|
||||
import modes.HuntMode;
|
||||
import net.NetPacket.MarbleNetFlags;
|
||||
|
|
@ -236,7 +237,7 @@ class MarbleWorld extends Scheduler {
|
|||
|
||||
var oobSchedule:Float;
|
||||
|
||||
var _cubemapNeedsUpdate:Bool = false;
|
||||
var _instancesNeedsUpdate:Bool = false;
|
||||
|
||||
var lock:Bool = false;
|
||||
|
||||
|
|
@ -1076,7 +1077,7 @@ class MarbleWorld extends Scheduler {
|
|||
if (!lastMoves.ourMoveApplied) {
|
||||
var ourMove = lastMoves.myMarbleUpdate;
|
||||
if (ourMove != null) {
|
||||
var ourMoveStruct = Net.clientConnection.moveManager.acknowledgeMove(ourMove.move.id, timeState);
|
||||
var ourMoveStruct = Net.clientConnection.acknowledgeMove(ourMove.move.id, timeState);
|
||||
lastMoves.ourMoveApplied = true;
|
||||
for (client => arr in lastMoves.otherMarbleUpdates) {
|
||||
var lastMove = null;
|
||||
|
|
@ -1157,11 +1158,11 @@ class MarbleWorld extends Scheduler {
|
|||
var ourLastMove = lastMoves.myMarbleUpdate;
|
||||
if (ourLastMove == null || marbleNeedsPrediction == 0)
|
||||
return -1;
|
||||
var ackLag = @:privateAccess Net.clientConnection.moveManager.queuedMoves.length;
|
||||
var ackLag = @:privateAccess Net.clientConnection.getQueuedMovesLength();
|
||||
|
||||
var ourLastMoveTime = ourLastMove.serverTicks;
|
||||
|
||||
var ourQueuedMoves = @:privateAccess Net.clientConnection.moveManager.queuedMoves.copy();
|
||||
var ourQueuedMoves = @:privateAccess Net.clientConnection.getQueuedMoves().copy();
|
||||
|
||||
var qm = ourQueuedMoves[0];
|
||||
var advanceTimeState = qm != null ? qm.timeState.clone() : timeState.clone();
|
||||
|
|
@ -1506,14 +1507,12 @@ class MarbleWorld extends Scheduler {
|
|||
marble.update(timeState, collisionWorld, this.pathedInteriors);
|
||||
}
|
||||
}
|
||||
_cubemapNeedsUpdate = true;
|
||||
_instancesNeedsUpdate = true;
|
||||
Renderer.dirtyBuffers = true;
|
||||
if (this.rewinding) {
|
||||
// Update camera separately
|
||||
marble.camera.update(timeState.currentAttemptTime, realDt);
|
||||
}
|
||||
ProfilerUI.measure("updateInstances");
|
||||
this.instanceManager.render();
|
||||
ProfilerUI.measure("updateParticles");
|
||||
if (this.rewinding) {
|
||||
this.particleManager.update(1000 * timeState.timeSinceLoad, -realDt * rewindManager.timeScale);
|
||||
|
|
@ -1555,13 +1554,16 @@ class MarbleWorld extends Scheduler {
|
|||
asyncLoadResources();
|
||||
if (this.playGui != null && _ready)
|
||||
this.playGui.render(e);
|
||||
if (this.marble != null && this.marble.cubemapRenderer != null && _ready) {
|
||||
ProfilerUI.measure("renderCubemap");
|
||||
if (_cubemapNeedsUpdate) {
|
||||
if (_instancesNeedsUpdate) {
|
||||
ProfilerUI.measure("updateInstances");
|
||||
this.instanceManager.render();
|
||||
if (this.marble != null && this.marble.cubemapRenderer != null && _ready) {
|
||||
ProfilerUI.measure("renderCubemap");
|
||||
|
||||
this.marble.cubemapRenderer.position.load(this.marble.getAbsPos().getPosition());
|
||||
this.marble.cubemapRenderer.render(e);
|
||||
_cubemapNeedsUpdate = false;
|
||||
}
|
||||
_instancesNeedsUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2298,6 +2300,8 @@ class MarbleWorld extends Scheduler {
|
|||
}
|
||||
}
|
||||
|
||||
CollisionPool.freeMemory();
|
||||
|
||||
radar.dispose();
|
||||
|
||||
if (this.playGui != null)
|
||||
|
|
|
|||
|
|
@ -64,10 +64,12 @@ class CollisionEntity implements IOctreeObject implements IBVHObject {
|
|||
// Generates the bvh
|
||||
public function finalize() {
|
||||
this.generateBoundingBox();
|
||||
#if hl
|
||||
this.bvh = new BVHTree();
|
||||
for (surface in this.surfaces) {
|
||||
this.bvh.add(surface);
|
||||
}
|
||||
#end
|
||||
// this.bvh.build();
|
||||
}
|
||||
|
||||
|
|
@ -240,9 +242,10 @@ class CollisionEntity implements IOctreeObject implements IBVHObject {
|
|||
// if (testDot > bestDot) {
|
||||
// bestDot = testDot;
|
||||
|
||||
var cinfo = new CollisionInfo();
|
||||
var cinfo = CollisionPool.alloc();
|
||||
cinfo.normal = normal.clone();
|
||||
cinfo.point = closest.clone();
|
||||
cinfo.collider = null;
|
||||
// cinfo.collider = this;
|
||||
cinfo.velocity = this.velocity.clone();
|
||||
cinfo.contactDistance = Math.sqrt(contactDist);
|
||||
|
|
|
|||
|
|
@ -40,10 +40,11 @@ class CollisionHull extends CollisionEntity {
|
|||
|
||||
var pt = GJK.gjk(sph, this.hull).epa;
|
||||
if (pt != null) {
|
||||
var cinfo = new CollisionInfo();
|
||||
var cinfo = CollisionPool.alloc();
|
||||
cinfo.normal = pt.normalized();
|
||||
cinfo.point = sph.position.sub(pt);
|
||||
cinfo.velocity = velocity;
|
||||
cinfo.collider = null;
|
||||
cinfo.contactDistance = sph.radius + pt.length();
|
||||
cinfo.restitution = restitution;
|
||||
cinfo.otherObject = this.go;
|
||||
|
|
|
|||
|
|
@ -10,12 +10,10 @@ class CollisionInfo {
|
|||
public var collider:CollisionEntity;
|
||||
public var otherObject:GameObject;
|
||||
public var friction:Float;
|
||||
public var vAtCMag:Float;
|
||||
public var normalForce:Float;
|
||||
public var restitution:Float;
|
||||
public var contactDistance:Float;
|
||||
public var force:Float;
|
||||
public var penetration:Float;
|
||||
|
||||
public function new() {}
|
||||
}
|
||||
|
|
|
|||
21
src/collision/CollisionPool.hx
Normal file
21
src/collision/CollisionPool.hx
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
package collision;
|
||||
|
||||
class CollisionPool {
|
||||
static var pool:Array<CollisionInfo> = [];
|
||||
static var currentPtr = 0;
|
||||
|
||||
public static function alloc() {
|
||||
if (pool.length <= currentPtr) {
|
||||
pool.push(new CollisionInfo());
|
||||
}
|
||||
return pool[currentPtr++];
|
||||
}
|
||||
|
||||
public static function clear() {
|
||||
currentPtr = 0;
|
||||
}
|
||||
|
||||
public static function freeMemory() {
|
||||
pool = [];
|
||||
}
|
||||
}
|
||||
|
|
@ -85,7 +85,7 @@ class SphereCollisionEntity extends CollisionEntity {
|
|||
|
||||
if (otherRadius * otherRadius * 1.01 > otherDist.lengthSq()) {
|
||||
var normDist = otherDist.normalized();
|
||||
var contact = new CollisionInfo();
|
||||
var contact = CollisionPool.alloc();
|
||||
contact.collider = this;
|
||||
contact.friction = 1;
|
||||
contact.restitution = 1;
|
||||
|
|
@ -95,7 +95,6 @@ class SphereCollisionEntity extends CollisionEntity {
|
|||
contact.normal = normDist.multiply(-1);
|
||||
contact.force = 0;
|
||||
contact.contactDistance = contact.point.distance(position);
|
||||
contact.penetration = radius - (position.sub(contact.point).dot(contact.normal));
|
||||
contacts.push(contact);
|
||||
|
||||
// var othercontact = new CollisionInfo();
|
||||
|
|
|
|||
|
|
@ -573,7 +573,8 @@ class HuntMode extends NullMode {
|
|||
"data/skies/gemCubemapUp3.png",
|
||||
'data/shapes/items/red.gem.png',
|
||||
"data/skies/gemCubemapUp.png",
|
||||
'sound/gem_collect.wav'
|
||||
'sound/gem_collect.wav',
|
||||
'sound/opponent_gem_collect.wav'
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import haxe.io.Bytes;
|
|||
import datachannel.RTCPeerConnection;
|
||||
import datachannel.RTCDataChannel;
|
||||
import net.MoveManager;
|
||||
import src.TimeState;
|
||||
|
||||
enum abstract GameplayState(Int) from Int to Int {
|
||||
var UNKNOWN;
|
||||
|
|
@ -55,5 +56,29 @@ abstract class GameConnection {
|
|||
state = GameplayState.GAME;
|
||||
}
|
||||
|
||||
public function queueMove(m:NetMove) {
|
||||
moveManager.queueMove(m);
|
||||
}
|
||||
|
||||
public inline function acknowledgeMove(m:Int, timeState:TimeState) {
|
||||
return moveManager.acknowledgeMove(m, timeState);
|
||||
}
|
||||
|
||||
public inline function getQueuedMoves() {
|
||||
return @:privateAccess moveManager.queuedMoves;
|
||||
}
|
||||
|
||||
public inline function getQueuedMovesLength() {
|
||||
return moveManager.getQueueSize();
|
||||
}
|
||||
|
||||
public function recordMove(marble:src.Marble, motionDir:h3d.Vector, timeState:TimeState) {
|
||||
return moveManager.recordMove(marble, motionDir, timeState);
|
||||
}
|
||||
|
||||
public function getNextMove() {
|
||||
return moveManager.getNextMove();
|
||||
}
|
||||
|
||||
public function sendBytes(b:haxe.io.Bytes) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ class MarblePrediction {
|
|||
if (p.netFlags != 0)
|
||||
subs += 1;
|
||||
// if (p.powerUpId != powerupItemId)
|
||||
// subs += 1; // temp
|
||||
if (tick % 10 == 0)
|
||||
subs += 1; // temp
|
||||
// if (isControl)
|
||||
// subs += Math.abs(blastAmount - p.blastAmount);
|
||||
return subs;
|
||||
|
|
|
|||
|
|
@ -343,7 +343,7 @@ class Net {
|
|||
var movePacket = new MarbleMovePacket();
|
||||
movePacket.deserialize(input);
|
||||
var cc = clientIdMap[movePacket.clientId];
|
||||
cc.moveManager.queueMove(movePacket.move);
|
||||
cc.queueMove(movePacket.move);
|
||||
|
||||
case PowerupPickup:
|
||||
var powerupPickupPacket = new PowerupPickupPacket();
|
||||
|
|
|
|||
|
|
@ -18,10 +18,6 @@ class Octree {
|
|||
|
||||
public function new() {
|
||||
this.root = new OctreeNode(this, 0);
|
||||
// Init the octree to a 1x1x1 cube
|
||||
this.root.bounds = new Bounds();
|
||||
this.root.bounds.xMin = this.root.bounds.yMin = this.root.bounds.zMin = 0;
|
||||
this.root.bounds.xMax = this.root.bounds.yMax = this.root.bounds.zMax = 1;
|
||||
this.objectToNode = new Map();
|
||||
}
|
||||
|
||||
|
|
@ -79,22 +75,24 @@ class Octree {
|
|||
count++;
|
||||
}
|
||||
}
|
||||
averagePoint = averagePoint.multiply(1 / count); // count should be greater than 0, because that's why we're growing in the first place.
|
||||
averagePoint.load(averagePoint.multiply(1 / count)); // count should be greater than 0, because that's why we're growing in the first place.
|
||||
// Determine the direction from the root center to the determined point
|
||||
var rootCenter = this.root.bounds.getCenter().toVector();
|
||||
var rootCenter = new Vector((this.root.xMax + this.root.xMin) / 2, (this.root.yMax + this.root.yMin) / 2, (this.root.zMax + this.root.zMin) / 2);
|
||||
var direction = averagePoint.sub(rootCenter); // Determine the "direction of growth"
|
||||
// Create a new root. The current root will become a quadrant in this new root.
|
||||
var newRoot = new OctreeNode(this, this.root.depth - 1);
|
||||
newRoot.bounds = this.root.bounds.clone();
|
||||
newRoot.bounds.xSize *= 2;
|
||||
newRoot.bounds.ySize *= 2;
|
||||
newRoot.bounds.zSize *= 2;
|
||||
newRoot.xMin = this.root.xMin;
|
||||
newRoot.yMin = this.root.yMin;
|
||||
newRoot.zMin = this.root.zMin;
|
||||
newRoot.xMax = 2 * this.root.xMax - this.root.xMin;
|
||||
newRoot.yMax = 2 * this.root.yMax - this.root.yMin;
|
||||
newRoot.zMax = 2 * this.root.zMax - this.root.zMin;
|
||||
if (direction.x < 0)
|
||||
newRoot.bounds.xMin -= this.root.bounds.xSize;
|
||||
newRoot.xMin -= this.root.xMax - this.root.xMin;
|
||||
if (direction.y < 0)
|
||||
newRoot.bounds.yMin -= this.root.bounds.ySize;
|
||||
newRoot.yMin -= this.root.yMax - this.root.yMin;
|
||||
if (direction.z < 0)
|
||||
newRoot.bounds.zMin -= this.root.bounds.zSize;
|
||||
newRoot.zMin -= this.root.zMax - this.root.zMin;
|
||||
if (this.root.count > 0) {
|
||||
var octantIndex = ((direction.x < 0) ? 1 : 0) + ((direction.y < 0) ? 2 : 0) + ((direction.z < 0) ? 4 : 0);
|
||||
newRoot.createOctants();
|
||||
|
|
@ -108,12 +106,12 @@ class Octree {
|
|||
|
||||
/** Tries to shrink the octree if large parts of the octree are empty. */
|
||||
public function shrink() {
|
||||
if (this.root.bounds.xSize < 1 || this.root.bounds.ySize < 1 || this.root.bounds.zSize < 1 || this.root.objects.length > 0)
|
||||
if (this.root.xMax - this.root.xMin < 1 || this.root.yMax - this.root.yMin < 1 || this.root.zMax - this.root.zMin < 1 || this.root.objects.length > 0)
|
||||
return;
|
||||
if (this.root.count == 0) {
|
||||
// Reset to default empty octree
|
||||
this.root.bounds.xMin = this.root.bounds.yMin = this.root.bounds.zMin = 0;
|
||||
this.root.bounds.xMax = this.root.bounds.yMax = this.root.bounds.zMin = 1;
|
||||
this.root.xMin = this.root.yMin = this.root.zMin = 0;
|
||||
this.root.xMax = this.root.yMax = this.root.zMax = 1;
|
||||
this.root.depth = 0;
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,13 @@ class OctreeNode implements IOctreeElement {
|
|||
public var position:Int;
|
||||
|
||||
/** The min corner of the bounding box. */
|
||||
public var bounds:Bounds;
|
||||
public var xMin:Float;
|
||||
|
||||
public var yMin:Float;
|
||||
public var zMin:Float;
|
||||
public var xMax:Float;
|
||||
public var yMax:Float;
|
||||
public var zMax:Float;
|
||||
|
||||
/** The size of the bounding box on all three axes. This forces the bounding box to be a cube. */
|
||||
public var octants:Array<OctreeNode> = null;
|
||||
|
|
@ -29,6 +35,12 @@ class OctreeNode implements IOctreeElement {
|
|||
public function new(octree:Octree, depth:Int) {
|
||||
this.octree = octree;
|
||||
this.depth = depth;
|
||||
this.xMin = 0;
|
||||
this.yMin = 0;
|
||||
this.zMin = 0;
|
||||
this.xMax = 1;
|
||||
this.yMax = 1;
|
||||
this.zMax = 1;
|
||||
}
|
||||
|
||||
public function insert(object:IOctreeObject) {
|
||||
|
|
@ -80,16 +92,13 @@ class OctreeNode implements IOctreeElement {
|
|||
for (i in 0...8) {
|
||||
var newNode = new OctreeNode(this.octree, this.depth + 1);
|
||||
newNode.parent = this;
|
||||
var newSize = this.bounds.getSize().multiply(1 / 2);
|
||||
newNode.bounds = this.bounds.clone();
|
||||
newNode.bounds.setMin(new Point(this.bounds.xMin
|
||||
+ newSize.x * ((i & 1) >> 0), this.bounds.yMin
|
||||
+ newSize.y * ((i & 2) >> 1),
|
||||
this.bounds.zMin
|
||||
+ newSize.z * ((i & 4) >> 2)));
|
||||
newNode.bounds.xSize = newSize.x;
|
||||
newNode.bounds.ySize = newSize.y;
|
||||
newNode.bounds.zSize = newSize.z;
|
||||
var newSize = new Vector(xMax - xMin, yMax - yMin, zMax - zMin);
|
||||
newNode.xMin = this.xMin + newSize.x * ((i & 1) >> 0);
|
||||
newNode.yMin = this.yMin + newSize.y * ((i & 2) >> 1);
|
||||
newNode.zMin = this.zMin + newSize.z * ((i & 4) >> 2);
|
||||
newNode.xMax = newNode.xMin + newSize.x;
|
||||
newNode.yMax = newNode.yMin + newSize.y;
|
||||
newNode.zMax = newNode.zMin + newSize.z;
|
||||
this.octants.push(newNode);
|
||||
}
|
||||
}
|
||||
|
|
@ -141,24 +150,53 @@ class OctreeNode implements IOctreeElement {
|
|||
this.octants = null; // ...then devare the octants
|
||||
}
|
||||
|
||||
public function largerThan(object:IOctreeObject) {
|
||||
return this.bounds.containsBounds(object.boundingBox);
|
||||
public inline function largerThan(object:IOctreeObject) {
|
||||
return xMin <= object.boundingBox.xMin && yMin <= object.boundingBox.yMin && zMin <= object.boundingBox.zMin && xMax >= object.boundingBox.xMax
|
||||
&& yMax >= object.boundingBox.yMax && zMax >= object.boundingBox.zMax;
|
||||
// return this.size > (box.xMax - box.xMin) && this.size > (box.yMax - box.yMin) && this.size > (box.zMax - box.zMin);
|
||||
}
|
||||
|
||||
public function containsCenter(object:IOctreeObject) {
|
||||
return this.bounds.contains(object.boundingBox.getCenter());
|
||||
public inline function containsCenter(object:IOctreeObject) {
|
||||
return this.containsPoint2(object.boundingBox.getCenter());
|
||||
}
|
||||
|
||||
public function containsPoint(point:Vector) {
|
||||
return this.bounds.contains(point.toPoint());
|
||||
public inline function containsPoint(p:Vector) {
|
||||
return p.x >= xMin && p.x < xMax && p.y >= yMin && p.y < yMax && p.z >= zMin && p.z < zMax;
|
||||
}
|
||||
|
||||
public inline function containsPoint2(p:h3d.col.Point) {
|
||||
return p.x >= xMin && p.x < xMax && p.y >= yMin && p.y < yMax && p.z >= zMin && p.z < zMax;
|
||||
}
|
||||
|
||||
inline function rayIntersection(r:Ray, bestMatch:Bool):Float {
|
||||
var minTx = (xMin - r.px) / r.lx;
|
||||
var minTy = (yMin - r.py) / r.ly;
|
||||
var minTz = (zMin - r.pz) / r.lz;
|
||||
var maxTx = (xMax - r.px) / r.lx;
|
||||
var maxTy = (yMax - r.py) / r.ly;
|
||||
var maxTz = (zMax - r.pz) / r.lz;
|
||||
|
||||
var realMinTx = Math.min(minTx, maxTx);
|
||||
var realMinTy = Math.min(minTy, maxTy);
|
||||
var realMinTz = Math.min(minTz, maxTz);
|
||||
var realMaxTx = Math.max(minTx, maxTx);
|
||||
var realMaxTy = Math.max(minTy, maxTy);
|
||||
var realMaxTz = Math.max(minTz, maxTz);
|
||||
|
||||
var minmax = Math.min(Math.min(realMaxTx, realMaxTy), realMaxTz);
|
||||
var maxmin = Math.max(Math.max(realMinTx, realMinTy), realMinTz);
|
||||
|
||||
if (minmax < maxmin)
|
||||
return -1;
|
||||
|
||||
return maxmin;
|
||||
}
|
||||
|
||||
public function raycast(rayOrigin:Vector, rayDirection:Vector, intersections:Array<OctreeIntersection>) {
|
||||
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)
|
||||
|
||||
if (this.bounds.rayIntersection(ray, true) == -1)
|
||||
if (rayIntersection(ray, true) == -1)
|
||||
return;
|
||||
|
||||
for (obj in this.objects) {
|
||||
|
|
@ -181,42 +219,22 @@ class OctreeNode implements IOctreeElement {
|
|||
}
|
||||
}
|
||||
|
||||
public function boundingSearch(bounds:Bounds, intersections:Array<IOctreeElement>) {
|
||||
if (this.bounds.collide(bounds)) {
|
||||
public function boundingSearch(b:Bounds, intersections:Array<IOctreeElement>) {
|
||||
if (!(xMin > b.xMax || yMin > b.yMax || zMin > b.zMax || xMax < b.xMin || yMax < b.yMin || zMax < b.zMin)) {
|
||||
for (obj in this.objects) {
|
||||
if (obj.boundingBox.collide(bounds))
|
||||
if (obj.boundingBox.collide(b))
|
||||
intersections.push(obj);
|
||||
}
|
||||
if (octants != null) {
|
||||
for (octant in this.octants)
|
||||
octant.boundingSearch(bounds, intersections);
|
||||
octant.boundingSearch(b, intersections);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getClosestPoint(point:Vector) {
|
||||
var closest = new Vector();
|
||||
if (this.bounds.xMin > point.x)
|
||||
closest.x = this.bounds.xMin;
|
||||
else if (this.bounds.xMax < point.x)
|
||||
closest.x = this.bounds.xMax;
|
||||
else
|
||||
closest.x = point.x;
|
||||
|
||||
if (this.bounds.yMin > point.y)
|
||||
closest.y = this.bounds.yMin;
|
||||
else if (this.bounds.yMax < point.y)
|
||||
closest.y = this.bounds.yMax;
|
||||
else
|
||||
closest.y = point.y;
|
||||
|
||||
if (this.bounds.zMin > point.z)
|
||||
closest.z = this.bounds.zMin;
|
||||
else if (this.bounds.zMax < point.z)
|
||||
closest.z = this.bounds.zMax;
|
||||
else
|
||||
closest.z = point.z;
|
||||
|
||||
public inline function getClosestPoint(point:Vector) {
|
||||
var closest = new Vector(Math.min(Math.max(this.xMin, point.x), this.xMax), Math.min(Math.max(this.yMin, point.y), this.yMax),
|
||||
Math.min(Math.max(this.zMin, point.z), this.zMax));
|
||||
return closest;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue