コード例 #1
0
ファイル: Integrator.cs プロジェクト: platvorm/fluviofx
        public string GetSource(VFXData data)
        {
            return($@"{FluvioFXBlock.CheckAlive(data)}
float invMass = 1.0f / mass;
float3 acceleration = force * invMass;
float3 v = dt * acceleration;

// Discard excessive velocities
if (any(isnan(v) || isinf(v)) || dot(v, v) > FLUVIO_MAX_SQR_VELOCITY_CHANGE)
{{
    v = 0;
}}
{source}");
        }
コード例 #2
0
        public static IEnumerable <VFXNamedExpression> GetParameters(
            CollisionBase block,
            IEnumerable <VFXNamedExpression> baseParameters)
        {
            var expressions = baseParameters;

            expressions = expressions.Concat(FluvioFXBlock.GetSolverDataExpressions(block));

            foreach (var expression in expressions)
            {
                yield return(expression);
            }
            ;

            yield return(new VFXNamedExpression(VFXValue.Constant(1.0f) / VFXBuiltInExpression.DeltaTime, "invDt"));
        }
コード例 #3
0
ファイル: Integrator.cs プロジェクト: wegiangb/fluviofx
        public IEnumerable <VFXPropertyWithValue> GetInputProperties(IEnumerable <VFXPropertyWithValue> baseProperties)
        {
            foreach (var inputProperty in baseProperties)
            {
                yield return(inputProperty);
            }

            if (inputPropertyTypes != null)
            {
                foreach (var type in inputPropertyTypes)
                {
                    if (type != null)
                    {
                        var typeProperties = FluvioFXBlock.PropertiesFromType(type);
                        foreach (var inputProperty in typeProperties)
                        {
                            yield return(inputProperty);
                        }
                    }
                }
            }
        }
コード例 #4
0
        public static IEnumerable <VFXPropertyWithValue> GetInputProperties(
            ICollisionSettings collisionSettings,
            IEnumerable <VFXPropertyWithValue> baseProperties)
        {
            var properties = baseProperties;

            if (collisionSettings.BoundaryPressure)
            {
                properties = properties
                             .Concat(FluvioFXBlock.PropertiesFromType(typeof(BoundaryPressureProperties)));
            }
            if (collisionSettings.BoundaryViscosity)
            {
                properties = properties
                             .Concat(FluvioFXBlock.PropertiesFromType(typeof(BoundaryViscosityProperties)));
            }
            if (collisionSettings.RepulsionForce)
            {
                properties = properties
                             .Concat(FluvioFXBlock.PropertiesFromType(typeof(RepulsionForceProperties)));
            }

            return(properties);
        }
コード例 #5
0
        public static string GetCollisionSource(
            ICollisionSettings settings,
            string baseSource,
            string collisionResponseSource,
            string roughSurfaceSource)
        {
            if (!settings.BoundaryPressure && !settings.BoundaryViscosity)
            {
                return(baseSource.Replace(collisionResponseSource, GetFluidResponseSource(settings, roughSurfaceSource)));
            }

            var proxyTestSource = baseSource
                                  .Replace("float3 nextPos = position + velocity * deltaTime;", "")
                                  .Replace("nextPos", "proxyPosition")
                                  .Replace("position", "dummyPosition")
                                  .Replace(collisionResponseSource, "    collisionTest = true;");

            var split = proxyTestSource.Split(new []
            {
                "\r\n",
                "\r",
                "\n"
            }, StringSplitOptions.None);

            proxyTestSource = string.Join("\n                ", split);

            var data = (settings as VFXBlock)?.GetData();

            return($@"{FluvioFXBlock.CheckAlive(data)}
{{
    float3 offset, proxyPosition, dummyPosition, dist;
    float density = 0;
    float pressure, lenSq, diffSq;
    bool collisionTest = false;

    float searchRadius = solverData_KernelSize.x;
    float step = solverData_KernelSize.w;

    float3 gridJitter = float3(FIXED_RAND3(0x5f7b48e2)) * step;

    float x, y, z;

    // Fluid density calculation
    for(x = -searchRadius; x < searchRadius; x += step)
    {{
        for(y = -searchRadius; y < searchRadius; y += step)
        {{
            for(z = -searchRadius; z < searchRadius; z += step)
            {{
                // Get proxy particle position
                offset = float3(x, y, z);
                proxyPosition = position + offset;

                // Snap to random grid, but keep the grid consistent per particle
                proxyPosition = (round(proxyPosition / step) * step) + gridJitter;
                collisionTest = false;
                {proxyTestSource}

                if (collisionTest)
                {{
                    // Range check
                    // TODO: We can optimize this away since we know the precise step size
                    dist = position - proxyPosition;
                    lenSq = dot(dist, dist);
                    if (lenSq < solverData_KernelSize.y)
                    {{
                        // Sum density
                        diffSq = solverData_KernelSize.y - lenSq;
                        density += mass * Poly6Calculate(diffSq, solverData_KernelFactors.x);
                    }}
                }}
            }}
        }}
    }}

    density = max(density, solverData_Fluid_MinimumDensity);
    pressure = solverData_Fluid_GasConstant * (density - solverData_Fluid_Density);

    float2 neighborDensityPressure = float2(
        solverData_Fluid_Density,
        {(settings.BoundaryPressure ? "GasConstant * solverData_Fluid_Density" : "0")});

    float len, len3, diff, bodyRadiusSq, scalar;
    float3 f, neighborVelocity, bodyDist;
    for(x = -searchRadius; x < searchRadius; x += step)
    {{
        for(y = -searchRadius; y < searchRadius; y += step)
        {{
            for(z = -searchRadius; z < searchRadius; z += step)
            {{
                if (abs(x) < step && abs(y) < step && abs(z) < step)
                {{
                    continue;
                }}

                // Get proxy particle position
                offset = float3(x, y, z);
                proxyPosition = position + offset;

                // Snap to random grid, but keep the grid consistent per particle
                proxyPosition = (round(proxyPosition / step) * step) + gridJitter;
                collisionTest = false;
                {proxyTestSource}

                if (collisionTest)
                {{
                    // Range check
                    // TODO: We can optimize this away since we know the precise step size
                    dist = position - proxyPosition;
                    lenSq = dot(dist, dist);
                    if (lenSq < solverData_KernelSize.y)
                    {{
                        // For kernels
                        lenSq = dot(dist, dist);
                        len = sqrt(lenSq);
                        len3 = len * len * len;
                        diffSq = solverData_KernelSize.y - lenSq;
                        diff = solverData_KernelSize.x - len;

                        {(settings.BoundaryPressure ? @"// Pressure term
                        scalar = mass
                            * (pressure + neighborDensityPressure.y) / (neighborDensityPressure.x * 2.0f);
                        f = SpikyCalculateGradient(dist, diff, len, solverData_KernelFactors.y);
                        f *= scalar;

                        force -= f;" : "")}

                        {(settings.BoundaryViscosity ? @"// Viscosity term
                        bodyDist = proxyPosition - CenterOfGravity;
                        bodyRadiusSq = sqrt(dot(bodyDist, bodyDist));
                        neighborVelocity = Velocity + (AngularVelocity / FLUVIO_TAU) * FLUVIO_TAU * bodyRadiusSq;

                        scalar = mass
                            * ViscosityCalculateLaplacian(
                                diff,
                                solverData_KernelSize.z,
                                solverData_KernelFactors.z)
                            * (1.0f / neighborDensityPressure.x);

                        f = neighborVelocity - velocity;
                        f *= scalar * Viscosity;

                        force += f;" : "")}
                    }}
                }}
            }}
        }}
    }}

    // Write totals to density/pressure (zw)
    density = max(densityPressure.z + density, solverData_Fluid_MinimumDensity);
    pressure = solverData_Fluid_GasConstant * (density - solverData_Fluid_Density);
    densityPressure.zw = float2(density, pressure);
}}

{baseSource.Replace(collisionResponseSource, GetFluidResponseSource(settings,roughSurfaceSource))}");
        }