private void SetRgInitForBalltree(GameObject go, Mesh mesh, RgInit rgInit) { rgInit.name_ = go.name; MeshComplex balltreeMC = new MeshComplex(); balltreeMC.Set(mesh); rgInit.meshCollider_Model_ = balltreeMC; Matrix4x4 m_MODEL_to_WORLD = go.transform.localToWorldMatrix; Vector3 scale = m_MODEL_to_WORLD.GetScalePre(); Vector3 normalizedScale = scale / scale.x; Matrix4x4 m_MODEL_to_NORMALIZEDSCALE = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, normalizedScale); rgInit.m_MODEL_to_WORLD_ = m_MODEL_to_NORMALIZEDSCALE; rgInit.useBalltree_ = true; float radius_rate = 1.0f - Data.BalltreeLOD; float radius_rateSq = radius_rate * radius_rate; float radius_rateSqClamped = Mathf.Clamp(radius_rateSq, 0.02f, 1.0f); rgInit.bt_radius_rate_ = radius_rateSqClamped; float requested_resolution1 = 10.0f / Mathf.Pow(radius_rateSqClamped, 5.0f); float requested_resolution2 = 10000.0f * (300.0f - 299.0f * (1.0f - Data.BalltreePrecision)); float mixedResolution = Mathf.Max(requested_resolution1, requested_resolution2); rgInit.bt_resolution_ = (uint)Mathf.Clamp(mixedResolution, 10000.0f, 3000000.0f); rgInit.bt_diameterMaxHoleToCover_rel_ = Mathf.Clamp(Data.BalltreeHoleCovering, 0.0001f, 1.0f); }
public void CreateBalltrees() { string folder; int pathIndex; bool assetsPath = CarFileUtils.DisplaySaveFolderDialog("CaronteFX - Balltree assets folder...", out folder, out pathIndex); if (!assetsPath) { return; } folder = folder.Substring(pathIndex); Dictionary <GameObject, uint> dictionaryGameObjectIdBalltree = new Dictionary <GameObject, uint>(); HashSet <BalltreeId> hashsetIdBalltree = new HashSet <BalltreeId>(); GameObject[] arrGameObject = FieldController.GetUnityGameObjects(); RgInit rgInit = new RgInit(); Matrix4x4 m_MODEL_to_WORLD = Matrix4x4.identity; bool isBakedRenderMesh = false; int nGameObject = arrGameObject.Length; for (int i = 0; i < nGameObject; i++) { int currentGOIdx = i + 1; float progress = (float)currentGOIdx / (float)nGameObject; EditorUtility.DisplayProgressBar("CaronteFX - Balltree Generator", "Creating balltree for " + nGameObject + " GameObjects. GameObject " + currentGOIdx + ".", progress); GameObject go = arrGameObject[i]; Mesh balltreeMesh = null; Caronte_Fx_Body cfxBody = CarBodyUtils.AddBodyComponentIfHasMesh(go); if (cfxBody != null) { if (Data.CreationMode == CNBalltreeGenerator.ECreationMode.USERENDERERS) { CarBodyUtils.GetRenderMeshData(go, ref balltreeMesh, out m_MODEL_to_WORLD, ref isBakedRenderMesh); } else if (Data.CreationMode == CNBalltreeGenerator.ECreationMode.USECOLLLIDERS) { CarBodyUtils.GetColliderMeshData(go, ref balltreeMesh, out m_MODEL_to_WORLD, ref isBakedRenderMesh); } if (balltreeMesh != null) { SetRgInitForBalltree(go, balltreeMesh, rgInit); uint id = RigidbodyManager.CreateBalltree(rgInit); dictionaryGameObjectIdBalltree.Add(go, id); hashsetIdBalltree.Add(new BalltreeId(id, balltreeMesh.name)); } } } int balltreeIdx = 1; int nBaltrees = hashsetIdBalltree.Count; Dictionary <uint, CRBalltreeAsset> dictionaryIdBalltreeBalltreeAsset = new Dictionary <uint, CRBalltreeAsset>(); foreach (BalltreeId balltreeId in hashsetIdBalltree) { float progress = (float)balltreeIdx / (float)nBaltrees; EditorUtility.DisplayProgressBar("CaronteFX - Balltree Generator", "Saving " + nBaltrees + " balltree assets. Balltree " + balltreeIdx + ".", progress); byte[] balltree_bytes = RigidbodyManager.GetBalltreeBytes(balltreeId.id_); byte[] balltreeCheckheader_bytes = RigidbodyManager.GetBalltreeCheckheaderBytes(balltreeId.id_); CarSphere[] arrLeafSphere = RigidbodyManager.GetBalltreeSpheres(balltreeId.id_); CRBalltreeAsset btAsset = CreateBallTreeAsset(balltreeId.name_, folder, balltree_bytes, balltreeCheckheader_bytes, arrLeafSphere); dictionaryIdBalltreeBalltreeAsset.Add(balltreeId.id_, btAsset); balltreeIdx++; } EditorUtility.ClearProgressBar(); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); ICollection <GameObject> goCollection = dictionaryGameObjectIdBalltree.Keys; foreach (GameObject go in goCollection) { Caronte_Fx_Body cfxBody = go.GetComponent <Caronte_Fx_Body>(); if (cfxBody == null) { cfxBody = go.AddComponent <Caronte_Fx_Body>(); } uint idBalltree = dictionaryGameObjectIdBalltree[go]; CRBalltreeAsset btAsset = dictionaryIdBalltreeBalltreeAsset[idBalltree]; cfxBody.SetBalltreeAsset(btAsset); EditorUtility.SetDirty(cfxBody); } }