Search Unity

uFlex - NVidia FLEX for Unity3D - Unified Visual FX [RELEASED]

Discussion in 'Assets and Asset Store' started by korzen303, Apr 15, 2016.

  1. ccc7861

    ccc7861

    Joined:
    Jan 19, 2016
    Posts:
    16
    Hello,
    SoftA connection softB, how to do without gap between them?
     
  2. s3-shimizu

    s3-shimizu

    Joined:
    Oct 29, 2015
    Posts:
    1
    Hello,
    this is the very asset I was looking for. Great integration.
    With uFlex v0.5, I'm currently testing fluid simulation. And I tested diffuse particles with some parameters but diffuse particles dont flow along the fluid particles, just fall by gravity. It looks like the parameters are not sent to Flex.
    Are diffuse particles unavaible now?
     
  3. DAU_JONES

    DAU_JONES

    Joined:
    Sep 5, 2014
    Posts:
    5
    @korzen303
    Sorry for the delayed reply. I was on holiday.
    I promised to post a benchmark to show the difference between a single GPU System and a dual System with one GPU dedicated for particle Simulation.

    Testsystem:
    Core i7 5820K@ 3.30 GHz
    32 GB RAM
    GPU 1 = NVIDIA GTX 970
    GPU 2 = NVIDIA GTX 780 Ti (dedicated to particle Simulation)
    Windows 10 64bit

    The Setup was as easy as Korzen303 described in post #71.

    First setup was running all on 1 GPU (GTX970)

    Each Color is a particle package of 32768 Particles
    1GPU_RENDERER_970_PARTICLES(32768).png 1GPU_RENDERER_970_PARTICLES(65536).png 1GPU_RENDERER_970_PARTICLES(98304).png

    32768 Particles @ 79 FPS
    65536 Particles @ 50,6 FPS
    98304 Particles @ 30,6 FPS
     
    Last edited: Sep 20, 2016
    korzen303 and elbows like this.
  4. DAU_JONES

    DAU_JONES

    Joined:
    Sep 5, 2014
    Posts:
    5
    Second setup was running rendering on GPU 1 (GTX970) and particle simulation on GPU 2 (GTX 780Ti)

    2GPU_RENDERER_970_PARTICLES(32768)_780TI.png 2GPU_RENDERER_970_PARTICLES(65536)_780TI.png 2GPU_RENDERER_970_PARTICLES(98304)_780TI.png

    32768 Particles @ 149,4 FPS
    65536 Particles @ 103,8 FPS
    98304 Particles @ 77,9 FPS
     
    korzen303 and elbows like this.
  5. crudeMe

    crudeMe

    Joined:
    Jul 8, 2015
    Posts:
    81
    Hi! Great looking asset. Read all thread and was wondering about smoke simulation as some people here.
    https://developer.nvidia.com/flex states that one of the key features are "Gases". This should be quite a demanding feature in my opinion. Any research on that matter? Thank you
     
  6. pan-master

    pan-master

    Joined:
    Nov 11, 2013
    Posts:
    124
    how to lock particles some particles to bones? I have created full set of particles for whole mesh. now I would like to drive inner particles alonge with bones. the motion of inner particles folowing bones would drive outer particles to five softbody fat sumulation looking like effect. but how can it be done?
     
  7. stefanob

    stefanob

    Joined:
    Nov 26, 2012
    Posts:
    45
    In your change log it says for version 0.45: Added small scale example scene
    Where can I find that scene? I have problems adjusting the Flex parameters for a small, thin, transparent pipe with water in it.
     
  8. Aaron-Meyers

    Aaron-Meyers

    Joined:
    Dec 8, 2009
    Posts:
    259
    on the subject of scale, it seems that uFlex operates at 10x the scale of Unity units (which are 1 meter).

    Is there any particular reason why this is the case? I'd prefer not to have to scale up everything else.
     
  9. Akhoris

    Akhoris

    Joined:
    Jan 16, 2014
    Posts:
    1
    I'm trying to move a sphere that is a softbody by input, like a character, but nothing happens. Any idea how I could make it work ?
     
  10. Pointcloud

    Pointcloud

    Joined:
    Nov 24, 2014
    Posts:
    33
    I am very much enjoying this package.
    A few quick, perhaps obtuse questions.

    1) How do you deal with scale? For example, the native fluid scale is quite large, it seems as if every particle is around 1 unity unit (1m). Is there a way to scale this down without everything exploding in every direction?

    2) This is a more obscure question regarding the simulations being used in VR with the leap motion. Using the HTC Vive with the leap motion I cannot successfully make a collision. I can to some degree, that is as long as any game object with a mesh collider exists at the setup of the game. The issue is that the leap motion hands appear and disappear based on the live tracking, so therefore their corresponding colliders appear and disappear, which seems to prevent the sim from responding to their colliders. Their native colliders are capsules however I have even tried migrating a cube with a mesh collider that worked externally from being parented to the fingertip and it would not influence the sim. Any suggestions?
     
  11. cleu

    cleu

    Joined:
    Oct 17, 2016
    Posts:
    1
    Maybe this isn't something for this board. But uFlex has the easy option to spawn in particles or fluids in a shape, ie spawn a bunch at once. I want to use this type of spawning for a project, to fill a container at the start of a game. But I can't find this in Unreal, does anyone know what that is called so I can google the right thing or just how to do it in unreal?
     
  12. leevermeulen

    leevermeulen

    Joined:
    Sep 17, 2014
    Posts:
    6
    Love this asset! Just tried it out with a Vive: https://twitter.com/Alientrap/status/788210172145565697 - Used NewtonVR + added particle grabbing

    One thing I couldn't figure out, or might be impossible - is there anyway to change the softness of soft bodies at runtime? I am looking into having something change from soft body to basically rigidbody. Or even a fluid to a soft body, to then a rigidbody.
     
  13. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    175
    Dear All,

    sorry for my recent lack of activity. I have started a new job in different country and things were a bit hectic. I will try to respond over the next few days to your posts.

    First of all, uFlex was thought as a wrapper enabling access to Flex library from Unity. The framework components are mainly for a quick-start and learning purposes. They are pretty straightforward so don't be afraid to modify and experimentate with them.


    Yes, it is possible to change the softness or even transform between different states.

    First, make sure that the dynamic container is checked in the solver component. Next, you can implement a custom processor that will modify the stiffness of the constraints. Alternatively, you can modify uflex components to achieve same thing. See, for example, how the "mass override" works in particles component.

    The latter would require a bit of extra scripting. The idea is to have both soft and rigid body constraints governing a single object and blend between them (soft body stiffness goes up, rigidbody stiffness down and vice-versa).

    Let us know about you results
     
  14. pan-master

    pan-master

    Joined:
    Nov 11, 2013
    Posts:
    124
    how to add more then one material to generated soft mesh? I have a mesh with a few materials. I can add only 1 material( sure there is an option in genereted skin rendere to add more materials) but even if I add more materials the textures are not placed corectly

    looks like a problem with UVs on generated softmesh
     
    Last edited: Oct 20, 2016
  15. CodeKiwi

    CodeKiwi

    Joined:
    Oct 27, 2016
    Posts:
    71
    Hi, thanks for creating this asset. I’ve been using UE4 for a while and wanted to try FleX in Unity. When I first tried it the editor would crash or the simulation would run really slow. It works great after I updated the drivers.

    I was testing some ideas and it looks like you can animate the rest positions of a rigid body. This allows you to create motors or interactive characters. I might try to get a character swimming in water at some point.


     
    Last edited: Oct 28, 2016
  16. CodeKiwi

    CodeKiwi

    Joined:
    Oct 27, 2016
    Posts:
    71
    I was just checking out the code. I’ve found it much easier to use than the UE4 implementation. It looks like it's easy to animate soft bodies as well as rigid bodies. I never managed to get animated soft bodies working in UE4. As a basic test I just tried scaling the rest positions (y axis). All I needed to do was enable “dynamic” in the FlexSolver and add the following code in FlexContainer.cs before “m_shapeRestPositions[shapeIndexOffset] = shapes.m_shapeRestPositions;”

    Code (CSharp):
    1. Vector3 pos = shapes.m_shapeRestPositions[i];
    2. pos.y *= 1.0f + (Time.timeSinceLevelLoad * 0.001f);
    3. shapes.m_shapeRestPositions[i] = pos;


    It should be possible to create a procedural animation e.g maybe a sine wave for a snake motion. I’ll probably look at exporting the rest positions and creating a mesh in blender from these points. Then add weights and export back to unity. Then a bones animation could be used to animate a rigid body or soft body character. I might also try giving the character multi-layers of FleX clothing and hair.
     
  17. CodeKiwi

    CodeKiwi

    Joined:
    Oct 27, 2016
    Posts:
    71
    I’ve included a basic test script for character motors. If anyone wants to test it just attach it to the Armadillo character and set “dynamic” to true in the Flex solver. For this example I also disabled gravity. It should work with soft bodies or rigid bodies. I’ll probably look at skeletal animation next.



    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using uFlex;
    5.  
    6. public enum CutAxis
    7. {
    8.     X,
    9.     Y,
    10.     Z
    11. }
    12.  
    13. public class FlexMotorTest : FlexProcessor // MonoBehaviour
    14. {
    15.     private FlexShapeMatching m_flexShapeMatching;
    16.     private FlexParticles m_particles;// = m_flexGameObjects[iId].GetComponent<FlexParticles>();
    17.     public float scale = 1;
    18.     public float rot = 0; // deg
    19.     public float rotPos = 0;
    20.     public Vector3 centerPos;
    21.     public CutAxis cutAxis = CutAxis.Y;
    22.     public float cutDistance = -3.25f;
    23.     public float cutPercent;
    24.     public float cutMovement;
    25.  
    26.     Vector3[] m_origShapeRestPositions;
    27.     Vector3[] m_origParticlePositions;
    28.     public Vector3[] m_origShapeCenters;
    29.  
    30.     void OnEnable()
    31.     {
    32.         if (m_flexShapeMatching == null)
    33.             m_flexShapeMatching = GetComponent<FlexShapeMatching>();
    34.  
    35.         if (m_particles == null)
    36.             m_particles = GetComponent<FlexParticles>();
    37.     }
    38.  
    39.     public override void PreContainerUpdate(FlexSolver solver, FlexContainer cntr, FlexParameters parameters)
    40.     {
    41.         if (m_origShapeRestPositions == null || m_origShapeRestPositions.Length == 0)
    42.         {
    43.             m_origShapeCenters = new Vector3[m_flexShapeMatching.m_shapeCenters.Length];
    44.             m_origParticlePositions = new Vector3[m_particles.m_particles.Length];
    45.             m_origShapeRestPositions = new Vector3[m_flexShapeMatching.m_shapeRestPositions.Length];
    46.  
    47.             for (int i = 0; i < m_flexShapeMatching.m_shapeRestPositions.Length; i++)
    48.             {
    49.                 m_origShapeRestPositions[i] = m_flexShapeMatching.m_shapeRestPositions[i];
    50.             }
    51.  
    52.             for (int i = 0; i < m_flexShapeMatching.m_shapeCenters.Length; i++)
    53.             {
    54.                 m_origShapeCenters[i] = m_flexShapeMatching.m_shapeCenters[i];
    55.             }
    56.  
    57.             for (int i = 0; i < m_particles.m_particles.Length; i++)
    58.             {
    59.                 int p = m_flexShapeMatching.m_shapeIndices[i];
    60.                 Vector3 pos = m_particles.m_particles[p].pos;
    61.                 m_origParticlePositions[i] = pos;
    62.             }
    63.  
    64.         }
    65.  
    66.         Quaternion qRot = Quaternion.identity;
    67.         switch (cutAxis)
    68.         {
    69.             case CutAxis.X: qRot = Quaternion.Euler(rot, 0, 0); break;
    70.             case CutAxis.Y: qRot = Quaternion.Euler(0, rot, 0); break;
    71.             case CutAxis.Z: qRot = Quaternion.Euler(0, 0, rot); break;
    72.         }
    73.      
    74.         centerPos.Set(0, 0, 0);
    75.  
    76.         int xCutTotal = 0;
    77.         FlexShapeMatching shapes = this.m_flexShapeMatching;
    78.  
    79.         int shapeIndex = 0;
    80.         int shapeIndexOffset = shapes.m_shapesIndex;
    81.         int shapeStart = 0;
    82.  
    83.         for (int s = 0; s < shapes.m_shapesCount; s++)
    84.         {
    85.             Vector3 shapeCenter = new Vector3();
    86.             shapeIndex++;
    87.  
    88.             int shapeEnd = shapes.m_shapeOffsets[s];
    89.  
    90.             int shapeCount = shapeEnd - shapeStart;
    91.             int origShapeIndexOffset = shapeIndexOffset;
    92.             for (int i = shapeStart; i < shapeEnd; ++i)
    93.             {
    94.                 Vector3 pos = m_origShapeRestPositions[i] + shapes.m_shapeCenters[s];
    95.  
    96.                 float cutValue = 0;
    97.                 switch (cutAxis)
    98.                 {
    99.                     case CutAxis.X: cutValue = pos.x; break;
    100.                     case CutAxis.Y: cutValue = pos.y; break;
    101.                     case CutAxis.Z: cutValue = pos.z; break;
    102.                 }
    103.  
    104.                 if (cutValue > cutDistance)
    105.                 {
    106.                     xCutTotal++;
    107.                     switch (cutAxis)
    108.                     {
    109.                         case CutAxis.X: pos.x += cutMovement; break;
    110.                         case CutAxis.Y: pos.y += cutMovement; break;
    111.                         case CutAxis.Z: pos.z += cutMovement; break;
    112.                     }
    113.  
    114.                     pos = qRot * pos;
    115.  
    116.                 }
    117.                 else
    118.                 {
    119.                     pos *= scale;
    120.                 }
    121.              
    122.                 shapes.m_shapeRestPositions[shapeIndexOffset] = pos;
    123.                 shapeCenter += pos;
    124.                 shapeIndexOffset++;
    125.             }
    126.  
    127.             shapeCenter /= shapeCount;
    128.  
    129.             // fix offsets, can't edit center position
    130.             for (int i = shapeStart; i < shapeEnd; ++i)
    131.             {
    132.                 Vector3 pos = shapes.m_shapeRestPositions[origShapeIndexOffset];
    133.                 pos -= shapeCenter;
    134.                 shapes.m_shapeRestPositions[origShapeIndexOffset] = pos;
    135.                 origShapeIndexOffset++;
    136.             }
    137.  
    138.             shapeStart = shapeEnd;
    139.         }
    140.     }
    141.  
    142. }
    143.  
     
    Last edited: Oct 29, 2016
    elbows likes this.
  18. ccc7861

    ccc7861

    Joined:
    Jan 19, 2016
    Posts:
    16
    high_noon:
      It was a wonderful !
     
  19. CodeKiwi

    CodeKiwi

    Joined:
    Oct 27, 2016
    Posts:
    71
    I managed to get a basic soft body skeleton animation working. I’ll post the code and instructions in another thread once I’ve cleaned it up a bit. In this short clip the mesh on the left is a standard bones animation. It turns into a spiky mesh which is used to animate the particle positions. The skinned mesh doesn’t exactly follow the particles because I only used rough settings for the soft body e.g particles too close, can’t overlap.

     
  20. CodeKiwi

    CodeKiwi

    Joined:
    Oct 27, 2016
    Posts:
    71
  21. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    175
    Awesome work @High_Noon !
    Please keep us posted about the progress and all the cool stuff coming
     
  22. theotrian

    theotrian

    Joined:
    Oct 27, 2013
    Posts:
    4
    Hey all! Has anyone figured out how to get collisions and contact points between uFlex and Unity PhysX? For instance, lets say a liquid simulation is lava and I want it to send a collision message to a character (with a collider) so they can switch to burning animation... Any ideas?
     
  23. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    175
    @theotrian use GetContacts to "get the particle contact planes. Note this will only include contacts that were active on the last substep of an update, and will include all contact planes generated within FlexParam::mShapeCollisionMargin."

    Then you will have to do the collision check on Unity side by yourself (i.e. Physics.OverlapSphere)
     
    infusionbru and theotrian like this.
  24. Dysangel

    Dysangel

    Joined:
    Jun 21, 2013
    Posts:
    2
    Hi Korzen,

    First off, thanks for the great plugin and making it so easy to get started with!

    Is it possible to have fluids with different viscosities interact in the same scene? I'm trying to make a simulation of sand + water. So far I only see a way to edit fluid settings for the whole scene, not specific fluid instances

    Thanks
     
    Last edited: Nov 7, 2016
  25. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    175
    The fluid viscosity in Flex is set per solver. You can have multiple Flex solvers in the scene (not tested in uFlex) but they won't interact with each other.

    Luckily for you, sand behaves like a granular material not like fluid. in flex you have got fluid - granular interactions out of the box. Check the granularDragon example scene
     
  26. eyalfx

    eyalfx

    Joined:
    Oct 8, 2010
    Posts:
    101
    Just purchased the package and tried running it on 5.4.2f2 . Started a fresh project and import the package. It's consistently crushing as soon as I hit the play button. Any ideas? Thanks.
     
  27. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    175
    @eyalfx Sometimes windows updates brakes something with the GPU drivers. Try reinstalling the latest version with "clean" option enabled.
     
  28. Quiet-Pixel

    Quiet-Pixel

    Joined:
    Aug 23, 2013
    Posts:
    44
    I was having the same issue with uFlex crashing Unity 5.4.2f2 as soon as any of the test scenes ran (on Windows 10, nVidia Titan X). Reinstalling the nVidia GPU drivers with the "clean" option fixed the issue. The demos work now.

    Thank you, Korzen.
     
  29. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    175
  30. Quiet-Pixel

    Quiet-Pixel

    Joined:
    Aug 23, 2013
    Posts:
    44
    Hi Korzen,

    Do you know if the NVidia Flex SDK imposes a limit on the number of vertices that can be in a CollisionTriangleMesh? Or if you have put a limit on them in your wrapper code?

    I built a little script that takes a height map and calculates vertices and triangles from it, and then passes those to Flex.UpdateTriangleMesh (). It works great for textures of size 256x256 or less, but larger textures cause the collision surface to stop working in uFlex. I know that Unity Meshes have a limit of 65535 vertices total, but since I am creating the vertex list and index list myself, and passing them directly to uFlex, I was hoping to get around the 65535 vertex limit.

    Do you know if there is a limit built in to your code or the Flex SDK?
     
  31. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    175
    The Flex docs don't mention any limits on this and I haven't experimented with large triangle meshes.
    uFlex does not impose any additional limits. Will check this tomorrow.
    Meanwhile, maybe try splitting the terrain in 256x256 chunks?
     
  32. Quiet-Pixel

    Quiet-Pixel

    Joined:
    Aug 23, 2013
    Posts:
    44
    Thank you for your feedback, Korzen.

    I did some more testing and you are right, the larger collision meshes are supported (larger than 65535 vertices). They do work, but evidently the triangle size was getting so small in my scene relative to the particles, that they are slipping through the collision surface. I am guessing the triangles are small enough that each particle is getting too many collisions against the surface for the numerical precision the solver is running at. Increasing the substeps prevented most of the particles from slipping through a 512x512 collider mesh, but was so slow to be usable.

    I either need to play with the solver settings to find the right stability, or accept 256x256 as the highest resolution collider for this scene.
     
  33. GregBahm

    GregBahm

    Joined:
    Jul 1, 2014
    Posts:
    3
    I appear to be in the same situation. Glad to hear there is a potential solution, because I was about to throw in the towel. Where can I find this "clean" option?
     
  34. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    175
    There is a checkbox which you can tick during GPU drivers installation.
     
  35. pan-master

    pan-master

    Joined:
    Nov 11, 2013
    Posts:
    124
    when uflex softbody is created UV and materials are not priserved. So when you have geometry with more then 1 material you wont be able to applay texutres corectly. Another thing,Is there a way to copy orginal blendhspae to created softbody geometry?
    Another Thing I have created xFlexSoftMesh and uFLexFluid ( all under one Uflex)
    I want to make fluid particles more sticky to uFlexSoftBodyMesh. I know that there is Adherence option. but adheracne does not change stickines to uflexSoftbody particles only The adheracne options works only between Fluids and Fluid Colliders not between UflexSoftoby and FLuids
     
    Last edited: Nov 26, 2016
  36. ccc7861

    ccc7861

    Joined:
    Jan 19, 2016
    Posts:
    16
    @pan-master:for more then 1 material ,you can add below code in FlexWindow.cs at 817 line
    mesh.uv = this.inputMesh.uv;
    if (this.inputMesh.subMeshCount > 1)
    {
    mesh.subMeshCount = this.inputMesh.subMeshCount;
    for (int i = 0; i < mesh.subMeshCount; i++)
    {
    mesh.SetIndices(this.inputMesh.GetIndices(i), MeshTopology.Triangles, i);
    }
    }
     
  37. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    175
  38. ccc7861

    ccc7861

    Joined:
    Jan 19, 2016
    Posts:
    16
    Share a uFlexSoftBody cut code:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using uFlex;
    5.  
    6. public class CutFlexUtil{
    7.  
    8.     public static void CutFlexSoft(Transform target, Plane plane)
    9.     {
    10.         CutFlexSoft(target, plane, CutTool.DeafaultPlane);
    11.     }
    12.     public static void CutFlexSoft(Transform target, Plane plane, Plane startPlane)
    13.     {
    14.         FlexShapeMatching shapes = target.GetComponent<FlexShapeMatching>();
    15.         FlexParticles particles = target.GetComponent<FlexParticles>();
    16.  
    17.         List<int> indicies = new List<int>();
    18.         List<int> offsets = new List<int>();
    19.        
    20.         List<int> otherIndices = new List<int>();
    21.  
    22.         int indexBeg = 0;
    23.         int indexEnd = 0;
    24.         for (int i = 0; i < shapes.m_shapesCount; ++i)
    25.         {
    26.             indexEnd = shapes.m_shapeOffsets[i];
    27.  
    28.             Vector3 shapeCenter = shapes.m_shapeCenters[i];
    29.             for (int j = indexBeg; j < indexEnd; ++j)
    30.             {
    31.                 int id = shapes.m_shapeIndices[j];
    32.                 Vector3 particlePos = particles.m_restParticles[id].pos;
    33.  
    34.                 if (plane.SameSide(shapeCenter, particlePos) == false)
    35.                 {
    36.                     if (startPlane.Equals(CutTool.DeafaultPlane) == false && startPlane.GetSide(particlePos) == false)
    37.                     {
    38.                         indicies.Add(id);
    39.                     }
    40.                     else
    41.                     {
    42.                      
    43.                         if (otherIndices.Contains(id) == false)
    44.                         {
    45.                             otherIndices.Add(id);
    46.                         }
    47.                     }
    48.                 }
    49.                 else
    50.                 {
    51.                     indicies.Add(id);
    52.                 }
    53.             }
    54.             offsets.Add(indicies.Count);
    55.             indexBeg = indexEnd;
    56.         }
    57.  
    58.         for (int i = 0; i < otherIndices.Count; i++)
    59.         {
    60.             if (indicies.Contains(otherIndices[i]) == false)
    61.             {
    62.                
    63.                 int index = FindClosedBoneIndexOnSameSide(shapes.m_shapeCenters, particles.m_restParticles[otherIndices[i]].pos, plane);
    64.                 int atIndex = offsets[index];
    65.                 indicies.Insert(atIndex, otherIndices[i]);
    66.                 for (int j = index; j < offsets.Count; j++)
    67.                 {
    68.                     offsets[j] += 1;
    69.                 }
    70.             }
    71.         }
    72.  
    73.         shapes.m_shapeIndicesCount = indicies.Count;
    74.         shapes.m_shapeIndices = indicies.ToArray();
    75.         shapes.m_shapeOffsets = offsets.ToArray();
    76.  
    77.         int shapeStart = 0;
    78.         int shapeIndex = 0;
    79.         int shapeIndexOffset = 0;
    80.         for (int s = 0; s < shapes.m_shapesCount; s++)
    81.         {
    82.             shapes.m_shapeTranslations[s] = new Vector3();
    83.             shapes.m_shapeRotations[s] = Quaternion.identity;
    84.  
    85.             shapeIndex++;
    86.  
    87.             int shapeEnd = shapes.m_shapeOffsets[s];
    88.             //-----------------------------------------cccc------------------------------------------------//
    89.  
    90.             Vector3 cen = Vector3.zero;
    91.             for (int i = shapeStart; i < shapeEnd; ++i)
    92.             {
    93.                 int p = shapes.m_shapeIndices[i];
    94.                 Vector3 pos = particles.m_restParticles[p].pos;
    95.                 cen += pos;
    96.             }
    97.             cen /= (shapeEnd - shapeStart);
    98.             shapes.m_shapeCenters[s] = cen;
    99.  
    100.             //--------------------------------------------cccc---------------------------------------------//
    101.             for (int i = shapeStart; i < shapeEnd; ++i)
    102.             {
    103.                 int p = shapes.m_shapeIndices[i];
    104.  
    105.                 // remap indices and create local space positions for each shape
    106.                 Vector3 pos = particles.m_restParticles[p].pos;
    107.                 shapes.m_shapeRestPositions[shapeIndexOffset] = pos - shapes.m_shapeCenters[s];
    108.  
    109.                 shapeIndexOffset++;
    110.             }
    111.  
    112.             shapeStart = shapeEnd;
    113.         }
    114.  
    115.  
    116.         Mesh mesh = target.GetComponent<SkinnedMeshRenderer>().sharedMesh;
    117.         BoneWeight[] boneWeights = new BoneWeight[mesh.vertexCount];
    118.         for (int i = 0; i < mesh.vertexCount; i++)
    119.         {
    120.             boneWeights[i] = mesh.boneWeights[i];
    121.             Vector3 vertexPos = mesh.vertices[i];
    122.             boneWeights[i] = CheckWeight(boneWeights[i], vertexPos, shapes.m_shapeCenters, plane);
    123.         }
    124.  
    125.     }
    126.     public static BoneWeight CheckWeight(BoneWeight weight, Vector3 vert, Vector3[] bones, Plane plane)
    127.     {
    128.         //return weight;
    129.         Vector3 shapeCenter = bones[weight.boneIndex0];
    130.         float value;
    131.  
    132.         int flag = 0;
    133.         if (plane.SameSide(shapeCenter, vert) == false)
    134.         {
    135.             value = weight.weight0;
    136.             weight.weight0 = 0;
    137.  
    138.  
    139.             int index = FindClosedBoneIndexOnSameSide(new Vector3[] { bones[weight.boneIndex1], bones[weight.boneIndex2], bones[weight.boneIndex3] }, vert, plane);
    140.             if (index == 0) weight.weight1 += value;
    141.             else if (index == 1) weight.weight2 += value;
    142.             else if (index == 2) weight.weight3 += value;
    143.  
    144.             flag++;
    145.         }
    146.  
    147.         shapeCenter = bones[weight.boneIndex1];
    148.         if (plane.SameSide(shapeCenter, vert) == false)
    149.         {
    150.             value = weight.weight1;
    151.             weight.weight1 = 0;
    152.             //
    153.             int index = FindClosedBoneIndexOnSameSide(new Vector3[] { bones[weight.boneIndex0], bones[weight.boneIndex2], bones[weight.boneIndex3] }, vert, plane);
    154.             if (index == 0) weight.weight0 += value;
    155.             else if (index == 1) weight.weight2 += value;
    156.             else if (index == 2) weight.weight3 += value;
    157.             flag++;
    158.         }
    159.         shapeCenter = bones[weight.boneIndex2];
    160.         if (plane.SameSide(shapeCenter, vert) == false)
    161.         {
    162.             value = weight.weight2;
    163.             weight.weight2 = 0;
    164.  
    165.             int index = FindClosedBoneIndexOnSameSide(new Vector3[] { bones[weight.boneIndex0], bones[weight.boneIndex1], bones[weight.boneIndex3] }, vert, plane);
    166.             if (index == 0) weight.weight0 += value;
    167.             else if (index == 1) weight.weight1 += value;
    168.             else if (index == 2) weight.weight3 += value;
    169.  
    170.             flag++;
    171.         }
    172.         shapeCenter = bones[weight.boneIndex3];
    173.         if (plane.SameSide(shapeCenter, vert) == false)
    174.         {
    175.             value = weight.weight3;
    176.             weight.weight3 = 0;
    177.  
    178.             int index = FindClosedBoneIndexOnSameSide(new Vector3[] { bones[weight.boneIndex0], bones[weight.boneIndex1], bones[weight.boneIndex2] }, vert, plane);
    179.             if (index == 0) weight.weight0 += value;
    180.             else if (index == 1) weight.weight1 += value;
    181.             else if (index == 2) weight.weight2 += value;
    182.  
    183.             flag++;
    184.         }
    185.         if (flag > 3)
    186.         {
    187.             Debug.Log(weight.weight0 + "------" + weight.weight1 + "------" + weight.weight2 + "------" + weight.weight3);
    188.  
    189.             weight.boneIndex0 = FindClosedBoneIndexOnSameSide(bones, vert, plane);
    190.             weight.weight0 = 1;
    191.         }
    192.  
    193.         return weight;
    194.  
    195.     }
    196.  
    197.     public static int FindClosedBoneIndexOnSameSide(Vector3[] BonePos, Vector3 vert, Plane plane)
    198.     {
    199.         int index = -1;
    200.         float dis = float.MaxValue;
    201.         for (int i = 0; i < BonePos.Length; i++)
    202.         {
    203.             if (plane.SameSide(BonePos[i], vert))
    204.             {
    205.                 if (Vector3.Distance(BonePos[i], vert) < dis)
    206.                 {
    207.                     index = i;
    208.                     dis = Vector3.Distance(BonePos[i], vert);
    209.                 }
    210.             }
    211.         }
    212.         return index;
    213.     }
    214. }
    215.  
     
    lulu_cecelia likes this.
  39. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    175
    @ccc7861 This is awesone! Thanks for sharing. Will give it a go as soon as possible.

    Cheers
     
  40. ccc7861

    ccc7861

    Joined:
    Jan 19, 2016
    Posts:
    16
    @korzen303  It is recommended that the “FlexExtraSpring ” be replaced by the following “FlexExtraSpring2”, and then we can have the function of the drag multiple points at the same time,And then I put mult points drag code out
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using uFlex;
    4.  
    5. namespace uFlex
    6. {
    7.     public class FlexExtraSpring2 : FlexProcessor
    8.     {
    9.         public FlexParticles m_bodyA;
    10.         public FlexParticles m_bodyB;
    11.         public int[] m_idAs;
    12.         public int[] m_idBs;
    13.  
    14.         public float m_restLength = 0;
    15.         public float m_stiffness = 1;
    16.         /// <summary>
    17.         ///
    18.         /// </summary>
    19.         public int springNum;
    20.         /// <summary>
    21.         ///
    22.         /// </summary>
    23.         public bool isLock = false;
    24.  
    25.         // Use this for initialization
    26.         void Start()
    27.         {
    28.             springNum = m_idAs.Length;
    29.         }
    30.         public override void PostContainerUpdate(FlexSolver solver, FlexContainer cntr, FlexParameters parameters)
    31.         {
    32.             if (isLock == false) return;
    33.             for (int i = 0; i < m_idAs.Length; i++)
    34.             {
    35.                 m_bodyA.m_particles[m_idAs[i]].pos = m_bodyB.m_particles[m_idBs[i]].pos;
    36.             }
    37.             base.PostContainerUpdate(solver, cntr, parameters);
    38.         }
    39.        
    40.         //
    41.     }
    42. }
     
  41. ccc7861

    ccc7861

    Joined:
    Jan 19, 2016
    Posts:
    16
    mult point drag code:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System;
    5. using uFlex;
    6.  
    7. public struct DrageDate
    8. {
    9.     public DrageDate(int _DrageLocalIndex, FlexParticles _drageParticles)
    10.     {
    11.         DrageLocalIndex = _DrageLocalIndex;
    12.         DrageParticles = _drageParticles;
    13.     }
    14.     public int DrageLocalIndex;
    15.     public FlexParticles DrageParticles;
    16. }
    17.  
    18. public struct ParticleData
    19. {
    20.     public ParticleData(float _dis, int _index)
    21.     {
    22.         dis = _dis;
    23.         index = _index;
    24.     }
    25.     public float dis;
    26.     public int index;
    27. }
    28.  
    29. public class FlexDragBase
    30. {
    31.  
    32.  
    33.     private GameObject gameObject;
    34.     private int dragLocalIndex = -1;
    35.     private float m_mouseMass = 0;
    36.     private FlexExtraSpring2 spring2;
    37.     private FlexParticles curParticles;
    38.     private int m_AddDragnum;
    39.  
    40.     public FlexDragBase(GameObject _gameObject)
    41.     {
    42.         gameObject = _gameObject;
    43.     }
    44.  
    45.     public void StartDrag(FlexContainer cntr, FlexParameters parameters, int dragGlobalIndex, int _m_AddDragnum)
    46.     {
    47.         m_AddDragnum = _m_AddDragnum;
    48.         curParticles = FlexUtils2.FindPartice(dragGlobalIndex);
    49.         dragLocalIndex = dragGlobalIndex - curParticles.m_particlesIndex;
    50.  
    51.         m_mouseMass = cntr.m_particles[dragLocalIndex + curParticles.m_particlesIndex].invMass;
    52.         cntr.m_particles[dragLocalIndex + curParticles.m_particlesIndex].invMass = 0.0f;
    53.  
    54.         AddClosedIndexs(cntr, parameters.m_radius, m_AddDragnum);
    55.  
    56.     }
    57.  
    58.     public void  UpdateDrag(FlexContainer cntr, Vector3 m_mousePos)
    59.     {
    60.         if (dragLocalIndex == -1) return;
    61.      
    62.         if (curParticles == null || curParticles.enabled == false)
    63.         {
    64.             StopDrag(cntr);
    65.             return;
    66.         }
    67.  
    68.         Vector3 pos = cntr.m_particles[dragLocalIndex + curParticles.m_particlesIndex].pos;
    69.         Vector3 p = Vector3.Lerp(pos, m_mousePos, 1f);
    70.         Vector3 delta = p - pos;
    71.         cntr.m_particles[dragLocalIndex + curParticles.m_particlesIndex].pos = p;
    72.         cntr.m_velocities[dragLocalIndex + curParticles.m_particlesIndex] = delta / Time.fixedTime;
    73.  
    74.     }
    75.  
    76.     public void StopDrag(FlexContainer cntr)
    77.     {
    78.         if (dragLocalIndex != -1)
    79.         {
    80.             cntr.m_particles[dragLocalIndex + curParticles.m_particlesIndex].invMass = m_mouseMass;
    81.             dragLocalIndex = -1;
    82.  
    83.             ClearSprings();
    84.  
    85.         }
    86.     }
    87.  
    88.     private void AddClosedIndexs(FlexContainer cntr, float radius, int m_AddDragnum)
    89.     {
    90.  
    91.         List<ParticleData> closedParticles = new List<ParticleData>();
    92.  
    93.         for (int i = 0; i < curParticles.m_particlesCount; i++)
    94.         {
    95.             if (i == dragLocalIndex) continue;
    96.             if (curParticles.m_particles[i].invMass == 0) continue;
    97.             float dis = Vector3.Distance(curParticles.m_particles[i].pos, curParticles.m_particles[dragLocalIndex].pos);
    98.             ParticleData pd = new ParticleData(dis,i);
    99.             closedParticles.Add(pd);
    100.         }
    101.         closedParticles.Sort((ParticleData a,ParticleData b)=> a.dis.CompareTo(b.dis));
    102.  
    103.         List<int> idAs = new List<int>();
    104.         List<int> idBs = new List<int>();
    105.         int count = 0;
    106.         for (int i = 0; i < closedParticles.Count; i++)
    107.         {
    108.             if (count >= m_AddDragnum) break;
    109.  
    110.             idAs.Add(closedParticles[i].index);
    111.             idBs.Add(dragLocalIndex);
    112.             count++;
    113.         }
    114.         if (idAs.Count > 0)
    115.         {
    116.             spring2 = gameObject.AddComponent<FlexExtraSpring2>();
    117.             spring2.m_bodyA = spring2.m_bodyB = curParticles;
    118.             spring2.m_idAs = idAs.ToArray();
    119.             spring2.m_idBs = idBs.ToArray();
    120.         }
    121.     }
    122.  
    123.     private void ClearSprings()
    124.     {
    125.         GameObject.DestroyImmediate(spring2);
    126.     }
    127.     //
    128. }
    129.  
    and With mouseDrag
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. namespace uFlex
    5. {
    6.     public enum MouseButton:int
    7.     {
    8.         MouseLeftButton = 0,
    9.         MouseRightButton = 1,
    10.         MouseMiddleButton = 2,
    11.     }
    12.     /// <summary>
    13.     /// Drag particles using mouse
    14.     /// </summary>
    15.     public class FlexMouseDrag2 : FlexProcessor
    16.     {
    17.         public MouseButton m_DragMouseBtn = MouseButton.MouseLeftButton;
    18.         public int m_AddDragnum = 0;
    19.         public BloodDiffuseVertex bloodForTemp;
    20.         private int m_mouseParticle = -1;
    21.         private float m_mouseT = 0;
    22.         private Vector3 m_mousePos = new Vector3();
    23.  
    24.         private FlexDragBase dragBase;
    25.  
    26.         public override void FlexStart(FlexSolver solver, FlexContainer cntr, FlexParameters parameters)
    27.         {
    28.             dragBase = new FlexDragBase(gameObject);
    29.             base.FlexStart(solver, cntr, parameters);
    30.         }
    31.  
    32.         public override void PostContainerUpdate(FlexSolver solver, FlexContainer cntr, FlexParameters parameters)
    33.         {
    34.             if (Input.GetMouseButtonDown(m_DragMouseBtn.GetHashCode()))
    35.             {
    36.                 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    37.                 m_mouseParticle = PickParticle(ray.origin, ray.direction, cntr.m_particles, cntr.m_phases, cntr.m_particlesCount, parameters.m_radius, ref m_mouseT);
    38.  
    39.                 if (m_mouseParticle != -1)
    40.                 {
    41.  
    42.                     dragBase.StartDrag(cntr, parameters, m_mouseParticle, m_AddDragnum);
    43.                 }
    44.             }
    45.  
    46.             if (Input.GetMouseButtonUp(m_DragMouseBtn.GetHashCode()))
    47.             {
    48.                 if (m_mouseParticle != -1)
    49.                 {
    50.                     dragBase.StopDrag(cntr);
    51.                     m_mouseParticle = -1;
    52.                 }
    53.             }
    54.  
    55.             if (m_mouseParticle != -1)
    56.             {
    57.                 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    58.                 m_mousePos = ray.origin + ray.direction * m_mouseT;
    59.  
    60.                 dragBase.UpdateDrag(cntr,m_mousePos);
    61.            
    62.             }
    63.         }
    64.      
    65.  
    66.         // finds the closest particle to a view ray
    67.         int PickParticle(Vector3 origin, Vector3 dir, Particle[] particles, int[] phases, int n, float radius, ref float t)
    68.         {
    69.             float maxDistSq = radius * radius;
    70.             float minT = float.MaxValue;
    71.             int minIndex = -1;
    72.  
    73.             for (int i = 0; i < n; ++i)
    74.             {
    75.                 if ((phases[i] & (int)Flex.Phase.eFlexPhaseFluid) != 0)
    76.                     continue;
    77.                 if (particles[i].invMass == 0) continue;
    78.  
    79.                 Vector3 p = particles[i].pos;
    80.                 Vector3 delta = p - origin;
    81.                 float tt = Vector3.Dot(delta, dir);
    82.  
    83.                 if (tt > 0.0f)
    84.                 {
    85.                     Vector3 perp = delta - tt * dir;
    86.  
    87.                     float dSq = perp.sqrMagnitude;
    88.  
    89.                     if (dSq < maxDistSq && tt < minT)
    90.                     {
    91.                         minT = tt;
    92.                         minIndex = i;
    93.                     }
    94.                 }
    95.             }
    96.  
    97.             t = minT;
    98.  
    99.             return minIndex;
    100.         }
    101.     }
    102. }
     
  42. GLID3R82

    GLID3R82

    Joined:
    Aug 7, 2013
    Posts:
    10
    Hi...
    in the video "New PhysX FleX features"
    after smoke simulation, the scene is a perfect Wind Tunnel for testing supercars...
    is it possible now with uFlex 0.5 to create the same Wind Tunnel? sample wind tunnel.jpg
     
  43. nickyoso1

    nickyoso1

    Joined:
    May 2, 2011
    Posts:
    85
    @korzen303 I saw this video from unite yesterday about high quality cloth physics. Somewhere in the video he compares what he has made to uFlex and he saw something in your code that seemed wrong to him. He then changed that and said that it improved performance by almost a factor of 2. He shows the code that he changed in the video, so that might be interesting for you to take a look at.

    Video link:
     
    nocanwin likes this.
  44. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    175
    Yes I am working on performance improvements as unity 5.5 added possibility to get a native pointers of compute buffers
     
  45. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    175
    OK, seemed like the profiling was slowing things down.

    I will add this fix to v0.6. If someone needs it asap s/he can simply change these two lines of code to get a nice performance bost.

    Code (CSharp):
    1.  
    2. //FlexAPI.cs line 661
    3. //public static extern void UpdateSolver(IntPtr s, float dt, int substeps, ref Timers timers);
    4. public static extern void UpdateSolver(IntPtr s, float dt, int substeps, IntPtr timers);
    5.  
    Code (CSharp):
    1.  
    2. //FlexSolver.cs line 210:
    3. void FixedUpdate()
    4. {
    5. //Flex.UpdateSolver(m_solverPtr, Time.fixedDeltaTime * m_fixedTimeStepMult, m_solverSubSteps, ref m_timers);
    6. Flex.UpdateSolver(m_solverPtr, Time.fixedDeltaTime * m_fixedTimeStepMult, m_solverSubSteps, IntPtr.Zero);
    7. }
     
    elbows likes this.
  46. elbows

    elbows

    Joined:
    Nov 28, 2009
    Posts:
    2,420
    Nvidia have shown off quite a number of different smoke solutions over the years. eg Nvidia Turbulence. Beyond the video you mention, I havent seen them heavily promoting FleX-based smoke, and my assumption is that their current preference is for their product called Nvidia Flow to be used for this purpose instead. The VR Funhouse edition of UE4.11 is probably the easiest way to see this stuff in action today - no reason I know of why someone couldn't make it work with Unity in a similar way to how this lovely FleX plugin has been done for Unity. Whether anybody will is another matter, I would certainly be a customer if they did. In the meantime there is a Unity Store asset called Fluidity which uses an older version of the underlying simulation technique - ie one that is bound to a grid as opposed to Flow which makes the grid dynamically expand as required.
     
    crudeMe likes this.
  47. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    175
    Exactly, I will remove this NVidia video as the smoke feature, which is not in Flex at the moment, may be indeed misleading. I have been looking at NVidia Flow integration as well.
     
    elbows likes this.
  48. crudeMe

    crudeMe

    Joined:
    Jul 8, 2015
    Posts:
    81
    Thank you. At last some light is shed upon nvidia smoke simulation.

    You have yourself a client then. Been following this thread for smoke simulation only.

    sorry for offtopic
     
  49. MelvinEng

    MelvinEng

    Joined:
    Jan 11, 2016
    Posts:
    14
    Hi Korzen,

    Just wondering if you're planning support for brittle/deformable fracturing? (with auto vertex/UV generation)
    There was brief mention of this sometime ago, but not much news since then...

    Cheers :)
    Melvin Eng
    Workshop Foundry
     
  50. korzen303

    korzen303

    Joined:
    Oct 2, 2012
    Posts:
    175
    @MelvinEng Hi, in the near future probably, it is a complex topic. In post #138 there is a code for soft-body cutting. Maybe it is a good starting point
     
unityunity