armory/Sources/armory/trait/NavMesh.hx
2019-12-19 23:54:08 +01:00

84 lines
1.9 KiB
Haxe
Executable file

package armory.trait;
#if arm_navigation
import armory.trait.navigation.Navigation;
import haxerecast.Recast;
#end
import iron.Trait;
import iron.data.Data;
import iron.math.Vec4;
class NavMesh extends Trait {
#if (!arm_navigation)
public function new() { super(); }
#else
// recast config:
@prop
public var cellSize: Float = 0.3; // voxelization cell size
@prop
public var cellHeight: Float = 0.2; // voxelization cell height
@prop
public var agentHeight: Float = 2.0; // agent capsule height
@prop
public var agentRadius: Float = 0.4; // agent capsule radius
@prop
public var agentMaxClimb: Float = 0.9; // how high steps agents can climb, in voxels
@prop
public var agentMaxSlope: Float = 45.0; // maximum slope angle, in degrees
var recast: Recast = null;
var ready = false;
public function new() {
super();
notifyOnInit(init);
}
function init() {
Navigation.active.navMeshes.push(this);
// Load navmesh
var name = "nav_" + cast(object, iron.object.MeshObject).data.name + ".arm";
Data.getBlob(name, function(b: kha.Blob) {
recast = Navigation.active.recast;
recast.OBJDataLoader(b.toString(), function() {
var settings = [
"cellSize" => cellSize,
"cellHeight" => cellHeight,
"agentHeight" => agentHeight,
"agentRadius" => agentRadius,
"agentMaxClimb" => agentMaxClimb,
"agentMaxSlope" => agentMaxSlope,
];
recast.settings(settings);
recast.buildSolo();
ready = true;
});
});
}
public function findPath(from: Vec4, to: Vec4, done: Array<Vec4>->Void) {
if (!ready) return;
recast.findPath(from.x, from.z, from.y, to.x, to.z, to.y, 200, function(path: Array<RecastWaypoint>) {
var ar: Array<Vec4> = [];
for (p in path) ar.push(new Vec4(p.x, p.z, p.y));
done(ar);
});
}
public function getRandomPoint(done: Vec4->Void) {
if (!ready) return;
recast.getRandomPoint(function(x: Float, y: Float, z: Float) {
done(new Vec4(x, z, -y));
});
}
#end
}