Skip to content

Commit

Permalink
feat: use asset optimized (#519)
Browse files Browse the repository at this point in the history
* wip

* wip

* fix format

Signed-off-by: Lean Mendoza <[email protected]>

* change asset optimized base url

---------

Signed-off-by: Lean Mendoza <[email protected]>
Co-authored-by: Mateo "Kuruk" Miccino <[email protected]>
  • Loading branch information
leanmendoza and kuruk-mm authored Dec 3, 2024
1 parent 633f826 commit 9b383cc
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 24 deletions.
45 changes: 44 additions & 1 deletion godot/src/decentraland_components/gltf_container.gd
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,49 @@ func _ready():
self.async_load_gltf.call_deferred()


func async_try_load_gltf_from_local_file(scene_file: String) -> void:
var main_tree = get_tree()
if not is_instance_valid(main_tree):
return

var err = ResourceLoader.load_threaded_request(scene_file)
if err != OK:
dcl_gltf_loading_state = GltfContainerLoadingState.FINISHED_WITH_ERROR
timer.stop()
return

var status = ResourceLoader.load_threaded_get_status(scene_file)
while status == 1:
await main_tree.process_frame
status = ResourceLoader.load_threaded_get_status(scene_file)

var resource = ResourceLoader.load_threaded_get(scene_file)
if resource == null:
dcl_gltf_loading_state = GltfContainerLoadingState.FINISHED_WITH_ERROR
timer.stop()
return

var gltf_node = resource.instantiate()
var instance_promise: Promise = Global.content_provider.instance_gltf_colliders(
gltf_node, dcl_visible_cmask, dcl_invisible_cmask, dcl_scene_id, dcl_entity_id
)
var res_instance = await PromiseUtils.async_awaiter(instance_promise)
if res_instance is PromiseError:
printerr("Error on fetch gltf: ", res_instance.get_error())
dcl_gltf_loading_state = GltfContainerLoadingState.FINISHED_WITH_ERROR
timer.stop()
return

dcl_pending_node = res_instance
timer.stop()


func async_load_gltf():
var content_mapping := Global.scene_runner.get_scene_content_mapping(dcl_scene_id)

self.dcl_gltf_src = dcl_gltf_src.to_lower()
if content_mapping.get_hash(dcl_gltf_src).is_empty():
var file_hash = content_mapping.get_hash(dcl_gltf_src)
if file_hash.is_empty():
dcl_gltf_loading_state = GltfContainerLoadingState.NOT_FOUND
timer.stop()
return
Expand All @@ -28,6 +66,11 @@ func async_load_gltf():
dcl_gltf_loading_state = GltfContainerLoadingState.LOADING
timer.start()

var scene_file = "res://glbs/" + file_hash + ".tscn"
if FileAccess.file_exists(scene_file + ".remap"):
await async_try_load_gltf_from_local_file(scene_file)
return

var promise = Global.content_provider.fetch_scene_gltf(dcl_gltf_src, content_mapping)
if promise == null:
printerr("Fatal error on fetch gltf: promise == null")
Expand Down
22 changes: 22 additions & 0 deletions godot/src/global.gd
Original file line number Diff line number Diff line change
Expand Up @@ -280,3 +280,25 @@ func open_network_inspector_ui():

add_child(network_inspector_window)
network_inspector_window.show()


func async_load_threaded(resource_path: String, promise: Promise) -> void:
prints("loading async", resource_path)

var main_tree = get_tree()
var err = ResourceLoader.load_threaded_request(resource_path)
if err != OK:
promise.reject("async_load_threaded error load_threaded_request not ok")
return

var status = ResourceLoader.load_threaded_get_status(resource_path)
while status == 1:
await main_tree.process_frame
status = ResourceLoader.load_threaded_get_status(resource_path)

var resource = ResourceLoader.load_threaded_get(resource_path)
if resource == null:
promise.reject("async_load_threaded error load_threaded_request result null")
return

promise.resolve_with_data(resource)
18 changes: 18 additions & 0 deletions godot/src/logic/scene_fetcher.gd
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ const EMPTY_SCENES = [
preload("res://assets/empty-scenes/EP_11.tscn")
]

const ASSET_OPTIMIZED_BASE_URL: String = "https://storage.kuruk.net"
#const ASSET_OPTIMIZED_BASE_URL: String = "http://localhost:3232"

const ADAPTATION_LAYER_URL: String = "https://renderer-artifacts.decentraland.org/sdk6-adaption-layer/main/index.min.js"
const FIXED_LOCAL_ADAPTATION_LAYER: String = ""

Expand Down Expand Up @@ -377,6 +380,21 @@ func async_load_scene(
)
return PromiseUtils.resolved(false)

var scene_hash_zip: String = "%s.zip" % scene_entity_id
var asset_url: String = "%s/%s.zip" % [ASSET_OPTIMIZED_BASE_URL, scene_entity_id]
var download_promise: Promise = Global.content_provider.fetch_file_by_url(
scene_hash_zip, asset_url
)
var download_res = await PromiseUtils.async_awaiter(download_promise)
if download_res is PromiseError:
printerr("Scene ", scene_entity_id, " is not optimized, failed to download zip.")
else:
var ok = ProjectSettings.load_resource_pack("user://content/" + scene_hash_zip, false)
if not ok:
printerr("Scene ", scene_entity_id, " failed to load optimized scene")
else:
print("Scene ", scene_entity_id, " zip loaded successfully.")

# the scene was removed while it was loading...
if not loaded_scenes.has(scene_entity_id):
printerr("the scene was removed while was loading ", scene_entity_id)
Expand Down
61 changes: 38 additions & 23 deletions lib/src/content/content_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,36 +582,51 @@ impl ContentProvider {
return promise;
}

let url = format!(
"{}{}",
content_mapping.bind().get_base_url(),
file_hash.clone()
);
let (promise, get_promise) = Promise::make_to_async();
let content_provider_context = self.get_context();

let loading_resources = self.loading_resources.clone();
let loaded_resources = self.loaded_resources.clone();
let hash_id = file_hash.clone();
TokioRuntime::spawn(async move {
#[cfg(feature = "use_resource_tracking")]
report_resource_start(&hash_id);
if godot::engine::FileAccess::file_exists(
format!("res://content/{}.remap", file_hash).into(),
) {
let resource_optimized_path = format!("res://content/{}.remap", file_hash);
DclGlobal::singleton().call(
"async_load_threaded".into(),
&[
resource_optimized_path.to_variant(),
promise.clone().to_variant(),
],
);
} else {
let url = format!(
"{}{}",
content_mapping.bind().get_base_url(),
file_hash.clone()
);
let content_provider_context = self.get_context();

loading_resources.fetch_add(1, Ordering::Relaxed);
let loading_resources = self.loading_resources.clone();
let loaded_resources = self.loaded_resources.clone();
let hash_id = file_hash.clone();
TokioRuntime::spawn(async move {
#[cfg(feature = "use_resource_tracking")]
report_resource_start(&hash_id);

let result = load_image_texture(url, hash_id.clone(), content_provider_context).await;
loading_resources.fetch_add(1, Ordering::Relaxed);

#[cfg(feature = "use_resource_tracking")]
if let Err(error) = &result {
report_resource_error(&hash_id, &error.to_string());
} else {
report_resource_loaded(&hash_id);
}
let result =
load_image_texture(url, hash_id.clone(), content_provider_context).await;

then_promise(get_promise, result);
#[cfg(feature = "use_resource_tracking")]
if let Err(error) = &result {
report_resource_error(&hash_id, &error.to_string());
} else {
report_resource_loaded(&hash_id);
}

loaded_resources.fetch_add(1, Ordering::Relaxed);
});
then_promise(get_promise, result);

loaded_resources.fetch_add(1, Ordering::Relaxed);
});
}

self.cached.insert(
file_hash,
Expand Down
4 changes: 4 additions & 0 deletions lib/src/content/resource_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ impl ResourceProvider {
#[cfg(feature = "use_resource_tracking")]
let mut current_size = 0;

if !response.status().is_success() {
return Err(format!("Failed to download file: {:?}", response.status()));
}

let mut file = fs::File::create(&tmp_dest)
.await
.map_err(|e| format!("File creation error: {:?}", e))?;
Expand Down

0 comments on commit 9b383cc

Please sign in to comment.