Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

It's just collide with quad

Discussion in 'Scripting' started by gabicolombo27, Sep 26, 2020.

  1. gabicolombo27

    gabicolombo27

    Joined:
    Jun 24, 2020
    Posts:
    3
    Please, I need help with this code. It's just collide with quad and I don't know what to do

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class SPHManagerSingleThread : MonoBehaviour
    6. {
    7.  
    8.     private struct SPHParticle
    9.     {
    10.         public Vector3 position;
    11.  
    12.         public Vector3 velocity;
    13.         public Vector3 forcePhysic;
    14.         public Vector3 forceHeading;
    15.  
    16.         public float density;
    17.         public float pressure;
    18.  
    19.         public int parameterID;
    20.  
    21.         public GameObject go;
    22.  
    23.  
    24.  
    25.         public void Init(Vector3 _position, int _parameterID, GameObject _go)
    26.         {
    27.             position = _position;
    28.             parameterID = _parameterID;
    29.             go = _go;
    30.  
    31.             velocity = Vector3.zero;
    32.             forcePhysic = Vector3.zero;
    33.             forceHeading = Vector3.zero;
    34.             density = 0.0f;
    35.             pressure = 0.0f;
    36.         }
    37.     }
    38.  
    39.  
    40.  
    41.     [System.Serializable]
    42.     private struct SPHParameters
    43.     {
    44.         #pragma warning disable 0649 // This line removes the warning saying that the variable is never assigned to. You can't assign a variable in a struct...
    45.         public float particleRadius;
    46.         public float smoothingRadius;
    47.         public float smoothingRadiusSq;
    48.         public float restDensity;
    49.         public float gravityMult;
    50.         public float particleMass;
    51.         public float particleViscosity;
    52.         public float particleDrag;
    53.         #pragma warning restore 0649
    54.     }
    55.  
    56.  
    57.  
    58.     private struct SPHCollider
    59.     {
    60.         public Vector3 position;
    61.         public Vector3 right;
    62.         public Vector3 up;
    63.         public Vector2 scale;
    64.  
    65.         public void Init(Transform _transform)
    66.         {
    67.             position = _transform.position;
    68.             right = _transform.right;
    69.             up = _transform.up;
    70.             scale = new Vector2(_transform.lossyScale.x / 2f, _transform.lossyScale.y / 2f);
    71.         }
    72.     }
    73.  
    74.  
    75.  
    76.     // Consts
    77.     private static Vector3 GRAVITY = new Vector3(0.0f, -9.81f, 0.0f);
    78.     private const float GAS_CONST = 2000.0f;
    79.     private const float DT = 0.0008f;
    80.     private const float BOUND_DAMPING = -0.5f;
    81.  
    82.     // Properties
    83.     [Header("Import")]
    84.     [SerializeField] private GameObject character0Prefab = null;
    85.  
    86.     [Header("Parameters")]
    87.     [SerializeField] private int parameterID = 0;
    88.     [SerializeField] private SPHParameters[] parameters = null;
    89.  
    90.     [Header("Properties")]
    91.     [SerializeField] private int amount = 250;
    92.     [SerializeField] private int rowSize = 16;
    93.  
    94.     // Data
    95.     private SPHParticle[] particles;
    96.  
    97.  
    98.  
    99.     private void Start()
    100.     {
    101.         InitSPH();
    102.     }
    103.  
    104.  
    105.  
    106.     private void Update()
    107.     {
    108.         ComputeDensityPressure();
    109.         ComputeForces();
    110.         Integrate();
    111.         ComputeColliders();
    112.  
    113.         ApplyPosition();
    114.     }
    115.  
    116.  
    117.  
    118.     private void InitSPH()
    119.     {
    120.         particles = new SPHParticle[amount];
    121.    
    122.         for (int i = 0; i < amount; i++)
    123.         {
    124.             float jitter = (Random.value * 2f - 1f) * parameters[parameterID].particleRadius * 0.1f;
    125.             float x = (i % rowSize) + Random.Range(-0.1f, 0.1f);
    126.             float y = 2 + (float)((i / rowSize) / rowSize) * 1.1f;
    127.             float z = ((i / rowSize) % rowSize) + Random.Range(-0.1f, 0.1f);
    128.  
    129.             GameObject go = Instantiate(character0Prefab);
    130.             go.transform.localScale = Vector3.one * parameters[parameterID].particleRadius;
    131.             go.transform.position = new Vector3(x + jitter, y, z + jitter);
    132.             go.name = "char" + i.ToString();
    133.  
    134.             particles.Init(new Vector3(x, y, z), parameterID, go);
    135.         }
    136.     }
    137.  
    138.  
    139.  
    140.     private static bool Intersect(SPHCollider collider, Vector3 position, float radius, out Vector3 penetrationNormal, out Vector3 penetrationPosition, out float penetrationLength)
    141.     {
    142.         Vector3 colliderProjection = collider.position - position;
    143.  
    144.         penetrationNormal = Vector3.Cross(collider.right, collider.up);
    145.         penetrationLength = Mathf.Abs(Vector3.Dot(colliderProjection, penetrationNormal)) - (radius / 2.0f);
    146.         penetrationPosition = collider.position - colliderProjection;
    147.  
    148.         return penetrationLength < 0.0f
    149.             && Mathf.Abs(Vector3.Dot(colliderProjection, collider.right)) < collider.scale.x
    150.             && Mathf.Abs(Vector3.Dot(colliderProjection, collider.up)) < collider.scale.y;
    151.     }
    152.  
    153.  
    154.  
    155.     private static Vector3 DampVelocity(SPHCollider collider, Vector3 velocity, Vector3 penetrationNormal, float drag)
    156.     {
    157.         Vector3 newVelocity = Vector3.Dot(velocity, penetrationNormal) * penetrationNormal * BOUND_DAMPING
    158.                             + Vector3.Dot(velocity, collider.right) * collider.right * drag
    159.                             + Vector3.Dot(velocity, collider.up) * collider.up * drag;
    160.         newVelocity = Vector3.Dot(newVelocity, Vector3.forward) * Vector3.forward
    161.                     + Vector3.Dot(newVelocity, Vector3.right) * Vector3.right
    162.                     + Vector3.Dot(newVelocity, Vector3.up) * Vector3.up;
    163.         return newVelocity;
    164.     }
    165.  
    166.  
    167.  
    168.     private void ComputeColliders()
    169.     {
    170.         // Get colliders
    171.         GameObject[] collidersGO = GameObject.FindGameObjectsWithTag("SPHCollider");
    172.         SPHCollider[] colliders = new SPHCollider[collidersGO.Length];
    173.         for (int i = 0; i < colliders.Length; i++)
    174.         {
    175.             colliders.Init(collidersGO.transform);
    176.         }
    177.  
    178.         for (int i = 0; i < particles.Length; i++)
    179.         {
    180.             for (int j = 0; j < colliders.Length; j++)
    181.             {
    182.                 // Check collision
    183.                 Vector3 penetrationNormal;
    184.                 Vector3 penetrationPosition;
    185.                 float penetrationLength;
    186.                 if (Intersect(colliders[j], particles.position, parameters[particles.parameterID].particleRadius, out penetrationNormal, out penetrationPosition, out penetrationLength))
    187.                 {
    188.                     particles.velocity = DampVelocity(colliders[j], particles.velocity, penetrationNormal, 1.0f - parameters[particles.parameterID].particleDrag);
    189.                     particles.position = penetrationPosition - penetrationNormal * Mathf.Abs(penetrationLength);
    190.                 }
    191.             }
    192.         }
    193.     }
    194.  
    195.  
    196.  
    197.     private void Integrate()
    198.     {
    199.         for (int i = 0; i < particles.Length; i++)
    200.         {
    201.             particles.velocity += DT * (particles.forcePhysic) / particles.density;
    202.             particles.position += DT * (particles.velocity );
    203.         }
    204.     }
    205.  
    206.  
    207.  
    208.     private void ComputeDensityPressure()
    209.     {
    210.         for (int i = 0; i < particles.Length; i++)
    211.         {
    212.             particles.density = 0.0f;
    213.  
    214.             for (int j = 0; j < particles.Length; j++)
    215.             {
    216.                 Vector3 rij = particles[j].position - particles.position;
    217.                 float r2 = rij.sqrMagnitude;
    218.  
    219.                 if (r2 < parameters[particles.parameterID].smoothingRadiusSq)
    220.                 {
    221.                     particles.density += parameters[particles.parameterID].particleMass * (315.0f / (64.0f * Mathf.PI * Mathf.Pow(parameters[particles.parameterID].smoothingRadius, 9.0f))) * Mathf.Pow(parameters[particles[i].parameterID].smoothingRadiusSq - r2, 3.0f);
    222.                 }
    223.             }
    224.  
    225.             particles[i].pressure = GAS_CONST * (particles[i].density - parameters[particles[i].parameterID].restDensity);
    226.         }
    227.     }
    228.  
    229.  
    230.  
    231.     private void ComputeForces()
    232.     {
    233.         for (int i = 0; i < particles.Length; i++)
    234.         {
    235.             Vector3 forcePressure = Vector3.zero;
    236.             Vector3 forceViscosity = Vector3.zero;
    237.  
    238.             // Physics
    239.             for (int j = 0; j < particles.Length; j++)
    240.             {
    241.                 if (i == j) continue;
    242.  
    243.                 Vector3 rij = particles[j].position - particles[i].position;
    244.                 float r2 = rij.sqrMagnitude;
    245.                 float r = Mathf.Sqrt(r2);
    246.  
    247.                 if (r < parameters[particles[i].parameterID].smoothingRadius)
    248.                 {
    249.                     forcePressure += -rij.normalized * parameters[particles[i].parameterID].particleMass * (particles[i].pressure + particles[j].pressure) / (2.0f * particles[j].density) * (-45.0f / (Mathf.PI * Mathf.Pow(parameters[particles[i].parameterID].smoothingRadius, 6.0f))) * Mathf.Pow(parameters[particles[i].parameterID].smoothingRadius - r, 2.0f);
    250.  
    251.                     forceViscosity += parameters[particles[i].parameterID].particleViscosity * parameters[particles[i].parameterID].particleMass * (particles[j].velocity - particles[i].velocity) / particles[j].density * (45.0f / (Mathf.PI * Mathf.Pow(parameters[particles[i].parameterID].smoothingRadius, 6.0f))) * (parameters[particles[i].parameterID].smoothingRadius - r);
    252.                 }
    253.             }
    254.  
    255.             Vector3 forceGravity = GRAVITY * particles[i].density * parameters[particles[i].parameterID].gravityMult;
    256.  
    257.             // Apply
    258.             particles[i].forcePhysic = forcePressure + forceViscosity + forceGravity;
    259.         }
    260.     }
    261.  
    262.  
    263.  
    264.     private void ApplyPosition()
    265.     {
    266.         for (int i = 0; i < particles.Length; i++)
    267.         {
    268.             particles[i].go.transform.position = particles[i].position;
    269.         }
    270.     }
    271. }


    This code was implemented with quad colliders, how can I implement box collider or mesh collider?? I need to take datas of mesh like artery for example.
     

    Attached Files:

    Last edited: Sep 26, 2020
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,724
    Do you have a question?
     
  3. gabicolombo27

    gabicolombo27

    Joined:
    Jun 24, 2020
    Posts:
    3
    Yes, how can I collide with others gameObjects? It's just collide with quad and I already used meshCollider but it's not work. I think there is a problem with this code.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,779
    This is not actually a useful observation, believe it or not.

    First of all, please use code tags: https://forum.unity.com/threads/using-code-tags-properly.143875/

    Second of all, don't dump the whole script in here and announce there's a problem. Nobody's gonna help you.

    Instead, here is how to actually report problems productively in the Unity3D forums:

    http://plbm.com/?p=220

    Help us to help you.
     
  5. gabicolombo27

    gabicolombo27

    Joined:
    Jun 24, 2020
    Posts:
    3
    I'm using this site for the first time. You don't need to answer like this.
    This code is a simulation fluid, but the particles just collide with quad. I need to implement box collider or mesh collider in this code.