Question by
wmaass88 · Feb 27, 2018 at 01:19 AM ·
matrix4x4.trs
Populating SpeeTree instances with a SWA file.
Hello,
I am trying to parse a SWA file and place a mass amount of SpeedTree trees. See SWA format below:
https://docs.speedtree.com/doku.php?id=swa_files
I can parse the file just fine but I am stuck on how to deal with the up/right vectors and scale values to properly position, rotate and scale the tree. My efforts so far produce lots of anomalies. The trees appear to move or shrink/grow as I move the camera, some trees are not rotated correctly, and more ugliness. I took a shot at using Matrix4x4 and SetTRS but this stuff is above my pay grade. My rough parser/populate function is below, any advice is greatly appreciated.
public void getFoliage(){
string line = "";
int sectionCount = 0;
string species = "none";
string subSpecies = "none";
string file = "none";
string path = Application.dataPath + "/test.swa";
StreamReader sr = new StreamReader (path);
if (sr != null) {
while (!sr.EndOfStream) {
line = sr.ReadLine ();
//see if we have encountered a new section of foliage in the swa file
if (line.Contains ("/")) {
//get the species info
string[] speciesInfo = line.Split("/"[0]);
species = speciesInfo [0];
subSpecies = speciesInfo [1];
file = speciesInfo [2].Remove(speciesInfo [2].Length - 4);
//get the count of this section
sectionCount = int.Parse (sr.ReadLine());
for (int i = 0; i <= sectionCount -1; i++)
{
//read and splt the line in
string[] temp = sr.ReadLine ().Split (" " [0]);
//create the position, up vector, right vector and scale
//note ST uses Z as up so we swap the values when assinging them
Vector3 position = new Vector3(float.Parse(temp[0]),float.Parse(temp[2]),float.Parse(temp[1]));
Vector3 upVector = new Vector3 (float.Parse (temp [3]), float.Parse (temp [5]), float.Parse (temp [4]));
Vector3 rightVector = new Vector3 (float.Parse (temp [6]), float.Parse (temp [8]), float.Parse (temp [7]));
float scale = float.Parse (temp [9]);
//create a vector3 for scaling in Unity
Vector3 scalerVal = new Vector3 (scale, scale, scale);
//create the rotation vector?
Vector3 v3 = Vector3.Cross (upVector, rightVector).normalized * Mathf.Rad2Deg;
Quaternion rotation = Quaternion.Euler(v3.x, v3.y, v3.z);
//instantiate the object
GameObject tempSt = (Instantiate(Resources.Load(file), position, Quaternion.identity) as GameObject);
//create an array of mesh filters to hold the tree and its LOD meshes
Component[] mf;
mf = tempSt.transform.GetComponentsInChildren<MeshFilter>();
int filter = 0;
foreach (MeshFilter m in mf) {
Vector3[] origVerts;
Vector3[] newVerts;
origVerts = m.mesh.vertices;
newVerts = new Vector3[origVerts.Length];
Matrix4x4 mt = Matrix4x4.identity;
mt.SetTRS(position, rotation, scalerVal);
int t = 0;
while (t < origVerts.Length) {
newVerts[t] = mt.MultiplyPoint3x4(origVerts[t]);
t++;
}
m.mesh.vertices = newVerts;
}
}
}
}
sr.Close();
}
}
}
Comment