forked from LeenkxTeam/LNXSDK
125 lines
3.5 KiB
Haxe
125 lines
3.5 KiB
Haxe
|
package iron.data;
|
||
|
|
||
|
#if lnx_stream
|
||
|
|
||
|
import haxe.ds.Vector;
|
||
|
import iron.data.SceneFormat;
|
||
|
import iron.data.MaterialData;
|
||
|
import iron.object.Object;
|
||
|
import iron.object.MeshObject;
|
||
|
import iron.object.CameraObject;
|
||
|
import iron.math.Vec4;
|
||
|
|
||
|
class SceneStream {
|
||
|
|
||
|
var checkMax = 64; // Objects checked per frame
|
||
|
var checkPos = 0;
|
||
|
var loadMax = 8; // Max objects loaded at once
|
||
|
var loading = 0; // Objects being loaded
|
||
|
var loadDistance = -1;
|
||
|
var unloadDistance = -1;
|
||
|
var sectors: Array<StreamSector>; // 100x100 groups
|
||
|
|
||
|
public function sceneTotal(): Int {
|
||
|
return sectors[0].handles.length;
|
||
|
}
|
||
|
|
||
|
public function new() {
|
||
|
sectors = [new StreamSector()];
|
||
|
}
|
||
|
|
||
|
public function remove() {}
|
||
|
|
||
|
public function add(object_file: String, data_ref: String, sceneName: String, armature: Armature, materials: Vector<MaterialData>, parent: Object, parentObject:TObj, obj: TObj) {
|
||
|
sectors[0].handles.push({ object_file: object_file, data_ref: data_ref, sceneName: sceneName, armature: armature, materials: materials, parent: parent, parentObject: parentObject, obj: obj, object: null, loading: false });
|
||
|
}
|
||
|
|
||
|
function setup(camera: CameraObject) {
|
||
|
loadDistance = Std.int(camera.data.raw.far_plane * 1.1);
|
||
|
unloadDistance = Std.int(camera.data.raw.far_plane * 1.5);
|
||
|
}
|
||
|
|
||
|
public function update(camera: CameraObject) {
|
||
|
if (loadDistance == -1) setup(camera);
|
||
|
|
||
|
if (loading >= loadMax) return; // Busy loading..
|
||
|
|
||
|
var sec = sectors[0];
|
||
|
var to = Std.int(Math.min(checkMax, sec.handles.length));
|
||
|
for (i in 0...to) {
|
||
|
|
||
|
var h = sec.handles[checkPos];
|
||
|
checkPos++;
|
||
|
if (checkPos >= sec.handles.length) checkPos = 0;
|
||
|
|
||
|
// Check radius in sector
|
||
|
var camX = camera.transform.worldx();
|
||
|
var camY = camera.transform.worldy();
|
||
|
var camZ = camera.transform.worldz();
|
||
|
var hx = h.obj.transform.values[3];
|
||
|
var hy = h.obj.transform.values[7];
|
||
|
var hz = h.obj.transform.values[11];
|
||
|
var cameraDistance = Vec4.distancef(camX, camY, camZ, hx, hy, hz);
|
||
|
var dim = h.obj.dimensions;
|
||
|
if (dim != null) {
|
||
|
var r = dim[0];
|
||
|
if (dim[1] > r) r = dim[1];
|
||
|
if (dim[2] > r) r = dim[2];
|
||
|
cameraDistance -= r;
|
||
|
// TODO: handle scale & rot
|
||
|
}
|
||
|
|
||
|
if (cameraDistance < loadDistance && h.object == null && !h.loading) { // Load mesh
|
||
|
// Wait for the parent object to be added to scene
|
||
|
if (h.parent == null) {
|
||
|
if (Scene.active.getChild(h.parentObject.name) == null) return;
|
||
|
h.parent = Scene.active.getChild(h.parentObject.name);
|
||
|
}
|
||
|
|
||
|
// Start loading
|
||
|
h.loading = true;
|
||
|
loading++;
|
||
|
iron.Scene.active.returnMeshObject(h.object_file, h.data_ref, h.sceneName, h.armature, h.materials, h.parent, h.parentObject, h.obj, function(object: Object) {
|
||
|
h.object = cast(object, MeshObject);
|
||
|
h.loading = false;
|
||
|
loading--;
|
||
|
});
|
||
|
if (loading >= loadMax) return;
|
||
|
}
|
||
|
else if (cameraDistance > unloadDistance && h.object != null) { // Unload mesh
|
||
|
// Remove objects
|
||
|
h.object.remove();
|
||
|
if (h.object.data.refcount <= 0) {
|
||
|
iron.data.Data.deleteMesh(h.object_file + h.data_ref);
|
||
|
}
|
||
|
h.object = null;
|
||
|
|
||
|
// Clear parents
|
||
|
if (h.parent.name != Scene.active.raw.name) {
|
||
|
h.parent = null;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
typedef TMeshHandle = {
|
||
|
var object_file: String;
|
||
|
var data_ref: String;
|
||
|
var sceneName: String;
|
||
|
var armature: Armature;
|
||
|
var materials: Vector<MaterialData>;
|
||
|
var parent: Object;
|
||
|
var parentObject: TObj;
|
||
|
var obj: TObj;
|
||
|
var object: MeshObject;
|
||
|
var loading: Bool;
|
||
|
}
|
||
|
|
||
|
class StreamSector {
|
||
|
public function new() {}
|
||
|
public var handles: Array<TMeshHandle> = []; // Mesh objects
|
||
|
}
|
||
|
|
||
|
#end
|