NVIDIAGameWorks / FleX

Other
664 stars 100 forks source link

Fluid leaves rigid constraint objects on higher speed through material #20

Open ghost opened 7 years ago

ghost commented 7 years ago

On higher speed movings of an rigid acting object (in my case a cup), the fluid within the cup leaves it unwanted through the material. The highest speed possible without leaving the cup in my test was about 0.065 units per frame. What I am doing wrong?

The cup has a dimension of about 2x3x2 units.

assuming 1 unit = 1 meter (which would be a very very big cup): on 25fps: 0.065 units per frame are 1.625 units per second ~5km/h (~3 mph)

if 1 unit = 1 decimeter: on 25fps: 0.065 units per frame are 0.1625 units per second ~0.59km/h (~0.36 mph)

if 1 unit = 1 centimeter: on 25fps: 0.065 units per frame are 0.01625 units per second ~0.059km/h (~0.036 mph)

So when a 3D person has a drink in a car, which drives maybe 25km/h (~15 mph) the fluid will not remain in the cup! Even if the person does not move the cup additionally to the car move.

The rigid constraint objects in my tests are build (and updated) in the scene's "Update" method using "AddTriangleMesh" function.

The particles are build this way (I use separate solvers for each fluid, if there is more than one):

      radius =  0.065f;
      float restDistance = radius*0.5f; 
    FlexSolvers[solverID]->g_params.collisionDistance = restDistance;
    FlexSolvers[solverID]->g_params.restitution = 0.0f;
    FlexSolvers[solverID]->g_params.relaxationFactor = 1.0f;
    FlexSolvers[solverID]->g_params.relaxationMode = eNvFlexRelaxationLocal;

    FlexSolvers[solverID]->g_params.anisotropyScale = 25.0f;
    FlexSolvers[solverID]->g_params.fluidRestDistance = FlexSolvers[solverID]->g_params.radius*0.5f;
    FlexSolvers[solverID]->g_params.smoothing = 0.5f;
    FlexSolvers[solverID]->g_params.maxSpeed = 0.5f*FlexSolvers[solverID]->g_numSubsteps*FlexSolvers[solverID]->g_params.radius / g_dt;

    CreateParticleGrid(... 2.0f, false, 0.0f, NvFlexMakePhase(group++, eNvFlexPhaseSelfCollide | eNvFlexPhaseFluid));

    if (FlexSolvers[solverID]->g_params.numIterations < 7)
       FlexSolvers[solverID]->g_params.numIterations = 7;

    FlexSolvers[solverID]->g_params.radius = radius;

    FlexSolvers[solverID]->g_diffuseScale = 0.5f;
    FlexSolvers[solverID]->g_params.diffuseBallistic = 16;
    FlexSolvers[solverID]->g_params.diffuseBuoyancy = 1.0f;
    FlexSolvers[solverID]->g_params.diffuseDrag = 1.0f;

                    FlexSolvers[solverID]->g_waveFloorTilt = 0.0f;
                    FlexSolvers[solverID]->g_waveFrequency = 1.5f;
                    FlexSolvers[solverID]->g_waveAmplitude = 2.0f;

settings for this fluid:

FPS 25  ; same problem at 60fps
@IOR 1.0

@SubSteps  4  ; no big difference if 16     (same problem even if its 24)
@Iterations 16                                    ; (same problem even if its 24)

@Adhesion 0.0
@Cohesion 0.025   ; fails when much lower
@SolidPressure 0.25
@DynamicFriction 0.5
@ParticleFriction 0.125
@Viscosity 0.0 ; no big difference if 4.0
@SurfaceTension  0  ; no big difference if 1.2
@VorticityConfinement 0.0
@Buoyancy  1.0
@Drag 0.8  ; no big difference if 0.0

; FLEX_RADIUS = 0.065
@CollisionDistance  0.0325 ;  = FLEX_RADIUS * 0.5
@FluidRestDistance FLEX_RADIUS * 0.5
@FlexParticleGrid 25,120,25
@FlexParticles 64*1024

I tested these setups:

FLEX_RADIUS = 0.065 ; 0.0325 = FLEX_RADIUS * 0.5 (as in demo) TEST1 CollisionDistance 0.0325 speed 0.065 (or lower) OK TEST2 CollisionDistance 0.0325 speed 0.075 sort of ok, only some diffuse particles leave the cup TEST3 CollisionDistance 0.0325 speed 0.08 sort of ok, only some diffuse particles leave the cup TEST4 CollisionDistance 0.0325 speed 0.2 FAIL
TEST5 CollisionDistance 0.0325 speed 0.4 FAIL

TEST6 CollisionDistance 0.02 speed 0.02 OK TEST7 CollisionDistance 0.02 speed 0.07 FAIL

NOTE: if a car moves 25km/h (15mph) that is ~6.9 meter/sec So if I would use meter units here a speed of 0.115 units per frame (on 60fps) would be required If I would use decimeter units here a speed of 1.15 units per frame (on 60fps) would be required

Speed 0.2 per frame on 60fps: 12m/s ~ 43km/h (26mph) on meter units Speed 0.4 per frame on 60fps: 24m/s ~ 86km/h (53mph) on meter units On these speeds (in reality) the fluid may leave the cup (based on its additional rotation angles), but never through the material!

Speed 0.2 per frame on 60fps: 1.2m/s ~ 4km/h (2mph) on decimeter units Speed 0.4 per frame on 60fps: 2.4m/s ~ 8km/h (5mph) on decimeter units So these speeds are common for this situation.

When a person moves the hand about 0.5 meters from right to left that can take half a second. which is about 1meter/s on 60fps that would be 0.0166 units per frame (on meter units) But it would be a speed of 0.166 units per frame on decimeter units (@ 60fps). And if 1 unit is 1 centimerter that even would be 1.66 units per frame!

The Cup has 2x3x2 units. So for a normal scenario a unit for that cup would be decimeters: 20x30x20 cm would still be a big cup. So I also scaled the cup down with factor 0.5 = 10x15x10 cm and with factor 0.2 = 4x6x4 cm For meter units I scaled the cup down with factor 0.05 (10x15x10 cm) => same results

object scale factor 0.05 (10x15x10 cm) on the cup allows max speed 0.065 units per frame => which is about 3.9 meters/s ~ 14km/h (if meter Units) BUT: the fluid particle ellipsoids are then much too big in relation to the object!!!

and on decimeters: 0.065 units per frame means 0.39m/s ~ 1.4km/h which is not even the half speed of 1m/s

Some Videos with the full-size cup Tests: FluidLeavesObject.zip NOTE: in the videos I switch between solid and wireframe, so that the fluid can be seen inside the cup.

Cup object from the Tests is in Cup0.obj file

I also tested the WaterBalloon Scene (64bit D3D Release version) : first I pressed "G" to remove gravity, then after a while "G" again to apply it. When the balloons come down they loose fluids although they are not teared. see video Flex_1_2_0_beta2_D3DreleaseDemo64bit.wmv


UPDATE SEP 24 2017:

And I tested to increase the speed over time, but unfortunately that also did not help. FLEX_RADIUS = 0.08 USE_SUBSTEPS = 24 USE_ITERATIONS = 24 COLLISION_DISTANCE = 0.07 simulation and Video @ 60fps in 3600 frames (=60sec on 60fps) the speed smoothly increases from 0.01 Units/frame to 0.2 Units per/frame, (using a cosinus function from 180°..360°)

but already at about frame 500 some fluid particles leave the cup. The speed at that position was (0.2 - 0.01) ((cos(180° + 180° (500/3600)) * 0.5)+0.5) ~ 0.0089 Units/frame.

On increasing the speed over 7200 Frames (=2min on 60fps) it remains iin the cup until about frame 900, where the speed is (0.2 -0.01) ((cos(180° + 180° (900/7200)) * 0.)+0.5) ~ 0.00723 Units/Frame

FluidSpeedIncrease.zip


I reduced substeps = 8 iterations = 8
FLEX_RADIUS = 0.1 COLLISION_DISTANCE = FLEX_RADIUS * 0.5 7200frames (on 60fps) Speed increase from 0.01 to 0.1 Units per Frame simulation and Video @ #60fps Fluid_7200_on_8substsep_8iteration.zip

So I can increase substeps+iterations and I can run the entire scene at a lower speed. Unfortunately even on high substeps/Iterations some fluids leave the object. I did not find a good useable way, cause high substeps/iterations slow down anything a lot and loosing particles is no good option in a HQ Video production.

ghost commented 6 years ago

I added some tests where the speed increases over time. Unfortunately without great success.

mmacklin commented 6 years ago

Hi there,

If increasing subsets is not helping it may leaking because of the internal limit of 6 contact planes per-particle. Because each triangle contributes a plane highly tessellated objects will easily overflow this limit. You might find that using a simpler triangle mesh, or a convex decomposition of the object and setting convex shapes would yield better results.

I will look into exposing this internal limit for a future build so that you could at least experiment with increasing it at the cost of some additional memory.

Cheers, Miles

ghost commented 6 years ago

Hi Miles, Thank you very much for your answer. After reducing the geometry tesselation, fluid behaviour really improved, but the object shape itself then cannot be so smooth curved as wanted, It would be great to have the ability to increase the internal limit. Thanks for looking into it.

convex decomposition of Cup0.obj would cause 32 pieces plus the floor Piece. UPDATED: 96 pieces required. (new Cup4.obj has better mesh topology)

Hurleyworks commented 6 years ago

Instant Meshes does a great job of mesh reduction while maintaining shape.

http://igl.ethz.ch/projects/instant-meshes/

On Mon, Sep 25, 2017 at 6:01 PM, Sheila69 notifications@github.com wrote:

Hi Miles, Thank you very much for your answer. After reducing the geometry tesselation, fluid behaviour really improved, but the object shape itself then cannot be so smooth curved as wanted, It would be great to have the ability to increase the internal limit. Thanks for looking into it.

convex decomposition of Cup0.obj would cause 32 pieces plus the floor piece, right? I'll try it.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/NVIDIAGameWorks/FleX/issues/20#issuecomment-332026642, or mute the thread https://github.com/notifications/unsubscribe-auth/AHvnv9CQojROyDkek-gn6-xdPUARs-V-ks5smCKzgaJpZM4PSIfS .

-- -Steve http://www.hurleyworks.com

ghost commented 6 years ago

During testing SDF as collision constraint for the Cup (yet I did not test convex decomposition) I noticed a memory leak, each time when pressing "R" in the "Shape Collision" sample scene. So I thought I should report it here. in helper.h within the "CreateSDF" function I added delete[] pfm.m_data; but this alone did not solve all of that leak.

mmacklin commented 6 years ago

Thanks Sheila, have checked in a fix that should make it for the final 1.2 release.

Cheers, Miles

ghost commented 6 years ago

SDF did not gave me the expected results, so I tried convex decomposition meshes on a very low tesselation level, still using triangle mesh collision:

Cup0.obj uses 256 vertices with 508 faces CupConvexDecom32_0_000.obj uses 32 vertices with 60 faces CupConvexDecom64_0_000.obj uses 64 vertices with 124 faces

ConvexDecompositionTests.zip


CupConvexDecom32_0_000.obj uses 32 vertices with 60 faces

Through the convex decomposition even the shape of the object has massivly changed, but unfortunately some fluid still goes through the material.

ConvexDecompositionCupTest0.wmv (60fps) uses a smooth speed up within 100 frames (1.6 seconds) from 0.01 units/frame to final speed 0.1 units/frame on FLEX_RADIUS = 0.1 USE_SUBSTEPS = 12 USE_ITERATIONS = 6 COLLISION_DISTANCE = FLEX_RADIUS * 0.5 Still fluid leaves after short time

ConvexDecompositionCupTest1.wmv (60fps) uses a smooth speed up within 600 frames (10 seconds) from 0.01 units/frame to final speed 0.1 units/frame on FLEX_RADIUS = 0.065 USE_SUBSTEPS = 12 USE_ITERATIONS = 6 COLLISION_DISTANCE = FLEX_RADIUS * 0.5 Still fluid leaves after short time.


CupConvexDecom64_0_000.obj uses 64 vertices with 124 faces

ConvexDecompositionCupTest2.wmv (60fps) uses a smooth speed up within 600 frames (10 seconds) from 0.01 units/frame to final speed 0.1 units/frame on FLEX_RADIUS = 0.065 USE_SUBSTEPS = 12 USE_ITERATIONS = 6 COLLISION_DISTANCE = FLEX_RADIUS * 0.5 fluid is ok during speed up, but when it stops to speed 0 abrupt directly, the fluid still does not leave the cup where it should. instead it leaves through material

ConvexDecompositionCupTest3.wmv (60fps) uses a smooth speed up within 600 frames (10 seconds) from 0.01 units/frame to final speed 0.2 units/frame on FLEX_RADIUS = 0.065 USE_SUBSTEPS = 12 USE_ITERATIONS = 6 COLLISION_DISTANCE = FLEX_RADIUS 0.5 fluid is leaving after half time (where speed is at ~0.095 = (0.2 - 0.01) ((cos(180° + 180° (300/600)) 0.5)+0.5) = (0.2 - 0.01) ((0 0.5)+0.5)


0.1 units/frame = 6.0 units/second (on 60fps) => on decimeter units 6.0/second = 0.6 meter/second = 2.16 km/h


result: the number of faces sharing a vertex can even be bigger than 6 on convex decompositioned meshes. see convex32.jpg, convex64.jpg, org_cup0.jpg Normally a quad-based mesh topology would be best, but the automatic convex decomposition algo I used, don't produce them.


ghost commented 6 years ago

Manual decomposition with a completely different topology now succeeds on triangle mesh collision. See CupMeshTopology.jpg (there 4 faces are mentioned; when trianglulated, these are actually 5)

MoreConvexDecompositionTests.zip

I updated again the Cup mesh (some double Vertices removed, so that ist clearer) Cup4.zip

VIDEO_20171007_013852_0.wmv (60fps) uses a smooth speed up within 600 frames (10 seconds) from 0.01 units/frame to final speed 0.2 units/frame on FLEX_RADIUS = 0.065 USE_SUBSTEPS = 12 USE_ITERATIONS = 6 COLLISION_DISTANCE = FLEX_RADIUS * 0.5

However, still when running at Speed 0.2 and then stopping abrupt to speed 0, the fluid still leaves through the material.

So next I'll try the cup as 96 eNvFlexShapeConvexMesh's out of combined triangles. 96 pieces = (32 quads of upper part to triangles = 64 triangles) and 32 triangles for bottom. Hope that it gives better results.

ghost commented 6 years ago

so finally I decompositioned the mesh in Cup4.obj (130 vertices, 256 faces) into 96 convex objects (applied as eNvFlexShapeConvexMesh). (more about how I did that, and the final 96 plane definitions are in 96convex_objects.txt)

Unfortunately the fluid is still leaving through the material. Even after I increased the plane distances of each convex object, the fluid leaves. 96ConvexDecom.zip

96convexDecompositionBodiesOverlapping_1_0.wmv (convexes with original distances) 96convexDecompositionBodiesOverlapping_1_5.wmv (bigger convexes, which overlap) both test videos (60fps) use a smooth speed up within 600 frames (10 seconds) from 0.01 units/frame to final speed 0.2 units/frame on FLEX_RADIUS = 0.065 USE_SUBSTEPS = 12 USE_ITERATIONS = 6 COLLISION_DISTANCE = FLEX_RADIUS * 0.5

The blue/cyan visible mesh/solid objects in the videos are the convex objects, not the real mesh. The real mesh object is completely hidden in these test videos. CompareOverlapping.jpg shows how the convex objects overlap. NOTE: of course I negated all the distances within the plane definitions. All convex objects have exactly 5 planes, describing them.

Are there more parameters to ensure for convex object's ?


So the best working solution for me yet is using a mesh topology with 6 or less triangles sharing a vertex, with triangle mesh collision. With the exception, that abrupt speed changes still cause the problem; such when a 3D person holds the cup, moves the arm fast and stops immediately.