示例#1
0
 internal void RaiseOnCollision(CollisionReport Report)
 {
     if (OnCollision != null)
       OnCollision(this,new CollisionEventArgs(Report));
 }
示例#2
0
        // Experimentální!
        internal void SolveCollision_Experimental(CollisionReport Report)
        {
            double cof = 0.3, cor = 0.5;
            double C = 1 / (1/Report.A.Mass + 1/Report.B.Mass);
            double AinvM = 1 / Report.A.Mass, BinvM = 1 / Report.B.Mass,AinvI = 1/Report.A.MomentOfInertia,BinvI = 1/Report.B.MomentOfInertia;

            Report.A.Model.Position += Report.MTD * (1 / Report.A.Mass * C);
            Report.B.Model.Position -= Report.MTD * (1 / Report.B.Mass * C);

            // apply friction impulses at contacts
            Vector pa = (Vector)Report.Pairs[0].A;
            Vector pb = (Vector)Report.Pairs[0].B;
            Vector ncol = Vector.Unit(Report.MTD);
            Vector ra = pa - Report.A.Model.Position;
            Vector rb = pb - Report.A.Model.Position;
            Vector va = Report.A.LinearVelocity + (ra.Perp()*Report.A.AngularVelocity[2]);
            Vector vb = Report.B.LinearVelocity + (rb.Perp()*Report.B.AngularVelocity[2]);
            Vector v = (va - vb);
            Vector vt = v - ncol*Vector.Dot(v,ncol);
            Vector nf = Vector.Unit(-vt); // friction normal

            // contact points separating, no impulses.
            if (Vector.Dot(v,ncol) > 0.0f) return;

            // collision impulse
            double jc = Vector.Dot(v,ncol) / ((AinvM + BinvM) +
                                        Vector.Dot(Vector.Cross(ra,ncol) , Vector.Cross(ra,ncol)) * AinvI +
                                        Vector.Dot(Vector.Cross(rb,ncol) , Vector.Cross(rb,ncol)) * BinvI);

            // friction impulse
            double jf = Vector.Dot(v,nf) / ((AinvM + BinvM) +
                                        Vector.Dot(Vector.Cross(ra,nf),Vector.Cross(ra,nf)) * AinvI +
                                        Vector.Dot(Vector.Cross(rb,nf),Vector.Cross(rb,nf)) * BinvI);

            // clamp friction.
            if (Math.Abs(jf) > Math.Abs(jc * cof))
                jf = Math.Abs(cof) * Math.Sign(jc);

            // total impulse restituted
            Vector impulse = ncol * (jc * -(1 + cor)) + nf * (-jf);

            Report.A.LinearVelocity += impulse * AinvM;
            Report.B.LinearVelocity -= impulse * BinvM;

            Report.A.AngularVelocity += Vector.Cross(ra,impulse) * AinvI;
            Report.B.AngularVelocity -= Vector.Cross(rb,impulse) * BinvI;
        }
示例#3
0
 /// <summary>
 /// Výchozí konstruktor
 /// </summary>
 /// <param name="Rep">Hlášení o kolizi</param>
 public CollisionEventArgs(CollisionReport Rep)
 {
     Report = Rep;
 }
示例#4
0
        /// <summary>
        /// Vyřeší konkrétní kolizi
        /// </summary>
        /// <param name="Report">Hlášení o kolizi</param>
        public void SolveCollision(CollisionReport Report)
        {
            double k = Math.Max(Report.A.ObjMaterial.RestitutionCoefficient,Report.B.ObjMaterial.RestitutionCoefficient);
            double f = Math.Max(Report.A.ObjMaterial.FrictionCoefficient, Report.B.ObjMaterial.FrictionCoefficient);
            double M = 1 / (1 / Report.A.Mass + 1 / Report.B.Mass);

            double I = (Math.Pow(Vector.Dot(Report.NAP, Report.N), 2) / Report.A.MomentOfInertia) + (Math.Pow(Vector.Dot(Report.NBP, Report.N), 2) / Report.B.MomentOfInertia);
            double Num = (-1 - k) * Vector.Dot(Report.RelativeVelocity, Report.N);
            double Denom = Vector.Dot(Report.N, Report.N) * ((1 / Report.A.Mass) + (1 / Report.B.Mass)) + I;
            double Impulse_C = Math.Round(Num / Denom,2);

            Report.A.Model.Position += Report.MTD / Report.A.Mass * M * (Report.B.Static ? 2.1 : 1);
            Report.B.Model.Position += -Report.MTD / Report.B.Mass * M * (Report.A.Static ? 2.1 : 1);

            if (Double.IsNaN(Impulse_C)) return;

            Report.A.LinearVelocity += Vector.Floor(Report.N * (Impulse_C / Report.A.Mass));
            Report.A.AngularVelocity[2] += Vector.Dot(Report.N, Report.NAP) * (Impulse_C / Report.A.MomentOfInertia);

            Report.B.LinearVelocity -= Vector.Floor(Report.N * (Impulse_C / Report.B.Mass));
            Report.B.AngularVelocity[2] -= Vector.Dot(Report.N, Report.NBP) * (Impulse_C / Report.B.MomentOfInertia);

            Report.A.Model.RaiseOnCollision(Report);
            Report.B.Model.RaiseOnCollision(Report);
        }