ThrowBall/Assets/Plugins/RayFire/Scripts/Classes/RFSnapshot.cs

212 lines
6.5 KiB
C#

#if UNITY_EDITOR
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
// Namespace
namespace RayFire
{
// Single object snapshot data
[Serializable]
public class RFSnapshot
{
// Vars
public string nm;
// Ids
public int oldId;
public int parentOldId;
public int newId;
[NonSerialized]public Transform newTm;
public Vector3 pos;
public Quaternion rot;
public Vector3 scale;
public List<string> mats;
public RFMesh mesh;
// Constructor
public RFSnapshot(GameObject go, bool compress)
{
nm = go.name;
oldId = go.GetInstanceID();
if (go.transform.parent != null)
parentOldId = go.transform.parent.gameObject.GetInstanceID();
pos = go.transform.position;
rot = go.transform.rotation;
scale = go.transform.localScale;
// Mesh
MeshFilter mf = go.GetComponent<MeshFilter>();
if (mf != null)
mesh = new RFMesh (mf.sharedMesh, compress);
// Materials
MeshRenderer mr = go.GetComponent<MeshRenderer>();
mats = new List<string>();
if (mr != null)
foreach (var mat in mr.sharedMaterials)
mats.Add (AssetDatabase.GetAssetPath (mat));
}
// Create object
public static GameObject Create (RFSnapshot cap, float sizeFilter)
{
// Mesh and size filtering
Mesh mesh = null;
if (cap.mesh.subMeshCount > 0)
{
// Size filtering
if (cap.mesh.bounds.size.magnitude < sizeFilter)
return null;
// Get mesh
mesh = cap.mesh.GetMesh();
}
// Object
GameObject go = new GameObject();
go.name = cap.nm;
go.transform.position = cap.pos;
go.transform.rotation = cap.rot;
go.transform.localScale = cap.scale;
// Mesh
if (mesh != null)
{
MeshFilter mf = go.AddComponent<MeshFilter>();
mf.sharedMesh = mesh;
}
// Materials
if (cap.mats.Count > 0)
{
MeshRenderer mr = go.AddComponent<MeshRenderer>();
List<Material> materials = new List<Material>(cap.mats.Count);
foreach (var matPath in cap.mats)
materials.Add ((Material)AssetDatabase.LoadAssetAtPath (matPath, typeof(Material)));
mr.sharedMaterials = materials.ToArray();
}
cap.newId = go.GetInstanceID();
cap.newTm = go.transform;
return go;
}
// Get parent new id by old id
public static void SetParent (List<RFSnapshot> list, int parentId, Transform tm, Transform parentTm)
{
foreach (var snap in list)
{
if (snap.oldId == parentId)
{
tm.parent = snap.newTm;
break;
}
tm.parent = parentTm;
}
}
}
// Snapshot asset
[Serializable]
public class RFSnapshotAsset
{
// Vars
public List<RFSnapshot> assets;
// Constructor
public RFSnapshotAsset()
{
assets = new List<RFSnapshot>();
}
// Constructor
public RFSnapshotAsset(List<GameObject> list, bool compress)
{
assets = new List<RFSnapshot>(list.Count);
foreach (var go in list)
assets.Add (new RFSnapshot (go, compress));
}
// Save asset
public static void Snapshot(GameObject gameObject, bool compress, string assetName)
{
// Get all nested game objects
List<Transform> tms = gameObject.GetComponentsInChildren<Transform>().ToList();
tms.Remove (gameObject.transform);
// No asset
if (tms.Count == 0)
{
Debug.Log ("RayFire Snapshot: " + gameObject.name + " has no children", gameObject);
return;
}
// Create asset data
List<GameObject> list = tms.Select (t => t.gameObject).ToList();
RFSnapshotAsset data = new RFSnapshotAsset (list, compress);
// Set Folder
string fld = Application.dataPath + "/RayFireSnapshots/";
if (Directory.Exists (fld) == false)
Directory.CreateDirectory(fld);
string nm = assetName + "_snapshot.json";
string stringData = JsonUtility.ToJson (data, true);
// Save data
File.WriteAllText (fld + nm, stringData);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
// Load asset
public static void Load(UnityEngine.Object snapshotAsset, GameObject gameObject, float sizeFilter)
{
// No asset
if (snapshotAsset == null)
{
Debug.Log ("RayFire Snapshot: " + gameObject.name + " Snapshot asset is not defined", gameObject);
return;
}
// Get path
string path1 = Application.dataPath;
string path2 = AssetDatabase.GetAssetPath(snapshotAsset);
path2 = path2.Remove (0, 6);
// Read
string dataString = File.ReadAllText (path1 + path2);
RFSnapshotAsset assetData = JsonUtility.FromJson<RFSnapshotAsset> (dataString);
// No asset
if (assetData == null)
{
Debug.Log ("RayFire Snapshot: " + gameObject.name + " Snapshot asset is not defined", gameObject);
return;
}
// Create objects from asset
if (assetData.assets.Count > 0)
foreach (var ast in assetData.assets)
RFSnapshot.Create (ast, sizeFilter);
// Set parents
foreach (var snap in assetData.assets)
{
RFSnapshot.SetParent (assetData.assets, snap.parentOldId, snap.newTm, gameObject.transform);
}
}
}
}
#endif