예제 #1
0
        private void EstimatePositions(float dt)
        {
            EstimatePositionsShader.SetFloat("dt", (float)dt);
            for (int j = 0; j < Bodies.Count; j++)
            {
                Body3d body = Bodies[j];
                if (GPUmode)
                {
                    EstimatePositionsShader.SetInt("numParticles", body.NumParticles);

                    EPS_UV_UPpredictedComputeBuffer[j].SetData(body.Predicted);
                    EPS_UV_UPpositionsComputeBuffer[j].SetData(body.Positions);
                    AEFS_EPS_UVvelocityComputeBuffer[j].SetData(body.Velocities);

                    EstimatePositionsShader.SetBuffer(estimatePositionsShaderHandle, "Predicted", EPS_UV_UPpredictedComputeBuffer[j]);
                    EstimatePositionsShader.SetBuffer(estimatePositionsShaderHandle, "Positions", EPS_UV_UPpositionsComputeBuffer[j]);
                    EstimatePositionsShader.SetBuffer(estimatePositionsShaderHandle, "Velocities", AEFS_EPS_UVvelocityComputeBuffer[j]);

                    EstimatePositionsShader.Dispatch(estimatePositionsShaderHandle, (body.NumParticles / 32) + 1, 1, 1);
                    EPS_UV_UPpredictedComputeBuffer[j].GetData(body.Predicted);
                }
                else
                {
                    for (int i = 0; i < body.NumParticles; i++)
                    {
                        body.Predicted[i] = body.Positions[i] + dt * body.Velocities[i];
                    }
                }
            }
        }
예제 #2
0
        public bool GPUmode = true;//true for GPU;
        public void init()
        {
            //init applyExternalForcesShaderHandle
            applyExternalForcesShaderHandle = ApplyExternalForcesShader.FindKernel("APPLYEXTERNALFORCE_1");
            ApplyExternalForcesShader.SetFloat("gravity", -9.81f);

            AEFS_EPS_UVvelocityComputeBuffer = new ComputeBuffer[Bodies.Count];
            for (int j = 0; j < Bodies.Count; j++)
            {
                Body3d body = Bodies[j];
                AEFS_EPS_UVvelocityComputeBuffer[j] = new ComputeBuffer(12, body.NumParticles);
            }

            estimatePositionsShaderHandle    = EstimatePositionsShader.FindKernel("ESTIMATEPOSITIONS");
            EPS_UV_UPpredictedComputeBuffer  = new ComputeBuffer[Bodies.Count];
            EPS_UV_UPpositionsComputeBuffer  = new ComputeBuffer[Bodies.Count];
            AEFS_EPS_UVvelocityComputeBuffer = new ComputeBuffer[Bodies.Count];
            for (int j = 0; j < Bodies.Count; j++)
            {
                Body3d body = Bodies[j];
                EPS_UV_UPpredictedComputeBuffer[j]  = new ComputeBuffer(16, body.NumParticles);
                EPS_UV_UPpositionsComputeBuffer[j]  = new ComputeBuffer(16, body.NumParticles);
                AEFS_EPS_UVvelocityComputeBuffer[j] = new ComputeBuffer(16, body.NumParticles);
            }



            updatePositionsShaderHandle  = UpdatePositionsShader.FindKernel("UPDATEPOSITION");
            updateVelocitiesShaderHandle = UpdateVelocitiesShader.FindKernel("UPDATEVELOCITIES");
        }
예제 #3
0
        //private void ConstrainVelocities()
        //{
        //    for (int i = 0; i < Bodies.Count; i++)
        //        Bodies[i].ConstrainVelocities();
        //}

        private void UpdatePositions()
        {
            for (int j = 0; j < Bodies.Count; j++)
            {
                Body3d body = Bodies[j];

                if (GPUmode)
                {
                    UpdatePositionsShader.SetInt("numParticles", body.NumParticles);

                    EPS_UV_UPpredictedComputeBuffer[j].SetData(body.Predicted);
                    EPS_UV_UPpositionsComputeBuffer[j].SetData(body.Positions);

                    UpdatePositionsShader.SetBuffer(updatePositionsShaderHandle, "Predicted", EPS_UV_UPpredictedComputeBuffer[j]);
                    UpdatePositionsShader.SetBuffer(updatePositionsShaderHandle, "Positions", EPS_UV_UPpositionsComputeBuffer[j]);

                    UpdatePositionsShader.Dispatch(updatePositionsShaderHandle, (body.NumParticles / 32) + 1, 1, 1);

                    EPS_UV_UPpositionsComputeBuffer[j].GetData(body.Positions);
                }
                else
                {
                    for (int i = 0; i < body.NumParticles; i++)
                    {
                        body.Positions[i] = body.Predicted[i];
                    }
                }
            }
        }
예제 #4
0
        internal FEMTetConstraint3d(Body3d body, int p0, int p1, int p2, int p3, double youngsModulus) : base(body)
        {
            P0 = p0;
            P1 = p1;
            P2 = p2;
            P3 = p3;

            YoungsModulus = youngsModulus;
            PoissonRatio  = 0.3;
            Correction    = new Vector3d[4];

            Vector3d x0 = Body.Positions[P0];
            Vector3d x1 = Body.Positions[P1];
            Vector3d x2 = Body.Positions[P2];
            Vector3d x3 = Body.Positions[P3];

            RestVolume = Math.Abs((1.0f / 6.0) * Vector3d.Dot(x3 - x0, Vector3d.Cross(x2 - x0, x1 - x0)));

            Matrix3x3d restMatrix = new Matrix3x3d();

            restMatrix.SetColumn(0, x0 - x3);
            restMatrix.SetColumn(1, x1 - x3);
            restMatrix.SetColumn(2, x2 - x3);

            InvRestMatrix = restMatrix.Inverse;
        }
        internal StrainTetConstraint3d(Body3d body, int p0, int p1, int p2, int p3, double stiffness) : base(body)
        {
            P0 = p0;
            P1 = p1;
            P2 = p2;
            P3 = p3;

            Stiffness        = stiffness;
            NormalizeStretch = false;
            NormalizeShear   = false;

            Correction = new Vector3[4];

            Vector3 x0 = body.Positions[P0];
            Vector3 x1 = body.Positions[P1];
            Vector3 x2 = body.Positions[P2];
            Vector3 x3 = body.Positions[P3];

            Matrix3x3d restMatrix = new Matrix3x3d();

            restMatrix.SetColumn(0, MathConverter.ToVector3d(x1 - x0));
            restMatrix.SetColumn(1, MathConverter.ToVector3d(x2 - x0));
            restMatrix.SetColumn(2, MathConverter.ToVector3d(x3 - x0));

            InvRestMatrix = restMatrix.Inverse;
        }
        private void CreateSpheres()
        {
            if (sphereMaterial == null)
            {
                return;
            }

            Spheres = new List <List <GameObject> >();

            for (int j = 0; j < Solver.Bodies.Count; j++)
            {
                Body3d body = Solver.Bodies[j];

                int   numParticles = body.NumParticles;
                float diam         = (float)body.ParticleDiameter;

                List <GameObject> spheres = new List <GameObject>(numParticles);

                for (int i = 0; i < numParticles; i++)
                {
                    Vector3 pos = body.Positions[i];

                    GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                    sphere.transform.parent     = transform;
                    sphere.transform.position   = pos;
                    sphere.transform.localScale = new Vector3(diam, diam, diam);
                    sphere.GetComponent <Collider>().enabled      = false;
                    sphere.GetComponent <MeshRenderer>().material = sphereMaterial;
                    spheres.Add(sphere);
                }


                Spheres.Add(spheres);
            }
        }
예제 #7
0
        private void AppyExternalForces(double dt)
        {
            ApplyExternalForcesShader.SetFloat("dt", (float)dt);

            for (int j = 0; j < Bodies.Count; j++)
            {
                Body3d body = Bodies[j];
                if (GPUmode)
                {
                    ApplyExternalForcesShader.SetInt("numParticles", body.NumParticles);
                    ApplyExternalForcesShader.SetFloat("damping", (float)body.Dampning);
                    AEFS_EPS_UVvelocityComputeBuffer[j].SetData(body.Velocities);

                    ApplyExternalForcesShader.SetBuffer(applyExternalForcesShaderHandle, "Velocities", AEFS_EPS_UVvelocityComputeBuffer[j]);
                    ApplyExternalForcesShader.Dispatch(applyExternalForcesShaderHandle, (body.NumParticles / 32) + 1, 1, 1);

                    AEFS_EPS_UVvelocityComputeBuffer[j].GetData(body.Velocities);
                }
                else
                {
                    for (int i = 0; i < body.NumParticles; i++)
                    {
                        body.Velocities[i] -= (body.Velocities[i] * (float)body.Dampning) * (float)dt;
                    }

                    for (int i = 0; i < Forces.Count; i++)
                    {
                        Forces[i].ApplyForce(dt, body);
                    }
                }
            }
        }
예제 #8
0
 public void AddBody(Body3d body)
 {
     if (Bodies.Contains(body))
     {
         return;
     }
     Bodies.Add(body);
 }
예제 #9
0
        internal BodyPlaneContact3d(Body3d body0, int i0, Vector3d normal, double dist)
        {
            Body0   = body0;
            this.i0 = i0;

            Normal   = normal;
            Distance = dist;
        }
        internal DistanceConstraint3d(Body3d body, int i0, int i1, double stiffness) : base(body)
        {
            this.i0 = i0;
            this.i1 = i1;

            CompressionStiffness = stiffness;
            StretchStiffness     = stiffness;
            RestLength           = (Body.Positions[i0] - Body.Positions[i1]).Magnitude;
        }
        public override void ApplyForce(double dt, Body3d body)
        {
            int len = body.NumParticles;

            for (int i = 0; i < len; i++)
            {
                body.Velocities[i] += (float)dt * MathConverter.ToVector3(Gravity);
            }
        }
        public override void ApplyForce(double dt, Body3d body)
        {
            int len = body.NumParticles;

            for (int i = 0; i < len; i++)
            {
                body.Velocities[i] += dt * Gravity;
            }
        }
        public override void ApplyForce(double dt, Body3d body)
        {
            string BufferName = "Velocities";

            CurrentShader.SetBuffer(_kernel, BufferName, body.GPUVelocities);
            CurrentShader.SetFloat("Gravity", (float)Gravity.y);
            CurrentShader.SetFloat("dt", (float)dt);
            CurrentShader.SetInt("MatterParticles", body.NumParticles);

            CurrentShader.Dispatch(_kernel, ShaderHelper.GetNumberOfDispatchGroups(body.NumParticles, BLOCK_SIZE), 1, 1);
        }
예제 #14
0
        private void UpdatePositions()
        {
            for (int j = 0; j < Bodies.Count; j++)
            {
                Body3d body = Bodies[j];

                for (int i = 0; i < body.NumParticles; i++)
                {
                    body.Positions[i] = body.Predicted[i];
                }
            }
        }
예제 #15
0
        private void EstimatePositions(float dt)
        {
            for (int j = 0; j < Bodies.Count; j++)
            {
                Body3d body = Bodies[j];

                for (int i = 0; i < body.NumParticles; i++)
                {
                    body.Predicted[i] = body.Positions[i] + dt * body.Velocities[i];
                }
            }
        }
예제 #16
0
        internal BendingConstraint3d(Body3d body, int i0, int i1, int i2, double stiffness) : base(body)
        {
            this.i0 = i0;
            this.i1 = i1;
            this.i2 = i2;

            Stiffness = stiffness;

            Vector3d center = (Body.Positions[i0] + Body.Positions[i1] + Body.Positions[i2]) / 3.0;

            RestLength = (Body.Positions[i2] - center).Magnitude;
        }
예제 #17
0
        private void DrawOutline(Camera camera)
        {
            Vector3 min = new Vector3(-GRID_SIZE, 0, -GRID_SIZE);
            Vector3 max = new Vector3(GRID_SIZE, 0, GRID_SIZE);

            DrawLines.DrawGrid(camera, Color.white, min, max, 1, transform.localToWorldMatrix);

            for (int j = 0; j < Solver.Bodies.Count; j++)
            {
                Body3d body = Solver.Bodies[j];
                //DrawLines.DrawBounds(camera, Color.green, body.Bounds, Matrix4x4d.Identity);
            }
        }
        internal BodyBodyContact3d(Body3d body0, int i0, Body3d body1, int i1)
        {
            Body0   = body0;
            this.i0 = i0;

            Body1   = body1;
            this.i1 = i1;

            Diameter  = Body0.ParticleRadius + Body1.ParticleRadius;
            Diameter2 = Diameter * Diameter;

            double sum = Body0.ParticleMass + Body1.ParticleMass;

            Mass0 = Body0.ParticleMass / sum;
            Mass1 = Body1.ParticleMass / sum;
        }
        internal IsometricBendingConstraint3d(Body3d body, int i0, int i1, int i2, int i3, float stiffness) : base(body)
        {
            this.i0       = i0;
            this.i1       = i1;
            this.i2       = i2;
            this.i3       = i3;
            BendStiffness = stiffness;

            Vector3d p0 = body.Positions[i0];
            Vector3d p1 = body.Positions[i1];
            Vector3d p2 = body.Positions[i2];
            Vector3d p3 = body.Positions[i3];

            // Compute matrix Q for quadratic bending
            Vector3d[] x = new Vector3d[] { p2, p3, p0, p1 };

            Vector3d e0 = x[1] - x[0];
            Vector3d e1 = x[2] - x[0];
            Vector3d e2 = x[3] - x[0];
            Vector3d e3 = x[2] - x[1];
            Vector3d e4 = x[3] - x[1];

            double c01 = CotTheta(e0, e1);
            double c02 = CotTheta(e0, e2);
            double c03 = CotTheta(e0 * -1.0, e3);
            double c04 = CotTheta(e0 * -1.0, e4);

            double A0 = 0.5 * e0.Cross(e1).Magnitude;
            double A1 = 0.5 * e0.Cross(e2).Magnitude;

            double coef = -3.0 / (2.0 * (A0 + A1));

            double[] K  = new double[] { c03 + c04, c01 + c02, -c01 - c03, -c02 - c04 };
            double[] K2 = new double[] { coef *K[0], coef *K[1], coef *K[2], coef *K[3] };

            Q = new Matrix4x4d();

            for (int j = 0; j < 4; j++)
            {
                for (int k = 0; k < j; k++)
                {
                    Q[j, k] = Q[k, j] = K[j] * K2[k];
                }

                Q[j, j] = K[j] * K2[j];
            }
        }
예제 #20
0
        private void AppyExternalForces(float dt)
        {
            for (int j = 0; j < Bodies.Count; j++)
            {
                Body3d body = Bodies[j];

                for (int i = 0; i < body.NumParticles; i++)
                {
                    body.Velocities[i] -= (body.Velocities[i] * body.Dampning) * dt;
                }

                for (int i = 0; i < Forces.Count; i++)
                {
                    Forces[i].ApplyForce(dt, body);
                }
            }
        }
        public void UpdateSpheres()
        {
            if (Spheres != null)
            {
                for (int j = 0; j < Solver.Bodies.Count; j++)
                {
                    Body3d            body    = Solver.Bodies[j];
                    List <GameObject> spheres = Spheres[j];

                    for (int i = 0; i < spheres.Count; i++)
                    {
                        Vector3 pos = body.Positions[i];
                        spheres[i].transform.position = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
                    }
                }
            }
        }
예제 #22
0
        private void UpdateVelocities(double dt)
        {
            double invDt      = 1.0 / dt;
            double threshold2 = SleepThreshold * dt;

            threshold2 *= threshold2;

            UpdateVelocitiesShader.SetFloat("invDt", (float)invDt);
            UpdateVelocitiesShader.SetFloat("threshold2", (float)threshold2);

            for (int j = 0; j < Bodies.Count; j++)
            {
                Body3d body = Bodies[j];

                if (GPUmode)
                {
                    UpdateVelocitiesShader.SetInt("numParticles", body.NumParticles);

                    EPS_UV_UPpredictedComputeBuffer[j].SetData(body.Predicted);
                    EPS_UV_UPpositionsComputeBuffer[j].SetData(body.Positions);
                    AEFS_EPS_UVvelocityComputeBuffer[j].SetData(body.Velocities);

                    UpdateVelocitiesShader.SetBuffer(updateVelocitiesShaderHandle, "Predicted", EPS_UV_UPpredictedComputeBuffer[j]);
                    UpdateVelocitiesShader.SetBuffer(updateVelocitiesShaderHandle, "Positions", EPS_UV_UPpositionsComputeBuffer[j]);
                    UpdateVelocitiesShader.SetBuffer(updateVelocitiesShaderHandle, "Velocities", AEFS_EPS_UVvelocityComputeBuffer[j]);

                    UpdateVelocitiesShader.Dispatch(updateVelocitiesShaderHandle, (body.NumParticles / 32) + 1, 1, 1);

                    AEFS_EPS_UVvelocityComputeBuffer[j].GetData(body.Velocities);
                }
                else
                {
                    for (int i = 0; i < body.NumParticles; i++)
                    {
                        Vector3 d = body.Predicted[i] - body.Positions[i];
                        body.Velocities[i] = d * (float)invDt;

                        double m = body.Velocities[i].sqrMagnitude;
                        if (m < threshold2)
                        {
                            body.Velocities[i] = Vector3.zero;
                        }
                    }
                }
            }
        }
        internal override void FindContacts(IList <Body3d> bodies, List <CollisionContact3d> contacts)
        {
            for (int j = 0; j < bodies.Count; j++)
            {
                Body3d body = bodies[j];

                int    numParticles = body.NumParticles;
                double radius       = body.ParticleRadius;

                for (int i = 0; i < numParticles; i++)
                {
                    double d = Vector3.Dot(Normal, body.Predicted[i]) + Distance - radius;

                    if (d < 0.0)
                    {
                        contacts.Add(new BodyPlaneContact3d(body, i, Normal, Distance));
                    }
                }
            }
        }
예제 #24
0
        internal ShapeMatchingConstraint3d(Body3d body, double mass, double stiffness) : base(body)
        {
            Stiffness     = stiffness;
            InvRestMatrix = Matrix3x3d.Identity;
            RestCm        = Vector3.zero;
            double wsum         = 0.0;
            int    numParticles = Body.NumParticles;

            for (int i = 0; i < numParticles; i++)
            {
                RestCm += Body.Positions[i] * (float)mass;
                wsum   += mass;
            }

            RestCm /= (float)wsum;

            Matrix3x3d A = new Matrix3x3d();

            RestPositions = new Vector3[numParticles];

            for (int i = 0; i < numParticles; i++)
            {
                Vector3 q = Body.Positions[i] - RestCm;

                A[0, 0] += mass * q.x * q.x;
                A[0, 1] += mass * q.x * q.y;
                A[0, 2] += mass * q.x * q.z;

                A[1, 0] += mass * q.y * q.x;
                A[1, 1] += mass * q.y * q.y;
                A[1, 2] += mass * q.y * q.z;

                A[2, 0] += mass * q.z * q.x;
                A[2, 1] += mass * q.z * q.y;
                A[2, 2] += mass * q.z * q.z;

                RestPositions[i] = q;
            }

            InvRestMatrix = A.Inverse;
        }
예제 #25
0
        internal DihedralConstraint3d(Body3d body, int i0, int i1, int i2, int i3, float stiffness) : base(body)
        {
            this.i0       = i0;
            this.i1       = i1;
            this.i2       = i2;
            this.i3       = i3;
            BendStiffness = stiffness;

            Vector3 p0 = body.Positions[i0];
            Vector3 p1 = body.Positions[i1];
            Vector3 p2 = body.Positions[i2];
            Vector3 p3 = body.Positions[i3];


            Vector3 n1 = Vector3.Cross((p2 - p0), (p3 - p0));

            n1 /= n1.sqrMagnitude;

            Vector3 n2 = Vector3.Cross((p3 - p1), (p2 - p1));

            n2 /= n2.sqrMagnitude;

            n1.Normalize();
            n2.Normalize();
            float dot = Vector3.Dot(n1, n2);

            if (dot < -1.0)
            {
                dot = -1.0f;
            }
            if (dot > 1.0)
            {
                dot = 1.0f;
            }

            RestAngle = Math.Acos(dot);
        }
예제 #26
0
        private void UpdateVelocities(float dt)
        {
            float invDt      = 1.0f / dt;
            float threshold2 = SleepThreshold * dt;

            threshold2 *= threshold2;

            for (int j = 0; j < Bodies.Count; j++)
            {
                Body3d body = Bodies[j];

                for (int i = 0; i < body.NumParticles; i++)
                {
                    Vector3f d = body.Predicted[i] - body.Positions[i];
                    body.Velocities[i] = d * invDt;

                    double m = body.Velocities[i].SqrMagnitude;
                    if (m < threshold2)
                    {
                        body.Velocities[i] = Vector3f.Zero;
                    }
                }
            }
        }
예제 #27
0
 internal Constraint3d(Body3d body)
 {
     Body = body;
 }
예제 #28
0
 internal StaticConstraint3d(Body3d body, int i) : base(body)
 {
     i0       = i;
     Position = body.Positions[i];
 }
 public abstract void ApplyForce(double dt, Body3d body);