Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  How to add particles to existing cloth object
#6
(09-10-2018, 05:46 PM)arrnav96 Wrote: Unfortunately it still doesn't change it's behaviour. The cloth point only drags itself as shown here. I want the pickedParticle to be dragged fully with mouse pointer. 

The edge particles of this mesh are fixed.

These are my current scripts -

ObiClothPicker.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);
           }

           else if (pickedParticleIndex >= 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 (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;
}
   }
}

ObiClothDragger.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);
               }
}
}

       void Picker_OnParticlePicked(object sender, ObiClothPicker.ParticlePickEventArgs e)
       {
           pickArgs = e;            
       }

       void Picker_OnParticleDragged (object sender, ObiClothPicker.ParticlePickEventArgs e)
{
pickArgs = e;            
       }

       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;
               }
           }
       }
       
       void Picker_OnParticleReleased (object sender, ObiClothPicker.ParticlePickEventArgs e)
{
           picker.durationsTouch = 0;

           Oni.SetParticleVelocities(picker.Cloth.Solver.OniSolver, new Vector4[] { new Vector4(0, 12, 0, 0) }, 1, picker.Cloth.particleIndices[e.particleIndex]);

           if (SlimeTypeSelector == TypeOfSlime.Liquid)
           {
               pickArgs = null;
           }
           else if (SlimeTypeSelector == TypeOfSlime.Sticky)
           {
               Oni.SetParticleInverseMasses(picker.Cloth.Solver.OniSolver, new float[] { 0.5f }, 1, picker.Cloth.particleIndices[e.particleIndex]);
               //Oni.SetParticleVelocities(picker.Cloth.Solver.OniSolver, new Vector4[] { new Vector4(1,2,1,0) }, 2, picker.Cloth.particleIndices[e.particleIndex]);
               picker.Cloth.Solver.RelinquishRenderablePositions();
           }
           else if (SlimeTypeSelector == TypeOfSlime.VerySticky)
           {
               Oni.SetParticleInverseMasses(picker.Cloth.Solver.OniSolver, new float[] { 0 }, 1, picker.Cloth.particleIndices[e.particleIndex]);
               Oni.SetParticleVelocities(picker.Cloth.Solver.OniSolver, new Vector4[] { Vector4.zero }, 1, picker.Cloth.particleIndices[e.particleIndex]);
               picker.Cloth.Solver.RelinquishRenderablePositions();
           }
       }

}
}

Well, the behaviour shown in the video is exactly what the script as it is written is supposed to do: drag a single cloth particle around.

I don't understand what you mean by "I want the pickedParticle to be dragged fully". If you want more particles around the pickedParticle to be dragged you'll have to set their positions as well.
Reply


Messages In This Thread
RE: How to add particles to existing cloth object - by josemendez - 09-10-2018, 06:26 PM