public void UpdateSimulating(CarAnimationData animData, UnityEngine.Mesh animBakingMesh, float eventTime, float deltaTime)
        {
            if (crAnimation_ == null)
            {
                return;
            }

            crAnimation_.Update(deltaTime);
            float targetTime = eventTime + deltaTime;

            for (int i = 0; i < arrSkinnedMeshRenderer_.Length; ++i)
            {
                uint idBody = arrIdBodySkinnedGameObjects_[i];
                SkinnedMeshRenderer smRenderer = arrSkinnedMeshRenderer_[i];

                GameObject gameObject = smRenderer.gameObject;

                smRenderer.BakeMesh(animBakingMesh);

                if (idBody != uint.MaxValue)
                {
                    Matrix4x4 m_MODEL_TO_WORLD = gameObject.transform.localToWorldMatrix;
                    RigidbodyManager.Rg_addEventTargetArrPos_WORLD((double)eventTime, (double)targetTime, idBody, ref m_MODEL_TO_WORLD, animBakingMesh.vertices);
                }
            }

            for (int i = 0; i < arrNormalMeshRenderer_.Length; ++i)
            {
                uint         idBody     = arrIdBodyNormalGameObjects_[i];
                MeshRenderer renderer   = arrNormalMeshRenderer_[i];
                GameObject   gameObject = renderer.gameObject;

                if (idBody != uint.MaxValue)
                {
                    Matrix4x4 m_MODEL_TO_WORLD = gameObject.transform.localToWorldMatrix;

                    if (crAnimation_.IsVertexAnimated(gameObject))
                    {
                        MeshFilter mf   = gameObject.GetComponent <MeshFilter>();
                        Mesh       mesh = mf.sharedMesh;
                        RigidbodyManager.Rg_addEventTargetArrPos_WORLD((double)eventTime, (double)targetTime, idBody, ref m_MODEL_TO_WORLD, mesh.vertices);
                    }
                    else
                    {
                        RigidbodyManager.Rg_addEventTargetPos_WORLD((double)eventTime, (double)targetTime, idBody, ref m_MODEL_TO_WORLD, 0.01);
                    }
                }
            }
            animData.timeAnimated_ += deltaTime;
        }
            public void SetModeAnimation(bool active)
            {
                foreach (uint idBody in arrIdBodyNormalGameObjects_)
                {
                    if (idBody != uint.MaxValue)
                    {
                        RigidbodyManager.Rg_setAnimatingMode(idBody, active);
                    }
                }

                foreach (uint idBody in arrIdBodySkinnedGameObjects_)
                {
                    if (idBody != uint.MaxValue)
                    {
                        RigidbodyManager.Rg_setAnimatingMode(idBody, active);
                    }
                }
            }
            public void UpdateSimulating(CRAnimationData animData, UnityEngine.Mesh animBakingMesh, float eventTime, float deltaTime)
            {
                animator_.Update(deltaTime);

                double targetTime = eventTime + deltaTime;

                for (int i = 0; i < arrSkinnedMeshRenderer_.Length; ++i)
                {
                    uint idBody = arrIdBodySkinnedGameObjects_[i];
                    SkinnedMeshRenderer smRenderer = arrSkinnedMeshRenderer_[i];

                    GameObject gameObject = smRenderer.gameObject;

                    smRenderer.BakeMesh(animBakingMesh);

                    if (idBody != uint.MaxValue)
                    {
                        Matrix4x4 m_MODEL_TO_WORLD = gameObject.transform.localToWorldMatrix;

                        RigidbodyManager.Rg_addEventTargetArrPos_WORLD((double)eventTime, targetTime, idBody, ref m_MODEL_TO_WORLD, animBakingMesh.vertices);
                    }
                }

                for (int i = 0; i < arrNormalMeshRenderer_.Length; ++i)
                {
                    uint         idBody     = arrIdBodyNormalGameObjects_[i];
                    MeshRenderer renderer   = arrNormalMeshRenderer_[i];
                    GameObject   gameObject = renderer.gameObject;

                    if (idBody != uint.MaxValue)
                    {
                        Matrix4x4 m_MODEL_TO_WORLD = gameObject.transform.localToWorldMatrix;

                        RigidbodyManager.Rg_addEventTargetPos_WORLD((double)eventTime, targetTime, idBody, ref m_MODEL_TO_WORLD, 0.01);
                    }
                }
                animData.timeAnimated_ += deltaTime;
            }
        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);
            }
        }