Skip to content

Commit

Permalink
Web assets support
Browse files Browse the repository at this point in the history
  • Loading branch information
AlvaroHG committed Oct 24, 2024
1 parent 221d61d commit 9a013c7
Showing 1 changed file with 81 additions and 57 deletions.
138 changes: 81 additions & 57 deletions unity/Assets/Scripts/BaseFPSAgentController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using MessagePack;
using MessagePack.Formatters;
using MessagePack.Resolvers;
Expand All @@ -22,6 +22,7 @@
using UnityStandardAssets.CrossPlatformInput;
using UnityStandardAssets.ImageEffects;
using UnityStandardAssets.Utility;
using Diagnostics = System.Diagnostics;
using Random = UnityEngine.Random;

namespace UnityStandardAssets.Characters.FirstPerson {
Expand Down Expand Up @@ -7602,7 +7603,7 @@ string backTexturePath
actionFinished(true);
}

public ActionFinished CreateRuntimeAsset(ProceduralAsset asset) {
public ActionFinished CreateRuntimeAsset(ProceduralAsset asset, bool returnObject = false) {
var assetDb = GameObject.FindObjectOfType<ProceduralAssetDatabase>();
if (assetDb.ContainsAssetKey(asset.name)) {
return new ActionFinished(
Expand All @@ -7627,27 +7628,20 @@ public ActionFinished CreateRuntimeAsset(ProceduralAsset asset) {
annotations: asset.annotations,
receptacleCandidate: asset.receptacleCandidate,
yRotOffset: asset.yRotOffset,
returnObject: returnObject,
serializable: asset.serializable,
parentTexturesDir: asset.parentTexturesDir
);
return new ActionFinished { success = true, actionReturn = assetData };
}

public ActionFinished CreateRuntimeAsset(
private static async Task<ProceduralAsset> LoadAssetAsync(
string id,
string dir,
string extension = ".msgpack.gz",
ObjectAnnotations annotations = null,
bool serializable = false
) {
var assetDb = GameObject.FindObjectOfType<ProceduralAssetDatabase>();
if (assetDb.ContainsAssetKey(id)) {
return new ActionFinished(
success: false,
errorMessage: $"'{id}' already exists in ProceduralAssetDatabase, trying to create procedural object twice, call `SpawnAsset` instead.",
toEmitState: true
);
}
var validDirs = new List<string>()
{
Application.persistentDataPath,
Expand All @@ -7663,20 +7657,14 @@ public ActionFinished CreateRuntimeAsset(
extension = !extension.StartsWith(".") ? $".{extension}" : extension;
extension = extension.Trim();
if (!supportedExtensions.Contains(extension)) {
return new ActionFinished(
success: false,
errorMessage: $"Unsupported extension `{extension}`. Only supported: {string.Join(", ", supportedExtensions)}",
actionReturn: null
throw new ArgumentException(
$"Unsupported extension `{extension}`. Only supported: {string.Join(", ", supportedExtensions)}"
);
}
var filename = $"{id}{extension}";
var filepath = Path.GetFullPath(Path.Combine(dir, id, filename));
if (!File.Exists(filepath)) {
return new ActionFinished(
success: false,
actionReturn: null,
errorMessage: $"Asset fiile '{filepath}' does not exist."
);
throw new FileNotFoundException($"Asset file '{filepath}' does not exist.");
}

// to support different
Expand Down Expand Up @@ -7716,43 +7704,46 @@ public ActionFinished CreateRuntimeAsset(
ObjectCreationHandling = ObjectCreationHandling.Replace
};
var json = reader.ReadToEnd();
// procAsset = Newtonsoft.Json.JsonConvert.DeserializeObject<ProceduralAsset>(reader.ReadToEnd(), serializer);
procAsset = JsonConvert.DeserializeObject<ProceduralAsset>(json);
} else {
return new ActionFinished(
success: false,
errorMessage: $"Unexpected error with extension `{extension}`, filepath: `{filepath}`, compression stages: {string.Join(".", presentStages)}. Only supported: {string.Join(", ", supportedExtensions)}",
actionReturn: null
throw new ArgumentException(
$"Unexpected error with extension `{extension}`, filepath: `{filepath}`, compression stages: {string.Join(".", presentStages)}. Only supported: {string.Join(", ", supportedExtensions)}"
);
}

procAsset.parentTexturesDir = Path.Combine(dir, id);

var assetData = ProceduralTools.CreateAsset(
vertices: procAsset.vertices,
normals: procAsset.normals,
name: procAsset.name,
triangles: procAsset.triangles,
uvs: procAsset.uvs,
albedoTexturePath: procAsset.albedoTexturePath,
metallicSmoothnessTexturePath: procAsset.metallicSmoothnessTexturePath,
normalTexturePath: procAsset.normalTexturePath,
emissionTexturePath: procAsset.emissionTexturePath,
colliders: procAsset.colliders,
physicalProperties: procAsset.physicalProperties,
visibilityPoints: procAsset.visibilityPoints,
annotations: procAsset.annotations ?? annotations,
receptacleCandidate: procAsset.receptacleCandidate,
yRotOffset: procAsset.yRotOffset,
returnObject: true,
serializable: serializable,
parent: null,
addAnotationComponent: false,
parentTexturesDir: procAsset.parentTexturesDir
);
return procAsset;
}

public ActionFinished CreateRuntimeAsset(
string id,
string dir,
string extension = ".msgpack.gz",
ObjectAnnotations annotations = null,
bool serializable = false
) {
var assetDb = GameObject.FindObjectOfType<ProceduralAssetDatabase>();
if (assetDb.ContainsAssetKey(id)) {
return new ActionFinished(
success: false,
errorMessage: $"'{id}' already exists in ProceduralAssetDatabase, trying to create procedural object twice, call `SpawnAsset` instead.",
toEmitState: true
);
}

var procAsset = LoadAssetAsync(
id: id,
dir: dir,
extension: extension,
annotations: annotations,
serializable: serializable
).Result;
procAsset.serializable = serializable;
procAsset.annotations = procAsset.annotations ?? annotations;

// Debug.Log($"root is null? {parent == null} - {parent}");
return new ActionFinished(success: true, actionReturn: assetData);
return CreateRuntimeAsset(asset: procAsset, returnObject: true);
}

public class UnityLoadableAsset {
Expand All @@ -7767,18 +7758,51 @@ public ActionFinished CreateRuntimeAssets(
List<UnityLoadableAsset> assets,
string dir = null
) {
foreach (var asset in assets) {
var actionFinished = CreateRuntimeAsset(
id: asset.id,
dir: dir ?? asset.dir,
extension: asset.extension,
annotations: asset.annotations
try {
#if UNITY_EDITOR
Diagnostics.Stopwatch stopWatch = new Diagnostics.Stopwatch();
stopWatch.Start();
#endif
// Load assets in parallel
var loadTasks = assets
.Select(asset =>
LoadAssetAsync(
id: asset.id,
dir: dir ?? asset.dir,
extension: asset.extension,
annotations: asset.annotations
)
)
.ToList();
Task.WhenAll(loadTasks).Wait();

var loadedAssets = loadTasks.Select(t => t.Result).ToList();

#if UNITY_EDITOR
stopWatch.Stop();
Debug.Log(
$"LoadAssetAsync took {stopWatch.ElapsedMilliseconds} ms, per asset time {stopWatch.ElapsedMilliseconds / assets.Count} ms"
);
if (!actionFinished.success) {
return actionFinished;
stopWatch.Restart();
#endif
// Create assets serially
foreach (var (asset, procAsset) in assets.Zip(loadedAssets, (a, p) => (a, p))) {
var actionFinished = CreateRuntimeAsset(asset: procAsset);
if (!actionFinished.success) {
return actionFinished;
}
}
#if UNITY_EDITOR
stopWatch.Stop();
Debug.Log(
$"CreateRuntimeAsset loop took {stopWatch.ElapsedMilliseconds} ms, per asset time {stopWatch.ElapsedMilliseconds / assets.Count} ms"
);
#endif

return ActionFinished.Success;
} catch (Exception ex) {
return new ActionFinished(success: false, errorMessage: ex.Message);
}
return ActionFinished.Success;
}

public void GetStreamingAssetsPath() {
Expand Down

0 comments on commit 9a013c7

Please sign in to comment.