Last active
April 11, 2021 20:00
-
-
Save ale2x72/d06da6cd940779dd712a022d98dadc98 to your computer and use it in GitHub Desktop.
Instantiate objects in Unity importing orientation from a Rhino file in t;O;X;Y;Z format (coordinates are comma separated) - see example file ZZ_Assemblage.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using UnityEngine; | |
public class ReadAssemblage : MonoBehaviour | |
{ | |
public bool debugMode; | |
[Range(0.5f, 5)] | |
public float axisLength; | |
[Header("AssemblyObjects")] | |
public GameObject[] AssemblyObjects; | |
public string fileName; | |
GameObject[] assemblage; | |
Vector3[] forwardVecs; | |
// Start is called before the first frame update | |
void Start() | |
{ | |
fileName = Application.dataPath + "\\" + fileName; | |
string[] data = File.ReadAllLines(fileName); | |
GameObject Collector = new GameObject("Assemblage"); | |
Collector.transform.position = Vector3.zero; | |
Collector.transform.rotation = Quaternion.identity; | |
assemblage = new GameObject[data.Length]; | |
forwardVecs = new Vector3[data.Length]; | |
for (int i = 0; i < data.Length; i++) | |
{ | |
// plantype structure: 0=type, 1=origin, 2=x, 3=y, 4=z | |
// separate type from plane OXYZ data | |
string[] planeType = data[i].Split(';'); | |
int type = Convert.ToInt32(planeType[0]); | |
string[][] vectors = new string[4][]; | |
for (int j = 1; j < planeType.Length; j++) | |
{ | |
vectors[j - 1] = 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); | |
forwardVecs[i] = fwVector; | |
Quaternion rot = Quaternion.identity; | |
// instantiate GameObject | |
assemblage[i] = Instantiate(AssemblyObjects[type], origin, rot); | |
assemblage[i].name = AssemblyObjects[type].name + "_" + i; | |
// align with up vector first | |
assemblage[i].transform.up = upVector; | |
// compute angle between current forward and target forward | |
float angle = Vector3.Angle(assemblage[i].transform.forward, forwardVecs[i]); | |
// rotate aling up vector | |
assemblage[i].transform.Rotate(0, angle, 0); | |
float newAngle = Vector3.Angle(assemblage[i].transform.forward, forwardVecs[i]); | |
// check if the rotation direction was wrong - in case rotate back twice | |
if (newAngle > 0.5) | |
assemblage[i].transform.Rotate(0, -2 * angle, 0); | |
// assign to parent | |
assemblage[i].transform.parent = Collector.transform; | |
float newDotProduct = Vector3.Dot(assemblage[i].transform.forward, forwardVecs[i]); | |
// check for outliers | |
if (1 - newDotProduct > 0.001) | |
Debug.Log(assemblage[i].name + " - angle: " + angle + " - newAngle: " + newAngle); | |
} | |
} | |
// 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); | |
} | |
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); | |
} | |
// Update is called once per frame | |
void Update() | |
{ | |
if (debugMode) | |
for (int i = 0; i < assemblage.Length; i++) | |
{ | |
DrawTransform(assemblage[i].transform, axisLength); | |
DrawVector(assemblage[i].transform.position, forwardVecs[i], 10, Color.black); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
0;0.000,-100.000,0.000;1.000,0.000,0.000;0.000,1.000,0.000;0.000,0.000,1.000 | |
0;6.111,-106.111,-0.222;0.000,-1.000,0.000;0.000,0.000,-1.000;1.000,0.000,0.000 | |
0;8.000,-96.222,0.000;1.000,0.000,0.000;0.000,0.000,1.000;0.000,-1.000,0.000 | |
1;-7.500,-100.111,-3.611;0.000,0.000,-1.000;1.000,0.000,0.000;0.000,-1.000,0.000 | |
1;-1.500,-101.611,3.889;-1.000,0.000,0.000;0.000,1.000,0.000;0.000,0.000,-1.000 | |
1;10.000,-104.611,1.389;0.000,1.000,0.000;0.000,0.000,-1.000;-1.000,0.000,0.000 | |
1;-3.500,-107.611,3.889;0.000,-1.000,0.000;1.000,0.000,0.000;0.000,0.000,1.000 | |
1;-2.500,-105.611,-0.111;1.000,0.000,0.000;0.000,1.000,0.000;0.000,0.000,1.000 | |
0;-8.000,-96.000,4.000;1.000,0.000,0.000;0.000,1.000,0.000;0.000,0.000,1.000 | |
0;5.889,-114.111,3.778;0.000,1.000,0.000;0.000,0.000,-1.000;-1.000,0.000,0.000 | |
0;10.111,-112.000,5.889;0.000,0.000,1.000;1.000,0.000,0.000;0.000,1.000,0.000 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment