private void GeneratePlant() { if (bottomPrefab != null) { root = (FractalPlantComponent)Instantiate(bottomPrefab); } else { root = (FractalPlantComponent)Instantiate(middlePrefab); } root.transform.parent = transform; root.transform.localPosition = Vector3.zero; root.transform.localRotation = Quaternion.identity; root.transform.localScale = Vector3.one; List<Vector3> termPositions = new List<Vector3>(); root.GenerateRecursive(height, maxRendererHeight, middlePrefab, topPrefab, ref termPositions); }
public void GenerateRecursive(int level, int maxRendererLevel, FractalPlantComponent selfPrefab, FractalPlantComponent termPrefab, ref List<Vector3> termPositions) { goalScale = transform.localScale; // higher levels are transform only if (level < maxRendererLevel) { Renderer[] r = GetComponentsInChildren<Renderer>(); for (int i = 0; i < r.Length; i++) { if (r[i].gameObject == gameObject) { DestroyImmediate(r[i]); } else { DestroyImmediate(r[i].gameObject); } } Collider c = GetComponentInChildren<Collider>(); if (c.gameObject == gameObject) { Destroy(c); } else { Destroy(c.gameObject); } } // rotate about upward axis if (randomizeYRotation) { transform.Rotate(Vector3.up, Random.Range(0f, 360f), Space.Self); } // rotate random angle if (maxAngle > 0f) { transform.Rotate(fromAngle(Random.Range(0f, 360f)), Random.Range(0f, maxAngle)); } // recurse if (level > 0) { InstantiateChildren(level, maxRendererLevel, selfPrefab, termPrefab, ref termPositions); } else { InstantiateTerminalComponent(level, termPrefab, ref termPositions); } // evaluate scale if (estimateScale() < minColliderScale) { Collider c = GetComponent<Collider>(); if (c != null) { Destroy(c); } } }
private void InstantiateChildren(int level, int maxRendererLevel, FractalPlantComponent selfPrefab, FractalPlantComponent termPrefab, ref List<Vector3> termPositions) { // pick children count float sum = 0f; System.Array.ForEach(childCountProbablities, e => sum += e); // choose children count float r = Random.Range(0f, sum); int childCount = System.Array.FindIndex(childCountProbablities, e => { if (e > r) { return true; } else { r -= e; return false; } }); // ensure no failures if (childCount == -1) { childCount = childCountProbablities.Length - 1; } children = new FractalPlantComponent[childCount]; // create children float curAngle = Random.Range(0f, 360f); for (int i = 0; i < childCount; i++) { FractalPlantComponent child = (FractalPlantComponent) Instantiate(selfPrefab); child.transform.parent = transform; child.transform.localPosition = mountPoint; child.transform.localRotation = Quaternion.identity; child.transform.localScale = new Vector3(relativeScale, relativeScale, relativeScale); // rotate for split if (childCount > 1) { child.transform.Rotate(fromAngle(curAngle), splitAngle); curAngle += 360f / childCount; } child.GenerateRecursive(level - 1, maxRendererLevel, selfPrefab, termPrefab, ref termPositions); children[i] = child; } }
private void InstantiateTerminalComponent(int level, FractalPlantComponent termPrefab, ref List<Vector3> termPositions) { Vector3 newWorldPos = transform.TransformPoint(mountPoint); if (termPrefab != null && validateTermPosition(newWorldPos, termPrefab.minTerminalDistance, termPositions)) { termPositions.Add(newWorldPos); FractalPlantComponent child = Instantiate(termPrefab); child.transform.position = newWorldPos; child.transform.parent = transform; //child.transform.localPosition = mountPoint; float scaleMult = 1f / estimateScale(); child.transform.localScale = termPrefab.transform.localScale * scaleMult; child.GenerateRecursive(0, 0, termPrefab, null, ref termPositions); children = new FractalPlantComponent[1]; children[0] = child; } }