コード例 #1
0
 void OnFlexUpdate(FlexContainer.ParticleData _particleData)
 {
     // Fill a local copy of the particles:
     _particleData.GetParticles(m_actor.indices[0], m_actor.indexCount, m_particles);
     if (firstRun)
     {
         firstRun = false; // only run this once:
         Debug.Log("Creating Mapping from Particles to Bones based on closest Vertex of the original mesh!");
         // TODO: re-check full algorithm below...
         Vector3[] cachedMeshVertices = referenceAnimSkin.sharedMesh.vertices;
         foreach (var i in m_particles)
         {
             Vector3 restPos = new Vector3();
             restPos.x = i.x;
             restPos.y = i.y;
             restPos.z = i.z;
             particleRestPositions.Add(restPos);
             particlePositions.Add(restPos);
             int     nearestIndexforParticle = GetNearestVertIndex(restPos, cachedMeshVertices);
             Vector3 VertOffset = restPos - cachedMeshVertices[nearestIndexforParticle];
             VertOffsetVectors.Add(VertOffset);
             nearestVertexIndexForParticle.Add(nearestIndexforParticle);
         }
         SetBoneWeights(cachedMeshVertices, nearestVertexIndexForParticle);
     }
     else // no update on firstRun! (that assumes that the animation starts from the rest position)
     {
         UpdateParticlePositions(_particleData);
     }
 }
コード例 #2
0
    // Update is called once per frame
    public override void OnFlexUpdate(FlexContainer.ParticleData _particleData)
    {
        //base.OnFlexUpdate(_particleData);

        if (m_actor && m_actor.container)
        {
            m_actor.container.AddFluidIndices(m_actor.indices, m_actor.indexCount);
        }

        if (Application.IsPlaying(this))
        {
            Vector4[] particles = new Vector4[10000];
            //_particleData.GetParticles(0, 9999, particles);
            _particleData.GetRestParticles(0, 9999, particles);

            Array.Sort <Vector4>(particles, new Comparison <Vector4>(
                                     (i1, i2) => Vector4.SqrMagnitude(i2).CompareTo(Vector4.SqrMagnitude(i1))));

            //RMMemoryManager rmm = Camera.main.GetComponent<RMMemoryManager>();
            //List<RMPrimitive> prims = rmm.RM_Prims;
            RayMarcher   rayMarcher = Camera.main.GetComponent <RayMarcher>();
            List <RMObj> renderList = rayMarcher.RenderList;
            Vector4      force;

            for (int i = 0; i < 28; ++i)
            {
                force  = particles[i];
                force += new Vector4(0.0f, -9.81f, 0.0f, 0.0f);
                renderList[i].transform.position += new Vector3(force.x, force.y, force.z) * Time.deltaTime;
            }
        }
    }
コード例 #3
0
        public void UpdateParticlePositions(FlexContainer.ParticleData _particleData)
        {
            // "Zero out" all particle postions first
            for (int i = 0; i < particlePositions.Count; i++)
            {
                particlePositions[i] = Vector3.zero;
            }
            // For each bone, check all particles it should affect and add the effect to that particlePosition:
            foreach (WeightList wList in particleBoneWeights)
            {
                foreach (ParticleBoneWeight pbw in wList.weights)
                {
                    // use the current transform of the bone to add its contribution to the new particle position:
                    Transform t = referenceAnimSkin.bones[wList.boneIndex];
                    // Adding the VertOffsetVector moves it from the original vertex to the particle
                    particlePositions[pbw.particleIndex] += t.localToWorldMatrix.MultiplyPoint3x4(pbw.localPosition) * pbw.weight + VertOffsetVectors[pbw.particleIndex];
                }
            }
            // We now have the particlePositions as they should be based on the animation,
            // BUT at the position of the reference animation's root bone in world space.
            // First move it back to local space relative to its root bone.
            // And then we should have to move it back to world space relative to this GameObject,
            // but for some reason that is not needed - but it breaks when this GameObject is rotated
            // (didn't test scaling). There must be something in the Flex setup that moves the points? :
            for (int i = 0; i < particlePositions.Count; i++)
            {
                particlePositions[i] = referenceAnimSkin.rootBone.transform.InverseTransformPoint(particlePositions[i]);
                //particlePositions[i] = this.transform.TransformPoint(particlePositions[i]);
            }
            // Now we should have the target particlePositions
            if (particlePositions.Count == 0) // this check shouldn't be needed now without uFlex, but leaving it in
            {
                return;
            }
            // Now for each particle, calculate how far it is from its intended (animation-)position:
            Vector3 _tempVector3;

            for (int particleIndex = 0; particleIndex < m_particles.Length; particleIndex++)
            {
                // casting a Vector4 to a Vector3 automatically discards the w component:
                _tempVector3 = particlePositions[particleIndex] - (Vector3)m_particles[particleIndex];
                particleDisplacementVector[particleIndex].x = _tempVector3.x;
                particleDisplacementVector[particleIndex].y = _tempVector3.y;
                particleDisplacementVector[particleIndex].z = _tempVector3.z;
            }
            // Now apply an appropriate velocity change to nudge the particle into the right direction:
            // Get/Set all velocities at the same time, as this is the most performant method:
            _particleData.GetVelocities(m_actor.indices[0], m_actor.indexCount, m_velocities);
            for (int i = 0; i < particleDisplacementVector.Length; i++)
            {
                // Note: we replicate roughly what ApplyImpulses in Actor would do, i.e. scale by weight:
                // impulse divided by particle mass (which is 1/w):
                m_velocities[i] += particleDisplacementVector[i] * m_particles[i].w;
            }
            _particleData.SetVelocities(m_actor.indices[0], m_actor.indexCount, m_velocities);
        }
コード例 #4
0
    private void OnFlexUpdate(FlexContainer.ParticleData particleData)
    {
        if (!Application.isPlaying)
        {
            return;
        }

        if (container && container.solver)
        {
            UpdateWind();
        }
    }
コード例 #5
0
    protected override void OnFlexUpdate(FlexContainer.ParticleData _particleData)
    {
        if (Application.isPlaying && m_referencePoints != null && m_referencePoints.Length >= 3)
        {
            Vector3    p0 = _particleData.GetParticle(m_referencePoints[0]);
            Vector3    p1 = _particleData.GetParticle(m_referencePoints[1]);
            Vector3    p2 = _particleData.GetParticle(m_referencePoints[2]);
            Vector3    clothZ = Vector3.Cross(p1 - p0, p2 - p0).normalized, clothY = Vector3.Cross(clothZ, p1 - p0).normalized;
            Quaternion globalRotation = Quaternion.LookRotation(clothZ, clothY) * Quaternion.Inverse(m_localRotation);
            Vector3    globalPosition = (p0 + p1 + p2) / 3 - globalRotation * m_localPosition;
            transform.position   = globalPosition;
            transform.rotation   = globalRotation;
            transform.hasChanged = false;
        }

        base.OnFlexUpdate(_particleData);
        if (hasSetFixed)
        {
            _particleData.SetParticle(indices[itopleft], new Vector4(topleft.x, topleft.y, topleft.z, 0));
            _particleData.SetParticle(indices[itopright], new Vector4(topright.x, topright.y, topright.z, 0));
        }
        else
        {
            topleft   = _particleData.GetParticle(indices[0]);
            topright  = _particleData.GetParticle(indices[0]);
            itopleft  = 0;
            itopright = 0;
            for (int i = 1; i < indices.Length; i++)
            {
                Vector3 now          = _particleData.GetParticle(indices[i]);
                Vector3 now2topleft  = topleft - now;
                Vector3 now2topright = topright - now;
                if (now2topleft.y <= 0 && now2topleft.x >= 0)
                {
                    topleft  = now;
                    itopleft = i;
                }
                if (now2topright.y <= 0 && now2topright.x <= 0)
                {
                    topright  = now;
                    itopright = i;
                }
            }
            hasSetFixed = true;
        }
    }
コード例 #6
0
    protected override void OnFlexUpdate(FlexContainer.ParticleData _particleData)
    {
        base.OnFlexUpdate(_particleData);

        /*
         * if (Application.isPlaying)
         * {
         *  Flex.Buffer buffer = Flex.AllocBuffer(FlexContainer.library, m_actor.container.maxParticles, sizeof(float) * 4, Flex.BufferType.Host);
         *  Flex.SetDiffuseParticles(m_actor.container.solver, buffer, buffer, m_actor.indexCount);
         *
         *  foreach (var index in m_actor.indices)
         *  {
         *      float sqrSpeed = _particleData.GetVelocity(index).sqrMagnitude;
         *      if (sqrSpeed >= sqrFoamSpeed)
         *      {
         *          Vector3 pos = _particleData.GetParticle(index);
         *          Instantiate(foam, pos, Quaternion.identity, transform);
         *      }
         *  }
         * }
         */
    }
コード例 #7
0
        /**
         * This will only run once by unregistering itself (until ReLock is called).
         */
        void OnFlexUpdate(FlexContainer.ParticleData _particleData)
        {
            m_actor.onFlexUpdate -= OnFlexUpdate; // only run once!
            m_actor.asset.ClearFixedParticles();
            _particleData.GetParticles(m_actor.indices[0], m_actor.indexCount, m_particles);
            // find all particles that are inside one of the colliders, and add it to fixedParticles:
            Collider[] to_be_locked_colls = GetComponents <Collider>();
            float      particleRadius     = m_actor.asset.particleSpacing; // not sure if this is the radius or the diameter

            for (int i = 0; i < m_particles.Length; i++)
            {
                Collider[] overlapped_colls = Physics.OverlapSphere(m_particles[i], particleRadius);
                foreach (Collider ovrlp_c in overlapped_colls)
                {
                    if (Array.IndexOf <Collider>(to_be_locked_colls, ovrlp_c) > -1)
                    {
                        m_actor.asset.FixedParticle(i, true);
                        break; // no need to check other colliders for this particle now
                    }
                }
            }
            m_actor.asset.Rebuild();
        }