Skip to content

Instantly share code, notes, and snippets.

@ale2x72
Last active June 11, 2022 14:00
Show Gist options
  • Save ale2x72/4d6b5c36be6379e1992168682fd8b007 to your computer and use it in GitHub Desktop.
Save ale2x72/4d6b5c36be6379e1992168682fd8b007 to your computer and use it in GitHub Desktop.
Read Assemblage 20220611
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEditor;
/*
Script by Alessio Erioli - Co-de-iT
(c) Co-de-iT 2022
*/
[ExecuteInEditMode]
public class ReadAssemblage : MonoBehaviour
{
public AssetCouple[] assetCouples;
GameObject[][] assemblage;
// for debug purposes
// Vector3[][] forwardVecs;
[Serializable]
public class AssetCouple
{
[Tooltip("Drag and drop a prefab here")]
public GameObject prefab;
[Tooltip("Drag and drop a .csv file here")]
public TextAsset planesFile;
}
// for debug purposes
//public bool debugMode;
//[Range(0.5f, 5)]
//public float axisLength;
private void Awake()
{
}
// Start is called before the first frame update
void Start()
{
LoadPlanes();
}
// Update is called once per frame
void Update()
{
// for debug purposes
// if (debugMode) DebugDraw();
}
public void LoadPlanes()//AssetCouple[] assetCouples)
{
// Load only if in Editor and another Assemblage does not exist
if (Application.isPlaying || GameObject.Find("Assemblage") != null) return;
string filePath = Application.dataPath + "\\Assemblages\\";
GameObject Collector = new GameObject("Assemblage");
Collector.transform.position = Vector3.zero;
Collector.transform.rotation = Quaternion.identity;
assemblage = new GameObject[assetCouples.Length][];
//forwardVecs = new Vector3[assetCouples.Length][]; // for debug purposes
for (int k = 0; k < assetCouples.Length; k++)
{
//string[] data = File.ReadAllLines(filePath + assetCouples[k].planesFile);
string[] data = assetCouples[k].planesFile.text.Split(Environment.NewLine.ToCharArray()[0]);
//forwardVecs[k] = new Vector3[data.Length]; // for debug purposes
assemblage[k] = new GameObject[data.Length];
for (int i = 0; i < data.Length; i++)
{
// plane structure: 0=origin, 1=x, 2=y, 3=z
// separate type from plane OXYZ data
string[] planeType = data[i].Split(';');
//int type = Convert.ToInt32(planeType[0]); // comment this line
if (planeType.Length < 4) continue;
string[][] vectors = new string[4][];
for (int j = 0; j < planeType.Length; j++)
{
vectors[j] = planeType[j].Split(',');
}
Vector3 planeO, planeX, planeY, planeZ;
planeO = new Vector3(Convert.ToSingle(vectors[0][0]), Convert.ToSingle(vectors[0][1]), Convert.ToSingle(vectors[0][2]));
planeX = new Vector3(Convert.ToSingle(vectors[1][0]), Convert.ToSingle(vectors[1][1]), Convert.ToSingle(vectors[1][2]));
planeY = new Vector3(Convert.ToSingle(vectors[2][0]), Convert.ToSingle(vectors[2][1]), Convert.ToSingle(vectors[2][2]));
planeZ = new Vector3(Convert.ToSingle(vectors[3][0]), Convert.ToSingle(vectors[3][1]), Convert.ToSingle(vectors[3][2]));
Vector3 origin = ToLeftHanded(planeO);
Vector3 fwVector = -ToLeftHanded(planeY);
Vector3 upVector = ToLeftHanded(planeZ);
Vector3 rightVector = -ToLeftHanded(planeX);
//forwardVecs[k][i] = fwVector; // for debug purposes
Quaternion rotated = QuaternionFromVectors(rightVector, upVector, fwVector);
// Instantiate as prefabs
// see: https://irfanbaysal.medium.com/instantiate-vs-prefabutility-instantiateprefab-747f43b5d717
Selection.activeObject = PrefabUtility.InstantiatePrefab(assetCouples[k].prefab, Collector.transform);
var tempPrefab = Selection.activeGameObject;
tempPrefab.transform.position = origin;
tempPrefab.transform.rotation = rotated;
// instantiate as GameObject (Clone)
//assemblage[k][i] = Instantiate(assetCouples[k].prefab, origin, rotated);
// assign to parent
//assemblage[k][i].transform.parent = Collector.transform;
// mark as static
//assemblage[k][i].isStatic = true;
// for debug purposes
//float newDotProduct = Vector3.Dot(assemblage[k][i].transform.forward, forwardVecs[k][i]);
//// check for outliers
//if (1 - newDotProduct > 0.001)
// Debug.Log(assemblage[k][i].name + " - angle: " + Mathf.Acos(newDotProduct));
}
}
}
// Note: Rhino right-handed XYZ orientation is translated in Unity's Left-Handed XZY
// to match how .OBJ are imported with the "Remap Z to OBJ Y" option when exporting from Rhino
// to account for the right-to-left hand transition, x and y coordinates become negative,
// and y and z are swapped
Vector3 ToLeftHanded(Vector3 vector)
{
return new Vector3(-vector.x, vector.z, -vector.y);
}
// code from Martin Baker
// https://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/
Quaternion QuaternionFromVectors(Vector3 XAxis, Vector3 YAxis, Vector3 ZAxis)
{
float m00, m01, m02, m10, m11, m12, m20, m21, m22;
float qx, qy, qz, qw;
// build the plane rotation matrix (mRC - R - row index, C - column index)
m00 = XAxis.x;
m10 = XAxis.y;
m20 = XAxis.z;
m01 = YAxis.x;
m11 = YAxis.y;
m21 = YAxis.z;
m02 = ZAxis.x;
m12 = ZAxis.y;
m22 = ZAxis.z;
float tr = m00 + m11 + m22;
float S;
if (tr > 0)
{
S = Mathf.Sqrt(tr + 1.0f) * 2; // S=4*qw
qw = 0.25f * S;
qx = (m21 - m12) / S;
qy = (m02 - m20) / S;
qz = (m10 - m01) / S;
}
else if ((m00 > m11) & (m00 > m22))
{
S = Mathf.Sqrt(1.0f + m00 - m11 - m22) * 2; // S=4*qx
qw = (m21 - m12) / S;
qx = 0.25f * S;
qy = (m01 + m10) / S;
qz = (m02 + m20) / S;
}
else if (m11 > m22)
{
S = Mathf.Sqrt(1.0f + m11 - m00 - m22) * 2; // S=4*qy
qw = (m02 - m20) / S;
qx = (m01 + m10) / S;
qy = 0.25f * S;
qz = (m12 + m21) / S;
}
else
{
S = Mathf.Sqrt(1.0f + m22 - m00 - m11) * 2; // S=4*qz
qw = (m10 - m01) / S;
qx = (m02 + m20) / S;
qy = (m12 + m21) / S;
qz = 0.25f * S;
}
return new Quaternion(qx, qy, qz, qw);
}
// for debug purposes only
//
//void DrawTransform(Transform t, float len)
//{
// Debug.DrawLine(t.position, t.position + t.forward * len, Color.cyan);
// Debug.DrawLine(t.position, t.position + t.up * len, Color.green);
// Debug.DrawLine(t.position, t.position + t.right * len, Color.red);
//}
//void DrawVector(Vector3 anchor, Vector3 vector, float len, Color col)
//{
// Debug.DrawLine(anchor, anchor + vector * len, col);
//}
//void DebugDraw()
//{
// for (int i = 0; i < assemblage.Length; i++)
// for (int j = 0; j < assemblage[i].Length; j++)
// {
// DrawTransform(assemblage[i][j].transform, axisLength);
// DrawVector(assemblage[i][j].transform.position, forwardVecs[i][j], 10, Color.black);
// }
//}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment