Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  How to add particles to existing cloth object
#10
I've followed your instructions and these are the changes I made to the code. I get a very glitchy result now where the selected particle does follow the pointer, but absolutely none of the other particles are affected by it's movement. 
The selected particle appears to simply stretch the face it belongs to.
I would like the surrounding particles to naturally move too if the selected particle is moved, without restraining the selected particle.
Picker.cs -
Code:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Obi{

   public class ObiClothPicker : MonoBehaviour {

public class ParticlePickEventArgs : EventArgs
       {
public int particleIndex;
public Vector3 worldPosition;

public ParticlePickEventArgs(int particleIndex, Vector3 worldPosition){
this.particleIndex = particleIndex;
this.worldPosition = worldPosition;
}
}

       GameObject FingerTrailSphere;

       public float FingerRadius = 20;
   
public event System.EventHandler<ParticlePickEventArgs> OnParticlePicked;
public event System.EventHandler<ParticlePickEventArgs> OnParticleHeld;
public event System.EventHandler<ParticlePickEventArgs> OnParticleDragged;
public event System.EventHandler<ParticlePickEventArgs> OnParticleReleased;

       private MeshCollider meshCollider;
private ObiClothBase cloth;        
       private Mesh currentCollisionMesh;

private Vector3 lastMousePos = Vector3.zero;
private int pickedParticleIndex = -1;
private float pickedParticleDepth = 0;

       [HideInInspector]
       public float durationsTouch;

       Vector3 tpos;

       public ObiClothBase Cloth{
get{return cloth;}
}

       ObiActor actor;

       void Awake(){
cloth = GetComponent<ObiClothBase>();
lastMousePos = Input.mousePosition;
           actor = GetComponent<ObiActor>();

           FingerTrailSphere = GameObject.Find("FingerFollowTrailObject");
       }

void OnEnable(){

// special case for skinned cloth, the collider must be added to the skeleton's root bone:
if (cloth is ObiCloth && ((ObiCloth)cloth).IsSkinned){

SkinnedMeshRenderer sk = cloth.GetComponent<SkinnedMeshRenderer>();
if (sk != null && sk.rootBone != null){
meshCollider = sk.rootBone.gameObject.AddComponent<MeshCollider>();
}
}
// regular cloth:
else{
meshCollider = gameObject.AddComponent<MeshCollider>();
}

// in case we were able to create the mesh collider, set it up:
if (meshCollider != null){
meshCollider.enabled = false;
meshCollider.hideFlags = HideFlags.HideAndDontSave;
}

if (cloth != null)
cloth.Solver.OnFrameBegin += Cloth_Solver_OnFrameBegin;
}

void OnDisable(){

// destroy the managed mesh collider:
GameObject.Destroy(meshCollider);

if (cloth != null)
cloth.Solver.OnFrameBegin -= Cloth_Solver_OnFrameBegin;
}    

       void Cloth_Solver_OnFrameBegin (object sender, EventArgs e)
{
if (meshCollider == null)
return;

           // Click:

           /*Touch myTouch = Input.GetTouch(0);

           Touch[] myTouches = Input.touches;
           for (int i = 0; i < Input.touchCount; i++)
           {
               Debug.Log(Input.touchCount);
           }*/
           if (Input.GetMouseButtonDown(0))
           {                            
               meshCollider.enabled = true;

GameObject.Destroy(currentCollisionMesh);
currentCollisionMesh = GameObject.Instantiate(cloth.clothMesh);
meshCollider.sharedMesh = currentCollisionMesh;

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

               tpos = ray.GetPoint(10);

               FingerTrailSphere.transform.position = tpos;

RaycastHit hitInfo;
if (meshCollider.Raycast(ray,out hitInfo,100))
               {
                   int[] tris = currentCollisionMesh.triangles;
Vector3[] vertices = currentCollisionMesh.vertices;

// find closest vertex in the triangle we just hit:
int closestVertex = -1;
float minDistance = float.MaxValue;

for (int i = 0; i < 3; ++i)
                   {
int vertex = tris[hitInfo.triangleIndex*3+i];
float distance = (vertices[vertex] - hitInfo.point).sqrMagnitude;
if (distance < minDistance){
minDistance = distance;
closestVertex = vertex;
}
}

// get particle index:
if (closestVertex >= 0 && closestVertex < cloth.topology.visualMap.Length)
                   {
pickedParticleIndex = cloth.topology.visualMap[closestVertex];
pickedParticleDepth = Mathf.Abs((cloth.transform.TransformPoint(vertices[closestVertex]) - Camera.main.transform.position).z);

if (OnParticlePicked != null)
                       {
Vector3 worldPosition = Camera.main.ScreenToWorldPoint (new Vector3 (Input.mousePosition.x, Input.mousePosition.y, pickedParticleDepth));
OnParticlePicked(this,new ParticlePickEventArgs(pickedParticleIndex, worldPosition));
}
}
}

               meshCollider.enabled = false;

}
           if (Input.GetMouseButton(0))
           {
               Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

               tpos = ray.GetPoint(0);

               // Drag:
               Vector3 mouseDelta = Input.mousePosition - lastMousePos;
               if (mouseDelta.magnitude > 0.01f && OnParticleDragged != null)
               {

                   //Vector3 worldPosition = Camera.main.ScreenToWorldPoint (new Vector3 (Input.mousePosition.x, Input.mousePosition.y, pickedParticleDepth));
                   Vector3 worldPosition = tpos;
                   OnParticleDragged(this, new ParticlePickEventArgs(pickedParticleIndex, worldPosition));
               }
           }

           else if (pickedParticleIndex >= 0)
           {                
               if (OnParticleHeld != null)
               {
                   Vector3 worldPosition = tpos;
//Vector3 worldPosition = Camera.main.ScreenToWorldPoint (new Vector3 (Input.mousePosition.x, Input.mousePosition.y, pickedParticleDepth));
OnParticleHeld(this,new ParticlePickEventArgs(pickedParticleIndex,worldPosition));
}
// Release:
if (Input.GetMouseButtonUp(0))
               {
if (OnParticleReleased != null){
Vector3 worldPosition = Camera.main.ScreenToWorldPoint (new Vector3 (Input.mousePosition.x, Input.mousePosition.y, pickedParticleDepth));
OnParticleReleased(this,new ParticlePickEventArgs(pickedParticleIndex,worldPosition));
}

pickedParticleIndex = -1;

}
}

lastMousePos = Input.mousePosition;
}
   }
}

Dragger.cs -
Code:
using System;
using UnityEngine;
using System.Collections;

namespace Obi
{
[RequireComponent(typeof(ObiClothPicker))]
public class ObiClothDragger : MonoBehaviour
{
public float springStiffness = 50;
public float springDamping = 1;

private ObiClothPicker picker;
private ObiClothPicker.ParticlePickEventArgs pickArgs;

       [HideInInspector]
       public enum TypeOfSlime { Liquid, Sticky, VerySticky};

       public TypeOfSlime SlimeTypeSelector;
       public float FingerRadius = 50;
       public float FingerDepthDurationFactor = 1.5f;

       Vector3 tpos;

       void OnEnable()
{
picker = GetComponent<ObiClothPicker>();
picker.OnParticlePicked += Picker_OnParticlePicked;
picker.OnParticleDragged += Picker_OnParticleDragged;
picker.OnParticleReleased += Picker_OnParticleReleased;
}

void OnDisable()
{
picker.OnParticlePicked -= Picker_OnParticlePicked;
picker.OnParticleDragged -= Picker_OnParticleDragged;
picker.OnParticleReleased -= Picker_OnParticleReleased;
       }

       void FixedUpdate ()
{
if (pickArgs != null){

ObiSolver solver = picker.Cloth.Solver;

               // Calculate picking position in solver space:
               Vector3 targetPosition = pickArgs.worldPosition;                
if (solver.simulateInLocalSpace)
targetPosition = solver.transform.InverseTransformPoint(targetPosition);

// Get particle position and velocity:
Vector4[] positions = new Vector4[1];
Vector4[] velocities = new Vector4[1];
int solverIndex = picker.Cloth.particleIndices[pickArgs.particleIndex];
Oni.GetParticlePositions(solver.OniSolver,positions,1,solverIndex);
Oni.GetParticleVelocities(solver.OniSolver,velocities,1,solverIndex);

// Calculate effective inverse mass:
float invMass = picker.Cloth.invMasses[pickArgs.particleIndex] * picker.Cloth.areaContribution[pickArgs.particleIndex];

if (invMass > 0)
               {
                   // Calculate and apply spring force:

                   //Vector4 force = (((new Vector4(targetPosition[0],-targetPosition[1],targetPosition[2],0) - positions[0]) * springStiffness - velocities[0] * springDamping) / (invMass)) * (picker.durationsTouch/FingerDepthDurationFactor);                    
                   //Oni.AddParticleExternalForce(picker.Cloth.Solver.OniSolver,ref force,new int[]{solverIndex},1);
                   Oni.SetParticlePositions(picker.Cloth.Solver.OniSolver, new Vector4[] { tpos }, 1, pickArgs.particleIndex);
               }
}
}

       float oldInvMass;

       void Picker_OnParticlePicked(object sender, ObiClothPicker.ParticlePickEventArgs e)
       {
           oldInvMass = picker.Cloth.invMasses[e.particleIndex] * picker.Cloth.areaContribution[e.particleIndex];
           Oni.SetParticlePositions(picker.Cloth.Solver.OniSolver, new Vector4[] { e.worldPosition }, 1, e.particleIndex);
           Oni.SetParticleVelocities(picker.Cloth.Solver.OniSolver, new Vector4[] { Vector4.zero }, 1, e.particleIndex);
           Oni.SetParticleInverseMasses(picker.Cloth.Solver.OniSolver, new float[] { 0 }, 1, e.particleIndex);
       }

       void Picker_OnParticleDragged(object sender, ObiClothPicker.ParticlePickEventArgs e)
       {
           Oni.SetParticlePositions(picker.Cloth.Solver.OniSolver, new Vector4[] { e.worldPosition }, 1, e.particleIndex);
       }

       void Picker_OnParticleReleased(object sender, ObiClothPicker.ParticlePickEventArgs e)
       {
           Oni.SetParticleInverseMasses(picker.Cloth.Solver.OniSolver, new float[] { oldInvMass }, 1, e.particleIndex);
       }

       void Update()
       {
           if (Input.GetMouseButton(0))
           {
               Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

               tpos = ray.GetPoint(10);

               if (picker.durationsTouch <= 4)
               {
                   picker.durationsTouch += Time.deltaTime;
               }
           }
       }

}
}
Reply


Messages In This Thread
RE: How to add particles to existing cloth object - by arrnav96 - 12-10-2018, 11:42 AM