void ApplyImpulses(FlexContainer.ParticleData _particleData)
 {
     if (m_currentAsset && m_instanceHandle)
     {
         FlexExt.Instance instance = m_instanceHandle.instance;
         int[]            indices  = new int[instance.numParticles];
         FlexUtils.FastCopy(instance.particleIndices, indices);
         foreach (var info in m_impulses)
         {
             if (info.impulse.sqrMagnitude < float.Epsilon)
             {
                 continue;
             }
             float mass = 0;
             foreach (var index in indices)
             {
                 if (info.particle == -1 || info.particle == index)
                 {
                     Vector4 particle = _particleData.GetParticle(index);
                     mass += 1.0f / particle.w;
                 }
             }
             if (mass < float.Epsilon)
             {
                 continue;
             }
             Vector3 velocityChange = info.impulse / mass;
             foreach (var index in indices)
             {
                 _particleData.SetVelocity(index, _particleData.GetVelocity(index) + velocityChange);
             }
         }
     }
 }
示例#2
0
        protected override void CreateInstance()
        {
            base.CreateInstance();

            if (handle)
            {
                FlexExt.Instance instance = handle.instance;
                if (instance.numParticles > 0)
                {
                    if (m_asset.fixedParticles.Length == 0)
                    {
                        int[] refPoints = new int[3] {
                            0, 1, 2
                        };                                        // @@@
                        Vector4[] particles = m_asset.particles;
                        //FlexUtils.ClothRefPoints(ref particles[0], particles.Length, ref refPoints[0]); // @@@ !!! Too slow
                        m_referencePoints = new int[] { indices[refPoints[0]], indices[refPoints[1]], indices[refPoints[2]] };
                        Vector3 p0 = particles[refPoints[0]], p1 = particles[refPoints[1]], p2 = particles[refPoints[2]];
                        m_localPosition = (p0 + p1 + p2) / 3;
                        Vector3 clothZ = Vector3.Cross(p1 - p0, p2 - p0).normalized;
                        Vector3 clothY = Vector3.Cross(clothZ, p1 - p0).normalized;
                        m_localRotation = Quaternion.LookRotation(clothZ, clothY);
                    }
                }
            }
        }
 void MoveFixedParticles(FlexContainer.ParticleData _particleData)
 {
     if (Application.isPlaying)
     {
         if (m_currentAsset && m_currentAsset.fixedParticles.Length > 0 && m_instanceHandle)
         {
             FlexExt.Instance instance  = m_instanceHandle.instance;
             Vector4[]        particles = m_currentAsset.particles;
             foreach (var index in m_currentAsset.fixedParticles)
             {
                 if (index < particles.Length)
                 {
                     Vector4 particle = transform.TransformPoint(particles[index]); particle.w = 0.0f;
                     _particleData.SetParticle(indices[index], particle);
                 }
             }
         }
     }
     else
     {
         if (m_currentAsset && m_instanceHandle)
         {
             FlexExt.Instance instance  = m_instanceHandle.instance;
             Vector4[]        particles = m_currentAsset.particles;
             for (int i = 0; i < particles.Length; ++i)
             {
                 Vector4 particle = transform.TransformPoint(particles[i]);
                 particle.w = _particleData.GetParticle(indices[i]).w;
                 _particleData.SetParticle(indices[i], particle);
             }
         }
     }
 }
        void TeleportParticles(FlexContainer.ParticleData _particleData)
        {
            Matrix4x4 offset = Matrix4x4.TRS(m_teleportPosition, Quaternion.identity, Vector3.one)
                               * Matrix4x4.TRS(Vector3.zero, m_teleportRotation, Vector3.one)
                               * Matrix4x4.TRS(Vector3.zero, Quaternion.Inverse(transform.rotation), Vector3.one)
                               * Matrix4x4.TRS(-transform.position, Quaternion.identity, Vector3.one);

            if (m_currentAsset && m_instanceHandle)
            {
                FlexExt.Instance instance = m_instanceHandle.instance;
                int[]            indices  = new int[instance.numParticles];
                FlexUtils.FastCopy(instance.particleIndices, indices);
                foreach (var index in indices)
                {
                    Vector4 particle = _particleData.GetParticle(index);
                    float   storeW   = particle.w;
                    particle   = offset.MultiplyPoint3x4(particle);
                    particle.w = storeW;
                    _particleData.SetParticle(index, particle);
                    _particleData.SetVelocity(index, Vector3.zero);
                }
            }
            transform.position   = m_teleportPosition;
            transform.rotation   = m_teleportRotation;
            transform.hasChanged = false;
        }
 protected virtual void CreateInstance()
 {
     if (m_currentContainer && m_currentContainer.handle && m_currentAsset && m_currentAsset.handle)
     {
         int        group = m_particleGroup < 0 ? ++sm_nextGroup : m_particleGroup;
         Flex.Phase flags = Flex.Phase.Default;
         if (m_selfCollide)
         {
             flags |= Flex.Phase.SelfCollide;
         }
         if (m_selfCollideFilter)
         {
             flags |= Flex.Phase.SelfCollideFilter;
         }
         if (m_fluid)
         {
             flags |= Flex.Phase.Fluid;
         }
         m_phase          = Flex.MakePhase(group, flags);
         m_instanceHandle = m_currentContainer.CreateInstance(m_currentAsset.handle, transform.localToWorldMatrix, Vector3.zero, m_phase, m_massScale);
         if (m_instanceHandle)
         {
             FlexExt.Instance instance = m_instanceHandle.instance;
             m_indices    = new int[m_currentAsset.maxParticles];
             m_indexCount = instance.numParticles;
             if (m_indexCount > 0)
             {
                 FlexUtils.FastCopy(instance.particleIndices, 0, ref m_indices[0], 0, sizeof(int) * m_indexCount);
             }
         }
     }
 }
 protected void SetIndices(int[] _indices, int _count)
 {
     m_indexCount = Mathf.Min(_count, m_currentAsset.maxParticles);
     Array.Copy(_indices, m_indices, m_indexCount);
     FlexExt.Instance instance = m_instanceHandle.instance;
     instance.numParticles = m_indexCount;
     if (m_indexCount > 0)
     {
         FlexUtils.FastCopy(ref m_indices[0], 0, instance.particleIndices, 0, sizeof(int) * m_indexCount);
     }
     m_instanceHandle.instance = instance;
 }
示例#7
0
        //This function is to set the initial velocity of the fluid
        bool PresetVelocities(FlexContainer.ParticleData _particleData)
        {
            Vector3 initVelocity = new Vector3(0, 0, -2.0f);              //Change the Vector to adjust the intial velocity

            FlexExt.Instance instance = m_instanceHandle.instance;
            int[]            indices  = new int[instance.numParticles];
            FlexUtils.FastCopy(instance.particleIndices, indices);

            foreach (var index in indices)
            {
                _particleData.SetVelocity(index, initVelocity);
            }
            return(true);
        }
        protected override void OnFlexUpdate(FlexContainer.ParticleData _particleData)
        {
            if (Application.isPlaying && handle)
            {
                FlexExt.Instance instance = handle.instance;
                Vector3          position = Vector3.zero;
                FlexUtils.FastCopy(instance.shapeTranslations, 0, ref position, 0, 12);
                Quaternion rotation = Quaternion.identity;
                FlexUtils.FastCopy(instance.shapeRotations, 0, ref rotation, 0, 16);
                transform.position   = position - rotation * m_asset.shapeCenters[0];
                transform.rotation   = rotation;
                transform.hasChanged = false;
            }

            base.OnFlexUpdate(_particleData);
        }
        void OnFlexUpdate(FlexContainer.ParticleData _particleData)
        {
            if (m_actor && m_actor.handle && m_skinningBones.Length > 0)
            {
                FlexExt.Instance instance = m_actor.handle.instance;
                int        boneCount      = m_skinningBones.Length;
                Vector3    bonePosition   = Vector3.zero;
                Quaternion boneRotation   = Quaternion.identity;

                for (int i = 0; i < boneCount; ++i)
                {
                    FlexUtils.FastCopy(instance.shapeTranslations, sizeof(float) * 3 * i, ref bonePosition, 0, sizeof(float) * 3);
                    m_skinningBones[i].position = bonePosition;
                    FlexUtils.FastCopy(instance.shapeRotations, sizeof(float) * 4 * i, ref boneRotation, 0, sizeof(float) * 4);
                    m_skinningBones[i].rotation = boneRotation;
                }
            }
        }
示例#10
0
        //This function is to get the velocity of 40 frames
        //And then call the CalcAcceleration function to calculate the accelerations
        bool CoutAccelerations(FlexContainer.ParticleData _particleData)
        {
            FlexExt.Instance instance = m_instanceHandle.instance;
            int[]            indices  = new int[instance.numParticles];
            FlexUtils.FastCopy(instance.particleIndices, indices);
            float totalzVelocity = 0;

            foreach (var index in indices)
            {
                totalzVelocity += _particleData.GetVelocity(index).z;
            }

            frameVelocity.Add(totalzVelocity / indices.Length);

            if (frameVelocity.Count >= 40)                              //Change the 40 to other numbers to adjust the time of data collections
            {
                return(CalcAcceleration());
            }
            else
            {
                return(false);
            }
        }
示例#11
0
 public static extern void FastCopy(IntPtr src, int srcOfs, ref FlexExt.Instance dst, int dstOfs, int size);
示例#12
0
 public static void FastCopy(IntPtr source, ref FlexExt.Instance destination)
 {
     FastCopy(source, 0, ref destination, 0, instanceSize);
 }
示例#13
0
 public static void FastCopy(ref FlexExt.Instance source, IntPtr destination)
 {
     FastCopy(ref source, 0, destination, 0, instanceSize);
 }
        void Create()
        {
            m_actor = GetComponentInParent <FlexActor>();
            if (m_actor == null)
            {
                Debug.LogError("_auxFlexDrawPartcles should be parented to a FlexActor");
                Debug.Break();
            }

            if (m_actor && m_actor.handle)
            {
                FlexExt.Instance instance = m_actor.handle.instance;

                int[] indices = new int[instance.numParticles];
                if (instance.numParticles > 0)
                {
                    FlexUtils.FastCopy(instance.particleIndices, indices);
                }

                m_mesh          = new Mesh();
                m_mesh.name     = "Flex Particles";
                m_mesh.vertices = new Vector3[1];

                if (m_actor is FlexSoftActor)
                {
                    int shapeCount = m_actor.asset.shapeOffsets.Length;
                    m_indexBuffers      = new ComputeBuffer[shapeCount];
                    m_particleMaterials = new Material[shapeCount];
                    m_mesh.subMeshCount = shapeCount;
                    for (int i = 0; i < shapeCount; ++i)
                    {
                        int start = i == 0 ? 0 : m_actor.asset.shapeOffsets[i - 1];
                        int count = m_actor.asset.shapeOffsets[i] - start;
                        m_mesh.SetIndices(new int[count], MeshTopology.Points, i);
                        m_indexBuffers[i] = new ComputeBuffer(count, 4);
                        int[] shape = new int[count];
                        for (int j = 0; j < count; ++j)
                        {
                            shape[j] = indices[m_actor.asset.shapeIndices[start + j]];
                        }
                        m_indexBuffers[i].SetData(shape);
                        m_particleMaterials[i]           = new Material(Shader.Find(PARTICLES_SHADER));
                        m_particleMaterials[i].hideFlags = HideFlags.HideAndDontSave;
                    }
                }
                else
                {
                    m_mesh.subMeshCount = 1;
                    m_mesh.SetIndices(new int[0], MeshTopology.Points, 0);
                    m_mesh.SetIndices(new int[instance.numParticles], MeshTopology.Points, 0);
                    m_indexBuffers = new ComputeBuffer[1];
                    if (instance.numParticles > 0)
                    {
                        m_indexBuffers[0] = new ComputeBuffer(instance.numParticles, sizeof(int));
                        m_indexBuffers[0].SetData(indices);
                    }
                    m_particleMaterials              = new Material[1];
                    m_particleMaterials[0]           = new Material(Shader.Find(PARTICLES_SHADER));
                    m_particleMaterials[0].hideFlags = HideFlags.HideAndDontSave;
                }

                m_mesh.bounds = m_actor.bounds;

                MeshFilter meshFilter = GetComponent <MeshFilter>();
                meshFilter.mesh = m_mesh;

                MeshRenderer meshRenderer = GetComponent <MeshRenderer>();
                meshRenderer.materials         = m_particleMaterials;
                meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
#if UNITY_EDITOR
                EditorUtility.SetSelectedRenderState(meshRenderer, EditorSelectedRenderState.Hidden);
#endif
                UpdateMesh();
            }
        }