Пример #1
0
    public void InitializeParticles()
    {
        for (int i = 0; i != mLatticeLocations.Count; ++i)
        {
            LatticeLocation ll = mLatticeLocations[i];

            for (int j = 0; j != ll.mParticles.Length; ++j)
            {
                if (null != ll.mParticles[j])
                {
                    continue;
                }

                SmParticle sp = GetSharedParticle(ll.mIndex, j);
                if (null != sp)
                {
                    ll.mParticles[j] = sp;
                }
                else
                {
                    ll.mParticles[j] = new SmParticle();
                    sp = ll.mParticles[j];
                    mParticles.Add(sp);
                    sp.LP   = ll;
                    sp.mX0  = GetParticleInitPostion(ll.mIndex, j);
                    sp.Mass = DefaultParticleMass;
                    sp.mX   = sp.mX0;
                    sp.mV   = Vector3.zero;
                    sp.mF   = Vector3.zero;
                }
            }
        }
    }
Пример #2
0
 public static int CompareSmParticle(SmParticle x, SmParticle y)
 {
     if (x == null)
     {
         if (y == null)
         {
             return(0);
         }
         else
         {
             return(-1);
         }
     }
     else
     {
         if (y == null)
         {
             return(1);
         }
         else
         {
             return(x.CreateTime.CompareTo(y.CreateTime));
         }
     }
 }
Пример #3
0
    // Update is called once per frame
    void Update()
    {
        for (int i = 0; i != mBodies.Count; ++i)
        {
            DeformableModel body = mBodies[i];

            body.ShapeMatch();
            body.CalculateParticleVelocities(h);
            body.PerformRegionDamping();
            body.ApplyParticleVelocities(h);

            for (int j = 0; j != body.mParticles.Count; ++j)
            {
                SmParticle particle = body.mParticles[j];
                particle.mF += vGravity;

                if (particle.mX.y < 0.0f)
                {
                    particle.mF.y -= particle.mX.y;
                    //particle.mF = Vector3.zero;
                    particle.mV   = Vector3.zero;
                    particle.mX.y = 0.0f;

                    //Debug.Log("Touch[" + j.ToString() + "]");
                }
            }
        }
    }
Пример #4
0
    public void CalculateInvariants()
    {
        Debug.Log("Calculating invariants...");

        for (int i = 0; i != mParticles.Count; ++i)
        {
            SmParticle particle = mParticles[i];
            particle.PerRegionMass = particle.Mass / particle.mParentRegions.Count;
        }

        for (int i = 0; i != mParticles.Count; ++i)
        {
            SmParticle p = mParticles[i];
            p.mSumData.mM.m00 = p.PerRegionMass;
            p.mSumData.mV     = p.PerRegionMass * p.mX0;
        }

        SumParticlesToRegions();

        for (int i = 0; i != mRegions.Count; ++i)
        {
            SmRegion r = mRegions[i];
            r.mM   = r.mSumData.mM.m00;
            r.mEx0 = r.mSumData.mV;
            r.mC0  = r.mEx0 / r.mM;
        }

        Debug.Log(" done.");
    }
Пример #5
0
    void AddForce()
    {
        string[] smBodyName = new string[] { "Penguin", "rubberduck", "Soccerball", "plane_lower" };
        foreach (string strName in smBodyName)
        {
            GameObject goBody = GameObject.Find(strName);
            if (null == goBody)
            {
                continue;
            }

            SmBody sb = goBody.GetComponent <SmBody>();
            if (null == sb)
            {
                continue;
            }

            float velocityMax  = 25.0f;
            float velocityHalf = velocityMax / 2.0f;

            Vector3 randomVelocity = new Vector3(0,
                                                 Random.Range(0.5f, 1.0f) * velocityMax - velocityHalf,
                                                 0);

            for (int i = 0; i != sb.mDeformableModel.mParticles.Count; ++i)
            {
                SmParticle particle = sb.mDeformableModel.mParticles[i];
                //particle.mX.y += 5.0f;
                particle.mV += (randomVelocity);
            }
        }
    }
Пример #6
0
    public static Summation FindIdenticalSummation(ref List <SmParticle> particles, int myLevel)
    {
        for (int m = 0; m != particles.Count; ++m)
        {
            LatticeLocation checkLp = particles[m].LP;

            for (int q = 0; q != checkLp.mSummations[myLevel].Count; ++q)
            {
                List <SmParticle> checkParticles = checkLp.mSummations[myLevel][q].mParticles;

                if (checkParticles.Count == particles.Count)
                {
                    bool bEqual = true;
                    for (int i = 0; i != checkParticles.Count; ++i)
                    {
                        SmParticle left  = checkParticles[i];
                        SmParticle right = particles[i];
                        if (left != right)
                        {
                            bEqual = false;
                            break;
                        }
                    }

                    if (bEqual)
                    {
                        return(checkLp.mSummations[myLevel][q]);
                    }
                }
            }
        }

        return(null);
    }
Пример #7
0
    /*
     * public void AddParticle(Point3 index)
     * {
     *      LatticeLocation l = new LatticeLocation();
     *      mLatticeLocations.Add(l);
     *      mLattice[index] = l;
     * l.mIndex = index;
     * l.Body = this;
     * l.Region = null;
     *
     * for (int xo = -1; xo <= 1; ++xo)
     * {
     *  for (int yo = -1; yo <= 1; ++yo)
     *  {
     *      for (int zo = -1; zo <= 1; ++zo)
     *      {
     *          Point3 check = new Point3(index.x + xo, index.y + yo, index.z + zo);
     *          if (!(xo == 0 && yo == 0 && zo == 0) && GetLatticeLocation(check) != null)
     *          {
     *              l.mImmediateNeighbors.Add(GetLatticeLocation(check));
     *              l.mImmediateNeighborsGrid[xo + 1, yo + 1, zo + 1] = GetLatticeLocation(check);
     *              GetLatticeLocation(check).mImmediateNeighbors.Add(l);
     *              GetLatticeLocation(check).mImmediateNeighborsGrid[-xo + 1, -yo + 1, -zo + 1] = l;
     *          }
     *          else
     *          {
     *              l.mImmediateNeighborsGrid[xo + 1, yo + 1, zo + 1] = null;
     *          }
     *      }
     *  }
     * }
     *
     * l.SmParticle = new SmParticle();
     * mParticles.Add(l.SmParticle);
     * l.SmParticle.LP = l;
     * l.SmParticle.mX0 = Vector3.Scale(new Vector3((float)index.x, (float)index.y, (float)index.z), mSpacing);
     * l.SmParticle.Mass = DefaultParticleMass;
     * l.SmParticle.mX = l.SmParticle.mX0;
     * l.SmParticle.mV = Vector3.zero;
     * l.SmParticle.mF = Vector3.zero;
     * }
     */

    public void Complete()
    {
        InitializeParticles();

        for (int i = 0; i != mLatticeLocations.Count; ++i)
        {
            LatticeLocation l = mLatticeLocations[i];
            l.IsEdge = (l.mImmediateNeighbors.Count != 26);
            l.CalculateNeighborhood();
        }

        GenerateSMRegions();

        for (int i = 0; i != mRegions.Count; ++i)
        {
            SmRegion r = mRegions[i];
            for (int j = 0; j != r.mParticles.Count; ++j)
            {
                SmParticle p = r.mParticles[j];
                p.mParentRegions.Add(r.LP);
            }
        }

        CalculateInvariants();

        //InitializeCells();		// Cells help with rendering
    }
Пример #8
0
 public void ApplyParticleVelocities(float h)
 {
     for (int i = 0; i != mParticles.Count; ++i)
     {
         SmParticle particle = mParticles[i];
         particle.mX = particle.mX + h * particle.mV;
     }
 }
Пример #9
0
    void AddForce2()
    {
        string[] smBodyName = new string[] { "Penguin", "rubberduck", "Soccerball", "plane_lower" };
        foreach (string strName in smBodyName)
        {
            GameObject goBody = GameObject.Find(strName);
            if (null == goBody)
            {
                continue;
            }

            SmBody sb = goBody.GetComponent <SmBody>();
            if (null == sb)
            {
                continue;
            }

            float velocityMax  = 500.0f;
            float velocityHalf = velocityMax / 2.0f;

            /*
             * Vector3 randomVelocity = new Vector3(0,
             * Random.Range(0.5f, 1.0f) * velocityMax - velocityHalf,
             * 0);
             */

            Vector3 randomVelocity = new Vector3(Random.Range(0.5f, 1.0f) * velocityMax - velocityHalf,
                                                 Random.Range(0.5f, 1.0f) * velocityMax - velocityHalf,
                                                 Random.Range(0.5f, 1.0f) * velocityMax - velocityHalf);

            /*
             * for (int i = 0; i != sb.mDeformableModel.mParticles.Count; ++i)
             * {
             * SmParticle particle = sb.mDeformableModel.mParticles[i];
             * //particle.mX.y += 5.0f;
             * particle.mV += (randomVelocity);
             * }
             */
            while (true)
            {
                int             index = Random.Range(0, sb.mDeformableModel.mLatticeLocations.Count);
                LatticeLocation ll    = sb.mDeformableModel.mLatticeLocations[index];
                if (ll.IsEdge)
                {
                    for (int i = 0; i != ll.mParticles.Length; ++i)
                    {
                        SmParticle particle = ll.mParticles[i];
                        particle.mF = randomVelocity;
                    }
                    break;
                }
            }
        }
    }
Пример #10
0
 void OnDrawGizmos()
 {
     for (int i = 0; i != mBodies.Count; ++i)
     {
         DeformableModel body = mBodies[i];
         for (int j = 0; j != body.mParticles.Count; ++j)
         {
             SmParticle p = body.mParticles[j];
             Gizmos.color = Color.red;
             Gizmos.DrawSphere(p.mX, 0.1f);
         }
     }
 }
Пример #11
0
    public void CalculateParticleVelocities(float h)
    {
        for (int i = 0; i != mParticles.Count; ++i)
        {
            SmParticle particle = mParticles[i];
            if (particle.mParentRegions.Count == 0)
            {
                particle.mV = particle.mV + h * (particle.mF / particle.Mass);
                particle.mG = particle.mX;
            }
            else
            {
                particle.mV = particle.mV + Alpha * (particle.mG - particle.mX) / h + h * (particle.mF / particle.Mass);
            }

            particle.mF = Vector3.zero;
        }
    }
Пример #12
0
    public void FindParticleRange(int dimension, ref int minDim, ref int maxDim)
    {
        minDim = int.MaxValue;
        maxDim = int.MinValue;

        for (int i = 0; i != mParticles.Count; ++i)
        {
            SmParticle p = mParticles[i];
            if (p.LP.mIndex[dimension] < minDim)
            {
                minDim = p.LP.mIndex[dimension];
            }

            if (p.LP.mIndex[dimension] > maxDim)
            {
                maxDim = p.LP.mIndex[dimension];
            }
        }
    }
Пример #13
0
    public void SumRegionsToParticles()
    {
        for (int i = 0; i != mSummations[1].Count; ++i)
        {
            Summation plate = mSummations[1][i];
            plate.SumFromParents();
        }

        for (int i = 0; i != mSummations[0].Count; ++i)
        {
            Summation bar = mSummations[0][i];
            bar.SumFromParents();
        }

        for (int i = 0; i != mParticles.Count; ++i)
        {
            SmParticle particle = mParticles[i];
            particle.SumFromParents();
        }
    }
Пример #14
0
    /*
     * void OnDrawGizmos()
     * {
     * }
     */

    void OnDrawGizmosSelected()
    {
        /*
         * if (null == mMeshFilters)
         *      return;
         *
         * Gizmos.color = Color.blue;
         * Gizmos.DrawWireCube(mBounds.center, mBounds.size);
         *
         * Gizmos.color = Color.green;
         * for (int i = 0; i != mMeshFilters.Length; ++i)
         * {
         *      MeshFilter mf = mMeshFilters[i];
         *      Gizmos.DrawWireCube(mf.mesh.bounds.center, mf.mesh.bounds.size);
         * }
         *
         * if (null == mCellInfos)
         *      return;
         */

        /*
         * int[] dimensions = new int[3]{mCellInfos.GetLength(0), mCellInfos.GetLength(1), mCellInfos.GetLength(2)};
         * for (int x = 0; x != dimensions[0]; ++x)
         * {
         *      for (int y = 0; y != dimensions[1]; ++y)
         *      {
         *              for (int z = 0; z != dimensions[2]; ++z)
         *              {
         *                      SmCellInfo info = mCellInfos[x,y,z];
         *                      if (info.mValid)
         *                      {
         *                              Gizmos.color = new Color(0, 0, 0, 0.1f);
         *                              Gizmos.DrawCube(info.mBounds.center, info.mBounds.size);
         *
         *                              Gizmos.color = Color.black;
         *                              Gizmos.DrawWireCube(info.mBounds.center, info.mBounds.size);
         *
         *                              Gizmos.color = Color.red;
         *                              Gizmos.DrawSphere(info.mBounds.center, 0.05f);
         *
         *                              for (int w = 0; w != mDeformableModel.mParticles.Count; ++w)
         *                              {
         *                                      Gizmos.DrawSphere(mDeformableModel.mParticles[w].mX, 0.03f);
         *                              }
         *
         *
         *                              LatticeLocation ll = mDeformableModel.GetLatticeLocation(new Point3(x,y,z));
         *                              Gizmos.color = Color.gray;
         *                              for (int w = 0; w != info.mVertices.Count; ++w)
         *                              {
         *                                      VertexPosition vp = info.mVertices[w];
         *                                      Vector3 vPos =
         *                                              ll.mParticles[0].mX0 * (1.0f - vp.mOriginPosition.x) * (1.0f - vp.mOriginPosition.y) * (1.0f - vp.mOriginPosition.z) +
         *                                              ll.mParticles[1].mX0 * (vp.mOriginPosition.x) * (1.0f - vp.mOriginPosition.y) * (1.0f - vp.mOriginPosition.z) +
         *                                              ll.mParticles[3].mX0 * (1.0f - vp.mOriginPosition.x) * (vp.mOriginPosition.y) * (1.0f - vp.mOriginPosition.z) +
         *                                              ll.mParticles[2].mX0 * (1.0f - vp.mOriginPosition.x) * (1.0f - vp.mOriginPosition.y) * (vp.mOriginPosition.z) +
         *                                              ll.mParticles[6].mX0 * (vp.mOriginPosition.x) * (1.0f - vp.mOriginPosition.y) * (vp.mOriginPosition.z) +
         *                                              ll.mParticles[5].mX0 * (1.0f - vp.mOriginPosition.x) * (vp.mOriginPosition.y) * (vp.mOriginPosition.z) +
         *                                              ll.mParticles[4].mX0 * (vp.mOriginPosition.x) * (vp.mOriginPosition.y) * (1.0f - vp.mOriginPosition.z) +
         *                                              ll.mParticles[7].mX0 * (vp.mOriginPosition.x) * (vp.mOriginPosition.y) * (vp.mOriginPosition.z);
         *
         *                                      Gizmos.DrawSphere(vPos, 0.01f);
         *                              }
         *                      }
         *              }
         *      }
         * }
         */

        if (null != mDeformableModel)
        {
            for (int j = 0; j != mDeformableModel.mParticles.Count; ++j)
            {
                SmParticle p = mDeformableModel.mParticles[j];
                Gizmos.color = Color.red;
                Gizmos.DrawSphere(transform.TransformPoint(p.mX), 0.03f);
            }

            for (int j = 0; j != mDeformableModel.mRegions.Count; ++j)
            {
                SmRegion r = mDeformableModel.mRegions[j];

                Bounds bounds = new Bounds(transform.TransformPoint(r.mParticles[0].mX), Vector3.zero);
                for (int k = 0; k != r.mParticles.Count; ++k)
                {
                    bounds.Encapsulate(transform.TransformPoint(r.mParticles[k].mX));
                }

                Gizmos.color = new Color(r.color.r, r.color.g, r.color.b, 0.05f);
                Gizmos.DrawCube(bounds.center, bounds.size);

                Gizmos.color = r.color;
                Gizmos.DrawWireCube(bounds.center, bounds.size);
            }
        }
    }
Пример #15
0
    public List <Summation> GenerateChildSums(int childLevel)
    {
        int splitDimension = childLevel;

        FindParticleRange(splitDimension, ref mMinDim, ref mMaxDim);

        List <Summation> newSums = new List <Summation>();

        Summation[] childArray = new Summation[mMaxDim - mMinDim + 1];
        for (int i = 0; i != mMaxDim - mMinDim + 1; ++i)
        {
            childArray[i] = new Summation();
        }

        for (int i = 0; i != mParticles.Count; ++i)
        {
            SmParticle p = mParticles[i];
            childArray[p.LP.mIndex[splitDimension] - mMinDim].mParticles.Add(p);
        }

        for (int i = mMinDim; i <= mMaxDim; ++i)
        {
            Summation child = childArray[i - mMinDim];

            if (child.mParticles.Count == 0)
            {
                child = null;
                childArray[i - mMinDim] = null;
            }
            else
            {
                child.mParticles.Sort(SmParticle.CompareSmParticle);
                child.LP = child.mParticles[0].LP;

                Summation identical = FindIdenticalSummation(ref child.mParticles, childLevel);

                if (null != identical)
                {
                    child = null;
                    childArray[i - mMinDim] = null;

                    mChildren.Add(identical);
                    identical.mParents.Add(this);
                }
                else
                {
                    newSums.Add(child);
                    mChildren.Add(child);
                    child.mParents.Add(this);
                    child.LP.mSummations[childLevel].Add(child);
                    LP.Body.mSummations[childLevel].Add(child);

                    if (childLevel > 0)
                    {
                        child.GenerateChildSums(childLevel - 1);
                    }
                    else
                    {
                        for (int m = 0; m != child.mParticles.Count; ++m)
                        {
                            SmParticle p = child.mParticles[m];
                            child.mChildren.Add(p);
                            p.mParents.Add(child);
                        }
                    }
                }
            }
        }

        System.Array.Clear(childArray, 0, childArray.Length);
        System.Array.Resize(ref childArray, 0);
        return(newSums);
    }
Пример #16
0
    void AddBody()
    {
        GameObject goPenguin = GameObject.Find("Penguin");

        if (null == goPenguin)
        {
            return;
        }

        SmBody smBody = goPenguin.GetComponent <SmBody>();

        if (null == smBody)
        {
            return;
        }


        DeformableModel body = new DeformableModel(new Vector3(smBody.Spacing, smBody.Spacing, smBody.Spacing));

        //body.W = 1;
        //body.Alpha = Random.Range(0.1f, 1.0f);
        //body.RegionDamping = Random.Range(0.1f, 1.0f);

        body.W             = 1;
        body.Alpha         = 0.75f;
        body.RegionDamping = 0.25f;

        mBodies.Add(body);


        //int width   = Random.Range(0, 3) + 2;
        //int height  = Random.Range(0, 20) + 2;
        //int depth     = Random.Range(0, 3) + 2;

        int width  = smBody.mCellInfos.GetLength(0);
        int height = smBody.mCellInfos.GetLength(1);
        int depth  = smBody.mCellInfos.GetLength(2);

        for (int x = 0; x != width; ++x)
        {
            for (int y = 0; y != height; ++y)
            {
                for (int z = 0; z != depth; ++z)
                {
                    SmBody.SmCellInfo info = smBody.mCellInfos[x, y, z];
                    if (info.mValid)
                    {
                        //body.AddParticle(new Point3(x, y, z));
                        body.AddCell(new Point3(x, y, z));
                    }
                }
            }
        }

        body.Complete();

        float velocityMax  = 25.0f;
        float velocityHalf = velocityMax / 2.0f;


        Vector3 randomVelocity = new Vector3(Random.Range(0.0f, 1.0f) * velocityMax - velocityHalf,
                                             Random.Range(0.5f, 1.0f) * velocityMax - velocityHalf,
                                             Random.Range(0.0f, 1.0f) * velocityMax - velocityHalf);



        //Vector3 randomVelocity = new Vector3(0.5f * velocityMax - velocityHalf,
        //    0.5f * velocityMax - velocityHalf,
        //    0.5f * velocityMax - velocityHalf);

        //Vector3 randomVelocity = new Vector3(9.0f, 2.8f, -6.8f);

        for (int i = 0; i != body.mParticles.Count; ++i)
        {
            SmParticle particle = body.mParticles[i];
            particle.mX.y += 5.0f;
            particle.mV   += (randomVelocity);
        }

        Debug.LogWarning("W[" + body.W.ToString() + "], Width[" + width.ToString() + "], Height[" + height.ToString() + "], Depth[" + depth.ToString() + "], Velocity[" + randomVelocity.ToString() + "]");
    }
Пример #17
0
    public void PerformRegionDamping()
    {
        if (RegionDamping == 0.0f)
        {
            return;
        }

        for (int i = 0; i != mParticles.Count; ++i)
        {
            SmParticle particle = mParticles[i];
            particle.mSumData.mV = particle.PerRegionMass * particle.mV;
            particle.mSumData.mM.SetColumn(0, Vector3.Cross(particle.mX, particle.mSumData.mV));

            Vector3 x = particle.mX;
            particle.mSumData.mM.m21 = particle.PerRegionMass * (x.z * x.z + x.y * x.y);
            particle.mSumData.mM.m01 = particle.PerRegionMass * (-x.x * x.y);
            particle.mSumData.mM.m02 = particle.PerRegionMass * (-x.x * x.z);
            particle.mSumData.mM.m11 = particle.PerRegionMass * (x.z * x.z + x.x * x.x);
            particle.mSumData.mM.m12 = particle.PerRegionMass * (-x.z * x.y);
            particle.mSumData.mM.m22 = particle.PerRegionMass * (x.y * x.y + x.x * x.x);
        }

        SumParticlesToRegions();

        for (int i = 0; i != mRegions.Count; ++i)
        {
            SmRegion  region = mRegions[i];
            Vector3   v      = Vector3.zero;
            Vector3   L      = Vector3.zero;
            Matrix3x3 I      = Matrix3x3.zero;

            Matrix3x3 FmixixiT = new Matrix3x3(
                region.mSumData.mM.m21, region.mSumData.mM.m01, region.mSumData.mM.m02,
                region.mSumData.mM.m01, region.mSumData.mM.m11, region.mSumData.mM.m12,
                region.mSumData.mM.m02, region.mSumData.mM.m12, region.mSumData.mM.m22);

            v = (1.0f / region.mM) * region.mSumData.mV;
            L = region.mSumData.mM.GetColumn(0) - Vector3.Cross(region.mC, region.mSumData.mV);
            I = FmixixiT - region.mM * MrMatrix(ref region.mC);

            Vector3 w = I.inverse * L;

            region.mSumData.mV = v;
            region.mSumData.mM.SetColumn(0, w);
            region.mSumData.mM.SetColumn(1, Vector3.Cross(w, region.mC));
        }

        SumRegionsToParticles();

        for (int i = 0; i != mParticles.Count; ++i)
        {
            SmParticle particle = mParticles[i];
            if (particle.mParentRegions.Count > 0)
            {
                Vector3 Fv  = particle.mSumData.mV;
                Vector3 Fw  = particle.mSumData.mM.GetColumn(0);
                Vector3 Fwc = particle.mSumData.mM.GetColumn(1);
                Vector3 dv  = (1.0f / particle.mParentRegions.Count) * (Fv + Vector3.Cross(Fw, particle.mX) - Fwc - (float)particle.mParentRegions.Count * particle.mV);

                particle.mV = particle.mV + RegionDamping * dv;
            }
        }
    }
Пример #18
0
    // Simulation
    public void ShapeMatch()
    {
        if (IsDirty)
        {
            CalculateInvariants();
            IsDirty = false;
        }

        for (int i = 0; i != mParticles.Count; ++i)
        {
            SmParticle particle = mParticles[i];
            particle.mSumData.mV = particle.PerRegionMass * particle.mX;
            particle.mSumData.mM = Matrix3x3.MultiplyWithTranspose(particle.PerRegionMass * particle.mX, particle.mX0);
        }

        SumParticlesToRegions();

        for (int i = 0; i != mRegions.Count; ++i)
        {
            SmRegion  r       = mRegions[i];
            Vector3   Fmixi   = r.mSumData.mV;
            Matrix3x3 Fmixi0T = r.mSumData.mM;

            r.mC = (1 / r.mM) * Fmixi;  //9
            r.mA = Fmixi0T - Matrix3x3.MultiplyWithTranspose(r.mM * r.mC, r.mC0);

            Matrix3x3 S = r.mA.transpose * r.mA;
            S = r.mEigenVectors.transpose * S * r.mEigenVectors;
            float[] eigenValues = new float[3];
            Jacobi.jacobi(3, ref S, ref eigenValues, ref r.mEigenVectors);

            for (int j = 0; j != 3; ++j)
            {
                if (eigenValues[j] <= 0.0f)
                {
                    eigenValues[j] = 0.05f;
                }

                eigenValues[j] = 1.0f / Mathf.Sqrt(eigenValues[j]);
            }

            Matrix3x3 DPrime = new Matrix3x3(eigenValues[0], 0, 0, 0, eigenValues[1], 0, 0, 0, eigenValues[2]);
            S = r.mEigenVectors * DPrime * r.mEigenVectors.transpose;

            r.mR = r.mA * S;

            if (r.mR.determinant < 0)
            {
                r.mR *= (-1.0f);
            }

            r.mT = r.mC - r.mR * r.mC0;

            r.mSumData.mM = r.mR;
            r.mSumData.mV = r.mT;
        }

        SumRegionsToParticles();

        for (int i = 0; i != mParticles.Count; ++i)
        {
            SmParticle particle = mParticles[i];

            float invNumParentRegions = 1.0f / particle.mParentRegions.Count;

            particle.mG = (invNumParentRegions * particle.mSumData.mM) * particle.mX0 + invNumParentRegions * particle.mSumData.mV;

            particle.mR = invNumParentRegions * particle.mSumData.mM;
        }
    }
Пример #19
0
    // Update is called once per frame
    void Update()
    {
        if (null != mDeformableModel)
        {
            mDeformableModel.ShapeMatch();
            mDeformableModel.CalculateParticleVelocities(h);
            mDeformableModel.PerformRegionDamping();
            mDeformableModel.ApplyParticleVelocities(h);


            for (int j = 0; j != mDeformableModel.mParticles.Count; ++j)
            {
                SmParticle particle = mDeformableModel.mParticles[j];
                particle.mF += vGravity;

                if (particle.mX.y < 0.0f)
                {
                    particle.mF.y -= particle.mX.y;
                    particle.mV    = Vector3.zero;
                    particle.mX.y  = 0.0f;
                }
            }
        }

        //deform mesh
        for (int x = 0; x != mCellInfos.GetLength(0); ++x)
        {
            for (int y = 0; y != mCellInfos.GetLength(1); ++y)
            {
                for (int z = 0; z != mCellInfos.GetLength(2); ++z)
                {
                    SmCellInfo info = mCellInfos[x, y, z];
                    if (info.mValid)
                    {
                        LatticeLocation ll = mDeformableModel.GetLatticeLocation(new Point3(x, y, z));
                        if (null == ll)
                        {
                            continue;
                        }

                        for (int w = 0; w != info.mVertices.Count; ++w)
                        {
                            VertexPosition vp = info.mVertices[w];

                            mMeshVertices[vp.mMeshIndex][vp.mVertexIndex] =
                                ll.mParticles[0].mX * (1.0f - vp.mOriginPosition.x) * (1.0f - vp.mOriginPosition.y) * (1.0f - vp.mOriginPosition.z) +
                                ll.mParticles[1].mX * (vp.mOriginPosition.x) * (1.0f - vp.mOriginPosition.y) * (1.0f - vp.mOriginPosition.z) +
                                ll.mParticles[3].mX * (1.0f - vp.mOriginPosition.x) * (1.0f - vp.mOriginPosition.y) * (vp.mOriginPosition.z) +
                                ll.mParticles[2].mX * (1.0f - vp.mOriginPosition.x) * (vp.mOriginPosition.y) * (1.0f - vp.mOriginPosition.z) +
                                ll.mParticles[6].mX * (vp.mOriginPosition.x) * (vp.mOriginPosition.y) * (1.0f - vp.mOriginPosition.z) +
                                ll.mParticles[5].mX * (1.0f - vp.mOriginPosition.x) * (vp.mOriginPosition.y) * (vp.mOriginPosition.z) +
                                ll.mParticles[4].mX * (vp.mOriginPosition.x) * (1.0f - vp.mOriginPosition.y) * (vp.mOriginPosition.z) +
                                ll.mParticles[7].mX * (vp.mOriginPosition.x) * (vp.mOriginPosition.y) * (vp.mOriginPosition.z);
                        }
                    }
                }
            }
        }

        Vector3 vLocal  = Vector3.zero;
        Vector3 vOrigin = Vector3.zero;

        for (int i = 0; i != mMeshFilters.Length; ++i)
        {
            MeshFilter mf = mMeshFilters[i];


            for (int j = 0; j != mMeshVertices[i].Length; ++j)
            {
                vLocal              = mMeshVertices[i][j];
                vOrigin             = mMeshTransforms[i].InverseTransformPoint(transform.TransformPoint(vLocal));
                mMeshVertices[i][j] = vOrigin;
            }

            mf.mesh.vertices = mMeshVertices[i];
            mf.mesh.RecalculateNormals();
            mf.mesh.RecalculateBounds();
        }
    }