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; } } } }
/* * 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 }
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); }
public static int CompareLatticeLocation(LatticeLocation x, LatticeLocation 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)); } } }
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; } } } }
public LatticeLocation GetLatticeLocation(Point3 index) { LatticeLocation result = null; if (mLattice.TryGetValue(index, out result)) { return(result); } return(null); }
public void AddCell(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; */ }
// Helper functions; public void GenerateSMRegions() { for (int i = 0; i != mLatticeLocationsWithExistentRegions.Count; ++i) { LatticeLocation l = mLatticeLocationsWithExistentRegions[i]; l.Region = new SmRegion(); mRegions.Add(l.Region); l.Region.LP = l; for (int j = 0; j != l.mNeighborhood.Count; ++j) { LatticeLocation l2 = l.mNeighborhood[j]; /* * l.Region.mParticles.Add(l2.SmParticle); */ for (int k = 0; k != 8; ++k) { if (false == l.Region.mParticles.Contains(l2.mParticles[k])) { l.Region.mParticles.Add(l2.mParticles[k]); } } } l.Region.mParticles.Sort(SmParticle.CompareSmParticle); l.Region.mEigenVectors = Matrix3x3.identity; } for (int i = 0; i != mRegions.Count; ++i) { SmRegion region = mRegions[i]; region.GenerateChildSums(1); } }
SmParticle GetSharedParticle(Point3 latticeIndex, int particleIndex) { List <Point3> neighbors = new List <Point3>(); List <int> sharedParticles = new List <int>(); switch (particleIndex) { case 0: neighbors.Add(new Point3(latticeIndex.x - 1, latticeIndex.y, latticeIndex.z)); sharedParticles.Add(1); neighbors.Add(new Point3(latticeIndex.x - 1, latticeIndex.y - 1, latticeIndex.z)); sharedParticles.Add(6); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y - 1, latticeIndex.z)); sharedParticles.Add(2); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y, latticeIndex.z - 1)); sharedParticles.Add(3); neighbors.Add(new Point3(latticeIndex.x - 1, latticeIndex.y, latticeIndex.z - 1)); sharedParticles.Add(4); neighbors.Add(new Point3(latticeIndex.x - 1, latticeIndex.y - 1, latticeIndex.z - 1)); sharedParticles.Add(7); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y - 1, latticeIndex.z - 1)); sharedParticles.Add(5); break; case 1: neighbors.Add(new Point3(latticeIndex.x + 1, latticeIndex.y, latticeIndex.z)); sharedParticles.Add(0); neighbors.Add(new Point3(latticeIndex.x + 1, latticeIndex.y - 1, latticeIndex.z)); sharedParticles.Add(2); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y - 1, latticeIndex.z)); sharedParticles.Add(6); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y, latticeIndex.z - 1)); sharedParticles.Add(4); neighbors.Add(new Point3(latticeIndex.x + 1, latticeIndex.y, latticeIndex.z - 1)); sharedParticles.Add(3); neighbors.Add(new Point3(latticeIndex.x + 1, latticeIndex.y - 1, latticeIndex.z - 1)); sharedParticles.Add(5); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y - 1, latticeIndex.z - 1)); sharedParticles.Add(7); break; case 2: neighbors.Add(new Point3(latticeIndex.x - 1, latticeIndex.y, latticeIndex.z)); sharedParticles.Add(6); neighbors.Add(new Point3(latticeIndex.x - 1, latticeIndex.y + 1, latticeIndex.z)); sharedParticles.Add(1); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y + 1, latticeIndex.z)); sharedParticles.Add(0); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y, latticeIndex.z - 1)); sharedParticles.Add(5); neighbors.Add(new Point3(latticeIndex.x - 1, latticeIndex.y, latticeIndex.z - 1)); sharedParticles.Add(7); neighbors.Add(new Point3(latticeIndex.x - 1, latticeIndex.y + 1, latticeIndex.z - 1)); sharedParticles.Add(4); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y + 1, latticeIndex.z - 1)); sharedParticles.Add(3); break; case 3: neighbors.Add(new Point3(latticeIndex.x - 1, latticeIndex.y, latticeIndex.z)); sharedParticles.Add(4); neighbors.Add(new Point3(latticeIndex.x - 1, latticeIndex.y - 1, latticeIndex.z)); sharedParticles.Add(7); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y - 1, latticeIndex.z)); sharedParticles.Add(5); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y, latticeIndex.z + 1)); sharedParticles.Add(0); neighbors.Add(new Point3(latticeIndex.x - 1, latticeIndex.y, latticeIndex.z + 1)); sharedParticles.Add(1); neighbors.Add(new Point3(latticeIndex.x - 1, latticeIndex.y - 1, latticeIndex.z + 1)); sharedParticles.Add(6); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y - 1, latticeIndex.z + 1)); sharedParticles.Add(2); break; case 4: neighbors.Add(new Point3(latticeIndex.x + 1, latticeIndex.y, latticeIndex.z)); sharedParticles.Add(3); neighbors.Add(new Point3(latticeIndex.x + 1, latticeIndex.y - 1, latticeIndex.z)); sharedParticles.Add(5); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y - 1, latticeIndex.z)); sharedParticles.Add(7); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y, latticeIndex.z + 1)); sharedParticles.Add(1); neighbors.Add(new Point3(latticeIndex.x + 1, latticeIndex.y, latticeIndex.z + 1)); sharedParticles.Add(0); neighbors.Add(new Point3(latticeIndex.x + 1, latticeIndex.y - 1, latticeIndex.z + 1)); sharedParticles.Add(2); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y - 1, latticeIndex.z + 1)); sharedParticles.Add(6); break; case 5: neighbors.Add(new Point3(latticeIndex.x - 1, latticeIndex.y, latticeIndex.z)); sharedParticles.Add(7); neighbors.Add(new Point3(latticeIndex.x - 1, latticeIndex.y + 1, latticeIndex.z)); sharedParticles.Add(4); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y + 1, latticeIndex.z)); sharedParticles.Add(3); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y, latticeIndex.z + 1)); sharedParticles.Add(2); neighbors.Add(new Point3(latticeIndex.x - 1, latticeIndex.y, latticeIndex.z + 1)); sharedParticles.Add(6); neighbors.Add(new Point3(latticeIndex.x - 1, latticeIndex.y + 1, latticeIndex.z + 1)); sharedParticles.Add(1); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y + 1, latticeIndex.z + 1)); sharedParticles.Add(0); break; case 6: neighbors.Add(new Point3(latticeIndex.x + 1, latticeIndex.y, latticeIndex.z)); sharedParticles.Add(2); neighbors.Add(new Point3(latticeIndex.x + 1, latticeIndex.y + 1, latticeIndex.z)); sharedParticles.Add(0); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y + 1, latticeIndex.z)); sharedParticles.Add(1); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y, latticeIndex.z - 1)); sharedParticles.Add(7); neighbors.Add(new Point3(latticeIndex.x + 1, latticeIndex.y, latticeIndex.z - 1)); sharedParticles.Add(5); neighbors.Add(new Point3(latticeIndex.x + 1, latticeIndex.y + 1, latticeIndex.z - 1)); sharedParticles.Add(3); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y + 1, latticeIndex.z - 1)); sharedParticles.Add(4); break; case 7: neighbors.Add(new Point3(latticeIndex.x + 1, latticeIndex.y, latticeIndex.z)); sharedParticles.Add(5); neighbors.Add(new Point3(latticeIndex.x + 1, latticeIndex.y + 1, latticeIndex.z)); sharedParticles.Add(3); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y + 1, latticeIndex.z)); sharedParticles.Add(4); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y, latticeIndex.z + 1)); sharedParticles.Add(6); neighbors.Add(new Point3(latticeIndex.x + 1, latticeIndex.y, latticeIndex.z + 1)); sharedParticles.Add(2); neighbors.Add(new Point3(latticeIndex.x + 1, latticeIndex.y + 1, latticeIndex.z + 1)); sharedParticles.Add(0); neighbors.Add(new Point3(latticeIndex.x, latticeIndex.y + 1, latticeIndex.z + 1)); sharedParticles.Add(1); break; default: return(null); } if (neighbors.Count != sharedParticles.Count) { return(null); } for (int i = 0; i != neighbors.Count; ++i) { LatticeLocation ll = GetLatticeLocation(neighbors[i]); if (null != ll) { if (null != ll.mParticles[sharedParticles[i]]) { return(ll.mParticles[sharedParticles[i]]); } } } return(null); }
public void CalculateNeighborhood() { mNeighborhood.Clear(); mNeighborhood.TrimExcess(); if (null == Body) { return; } if (Body.W == 1) { mNeighborhood = mImmediateNeighbors; mNeighborhood.Sort(LatticeLocation.CompareLatticeLocation); } else { uint newTouch = (uint)(Random.Range(0, int.MaxValue)); Queue <LatticeLocation> next = new Queue <LatticeLocation>(); int currentDepth = 0; int remainingAtThisDepth = 1; int elementsAtNextDepth = 0; next.Enqueue(this); TheTouch = newTouch; while (next.Count != 0) { LatticeLocation u = next.Dequeue(); mNeighborhood.Add(u); if (currentDepth < Body.W) { for (int i = 0; i != u.mImmediateNeighbors.Count; ++i) { LatticeLocation neighbor = u.mImmediateNeighbors[i]; if (neighbor.TheTouch != newTouch) { neighbor.TheTouch = newTouch; next.Enqueue(neighbor); ++elementsAtNextDepth; } } } --remainingAtThisDepth; if (remainingAtThisDepth == 0) { ++currentDepth; remainingAtThisDepth = elementsAtNextDepth; elementsAtNextDepth = 0; } } mNeighborhood.Sort(LatticeLocation.CompareLatticeLocation); next.Clear(); next.TrimExcess(); } // RegionExists = true; for (int i = 0; i != Body.mLatticeLocationsWithExistentRegions.Count; ++i) { LatticeLocation check = Body.mLatticeLocationsWithExistentRegions[i]; if (check.mNeighborhood.Count == mNeighborhood.Count) { bool bEqual = true; for (int j = 0; j != check.mNeighborhood.Count; ++j) { LatticeLocation left = check.mNeighborhood[j]; LatticeLocation right = mNeighborhood[j]; if (left != right) { bEqual = false; break; } } if (bEqual) { RegionExists = false; break; } } } if (RegionExists) { Body.mLatticeLocationsWithExistentRegions.Add(this); } }
// 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(); } }