Skip to content

Commit 9157786

Browse files
epernodfredroy
andcommitted
[Full API][src] Update SofaUnity scripts to support android build (#63)
* handle android (no plugins, assert unzip/zip into stream). NEED SHAPZIPLIB ! * fix action timing * add SharpZipCommands * add action which will zip ALL the assets folder and set it into StreamingAssets --------- Co-authored-by: Frederick Roy <fredroy@users.noreply.github.com>
1 parent a3f2698 commit 9157786

7 files changed

Lines changed: 171 additions & 19 deletions

File tree

Plugins/SofaUnityAPI/SofaContextAPI.cs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using UnityEngine;
33
using System.Runtime.InteropServices;
4+
using System.Collections.Generic;
45

56
namespace SofaUnityAPI
67
{
@@ -18,6 +19,44 @@ public class SofaContextAPI : IDisposable
1819

1920
private bool m_isReady = false;
2021

22+
public static string getResourcesPath()
23+
{
24+
#if UNITY_ANDROID && !UNITY_EDITOR
25+
return Application.persistentDataPath;
26+
#else
27+
return Application.dataPath;
28+
#endif
29+
}
30+
31+
void CopyAssetToPersistent()
32+
{
33+
string sofaUnityResourcesPath = getResourcesPath() + "/SofaUnity";
34+
#if UNITY_STANDALONE_WIN && !UNITY_EDITOR && TEST_PERSISTENT_WIN // to test the zip/unzip mechanism on Windows
35+
// Merely a test to see if it is really doing its job
36+
Debug.Log("unzipping to persistent data path (windows)");
37+
Utility_SharpZipCommands.ExtractTGZ (Application.streamingAssetsPath + "/" + "Data.tgz",Application.persistentDataPath);
38+
#endif
39+
#if UNITY_ANDROID && !UNITY_EDITOR
40+
//if stub file Resources.data doesn't exist, extract default data...
41+
if (File.Exists(sofaUnityResourcesPath + "/" + "Resources.data") == false)
42+
{
43+
Debug.Log("Resources.data doesn't exist, creating it for the first time.");
44+
//copy tgz to directory where we can extract it
45+
WWW www = new WWW(Application.streamingAssetsPath + "/Resources.tgz");
46+
while (!www.isDone) { }
47+
System.IO.File.WriteAllBytes(Application.persistentDataPath + "/" + "Resources.tgz", www.bytes);
48+
//extract it
49+
Utility_SharpZipCommands.ExtractTGZ(Application.persistentDataPath + "/" + "Resources.tgz", sofaUnityResourcesPath);
50+
//delete tgz
51+
File.Delete(Application.persistentDataPath + "/" + "Resources.tgz");
52+
}
53+
else
54+
{
55+
Debug.Log("Resources.data does exist, will not extract default data.");
56+
}
57+
#endif
58+
}
59+
2160
/// Default constructor, will create the pointer to SofaPhysicsAPI
2261
public SofaContextAPI(bool async)
2362
{
@@ -34,6 +73,13 @@ public SofaContextAPI(bool async)
3473
return;
3574
}
3675

76+
// Prepare Data
77+
Debug.Log("data:" + Application.dataPath);
78+
Debug.Log("persistent:" + Application.persistentDataPath);
79+
Debug.Log("streaming:" + Application.streamingAssetsPath);
80+
81+
CopyAssetToPersistent();
82+
3783
// load the sofaIni file
3884
string pathIni = Application.dataPath + "/SofaUnity/Plugins/Native/x64/sofa.ini";
3985
string sharePath = sofaPhysicsAPI_loadSofaIni(m_native, pathIni);
@@ -63,7 +109,6 @@ public SofaContextAPI(bool async)
63109
Dispose();
64110
}
65111

66-
67112
/// Dispose method to release the object
68113
public void Dispose()
69114
{

Scripts/Core/System/PluginManager.cs

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -191,20 +191,42 @@ public void ClearSavedPlugin()
191191
}
192192

193193

194-
/// Method to load the plugins one by one from the list of enable plugins
195-
public void LoadPlugins()
194+
public string getPluginFullPrefixPath()
196195
{
197196
string pluginPath = "";
198197
if (Application.isEditor)
199198
pluginPath = "/SofaUnity/Plugins/Native/x64/";
200199
else
200+
#if UNITY_ANDROID
201+
pluginPath = "/Plugins/Android/";
202+
#else
201203
pluginPath = "/Plugins/x86_64/";
204+
#endif
205+
return Application.dataPath + pluginPath + "/";
206+
}
207+
208+
public string getPluginFullName(string pluginName)
209+
{
210+
string pluginFullPath = "";
211+
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
212+
pluginFullPath = pluginName + ".dll";
213+
#elif UNITY_EDITOR_LINUX || UNITY_STANDALONE_LINUX || UNITY_ANDROID
214+
pluginFullPath = "lib" + pluginName + ".so";
215+
#endif
216+
return pluginFullPath;
217+
}
218+
219+
/// Method to load the plugins one by one from the list of enable plugins
220+
public void LoadPlugins()
221+
{
222+
string fullPrefixPath = getPluginFullPrefixPath();
202223

203224
// Internally load all default plugins from core and module
204-
m_sofaAPI.loadDefaultPlugins(Application.dataPath + pluginPath);
225+
m_sofaAPI.loadDefaultPlugins(fullPrefixPath);
205226

206227
foreach (string pluginName in m_savedPlugins)
207228
{
229+
string fullPluginPath = getPluginFullPrefixPath() + getPluginFullName(pluginName);
208230
#if UNITY_EDITOR
209231
Plugin plug = PluginManager.Instance.GetPluginByName(pluginName);
210232
if (plug == null || plug.IsAvailable == false)
@@ -215,24 +237,19 @@ public void LoadPlugins()
215237
else
216238
{
217239
plug.IsEnable = true;
218-
m_sofaAPI.loadPlugin(Application.dataPath + pluginPath + pluginName + ".dll");
240+
m_sofaAPI.loadPlugin(fullPluginPath);
219241
}
220242
#else
221-
m_sofaAPI.loadPlugin(Application.dataPath + pluginPath + pluginName + ".dll");
243+
m_sofaAPI.loadPlugin(fullPluginPath);
222244
#endif
223245
}
224246
}
225247

226-
227248
public void LoadPlugin(string pluginName)
228249
{
229-
string pluginPath = "";
230-
if (Application.isEditor)
231-
pluginPath = "/SofaUnity/Plugins/Native/x64/";
232-
else
233-
pluginPath = "/Plugins/x86_64/";
250+
string fullPluginPath = getPluginFullPrefixPath() + getPluginFullName(pluginName);
234251

235-
m_sofaAPI.loadPlugin(Application.dataPath + pluginPath + pluginName + ".dll");
252+
m_sofaAPI.loadPlugin(fullPluginPath);
236253
}
237254

238255

Scripts/Core/System/SceneFileManager.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public string PythonSceneFilename
9696
/// method to get the full path of the file inside the unity asset
9797
public string AbsoluteFilename()
9898
{
99-
return Application.dataPath + m_filename;
99+
return SofaContextAPI.getResourcesPath() + m_filename;
100100
}
101101

102102

@@ -108,7 +108,7 @@ public string AbsoluteFilename()
108108
/// Internal method to check if the filename is valid
109109
protected bool CheckValidFilename(string newFilename)
110110
{
111-
if (!File.Exists(Application.dataPath + newFilename)) // if not found test with relative path
111+
if (!File.Exists(SofaContextAPI.getResourcesPath() + newFilename)) // if not found test with relative path
112112
{
113113
int pos = newFilename.IndexOf("Assets", 0);
114114
if (pos > 0)
@@ -122,7 +122,7 @@ protected bool CheckValidFilename(string newFilename)
122122
newFilename = "/SofaUnity/" + newFilename;
123123
}
124124

125-
if (!File.Exists(Application.dataPath + newFilename)) // try again with relative path
125+
if (!File.Exists(SofaContextAPI.getResourcesPath() + newFilename)) // try again with relative path
126126
{
127127
return false;
128128
}

Scripts/SofaContext.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,8 +378,9 @@ void Init()
378378
m_pluginMgr.SetSofaContextAPI(m_impl);
379379

380380
// Load SOFA plugins
381+
#if !UNITY_ANDROID
381382
m_pluginMgr.LoadPlugins();
382-
383+
#endif
383384
// start sofa instance
384385
if (m_log)
385386
Debug.Log("## SofaContext status before start: " + m_impl.contextStatus());

Scripts/Utils/GenerateZIP.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using UnityEditor;
2+
using UnityEngine;
3+
4+
#if UNITY_EDITOR
5+
public class GenerateZIP
6+
{
7+
[MenuItem("Assets/Build ZIP")]
8+
static void BuildZIP()
9+
{
10+
string dataDirectory = Application.dataPath + "/SofaUnity/";
11+
string fileToCreate = Application.streamingAssetsPath + "/Resources.tgz";
12+
13+
Utility_SharpZipCommands.CreateTarGZ_FromDirectory(fileToCreate, dataDirectory);
14+
}
15+
}
16+
#endif

Scripts/Utils/KeyActionsRecorder.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
public class KeyActionsRecorder : MonoBehaviour
77
{
8-
98
public bool recordMode = true;
109
public SofaObjectController m_controller = null;
1110

@@ -18,6 +17,9 @@ public class KeyActionsRecorder : MonoBehaviour
1817
// Start is called before the first frame update
1918
void Start()
2019
{
20+
#if UNITY_ANDROID && !UNITY_EDITOR
21+
recordMode = false;
22+
#endif
2123
step = 0;
2224
if(!recordMode)
2325
{
@@ -39,7 +41,7 @@ void FixedUpdate()
3941
if (step >= m_keysTime.Count || m_controller == null)
4042
return;
4143

42-
if (Mathf.Abs(currentTime - m_keysTime[step]) < 0.01) // change action
44+
if (currentTime >= m_keysTime[step]) // change action
4345
{
4446
currentAction = m_keysAction[step];
4547

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using System.IO;
2+
using Unity.SharpZipLib.GZip;
3+
using Unity.SharpZipLib.Tar;
4+
5+
public class Utility_SharpZipCommands
6+
{
7+
8+
//// Calling example
9+
//CreateTarGZ(@"c:\temp\gzip-test.tar.gz", @"c:\data");
10+
11+
//USE THIS:
12+
public static void CreateTarGZ_FromDirectory(string tgzFilename, string sourceDirectory)
13+
{
14+
15+
Stream outStream = File.Create(tgzFilename);
16+
Stream gzoStream = new GZipOutputStream(outStream);
17+
TarArchive tarArchive = TarArchive.CreateOutputTarArchive(gzoStream);
18+
19+
// Note that the RootPath is currently case sensitive and must be forward slashes e.g. "c:/temp"
20+
// and must not end with a slash, otherwise cuts off first char of filename
21+
// This is scheduled for fix in next release
22+
tarArchive.RootPath = sourceDirectory.Replace('\\', '/');
23+
if (tarArchive.RootPath.EndsWith("/"))
24+
tarArchive.RootPath = tarArchive.RootPath.Remove(tarArchive.RootPath.Length - 1);
25+
26+
AddDirectoryFilesToTar(tarArchive, sourceDirectory, true);
27+
28+
tarArchive.Close();
29+
}
30+
31+
public static void AddDirectoryFilesToTar(TarArchive tarArchive, string sourceDirectory, bool recurse)
32+
{
33+
34+
// Optionally, write an entry for the directory itself.
35+
// Specify false for recursion here if we will add the directory's files individually.
36+
//
37+
TarEntry tarEntry = TarEntry.CreateEntryFromFile(sourceDirectory);
38+
tarArchive.WriteEntry(tarEntry, false);
39+
40+
// Write each file to the tar.
41+
//
42+
string[] filenames = Directory.GetFiles(sourceDirectory);
43+
foreach (string filename in filenames)
44+
{
45+
tarEntry = TarEntry.CreateEntryFromFile(filename);
46+
tarArchive.WriteEntry(tarEntry, true);
47+
}
48+
49+
if (recurse)
50+
{
51+
string[] directories = Directory.GetDirectories(sourceDirectory);
52+
foreach (string directory in directories)
53+
AddDirectoryFilesToTar(tarArchive, directory, recurse);
54+
}
55+
}
56+
57+
public static void ExtractTGZ(string gzArchiveName, string destFolder)
58+
{
59+
Stream inStream = File.OpenRead(gzArchiveName);
60+
Stream gzipStream = new GZipInputStream(inStream);
61+
62+
TarArchive tarArchive = TarArchive.CreateInputTarArchive(gzipStream);
63+
tarArchive.ExtractContents(destFolder);
64+
tarArchive.Close();
65+
66+
gzipStream.Close();
67+
inStream.Close();
68+
69+
}
70+
71+
} // Calling example

0 commit comments

Comments
 (0)