/** * Add a particle to the grid structure. * \param hash cell hash, can be computed from the cellIndex (next parameter) using ComputeCellHash. * \param cellIndex 3-dimensional index of the cell to add the particle to. * \param p the particle that should be added to the grid. */ public void AddParticle(int hash, Vector3 cellIndex, ObiClothParticle p) { //See if the cell exists and insert the particle in it: Cell cell = null; if (cells.TryGetValue(hash,out cell)){ cell.AddParticle(p); }else{ cell = new Cell(this,cellIndex,hash); cell.AddParticle(p); cells[hash] = cell; } }
public VirtualCollisionConstraint(Transform transform, ObiClothParticle particle, ObiClothParticle particle2, ObiClothParticle particle3, Vector3 vpPosition,Vector3 vpBarycentricCoords, Rigidbody rigidbody, Vector3 point, Vector3 normal, float distance, float friction) : base(transform,particle,rigidbody,point,normal,distance,friction) { this.particle2 = particle2; this.particle3 = particle3; this.vpPosition = vpPosition; this.vpBarycentricCoords = vpBarycentricCoords; this.vpWeight = ObiUtils.BarycentricInterpolation(particle.w,particle2.w,particle3.w,vpBarycentricCoords); this.scaleFactor = ObiUtils.BarycentricExtrapolationScale(vpBarycentricCoords); this.weightSum = vpWeight + rigidbodyWeight; }
public SelfCollisionConstraint(Transform transform, ObiClothParticle particle1, ObiClothParticle particle2, Vector3 point, Vector3 normal, float distance, float friction) : base(transform) { this.transform = transform; this.particle1 = particle1; this.particle2 = particle2; this.point = point; this.normal = normal; this.distance = distance; this.weightSum = particle1.w + particle2.w; this.frictionCoeff = friction; }
public CollisionConstraint(Transform transform, ObiClothParticle particle, Rigidbody rigidbody, Vector3 point, Vector3 normal, float distance, float friction) : base(transform) { this.transform = transform; this.particle = particle; this.wspoint = point; this.point = transform.InverseTransformPoint(point); this.normal = transform.InverseTransformDirection(normal); this.distance = distance; this.rigidbody = rigidbody; this.rigidbodyWeight = (rigidbody == null || rigidbody.isKinematic) ? 0 : 1/rigidbody.mass; this.weightSum = particle.w + rigidbodyWeight; this.frictionCoeff = friction; }
public Vector3 wind = Vector3.zero; /**< Wind force vector expressed in world space.*/ #endregion Fields #region Methods public void ApplyAerodynamicsToParticle(ObiClothParticle p, Vector3 normal, Vector3 localSpaceWind, float dt) { Profiler.BeginSample("Aerodynamics"); if (enabled){ float halfAirDensity = airDensity * 0.5f; /// air density in kg/m3. Vector3 relVelocity = p.velocity - localSpaceWind; //relative velocity between particle and wind force. float relVelSqrMag = relVelocity.sqrMagnitude; //squared magnitude of relative velocity. Vector3 relVelocityNorm = relVelocity.normalized; //direction of relative velocity. // Calculate surface normal: Vector3 surfNormal = normal.normalized * Mathf.Sign(Vector3.Dot(normal,relVelocityNorm)); // Calculate aerodynamic factor. This is just a fancy name for a common part of the lift and drag calculations. float aerodynamicFactor = halfAirDensity * relVelSqrMag * p.areaContribution; // Calculate dot product between the surface normal at the particle's position, and the relative velocity direction. float dotNRV = Vector3.Dot(surfNormal,relVelocity.normalized); // Calculate drag force: float dragMagnitude = dragCoefficient * aerodynamicFactor; Vector3 fDrag = - dragMagnitude * dotNRV * relVelocityNorm; // Calculate lift force: float liftMagnitude = liftCoefficient * aerodynamicFactor; Vector3 fLift = liftMagnitude * dotNRV * Vector3.Cross(Vector3.Cross(surfNormal,relVelocityNorm),relVelocityNorm).normalized; // Apply both forces as accelerations: p.velocity += fDrag * p.w * dt; // a = F/m p.velocity += fLift * p.w * dt; // a = F/m } Profiler.EndSample(); }
/** * Removes the supplied particle from this cell, then destroys the cell if no particles are stored in it. */ public void RemoveParticle(ObiClothParticle p) { //Remove the particle from the cell. particles.Remove(p); //If the cell is now empty, remove the cell from the grid: if (particles.Count == 0) grid.cells.Remove(hash); }
/** * Adds to this cell a reference to the supplied particle. */ public void AddParticle(ObiClothParticle p) { //Add the particle index to the cell: particles.Add(p); }
/** * If the supplied particle cell hash is equal to the one calculated from the supplied cellIndex, nothing is done. Else, * the particle is removed from its current cell and then added to the cell indicated by cellIndex. */ public void UpdateParticle(ObiClothParticle p, Vector3 cellIndex) { int hash = ComputeCellHash(cellIndex); if (hash != p.gridCellHash){ RemoveParticle(p.gridCellHash,p); AddParticle(hash,cellIndex,p); p.gridCellHash = hash; } }
/** * Remove a particle from the grid structure. * \param hash cell hash, can be computed using ComputeCellHash. * \param p the particle that should be removed from the grid. */ public void RemoveParticle(int hash, ObiClothParticle p) { //See if the cell exists, and in that case, remove the particle from it: Cell cell = null; if (cells.TryGetValue(hash,out cell)){ cell.RemoveParticle(p); } }