void LogParticleState(int id)
    {
        var particleRenderers = GameObject.FindObjectsOfType <Particles>();

        foreach (var particleRenderer in particleRenderers)
        {
            if (!particleRenderer.gameObject.activeSelf || particleRenderer.frameData.Frame == null)
            {
                continue;
            }
            SimData.SimFrame frame = (SimData.SimFrame)particleRenderer.frameData.Frame;
            unsafe
            {
                var found = FindParticle(particleRenderer.frameData.ParticleBuffer, particleRenderer.frameData.NumParticles, id);
                if (found.HasValue)
                {
                    var p = found.Value;
                    Debug.Log(string.Format("Target particle: id {0}, type {1}, flags {2:X}, pos {3}, rot {4}, r {5}, debugVector {6}",
                                            p.id,
                                            p.type,
                                            p.flags,
                                            p.pos.UnityVector().ToString("F4"),
                                            p.rot.UnityQuaternion().ToString("F4"),
                                            p.radius,
                                            p.debugVector.UnityQuaternion().ToString("F6")
                                            ));
                }

                //for (var i = 0; i < frame.particles.Length; i++)
                //{
                //    var p = UnsafeUtility.ReadArrayElement<SimData.Particle>(frame.particles.GetUnsafeReadOnlyPtr(), i);

                //    if (p.id == id)
                //    {
                //        Debug.Log(string.Format("Target particle: id {0}, type {1}, flags {2:X}, pos {3}, rot {4}, r {5}, debugVector {6}",
                //            p.id,
                //            p.type,
                //            p.flags,
                //            p.pos.UnityVector().ToString("F4"),
                //            p.rot.UnityQuaternion().ToString("F4"),
                //            p.radius,
                //            p.debugVector.UnityQuaternion().ToString("F6")
                //        ));

                //        return;
                //    }
                //}
            }
        }
    }
    void Update()
    {
        if (Input.GetButtonDown("Fire1") && !EventSystem.current.IsPointerOverGameObject())
        {
            Ray ray = camera.ScreenPointToRay(Input.mousePosition);
            targetParticleRenderer = null;
            targetParticle         = null;
            int   targetParticleIdx  = -1;
            float targetParticleDist = float.MaxValue;
            var   particleRenderers  = GameObject.FindObjectsOfType <Particles>();
            foreach (var particleRenderer in particleRenderers)
            {
                if (!particleRenderer.gameObject.activeSelf || particleRenderer.frameData.Frame == null)
                {
                    continue;
                }
                SimData.SimFrame frame = (SimData.SimFrame)particleRenderer.frameData.Frame;
                unsafe
                {
                    for (var i = 0; i < frame.particles.Length; i++)
                    {
                        var p = UnsafeUtility.ReadArrayElement <SimData.Particle>(frame.particles.GetUnsafeReadOnlyPtr(), i);

                        if (
                            (p.flags & SimData.PARTICLE_FLAG_ACTIVE) < 1 ||
                            p.pos.x < particleVisibleRangeXSlider.LowValue ||
                            p.pos.x > particleVisibleRangeXSlider.HighValue ||
                            p.pos.y < particleVisibleRangeYSlider.LowValue ||
                            p.pos.y > particleVisibleRangeYSlider.HighValue ||
                            p.pos.z < particleVisibleRangeZSlider.LowValue ||
                            p.pos.z > particleVisibleRangeZSlider.HighValue
                            )
                        {
                            continue;
                        }
                        var pPos        = p.pos.UnityVector();
                        var particlePos = particleRenderer.transform.position + pPos * particleRenderer.DrawScale;
                        //Debug.Log("particlePos " + p.id + ", " + particlePos.ToString("F4") + ", r " + p.radius * 10);
                        if (IntersectRaySphere(ray, particlePos, p.radius * particleRenderer.DrawScale))
                        {
                            var particleDist = (ray.origin - particlePos).magnitude;
                            if (particleDist < targetParticleDist)
                            {
                                targetParticleRenderer = particleRenderer;
                                targetParticleIdx      = i;
                                targetParticle         = p;
                                targetParticleDist     = particleDist;
                            }
                        }
                    }

                    //fixed (SimData.Particle* ps = particleRenderer.frameData.Frame.particles.GetUnsafeReadOnlyPtr())
                    //{
                    //    Debug.Log("ps " + m[0] + ", " + m[1] + ", " + m[2] + ", " + m[3]);
                    //}
                }
            }

            if (targetParticle != null)
            {
                SimData.Particle tp = (SimData.Particle)targetParticle;
                //LogParticleState(tp.id);

                foreach (var particleRenderer in particleRenderers)
                {
                    particleRenderer.TargetParticleId = tp.id;
                }
            }
            else
            {
                foreach (var particleRenderer in particleRenderers)
                {
                    particleRenderer.TargetParticleId = -1;
                }
            }
        }

        ResolveTargetParticle();

        //if (Input.GetKeyDown(KeyCode.X))
        //{
        //    if (targetParticle != null)
        //    {
        //        SimData.Particle tp = (SimData.Particle)targetParticle;

        //        LogParticleState(tp.id);
        //    }
        //}
    }