コード例 #1
0
ファイル: ObiClothProxy.cs プロジェクト: may1702/Liquids
        /**
         * Retrieves the indices of the particles that influece a given vertex. In the weight
         * field of each influence, the squared distance from the particle to the vertex is provided.
         */
        public List <ParticleInfluence> GetParticleInfluences(Vector3 vertex)
        {
            // TODO: try to make it faster.
            List <ParticleInfluence> allInfluences = new List <ParticleInfluence>();

            // Get squared distance to all particles:
            for (int i = 0; i < proxy.positions.Length; ++i)
            {
                ParticleInfluence influence = new ParticleInfluence();
                influence.particleIndex = i;
                influence.bindVector    = transform.InverseTransformVector(transform.TransformPoint(vertex) - proxy.GetParticlePosition(i));
                influence.weight        = influence.bindVector.sqrMagnitude;
                allInfluences.Add(influence);
            }

            // Sort by distance:
            allInfluences.Sort(
                delegate(ParticleInfluence x, ParticleInfluence y)
            {
                return(x.weight.CompareTo(y.weight));
            });

            // Return the K nearest:
            return(allInfluences.GetRange(0, numInfluences));
        }
コード例 #2
0
ファイル: ObiClothProxy.cs プロジェクト: may1702/Liquids
        /**
         * Binds the mesh to the proxy particle actor.
         */
        public void BindToProxy()
        {
            initialized  = false;
            initializing = false;

            if (deformedMesh == null || proxy == null)
            {
                return;
            }

            initializing = true;

            influences = new ParticleInfluence[deformedMesh.vertexCount * numInfluences];
            bindPoses  = new Quaternion[proxy.positions.Length];

            // Get particle bind poses:
            for (int i = 0; i < proxy.positions.Length; ++i)
            {
                Quaternion proxyToLocal = Quaternion.Inverse(transform.rotation) * proxy.transform.rotation;
                bindPoses[i] = Quaternion.Inverse(proxyToLocal * proxy.sharedTopology.referenceOrientation[i]);
            }

            Vector3[] vertices = deformedMesh.vertices;

            //TODO: if the vertex position has already been processed, skip it. use unique positions only.
            for (int i = 0; i < vertices.Length; ++i)
            {
                // Find nearest "numInfluences" proxy particles:
                List <ParticleInfluence> infs = GetParticleInfluences(vertices[i]);

                // Calculate weights using shepard's method:
                float total = 0;
                for (int j = 0; j < infs.Count; ++j)
                {
                    ParticleInfluence pi = infs[j];
                    pi.weight = 1.0f / (float)Math.Pow(Mathf.Sqrt(pi.weight), falloff);
                    infs[j]   = pi;
                    total    += infs[j].weight;
                }

                // Normalize to get final linear weights:
                for (int j = 0; j < infs.Count; ++j)
                {
                    ParticleInfluence pi = infs[j];
                    pi.weight = pi.weight / total;
                    infs[j]   = pi;
                }

                // Insert this vertex's influence in the array:
                for (int j = 0; j < numInfluences; ++j)
                {
                    influences[i * numInfluences + j] = infs[j];
                }
            }

            initializing = false;
            initialized  = true;
        }