Пример #1
0
        public ContactResult Submit(ContactModel contact, ContactSettings contactSettings)
        {
            var result = new ContactResult();
            if (contact == null) throw new ArgumentNullException("Missing contact form data");
            if (contactSettings == null) throw new ArgumentNullException("Missing settings");

            if (logger != null) logger.LogInformation("Contact: {0} / {1} / {2} [Email: {3}, Post: {4}, Recaptcha: {5}]",
                contact.ContactName, contact.Email, contact.Phone, contactSettings.EmailSettings?.Enabled,
                contactSettings.PostSettings?.Enabled, contactSettings.RecaptchaSettings?.Enabled);

            if (contactSettings.RecaptchaSettings != null
                && contactSettings.RecaptchaSettings.Enabled
                && !string.IsNullOrEmpty(contactSettings.RecaptchaSettings.RecaptchaKey))
            {
                // Check Recaptcha
                var recaptchaService = new RecaptchaService();
                result.RecaptchaResult = recaptchaService.Validate(contactSettings.RecaptchaSettings, logger);
                if (result.RecaptchaResult.ServiceResultType != ServiceResultType.Success) return result;  // Stop processing immediately
            }

            if (contactSettings.EmailSettings != null && contactSettings.EmailSettings.Enabled)
            {
                var emailService = new EmailService();
                result.EmailResult = emailService.SendEmail(contact, contactSettings.EmailSettings, logger);
            }

            if (contactSettings.PostSettings != null && contactSettings.PostSettings.Enabled && !string.IsNullOrEmpty(contactSettings.PostSettings.PostURL))
            {
                var postService = new PostService();
                result.PostResult = postService.Post(contact, contactSettings.PostSettings, logger);
            }
            return result;
        }
Пример #2
0
        public string GetResultHTML(ContactResult result, ContactSettings contactSettings)
        {
            StringBuilder sbResult = new StringBuilder();
            sbResult.AppendLine(result.Success ? "Successfully executed: <br />" : "Execution result: <br />");
            if (result.EmailResult != null && result.EmailResult.ServiceResultType != ServiceResultType.None)
                sbResult.AppendFormat("{0} <br/>", result.EmailResult.Message);
            if (result.PostResult != null && result.PostResult.ServiceResultType != ServiceResultType.None)
                sbResult.AppendFormat("{0} <br/>", result.PostResult.Message);
            if (result.RecaptchaResult != null && result.RecaptchaResult.ServiceResultType != ServiceResultType.Success)
                sbResult.AppendFormat("Invalid reCAPTCHA: {0} <br/>", result.RecaptchaResult.Message);

            if (!string.IsNullOrEmpty(contactSettings.PostSettings.RedirectURL) && contactSettings.PostSettings.RedirectSeconds >= 0)
            {
                var redirectURL = string.Format(contactSettings.PostSettings.RedirectURL, result.Success ? "1" : "0");
                // Show 'Click to continue'
                sbResult.AppendFormat("<a href='{0}'>{1}</a>", redirectURL, contactSettings.PostSettings.RedirectText);

                if (contactSettings.PostSettings.RedirectSeconds > 0)
                {
                    // JS redirect after RedirectSeconds
                    sbResult.AppendFormat("\r\n<script type='text/javascript'>setTimeout(function() {{document.location.href='{0}'}}, {1})</script>",
                        redirectURL, contactSettings.PostSettings.RedirectSeconds * 1000);
                }
            }
            return sbResult.ToString();
        }
Пример #3
0
        public static AlienResult ConvertToResult(
            Alien alien,
            ContactResult contactResult,
            PassportResult passportResult,
            OrganizationResult organizationResult,
            StateRegistrationResult stateRegistrationResult)
        {
            Contract.Argument.IsNotNull(alien, nameof(alien));
            Contract.Argument.IsNotNull(contactResult, nameof(contactResult));
            Contract.Argument.IsNotNull(passportResult, nameof(passportResult));
            Contract.Argument.IsNotNull(organizationResult, nameof(organizationResult));
            Contract.Argument.IsNotNull(stateRegistrationResult, nameof(stateRegistrationResult));

            return(new AlienResult
            {
                Id = alien.Id,
                InvitationId = alien.InvitationId,
                Contact = contactResult,
                Passport = passportResult,
                Organization = organizationResult,
                StateRegistration = stateRegistrationResult,
                Position = alien.Position,
                WorkPlace = alien.WorkPlace,
                WorkAddress = alien.WorkAddress,
                StayAddress = alien.StayAddress
            });
        }
Пример #4
0
        private void backgroundWorkerContact_DoWork(object sender, DoWorkEventArgs e)
        {
            WechatRobot   robot   = Global.robot;
            ContactResult contact = protocol.GetContact(robot.Cookie, robot.CookieStr);

            e.Result = contact;
        }
Пример #5
0
        private void ExtractCollisionData(ContactResult point, out Projectile proj, out Alien alien, out Player player, out Pickup pickup)
        {
            proj   = null;
            alien  = null;
            player = null;
            pickup = null;
            var shapes = new Shape[] { point.Shape1, point.Shape2 };

            foreach (var shape in shapes)
            {
                if (shape.UserData is Projectile && proj == null)
                {
                    proj = shape.UserData as Projectile;
                }
                else if (shape.UserData is Alien)
                {
                    alien = shape.UserData as Alien;
                }
                else if (shape.UserData is Player)
                {
                    player = shape.UserData as Player;
                }
                else if (shape.UserData is Pickup)
                {
                    pickup = shape.UserData as Pickup;
                }
            }
        }
        protected void Button1_Click(object sender, EventArgs e)
        {
            ContactResult cr  = new ContactResult();
            GlobalVar     var = new GlobalVar();

            try
            {
                SqlDataAdapter da = new SqlDataAdapter();
                using (SqlConnection openCon = new SqlConnection(var.connectionString))
                {
                    string saveStaff = "SELECT  [AndroidLog],[AndroidLat] FROM  [AndroidTrack] where [DateRegister]= (select max([DateRegister]) from AndroidTrack)";

                    using (SqlCommand querySaveStaff = new SqlCommand(saveStaff))
                    {
                        querySaveStaff.Connection = openCon;
                        DataSet ds = new DataSet();
                        openCon.Open();
                        DataTable table = new DataTable();
                        table.Load(querySaveStaff.ExecuteReader());
                        ds.Tables.Add(table);
                        Response.Redirect("http://www.google.com/maps/place/" + Convert.ToString(table.Rows[0]["AndroidLat"]) + "," + Convert.ToString(table.Rows[0]["AndroidLog"]));
                        openCon.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                Response.Write(ex.Message);
            }
        }
Пример #7
0
        private void backgroundWorkerContact_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            ContactResult contact = e.Result as ContactResult;

            InitContact(contact.MemberList);
            Global.robot.Contact = contact.MemberList.ToList();
            LogOut("联系人获取完成");
        }
Пример #8
0
        private void BallContact(ContactResult point)
        {
            Shape shape1 = point.Shape1, shape2 = point.Shape2;
            Body  body1 = point.Shape1.GetBody(), body2 = point.Shape2.GetBody();
            float ballTackleSpeed;
            Body  anotherBody;

            if ((anotherBody = this.GetAnotherBodyInContact(point, this.ball)) == null)
            {
                return;
            }

            if (anotherBody == this.goalLeft)
            {
                this.ball.ApplyForce(new Vec2(0.005f, 0), this.ball.GetPosition());
                if (shape1.UserData as string == "Post" || shape2.UserData as string == "Post")
                {
                    if ((ballTackleSpeed = this.GetBallCollisionSpeed()) > 0.02f)
                    {
                        this.BallPostTackled(ballTackleSpeed);
                    }

                    return;
                }
            }

            if (anotherBody == this.goalRight)
            {
                this.ball.ApplyForce(new Vec2(-0.005f, 0), this.ball.GetPosition());
                if (shape1.UserData as string == "Post" || shape2.UserData as string == "Post")
                {
                    if ((ballTackleSpeed = this.GetBallCollisionSpeed()) > 0.02f)
                    {
                        this.BallPostTackled(ballTackleSpeed);
                    }

                    return;
                }
            }

            if (anotherBody == this.ground)
            {
                if (this.ball.GetAngularVelocity() * 0.15 * (this.ball.GetAngularVelocity() > 0 ? 1 : -1) >
                    0.85 * this.ball.GetLinearVelocity().X *(this.ball.GetLinearVelocity().X > 0 ? 1 : -1))
                {
                    this.ball.SetAngularVelocity(this.ball.GetAngularVelocity() * 0.94f);
                }
            }

            if ((ballTackleSpeed = this.GetBallCollisionSpeed()) > 0.02f)
            {
                this.BallTackled?.Invoke(ballTackleSpeed);
            }
        }
Пример #9
0
        private Person GetPersonDetails(KerberosResult ucdKerbPerson, ContactResult ucdContact)
        {
            return(new Person

            {
                GivenName = string.IsNullOrWhiteSpace(ucdKerbPerson.DFirstName) ? ucdKerbPerson.OFirstName : ucdKerbPerson.DFirstName,
                Surname = string.IsNullOrWhiteSpace(ucdKerbPerson.DLastName) ? ucdKerbPerson.OLastName : ucdKerbPerson.DLastName,
                FullName = string.IsNullOrWhiteSpace(ucdKerbPerson.DFullName) ? ucdKerbPerson.OFullName : ucdKerbPerson.DFullName,
                Kerberos = ucdKerbPerson.UserId,
                Mail = ucdContact.Email,
                WorkPhone = ucdContact.WorkPhone
            });
        }
Пример #10
0
        private Body GetAnotherBodyInContact(ContactResult point, Body body)
        {
            Body body1 = point.Shape1.GetBody(), body2 = point.Shape2.GetBody();

            if (body1 != body && body2 != body)
            {
                return(null);
            }

            if (body1 == body)
            {
                return(body2);
            }
            else
            {
                return(body1);
            }
        }
Пример #11
0
        public static async Task <ContactResult> GetContactUs(string url)
        {
            ContactResult objData = new ContactResult();

            try
            {
                using (var client = new HttpClient())
                {
                    client.BaseAddress = new Uri(url);
                    var result = await client.GetAsync(url);

                    var place = result.Content.ReadAsStringAsync().Result;
                    objData = JsonConvert.DeserializeObject <ContactResult>(await result.Content.ReadAsStringAsync());
                }
            }
            catch (Exception ex)
            {
            }
            return(objData);
        }
Пример #12
0
        /// <summary>
        /// 获取联系人信息
        /// </summary>
        /// <returns></returns>
        public ContactResult GetContact(WechatCookie wechatCookie, string cookieStr)
        {
            string url = string.Format(WechatUrl.ContentUrl, wechatCookie.Pass_Ticket, WechatCommon.GetTicks(), wechatCookie.Skey);

            string html = HttpCommon.instance.PostHttp(url, "{}", ContentType.json, cookieStr);

            AppLog.WriteInfo(string.Format("协议:{0},结果:{1}", "GetContact", html));

            ContactResult contact = new ContactResult();

            try
            {
                if (!string.IsNullOrEmpty(html) && html != "操作超时")
                {
                    contact = JsonConvert.DeserializeObject <ContactResult>(html);
                }
            }
            catch (Exception ex)
            {
                AppLog.WriteError(ex.Message);
            }
            return(contact);
        }
Пример #13
0
        public override void Result(ContactResult point)
        {
            Projectile proj   = null;
            Alien      alien  = null;
            Player     player = null;
            Pickup     pickup = null;

            ExtractCollisionData(point, out proj, out alien, out player, out pickup);

            if (proj != null)
            {
                if (proj.Active)
                {
                    if (alien != null)
                    {
                        Logger.Info("projectile collided with alien");
                        alien.OnCollision(proj, point.Position);
                        proj.OnCollision(alien, point.Position);
                    }
                    else if (player != null)
                    {
                        Logger.Info("projectile collided with player");
                        player.OnCollision(proj, point.Position);
                        proj.OnCollision(player, point.Position);
                    }
                }
            }
            else if (pickup != null && player != null)
            {
                pickup.OnCollision(player, point.Position);
                player.OnCollision(pickup, point.Position);
            }
            else
            {
                base.Result(point);
            }
        }
Пример #14
0
        public static EmployeeResult ConvertToResult(
            Employee employee,
            ContactResult contactResult,
            PassportResult passportResult,
            OrganizationResult organizationResult,
            StateRegistrationResult stateRegistrationResult)
        {
            Contract.Argument.IsNotNull(employee, nameof(employee));

            return(new EmployeeResult
            {
                Id = employee.Id,
                Contact = contactResult,
                Passport = passportResult,
                Organization = organizationResult,
                StateRegistration = stateRegistrationResult,
                ManagerId = employee.ManagerId,
                AcademicDegree = employee.AcademicDegree,
                AcademicRank = employee.AcademicRank,
                Education = employee.Education,
                Position = employee.Position,
                WorkPlace = employee.WorkPlace
            });
        }
Пример #15
0
        // don't like this
        public override List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count)
        {
            if (actor != null)
            {
                IntPtr geom;
                if (actor is OdePrim)
                    geom = ((OdePrim)actor).prim_geom;
                else if (actor is OdeCharacter)
                    geom = ((OdePrim)actor).prim_geom;
                else
                    return new List<ContactResult>();
                if (geom == IntPtr.Zero)
                    return new List<ContactResult>();

                ContactResult[] ourResults = null;
                RayCallback retMethod = delegate(List<ContactResult> results)
                {
                    ourResults = new ContactResult[results.Count];
                    results.CopyTo(ourResults, 0);
                };
                int waitTime = 0;
                m_rayCastManager.QueueRequest(geom,position, direction, length, Count, retMethod);
                while (ourResults == null && waitTime < 1000)
                {
                    Thread.Sleep(1);
                    waitTime++;
                }
                if (ourResults == null)
                    return new List<ContactResult>();
                return new List<ContactResult>(ourResults);
            }
            return new List<ContactResult>();
        }
Пример #16
0
        private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
        {
            List<ContactResult> contacts = new List<ContactResult>();

            Vector3 ab = rayEnd - rayStart;

            World.ForEachScenePresence(delegate(ScenePresence sp)
            {
                Vector3 ac = sp.AbsolutePosition - rayStart;
//                Vector3 bc = sp.AbsolutePosition - rayEnd;

                double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));

                if (d > 1.5)
                    return;

                double d2 = Vector3.Dot(Vector3.Negate(ab), ac);

                if (d2 > 0)
                    return;

                double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
                Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));

                if (!InBoundingBox(sp, p))
                    return;

                ContactResult result = new ContactResult ();
                result.ConsumerID = sp.LocalId;
                result.Depth = Vector3.Distance(rayStart, p);
                result.Normal = Vector3.Zero;
                result.Pos = p;

                contacts.Add(result);
            });

            return contacts.ToArray();
        }
Пример #17
0
        // This is the standard Near. g1 is the ray
        private void near(IntPtr space, IntPtr g1, IntPtr g2)
        {
            if (g2 == IntPtr.Zero || g1 == g2)
            {
                return;
            }

            if (m_contactResults.Count >= CurrentMaxCount)
            {
                return;
            }

            if (SafeNativeMethods.GeomIsSpace(g2))
            {
                try
                {
                    SafeNativeMethods.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
                }
                catch (Exception e)
                {
                    m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message);
                }
                return;
            }

            int count = 0;

            try
            {
                count = SafeNativeMethods.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, SafeNativeMethods.ContactGeom.unmanagedSizeOf);
            }
            catch (Exception e)
            {
                m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message);
                return;
            }

            if (count == 0)
            {
                return;
            }

            /*
             *          uint cat1 = d.GeomGetCategoryBits(g1);
             *          uint cat2 = d.GeomGetCategoryBits(g2);
             *          uint col1 = d.GeomGetCollideBits(g1);
             *          uint col2 = d.GeomGetCollideBits(g2);
             */

            uint         ID = 0;
            PhysicsActor p2 = null;

            m_scene.actor_name_map.TryGetValue(g2, out p2);

            if (p2 == null)
            {
                return;
            }

            switch (p2.PhysicsActorType)
            {
            case (int)ActorTypes.Prim:

                RayFilterFlags thisFlags;

                if (p2.IsPhysical)
                {
                    thisFlags = RayFilterFlags.physical;
                }
                else
                {
                    thisFlags = RayFilterFlags.nonphysical;
                }

                if (p2.Phantom)
                {
                    thisFlags |= RayFilterFlags.phantom;
                }

                if (p2.IsVolumeDtc)
                {
                    thisFlags |= RayFilterFlags.volumedtc;
                }

                if ((thisFlags & CurrentRayFilter) == 0)
                {
                    return;
                }

                ID = ((OdePrim)p2).LocalID;
                break;

            case (int)ActorTypes.Agent:

                if ((CurrentRayFilter & RayFilterFlags.agent) == 0)
                {
                    return;
                }
                else
                {
                    ID = ((OdeCharacter)p2).LocalID;
                }
                break;

            case (int)ActorTypes.Ground:

                if ((CurrentRayFilter & RayFilterFlags.land) == 0)
                {
                    return;
                }
                break;

            case (int)ActorTypes.Water:

                if ((CurrentRayFilter & RayFilterFlags.water) == 0)
                {
                    return;
                }
                break;

            default:
                break;
            }

            SafeNativeMethods.ContactGeom curcontact = new SafeNativeMethods.ContactGeom();

            // closestHit for now only works for meshs, so must do it for others
            if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0)
            {
                // Loop all contacts, build results.
                for (int i = 0; i < count; i++)
                {
                    if (!GetCurContactGeom(i, ref curcontact))
                    {
                        break;
                    }

                    ContactResult collisionresult = new ContactResult();
                    collisionresult.ConsumerID = ID;
                    collisionresult.Pos.X      = curcontact.pos.X;
                    collisionresult.Pos.Y      = curcontact.pos.Y;
                    collisionresult.Pos.Z      = curcontact.pos.Z;
                    collisionresult.Depth      = curcontact.depth;
                    collisionresult.Normal.X   = curcontact.normal.X;
                    collisionresult.Normal.Y   = curcontact.normal.Y;
                    collisionresult.Normal.Z   = curcontact.normal.Z;
                    lock (m_contactResults)
                    {
                        m_contactResults.Add(collisionresult);
                        if (m_contactResults.Count >= CurrentMaxCount)
                        {
                            return;
                        }
                    }
                }
            }
            else
            {
                // keep only closest contact
                ContactResult collisionresult = new ContactResult();
                collisionresult.ConsumerID = ID;
                collisionresult.Depth      = float.MaxValue;

                for (int i = 0; i < count; i++)
                {
                    if (!GetCurContactGeom(i, ref curcontact))
                    {
                        break;
                    }

                    if (curcontact.depth < collisionresult.Depth)
                    {
                        collisionresult.Pos.X    = curcontact.pos.X;
                        collisionresult.Pos.Y    = curcontact.pos.Y;
                        collisionresult.Pos.Z    = curcontact.pos.Z;
                        collisionresult.Depth    = curcontact.depth;
                        collisionresult.Normal.X = curcontact.normal.X;
                        collisionresult.Normal.Y = curcontact.normal.Y;
                        collisionresult.Normal.Z = curcontact.normal.Z;
                    }
                }

                if (collisionresult.Depth != float.MaxValue)
                {
                    lock (m_contactResults)
                        m_contactResults.Add(collisionresult);
                }
            }
        }
Пример #18
0
        public override void Result(ContactResult point)
        {
            base.Result(point);

            onResult?.Invoke((InfoBody)point.Shape1.GetBody().GetUserData(), (InfoBody)point.Shape2.GetBody().GetUserData());
        }
Пример #19
0
        public override void Result(ContactResult point)
        {
            base.Result(point);

            OnResult?.Invoke((MyModel3D)point.Shape1.GetBody().GetUserData(), (MyModel3D)point.Shape2.GetBody().GetUserData());
        }
Пример #20
0
 public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count)
 {
     ContactResult[] ourResults = null;
     RayCallback retMethod = delegate(List<ContactResult> results)
                                 {
                                     ourResults = new ContactResult[results.Count];
                                     results.CopyTo(ourResults, 0);
                                 };
     int waitTime = 0;
     m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod);
     while (ourResults == null && waitTime < 1000)
     {
         Thread.Sleep(1);
         waitTime++;
     }
     if (ourResults == null)
         return new List<ContactResult>();
     return new List<ContactResult>(ourResults);
 }
Пример #21
0
        // This is the standard Near.   Uses space AABBs to speed up detection.
        private void near(IntPtr space, IntPtr g1, IntPtr g2)
        {
            if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
            {
                return;
            }
//            if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass)
//                return;

            // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
            if (SafeNativeMethods.GeomIsSpace(g1) || SafeNativeMethods.GeomIsSpace(g2))
            {
                if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
                {
                    return;
                }

                // Separating static prim geometry spaces.
                // We'll be calling near recursivly if one
                // of them is a space to find all of the
                // contact points in the space
                try
                {
                    SafeNativeMethods.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
                }
                catch (AccessViolationException)
                {
                    m_log.Warn("[PHYSICS]: Unable to collide test a space");
                    return;
                }
                //Colliding a space or a geom with a space or a geom. so drill down

                //Collide all geoms in each space..
                //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback);
                //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback);
                return;
            }

            if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
            {
                return;
            }

            int count = 0;

            try
            {
                if (g1 == g2)
                {
                    return; // Can't collide with yourself
                }
                lock (contacts)
                {
                    count = SafeNativeMethods.Collide(g1, g2, contacts.GetLength(0), contacts, SafeNativeMethods.ContactGeom.unmanagedSizeOf);
                }
            }
            catch (SEHException)
            {
                m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory.  This could be a result of really irregular terrain.  If this repeats continuously, restart using Basic Physics and terrain fill your terrain.  Restarting the sim.");
            }
            catch (Exception e)
            {
                m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message);
                return;
            }

            PhysicsActor p1 = null;
            PhysicsActor p2 = null;

            if (g1 != IntPtr.Zero)
            {
                m_scene.actor_name_map.TryGetValue(g1, out p1);
            }

            if (g2 != IntPtr.Zero)
            {
                m_scene.actor_name_map.TryGetValue(g1, out p2);
            }

            // Loop over contacts, build results.
            for (int i = 0; i < count; i++)
            {
                if (p1 != null)
                {
                    if (p1 is OdePrim)
                    {
                        ContactResult collisionresult = new ContactResult();

                        collisionresult.ConsumerID = p1.LocalID;
                        collisionresult.Pos        = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
                        collisionresult.Depth      = contacts[i].depth;
                        collisionresult.Normal     = new Vector3(contacts[i].normal.X, contacts[i].normal.Y,
                                                                 contacts[i].normal.Z);
                        lock (m_contactResults)
                            m_contactResults.Add(collisionresult);
                    }
                }

                if (p2 != null)
                {
                    if (p2 is OdePrim)
                    {
                        ContactResult collisionresult = new ContactResult();

                        collisionresult.ConsumerID = p2.LocalID;
                        collisionresult.Pos        = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
                        collisionresult.Depth      = contacts[i].depth;
                        collisionresult.Normal     = new Vector3(contacts[i].normal.X, contacts[i].normal.Y,
                                                                 contacts[i].normal.Z);

                        lock (m_contactResults)
                            m_contactResults.Add(collisionresult);
                    }
                }
            }
        }
Пример #22
0
        public override void Result(ContactResult point)
        {
            base.Result(point);

            OnResult?.Invoke((BaseMissionObjectController)point.Shape1.GetBody().GetUserData(), (BaseMissionObjectController)point.Shape2.GetBody().GetUserData());
        }
Пример #23
0
        private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
        {
            Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
            List<ContactResult> contacts = new List<ContactResult>();

            Vector3 ab = rayEnd - rayStart;

            World.ForEachSOG(delegate(SceneObjectGroup group)
            {
                if (m_host.ParentGroup == group)
                    return;

                if (group.IsAttachment)
                    return;

                if (group.RootPart.PhysActor == null)
                {
                    if (!includePhantom)
                        return;
                }
                else
                {
                    if (group.RootPart.PhysActor.IsPhysical)
                    {
                        if (!includePhysical)
                            return;
                    }
                    else
                    {
                        if (!includeNonPhysical)
                            return;
                    }
                }

                // Find the radius ouside of which we don't even need to hit test
                float minX;
                float maxX;
                float minY;
                float maxY;
                float minZ;
                float maxZ;

                float radius = 0.0f;

                group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);

                if (Math.Abs(minX) > radius)
                    radius = Math.Abs(minX);
                if (Math.Abs(minY) > radius)
                    radius = Math.Abs(minY);
                if (Math.Abs(minZ) > radius)
                    radius = Math.Abs(minZ);
                if (Math.Abs(maxX) > radius)
                    radius = Math.Abs(maxX);
                if (Math.Abs(maxY) > radius)
                    radius = Math.Abs(maxY);
                if (Math.Abs(maxZ) > radius)
                    radius = Math.Abs(maxZ);
                radius = radius*1.413f;
                Vector3 ac = group.AbsolutePosition - rayStart;
//                Vector3 bc = group.AbsolutePosition - rayEnd;

                double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));

                // Too far off ray, don't bother
                if (d > radius)
                    return;

                // Behind ray, drop
                double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
                if (d2 > 0)
                    return;

                ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
                EntityIntersection intersection = group.TestIntersection(ray, true, false);
                // Miss.
                if (!intersection.HitTF)
                    return;

                Vector3 b1 = group.AbsolutePosition + new Vector3(minX, minY, minZ);
                Vector3 b2 = group.AbsolutePosition + new Vector3(maxX, maxY, maxZ);
                //m_log.DebugFormat("[LLCASTRAY]: min<{0},{1},{2}>, max<{3},{4},{5}> = hitp<{6},{7},{8}>", b1.X,b1.Y,b1.Z,b2.X,b2.Y,b2.Z,intersection.ipoint.X,intersection.ipoint.Y,intersection.ipoint.Z);
                if (!(intersection.ipoint.X >= b1.X && intersection.ipoint.X <= b2.X &&
                    intersection.ipoint.Y >= b1.Y && intersection.ipoint.Y <= b2.Y &&
                    intersection.ipoint.Z >= b1.Z && intersection.ipoint.Z <= b2.Z))
                    return;

                ContactResult result = new ContactResult ();
                result.ConsumerID = group.LocalId;
                result.Depth = intersection.distance;
                result.Normal = intersection.normal;
                result.Pos = intersection.ipoint;

                contacts.Add(result);
            });

            return contacts.ToArray();
        }
 public override void Result(ContactResult point)
 {
     this.OnResult?.Invoke(point);
     base.Result(point);
 }
        // This is the standard Near.   Uses space AABBs to speed up detection.
        private void near(IntPtr space, IntPtr g1, IntPtr g2)
        {
            //Don't test against heightfield Geom, or you'll be sorry!

            // Exclude heightfield geom

            if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
            {
                return;
            }
            if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass ||
                d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass)
            {
                return;
            }

            // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
            if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
            {
                if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
                {
                    return;
                }

                // Separating static prim geometry spaces.
                // We'll be calling near recursivly if one
                // of them is a space to find all of the
                // contact points in the space
                try
                {
                    d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
                }
                catch (AccessViolationException)
                {
                    MainConsole.Instance.Warn("[PHYSICS]: Unable to collide test a space");
                    return;
                }

                return;
            }

            if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
            {
                return;
            }

            int count = 0;

            try
            {
                if (g1 == g2)
                {
                    return; // Can't collide with yourself
                }
                count = d.CollidePtr(g1, g2, (contactsPerCollision & 0xffff), ContactgeomsArray,
                                     d.ContactGeom.unmanagedSizeOf);
            }
            catch (SEHException)
            {
                MainConsole.Instance.Error(
                    "[PHYSICS]: The Operating system shut down ODE because of corrupt memory.  This could be a result of really irregular terrain.  If this repeats continuously, restart using Basic Physics and terrain fill your terrain.  Restarting the sim.");
            }
            catch (Exception e)
            {
                MainConsole.Instance.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e);
                return;
            }

            PhysicsActor p1 = null;

            if (g1 != IntPtr.Zero)
            {
                m_scene.actor_name_map.TryGetValue(g1, out p1);
            }

            // Loop over contacts, build results.
            d.ContactGeom curContact = new d.ContactGeom();
            for (int i = 0; i < count; i++)
            {
                if (!GetCurContactGeom(i, ref curContact))
                {
                    break;
                }

                if (p1 != null)
                {
                    if (p1 is AuroraODEPrim)
                    {
                        ContactResult collisionresult = new ContactResult
                        {
                            ConsumerID = ((AuroraODEPrim)p1).LocalID,
                            Pos        =
                                new Vector3(curContact.pos.X, curContact.pos.Y,
                                            curContact.pos.Z),
                            Depth  = curContact.depth,
                            Normal =
                                new Vector3(curContact.normal.X,
                                            curContact.normal.Y,
                                            curContact.normal.Z)
                        };

                        lock (m_contactResults)
                            m_contactResults.Add(collisionresult);
                    }
                }
            }
        }
Пример #26
0
 public override void Result(ContactResult point)
 {
     base.Result(point);
 }
Пример #27
0
        private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom, int max)
        {
            List<ContactResult> contacts = World.PhysicsScene.RaycastWorld(rayStart, Vector3.Normalize(rayEnd - rayStart), Vector3.Distance(rayEnd, rayStart), max);

            for (int i = 0; i < contacts.Count; i++)
            {
                ISceneEntity grp = World.GetGroupByPrim(contacts[i].ConsumerID);
                if(grp == null || (!includePhysical && grp.RootChild.PhysActor.IsPhysical) ||
                    (!includeNonPhysical && !grp.RootChild.PhysActor.IsPhysical))
                    contacts.RemoveAt(i--);
            }

            if (includePhantom)
            {
                Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));

                Vector3 ab = rayEnd - rayStart;

                ISceneEntity[] objlist = World.Entities.GetEntities();
                foreach (ISceneEntity group in objlist)
                {
                    if (m_host.ParentEntity == group)
                        continue;

                    if (group.IsAttachment)
                        continue;

                    if (group.RootChild.PhysActor != null)
                        continue;

                    // Find the radius ouside of which we don't even need to hit test
                    float minX;
                    float maxX;
                    float minY;
                    float maxY;
                    float minZ;
                    float maxZ;

                    float radius = 0.0f;

                    group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);

                    if (Math.Abs(minX) > radius)
                        radius = Math.Abs(minX);
                    if (Math.Abs(minY) > radius)
                        radius = Math.Abs(minY);
                    if (Math.Abs(minZ) > radius)
                        radius = Math.Abs(minZ);
                    if (Math.Abs(maxX) > radius)
                        radius = Math.Abs(maxX);
                    if (Math.Abs(maxY) > radius)
                        radius = Math.Abs(maxY);
                    if (Math.Abs(maxZ) > radius)
                        radius = Math.Abs(maxZ);
                    radius = radius * 1.413f;
                    Vector3 ac = group.AbsolutePosition - rayStart;
                    //                Vector3 bc = group.AbsolutePosition - rayEnd;

                    double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));

                    // Too far off ray, don't bother
                    if (d > radius)
                        continue;

                    // Behind ray, drop
                    double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
                    if (d2 > 0)
                        continue;

                    ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
                    EntityIntersection intersection = group.TestIntersection(ray, true, false);
                    // Miss.
                    if (!intersection.HitTF)
                        continue;

                    Vector3 b1 = new Vector3(minX, minY, minZ);
                    Vector3 b2 = new Vector3(maxX, maxY, maxZ);
                    //m_log.DebugFormat("[LLCASTRAY]: min<{0},{1},{2}>, max<{3},{4},{5}> = hitp<{6},{7},{8}>", b1.X,b1.Y,b1.Z,b2.X,b2.Y,b2.Z,intersection.ipoint.X,intersection.ipoint.Y,intersection.ipoint.Z);
                    if (!(intersection.ipoint.X >= b1.X && intersection.ipoint.X <= b2.X &&
                        intersection.ipoint.Y >= b1.Y && intersection.ipoint.Y <= b2.Y &&
                        intersection.ipoint.Z >= b1.Z && intersection.ipoint.Z <= b2.Z))
                        continue;

                    ContactResult result = new ContactResult();
                    result.ConsumerID = group.LocalId;
                    result.Depth = intersection.distance;
                    result.Normal = intersection.normal;
                    result.Pos = intersection.ipoint;

                    contacts.Add(result);
                }
            }

            return contacts.ToArray();
        }
Пример #28
0
        /// <summary>
        /// Gets the result of a ContactType on a set of PhysicalAttributes.
        /// </summary>
        /// <param name="attackerPhysAttributes">The attacker's set of PhysicalAttributes.</param>
        /// <param name="contactType">The ContactType performed.</param>
        /// <param name="contactProperty">The ContactProperty of the contact.</param>
        /// <param name="victimPaybacks">The victim's set of Paybacks to test against.</param>
        /// <param name="attackerContactExceptions">The attacker's contact exceptions; the set PhysicalAttributes to ignore.</param>
        /// <returns>A ContactResultInfo of the interaction.</returns>
        public static ContactResultInfo GetContactResult(IList <PhysicalAttributes> attackerPhysAttributes, ContactTypes contactType, ContactProperties contactProperty, IList <PaybackHolder> victimPaybacks, params PhysicalAttributes[] attackerContactExceptions)
        {
            //Return the default value
            if (victimPaybacks == null || victimPaybacks.Count == 0)
            {
                return(ContactResultInfo.Default);
            }

            /*0. Initialize a list of Paybacks, called PaybackList
             * 1. Go through all of the Victim's Paybacks
             *   2. Check if the Payback's PaybackContacts contains the ContactType of the attack
             *      3a. If so, check if the Attacker has any ContactExceptions for the Payback's PhysAttribute
             *         4a. If so, ignore it and continue
             *         4b. If not, check if the Payback covers any of the attack's ContactProperties
             *            5a. If so, check if the Attacker has the same PhysAttribute as the Payback's
             *               6a. If so, examine the SamePhysAttrResult and go to 7a
             *               6b. If not, examine the PaybackContactResult and go to 7a
             *                  7a. If the ContactResult is a Failure, return that Payback value
             *                  7b. If the ContactResult is a Success, ignore it and continue
             *                  7c. If the ContactResult is a PartialSuccess, add it to PaybackList and continue
             *         4c. If not, ignore it and continue
             *      3b. If not, continue */

            //The Paybacks that will be combined
            List <PaybackHolder> combinedPaybacks = new List <PaybackHolder>();

            //Look through the Paybacks
            for (int i = 0; i < victimPaybacks.Count; i++)
            {
                PaybackHolder payback = victimPaybacks[i];

                //Check if the Payback covers this ContactType
                if (payback.PaybackContacts != null && payback.PaybackContacts.Contains(contactType) == true)
                {
                    //If there are contact exceptions for this PhysicalAttribute, ignore this Payback
                    if (attackerContactExceptions.Contains(payback.PhysAttribute) == true)
                    {
                        continue;
                    }

                    //Check if the Payback covers the ContactProperty
                    if (payback.ContactProperties != null && payback.ContactProperties.Contains(contactProperty) == false)
                    {
                        continue;
                    }

                    ContactResult contactResult = payback.PaybackContactResult;

                    //Check if the Attacker has the PhysicalAttribute the Payback is associated with, and adjust the ContactResult if so
                    if (attackerPhysAttributes.Contains(payback.PhysAttribute) == true)
                    {
                        contactResult = payback.SamePhysAttrResult;
                    }

                    //If a Failure, use this Payback
                    if (contactResult == ContactResult.Failure)
                    {
                        return(new ContactResultInfo(payback, contactResult));
                    }
                    //If a PartialSuccess, add it to the list
                    else if (contactResult == ContactResult.PartialSuccess)
                    {
                        combinedPaybacks.Add(payback);
                    }
                }
            }

            //Combine all the Paybacks in the list
            PaybackHolder finalPayback = PaybackHolder.CombinePaybacks(combinedPaybacks);

            return(new ContactResultInfo(finalPayback, finalPayback.PaybackContactResult));
        }
Пример #29
0
        private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
        {
            double[,] heightfield = World.Heightmap.GetDoubles();
            List<ContactResult> contacts = new List<ContactResult>();

            double min = 2048.0;
            double max = 0.0;

            // Find the min and max of the heightfield
            for (int x = 0 ; x < World.Heightmap.Width ; x++)
            {
                for (int y = 0 ; y < World.Heightmap.Height ; y++)
                {
                    if (heightfield[x, y] > max)
                        max = heightfield[x, y];
                    if (heightfield[x, y] < min)
                        min = heightfield[x, y];
                }
            }


            // A ray extends past rayEnd, but doesn't go back before
            // rayStart. If the start is above the highest point of the ground
            // and the ray goes up, we can't hit the ground. Ever.
            if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
                return null;

            // Same for going down
            if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
                return null;

            List<Tri> trilist = new List<Tri>();

            // Create our triangle list
            for (int x = 1 ; x < World.Heightmap.Width ; x++)
            {
                for (int y = 1 ; y < World.Heightmap.Height ; y++)
                {
                    Tri t1 = new Tri();
                    Tri t2 = new Tri();

                    Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
                    Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
                    Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
                    Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);

                    t1.p1 = p1;
                    t1.p2 = p2;
                    t1.p3 = p3;

                    t2.p1 = p3;
                    t2.p2 = p4;
                    t2.p3 = p1;

                    trilist.Add(t1);
                    trilist.Add(t2);
                }
            }

            // Ray direction
            Vector3 rayDirection = rayEnd - rayStart;

            foreach (Tri t in trilist)
            {
                // Compute triangle plane normal and edges
                Vector3 u = t.p2 - t.p1;
                Vector3 v = t.p3 - t.p1;
                Vector3 n = Vector3.Cross(u, v);

                if (n == Vector3.Zero)
                    continue;

                Vector3 w0 = rayStart - t.p1;
                double a = -Vector3.Dot(n, w0);
                double b = Vector3.Dot(n, rayDirection);

                // Not intersecting the plane, or in plane (same thing)
                // Ignoring this MAY cause the ground to not be detected
                // sometimes
                if (Math.Abs(b) < 0.000001)
                    continue;

                double r = a / b;

                // ray points away from plane
                if (r < 0.0)
                    continue;

                Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);

                float uu = Vector3.Dot(u, u);
                float uv = Vector3.Dot(u, v);
                float vv = Vector3.Dot(v, v);
                Vector3 w = ip - t.p1;
                float wu = Vector3.Dot(w, u);
                float wv = Vector3.Dot(w, v);
                float d = uv * uv - uu * vv;

                float cs = (uv * wv - vv * wu) / d;
                if (cs < 0 || cs > 1.0)
                    continue;
                float ct = (uv * wu - uu * wv) / d;
                if (ct < 0 || (cs + ct) > 1.0)
                    continue;

                // Add contact point
                ContactResult result = new ContactResult ();
                result.ConsumerID = 0;
                result.Depth = Vector3.Distance(rayStart, ip);
                result.Normal = n;
                result.Pos = ip;

                contacts.Add(result);
            }

            if (contacts.Count == 0)
                return null;

            contacts.Sort(delegate(ContactResult a, ContactResult b)
            {
                return (int)(a.Depth - b.Depth);
            });

            return contacts[0];
        }
Пример #30
0
        public override void Result(ContactResult point)
        {
            base.Result(point);

            onResult?.Invoke(point);
        }
        // This is the standard Near.   Uses space AABBs to speed up detection.
        private void near(IntPtr space, IntPtr g1, IntPtr g2)
        {

            //Don't test against heightfield Geom, or you'll be sorry!
            
            /*
             terminate called after throwing an instance of 'std::bad_alloc'
                  what():  std::bad_alloc
                Stacktrace:
                 
                  at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0x00004>
                  at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0xffffffff>
                  at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0x00280>
                  at (wrapper native-to-managed) OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0xfff
                fffff>
                  at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0x00004>
                  at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0xffffffff>
                  at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.RayCast (OpenSim.Region.Physics.OdePlugin.ODERayCastRequest) <
                0x00114>
                  at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.ProcessQueuedRequests () <0x000eb>
                  at OpenSim.Region.Physics.OdePlugin.OdeScene.Simulate (single) <0x017e6>
                  at OpenSim.Region.Framework.Scenes.SceneGraph.UpdatePhysics (double) <0x00042>
                  at OpenSim.Region.Framework.Scenes.Scene.Update () <0x0039e>
                  at OpenSim.Region.Framework.Scenes.Scene.Heartbeat (object) <0x00019>
                  at (wrapper runtime-invoke) object.runtime_invoke_void__this___object (object,intptr,intptr,intptr) <0xffffffff>
                 
                Native stacktrace:
                 
                        mono [0x80d2a42]
                        [0xb7f5840c]
                        /lib/i686/cmov/libc.so.6(abort+0x188) [0xb7d1a018]
                        /usr/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x158) [0xb45fc988]
                        /usr/lib/libstdc++.so.6 [0xb45fa865]
                        /usr/lib/libstdc++.so.6 [0xb45fa8a2]
                        /usr/lib/libstdc++.so.6 [0xb45fa9da]
                        /usr/lib/libstdc++.so.6(_Znwj+0x83) [0xb45fb033]
                        /usr/lib/libstdc++.so.6(_Znaj+0x1d) [0xb45fb11d]
                        libode.so(_ZN13dxHeightfield23dCollideHeightfieldZoneEiiiiP6dxGeomiiP12dContactGeomi+0xd04) [0xb46678e4]
                        libode.so(_Z19dCollideHeightfieldP6dxGeomS0_iP12dContactGeomi+0x54b) [0xb466832b]
                        libode.so(dCollide+0x102) [0xb46571b2]
                        [0x95cfdec9]
                        [0x8ea07fe1]
                        [0xab260146]
                        libode.so [0xb465a5c4]
                        libode.so(_ZN11dxHashSpace8collide2EPvP6dxGeomPFvS0_S2_S2_E+0x75) [0xb465bcf5]
                        libode.so(dSpaceCollide2+0x177) [0xb465ac67]
                        [0x95cf978e]
                        [0x8ea07945]
                        [0x95cf2bbc]
                        [0xab2787e7]
                        [0xab419fb3]
                        [0xab416657]
                        [0xab415bda]
                        [0xb609b08e]
                        mono(mono_runtime_delegate_invoke+0x34) [0x8192534]
                        mono [0x81a2f0f]
                        mono [0x81d28b6]
                        mono [0x81ea2c6]
                        /lib/i686/cmov/libpthread.so.0 [0xb7e744c0]
                        /lib/i686/cmov/libc.so.6(clone+0x5e) [0xb7dcd6de]             
             */

            // Exclude heightfield geom

            if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
                return;
            if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass)
                return;

            // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
            if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
            {
                if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
                    return;
                
                // Separating static prim geometry spaces.
                // We'll be calling near recursivly if one
                // of them is a space to find all of the
                // contact points in the space
                try
                {
                    d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
                }
                catch (AccessViolationException)
                {
                    m_log.Warn("[PHYSICS]: Unable to collide test a space");
                    return;
                }
                //Colliding a space or a geom with a space or a geom. so drill down

                //Collide all geoms in each space..
                //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback);
                //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback);
                return;
            }

            if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
                return;

            int count = 0;
            try
            {
                
                if (g1 == g2)
                    return; // Can't collide with yourself

                lock (contacts)
                {
                    count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf);
                }
            }
            catch (SEHException)
            {
                m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory.  This could be a result of really irregular terrain.  If this repeats continuously, restart using Basic Physics and terrain fill your terrain.  Restarting the sim.");
            }
            catch (Exception e)
            {
                m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message);
                return;
            }

            PhysicsActor p1 = null;
            PhysicsActor p2 = null;

            if (g1 != IntPtr.Zero)
                m_scene.actor_name_map.TryGetValue(g1, out p1);

            if (g2 != IntPtr.Zero)
                m_scene.actor_name_map.TryGetValue(g1, out p2);

            // Loop over contacts, build results.
            for (int i = 0; i < count; i++)
            {
                if (p1 != null) { 
                    if (p1 is OdePrim)
                    {
                        ContactResult collisionresult = new ContactResult();
                    
                        collisionresult.ConsumerID = ((OdePrim)p1).m_localID;
                        collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
                        collisionresult.Depth = contacts[i].depth;
                        
                        lock (m_contactResults)
                            m_contactResults.Add(collisionresult);
                    }
                }

                if (p2 != null)
                {
                    if (p2 is OdePrim)
                    {
                        ContactResult collisionresult = new ContactResult();

                        collisionresult.ConsumerID = ((OdePrim)p2).m_localID;
                        collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
                        collisionresult.Depth = contacts[i].depth;

                        lock (m_contactResults)
                            m_contactResults.Add(collisionresult);
                    }
                }

                
            }

        }
Пример #32
0
        public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
        {
            Vector3 dir = new Vector3((float) (end - start).x, (float) (end - start).y, (float) (end - start).z);
            Vector3 startvector = new Vector3((float) start.x, (float) start.y, (float) start.z);
            Vector3 endvector = new Vector3((float) end.x, (float) end.y, (float) end.z);

            int count = 0;
            int detectPhantom = 0;
            int dataFlags = 0;
            int rejectTypes = 0;

            for (int i = 0; i < options.Length; i += 2)
            {
                if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
                {
                    count = options.GetLSLIntegerItem(i + 1);
                }
                else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
                {
                    detectPhantom = options.GetLSLIntegerItem(i + 1);
                }
                else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
                {
                    dataFlags = options.GetLSLIntegerItem(i + 1);
                }
                else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
                {
                    rejectTypes = options.GetLSLIntegerItem(i + 1);
                }
            }

            LSL_List list = new LSL_List();
            List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count);

            double distance = Util.GetDistanceTo(startvector, endvector);
            if (distance == 0)
                distance = 0.001;
            Vector3 posToCheck = startvector;
            ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
            List<IScenePresence> presences =
                new List<IScenePresence>(World.Entities.GetPresences(startvector, (float) distance));
            bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
            bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
            bool checkNonPhysical =
                !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
            bool checkPhysical =
                !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
            for (float i = 0; i <= distance; i += 0.1f)
            {
                posToCheck = startvector + (dir*(i/(float) distance));
                float groundHeight = channel[(int) (posToCheck.X + startvector.X), (int) (posToCheck.Y + startvector.Y)];
                if (checkTerrain && groundHeight > posToCheck.Z)
                {
                    ContactResult result = new ContactResult
                                               {
                                                   ConsumerID = 0,
                                                   Depth = 0,
                                                   Normal = Vector3.Zero,
                                                   Pos = posToCheck
                                               };
                    results.Add(result);
                    checkTerrain = false;
                }
                if (checkAgents)
                {
                    for (int presenceCount = 0; presenceCount < presences.Count; presenceCount++)
                    {
                        IScenePresence sp = presences[presenceCount];
                        if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X))
                        {
                            ContactResult result = new ContactResult
                                                       {
                                                           ConsumerID = sp.LocalId,
                                                           Depth = 0,
                                                           Normal = Vector3.Zero,
                                                           Pos = posToCheck
                                                       };
                            results.Add(result);
                            presences.RemoveAt(presenceCount);
                            if (presenceCount > 0)
                                presenceCount--; //Reset its position since we removed this one
                        }
                    }
                }
            }
            int refcount = 0;
            List<ContactResult> newResults = new List<ContactResult>();
            foreach (ContactResult result in results)
            {
                foreach (ContactResult r in newResults)
                    if (r.ConsumerID == result.ConsumerID)
                        newResults.Add(result);
            }
            castRaySort(startvector, ref newResults);
            foreach (ContactResult result in newResults)
            {
                if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND &&
                    result.ConsumerID == 0)
                    continue;

                IEntity entity = World.GetSceneObjectPart(result.ConsumerID);
                if (entity == null &&
                    (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS)
                    entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents
                if (entity == null)
                {
                    list.Add(UUID.Zero);
                    if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
                        list.Add(0);
                    list.Add(result.Pos);
                    if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
                        list.Add(result.Normal);
                    refcount++;
                    continue; //Can't find it, so add UUID.Zero
                }

                /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity &&
                    ((ISceneChildEntity)intersection.obj).PhysActor == null)
                    continue;*/
                //Can't do this ATM, physics engine knows only of non phantom objects

                if (entity is ISceneChildEntity && ((ISceneChildEntity) entity).PhysActor != null &&
                    ((ISceneChildEntity) entity).PhysActor.IsPhysical)
                {
                    if (!checkPhysical)
                        continue;
                }
                else if (entity is ISceneChildEntity)
                    if (!checkNonPhysical)
                        continue;

                refcount++;
                if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY &&
                    entity is ISceneChildEntity)
                    list.Add(((ISceneChildEntity) entity).ParentEntity.UUID);
                else
                    list.Add(entity.UUID);

                if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
                    if (entity is ISceneChildEntity)
                        list.Add(entity.LinkNum);
                    else
                        list.Add(0);

                list.Add(result.Pos);
                if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
                    list.Add(result.Normal);
            }

            list.Add(refcount);
                //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED

            return list;
        }
Пример #33
0
        public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
        {
            m_host.AddScriptLPS(1);

            Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z);
            Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z);
            Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z);

            int count = 0;
//            int detectPhantom = 0;
            int dataFlags = 0;
            int rejectTypes = 0;

            for (int i = 0; i < options.Length; i += 2)
            {
                if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
                {
                    count = options.GetLSLIntegerItem(i + 1);
                }
//                else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
//                {
//                    detectPhantom = options.GetLSLIntegerItem(i + 1);
//                }
                else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
                {
                    dataFlags = options.GetLSLIntegerItem(i + 1);
                }
                else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
                {
                    rejectTypes = options.GetLSLIntegerItem(i + 1);
                }
            }

            LSL_List list = new LSL_List();
            List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count);

            double distance = Util.GetDistanceTo(startvector, endvector);

            if (distance == 0)
                distance = 0.001;

            Vector3 posToCheck = startvector;
            ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();

            bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
            bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
            bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
            bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);

            for (float i = 0; i <= distance; i += 0.1f)
            {
                posToCheck = startvector  + (dir * (i / (float)distance));

                if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z)
                {
                    ContactResult result = new ContactResult();
                    result.ConsumerID = 0;
                    result.Depth = 0;
                    result.Normal = Vector3.Zero;
                    result.Pos = posToCheck;
                    results.Add(result);
                    checkTerrain = false;
                }

                if (checkAgents)
                {
                    World.ForEachRootScenePresence(delegate(ScenePresence sp)
                    {
                        if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X))
                        {
                            ContactResult result = new ContactResult ();
                            result.ConsumerID = sp.LocalId;
                            result.Depth = 0;
                            result.Normal = Vector3.Zero;
                            result.Pos = posToCheck;
                            results.Add(result);
                        }
                    });
                }
            }

            int refcount = 0;
            foreach (ContactResult result in results)
            {
                if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND)
                    == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0)
                    continue;

                ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID);

                if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS)
                    entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents

                if (entity == null)
                {
                    list.Add(UUID.Zero);

                    if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
                        list.Add(0);

                    list.Add(result.Pos);

                    if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
                        list.Add(result.Normal);

                    continue; //Can't find it, so add UUID.Zero
                }

                /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity &&
                    ((ISceneChildEntity)intersection.obj).PhysActor == null)
                    continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects

                if (entity is SceneObjectPart)
                {
                    PhysicsActor pa = ((SceneObjectPart)entity).PhysActor;

                    if (pa != null && pa.IsPhysical)
                    {
                        if (!checkPhysical)
                            continue;
                    }
                    else
                    {
                        if (!checkNonPhysical)
                            continue;
                    }
                }

                refcount++;
                if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart)
                    list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
                else
                    list.Add(entity.UUID);

                if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
                {
                    if (entity is SceneObjectPart)
                        list.Add(((SceneObjectPart)entity).LinkNum);
                    else
                        list.Add(0);
                }

                list.Add(result.Pos);

                if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
                    list.Add(result.Normal);
            }

            list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED

            return list;
        }
        // This is the standard Near. g2 is the ray
        private void near(IntPtr space, IntPtr g1, IntPtr g2)
        {
            //Don't test against heightfield Geom, or you'll be sorry!
            // Exclude heightfield geom

            if (g1 == IntPtr.Zero || g1 == g2)
                return;

            if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass)
                return;

            // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
            if (d.GeomIsSpace(g1))
            {
                try
                {
                    d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
                }
                catch (Exception e)
                {
                    m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message);
                }
                return;
            }

            int count = 0;
            try
            {
                count = d.CollidePtr(g1, g2, ColisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
            }
            catch (SEHException)
            {
                m_log.Error("[PHYSICS Ray]: The Operating system shut down ODE because of corrupt memory.  This could be a result of really irregular terrain.  If this repeats continuously, restart using Basic Physics and terrain fill your terrain.  Restarting the sim.");
            }
            catch (Exception e)
            {
                m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message);
                return;
            }

            if (count == 0)
                return;

            PhysicsActor p1 = null;

            if (g1 != IntPtr.Zero)
                m_scene.actor_name_map.TryGetValue(g1, out p1);

            d.ContactGeom curcontact = new d.ContactGeom();
            // Loop over contacts, build results.
            for (int i = 0; i < count; i++)
            {
                if (!GetCurContactGeom(i, ref curcontact))
                    break;
                if (p1 != null) { 
                    if (p1 is OdePrim)
                    {
                        ContactResult collisionresult = new ContactResult();
                    
                        collisionresult.ConsumerID = ((OdePrim)p1).m_localID;
                        collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
                        collisionresult.Depth = curcontact.depth;
                        collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
                                                             curcontact.normal.Z);
                        lock (m_contactResults)
                            m_contactResults.Add(collisionresult);
                    }
                }
            }
        }
        // This is the standard Near.   Uses space AABBs to speed up detection.
        private void near(IntPtr space, IntPtr g1, IntPtr g2)
        {
            //Don't test against heightfield Geom, or you'll be sorry!

            /*
             * terminate called after throwing an instance of 'std::bad_alloc'
             *    what():  std::bad_alloc
             *  Stacktrace:
             *
             *    at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0x00004>
             *    at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0xffffffff>
             *    at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0x00280>
             *    at (wrapper native-to-managed) OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0xfff
             *  fffff>
             *    at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0x00004>
             *    at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0xffffffff>
             *    at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.RayCast (OpenSim.Region.Physics.OdePlugin.ODERayCastRequest) <
             *  0x00114>
             *    at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.ProcessQueuedRequests () <0x000eb>
             *    at OpenSim.Region.Physics.OdePlugin.OdeScene.Simulate (single) <0x017e6>
             *    at OpenSim.Region.Framework.Scenes.SceneGraph.UpdatePhysics (double) <0x00042>
             *    at OpenSim.Region.Framework.Scenes.Scene.Update () <0x0039e>
             *    at OpenSim.Region.Framework.Scenes.Scene.Heartbeat (object) <0x00019>
             *    at (wrapper runtime-invoke) object.runtime_invoke_void__this___object (object,intptr,intptr,intptr) <0xffffffff>
             *
             *  Native stacktrace:
             *
             *          mono [0x80d2a42]
             *          [0xb7f5840c]
             *          /lib/i686/cmov/libc.so.6(abort+0x188) [0xb7d1a018]
             *          /usr/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x158) [0xb45fc988]
             *          /usr/lib/libstdc++.so.6 [0xb45fa865]
             *          /usr/lib/libstdc++.so.6 [0xb45fa8a2]
             *          /usr/lib/libstdc++.so.6 [0xb45fa9da]
             *          /usr/lib/libstdc++.so.6(_Znwj+0x83) [0xb45fb033]
             *          /usr/lib/libstdc++.so.6(_Znaj+0x1d) [0xb45fb11d]
             *          libode.so(_ZN13dxHeightfield23dCollideHeightfieldZoneEiiiiP6dxGeomiiP12dContactGeomi+0xd04) [0xb46678e4]
             *          libode.so(_Z19dCollideHeightfieldP6dxGeomS0_iP12dContactGeomi+0x54b) [0xb466832b]
             *          libode.so(dCollide+0x102) [0xb46571b2]
             *          [0x95cfdec9]
             *          [0x8ea07fe1]
             *          [0xab260146]
             *          libode.so [0xb465a5c4]
             *          libode.so(_ZN11dxHashSpace8collide2EPvP6dxGeomPFvS0_S2_S2_E+0x75) [0xb465bcf5]
             *          libode.so(dSpaceCollide2+0x177) [0xb465ac67]
             *          [0x95cf978e]
             *          [0x8ea07945]
             *          [0x95cf2bbc]
             *          [0xab2787e7]
             *          [0xab419fb3]
             *          [0xab416657]
             *          [0xab415bda]
             *          [0xb609b08e]
             *          mono(mono_runtime_delegate_invoke+0x34) [0x8192534]
             *          mono [0x81a2f0f]
             *          mono [0x81d28b6]
             *          mono [0x81ea2c6]
             *          /lib/i686/cmov/libpthread.so.0 [0xb7e744c0]
             *          /lib/i686/cmov/libc.so.6(clone+0x5e) [0xb7dcd6de]
             */

            // Exclude heightfield geom

            if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
            {
                return;
            }
            if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass ||
                d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass)
            {
                return;
            }

            // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
            if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
            {
                if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
                {
                    return;
                }

                // Separating static prim geometry spaces.
                // We'll be calling near recursivly if one
                // of them is a space to find all of the
                // contact points in the space
                try
                {
                    d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
                }
                catch (AccessViolationException)
                {
                    MainConsole.Instance.Warn("[PHYSICS]: Unable to collide test a space");
                    return;
                }
                //Colliding a space or a geom with a space or a geom. so drill down

                //Collide all geoms in each space..
                //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback);
                //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback);
                return;
            }

            if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
            {
                return;
            }

            int count = 0;

            try
            {
                if (g1 == g2)
                {
                    return; // Can't collide with yourself
                }
                count = d.CollidePtr(g1, g2, (contactsPerCollision & 0xffff), ContactgeomsArray,
                                     d.ContactGeom.unmanagedSizeOf);
            }
            catch (SEHException)
            {
                MainConsole.Instance.Error(
                    "[PHYSICS]: The Operating system shut down ODE because of corrupt memory.  This could be a result of really irregular terrain.  If this repeats continuously, restart using Basic Physics and terrain fill your terrain.  Restarting the sim.");
            }
            catch (Exception e)
            {
                MainConsole.Instance.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e);
                return;
            }

            PhysicsActor p1 = null;

            if (g1 != IntPtr.Zero)
            {
                m_scene.actor_name_map.TryGetValue(g1, out p1);
            }

            // Loop over contacts, build results.
            d.ContactGeom curContact = new d.ContactGeom();
            for (int i = 0; i < count; i++)
            {
                if (!GetCurContactGeom(i, ref curContact))
                {
                    break;
                }

                if (p1 != null)
                {
                    if (p1 is AuroraODEPrim)
                    {
                        ContactResult collisionresult = new ContactResult
                        {
                            ConsumerID = ((AuroraODEPrim)p1).LocalID,
                            Pos        =
                                new Vector3(curContact.pos.X, curContact.pos.Y,
                                            curContact.pos.Z),
                            Depth  = curContact.depth,
                            Normal =
                                new Vector3(curContact.normal.X,
                                            curContact.normal.Y,
                                            curContact.normal.Z)
                        };

                        lock (m_contactResults)
                            m_contactResults.Add(collisionresult);
                    }
                }
            }
        }
        public static InteractionResult GetDamageInteractionOld(InteractionParamHolder interactionParam)
        {
            InteractionResult finalInteractionResult = new InteractionResult();

            BattleEntity attacker    = interactionParam.Attacker;
            BattleEntity victim      = interactionParam.Victim;
            ContactTypes contactType = interactionParam.ContactType;
            Elements     element     = interactionParam.DamagingElement;

            StatusChanceHolder[] statuses = interactionParam.Statuses;
            int  damage   = interactionParam.Damage;
            bool piercing = interactionParam.Piercing;

            //Get contact results
            ContactResultInfo contactResultInfo = victim.EntityProperties.GetContactResult(attacker, contactType);
            ContactResult     contactResult     = contactResultInfo.ContactResult;

            //Retrieve an overridden type of Elemental damage to inflict based on the Victim's PhysicalAttributes
            //(Ex. The Ice Power Badge only deals Ice damage to Fiery entities)
            ElementOverrideHolder newElement = attacker.EntityProperties.GetTotalElementOverride(victim);

            if (newElement.Element != Elements.Invalid)
            {
                //Add the number of element overrides to the damage if the element used already exists as an override and the victim has a Weakness
                //to the Element. This allows Badges such as Ice Power to deal more damage if used in conjunction with attacks
                //that deal the same type of damage (Ex. Ice Power and Ice Smash deal 2 additional damage total rather than 1).
                //If any new knowledge is discovered to improve this, this will be changed
                //Ice Power is the only Badge of its kind across the first two PM games that does anything like this
                if (element == newElement.Element && victim.EntityProperties.HasWeakness(element) == true)
                {
                    damage += newElement.OverrideCount;
                }

                element = newElement.Element;
            }

            /*Get the total damage dealt to the Victim. The amount of Full or Half Payback damage dealt to the Attacker
             * uses the resulting damage value from this because Payback uses the total damage that would be dealt to the Victim.
             * This occurs before factoring in elemental resistances/weaknesses from the Attacker*/
            ElementDamageResultHolder victimElementDamage = GetElementalDamage(victim, element, damage);

            int unscaledVictimDamage = victimElementDamage.Damage;

            //Subtract damage reduction (P-Up, D-Down and P-Down, D-Up Badges)
            unscaledVictimDamage -= victim.BattleStats.DamageReduction;

            //Check if the attack hit. If not, then don't consider defensive actions
            bool attackHit = interactionParam.CantMiss == true ? true : attacker.AttemptHitEntity(victim);

            //Defense added from Damage Dodge Badges upon a successful Guard
            int damageDodgeDefense = 0;

            //Defensive actions take priority. If the attack didn't hit, don't check for defensive actions
            BattleGlobals.DefensiveActionHolder?victimDefenseData = null;
            if (attackHit == true)
            {
                victimDefenseData = victim.GetDefensiveActionResult(unscaledVictimDamage, statuses, interactionParam.DamageEffect);
            }

            if (victimDefenseData.HasValue == true)
            {
                unscaledVictimDamage = victimDefenseData.Value.Damage;
                statuses             = victimDefenseData.Value.Statuses;
                //If the Defensive action dealt damage and the contact was direct
                //the Defensive action has caused a Failure for the Attacker (Ex. Superguarding)
                if ((contactType == ContactTypes.TopDirect || contactType == ContactTypes.SideDirect) && victimDefenseData.Value.ElementHolder.HasValue == true)
                {
                    contactResult = ContactResult.Failure;
                }

                //Factor in the additional Guard defense for all DefensiveActions (for now, at least)
                damageDodgeDefense = victim.GetEquippedBadgeCount(BadgeGlobals.BadgeTypes.DamageDodge);
            }

            //Subtract Defense on non-piercing damage
            if (piercing == false)
            {
                int totalDefense = victim.BattleStats.TotalDefense + damageDodgeDefense;
                unscaledVictimDamage -= totalDefense;
            }

            int scaledVictimDamage = unscaledVictimDamage;

            //Factor in Double Pain for the Victim
            scaledVictimDamage *= (1 + victim.GetEquippedBadgeCount(BadgeGlobals.BadgeTypes.DoublePain));

            //Factor in Last Stand for the Victim, if the Victim is in Danger or Peril
            if (victim.IsInDanger == true)
            {
                //PM rounds down, whereas TTYD rounds up. We're going with the latter
                //TTYD always ceilings the value (Ex. 3.2 turns to 4)
                int lastStandDivider = (1 + victim.GetEquippedBadgeCount(BadgeGlobals.BadgeTypes.LastStand));
                scaledVictimDamage = (int)Math.Ceiling(scaledVictimDamage / (float)lastStandDivider);
            }

            /*If the Victim is Invincible, ignore all damage and Status Effects
             * If the Attacker is Invincible, ignore all Payback damage and Status Effects
             *
             * It won't ignore the Payback's effects automatically; that has to be done manually by adding
             * contact exceptions or something else*/

            //Clamp Victim damage
            scaledVictimDamage = UtilityGlobals.Clamp(scaledVictimDamage, BattleGlobals.MinDamage, BattleGlobals.MaxDamage);

            #region Victim Damage Dealt

            //Calculating damage dealt to the Victim
            if (contactResult == ContactResult.Success || contactResult == ContactResult.PartialSuccess)
            {
                //Get the Status Effects to inflict on the Victim
                StatusChanceHolder[] victimInflictedStatuses = GetFilteredInflictedStatuses(victim, statuses);

                //Check if the Victim is Invincible. If so, ignore all damage and Status Effects
                if (victim.EntityProperties.GetAdditionalProperty <bool>(AdditionalProperty.Invincible) == true)
                {
                    scaledVictimDamage = 0;
                    victimElementDamage.InteractionResult = ElementInteractionResult.Damage;
                    victimInflictedStatuses = null;
                }

                finalInteractionResult.VictimResult = new InteractionHolder(victim, scaledVictimDamage, element,
                                                                            victimElementDamage.InteractionResult, contactType, piercing, victimInflictedStatuses, attackHit, DamageEffects.None);
            }

            #endregion

            #region Attacker Damage Dealt

            //Calculating damage dealt to the Attacker
            if (contactResult == ContactResult.Failure || contactResult == ContactResult.PartialSuccess)
            {
                //The damage the Attacker dealt to the Victim
                int           damageDealt   = unscaledVictimDamage;
                PaybackHolder paybackHolder = contactResultInfo.Paybackholder;

                //Override the PaybackHolder with a Defensive Action's results, if any
                if (victimDefenseData.HasValue == true && victimDefenseData.Value.ElementHolder.HasValue == true)
                {
                    damageDealt   = victimDefenseData.Value.ElementHolder.Value.Damage;
                    paybackHolder = new PaybackHolder(PaybackTypes.Constant, victimDefenseData.Value.ElementHolder.Value.Element, damageDealt);
                }

                //Get the damage done to the Attacker, factoring in Weaknesses/Resistances
                ElementDamageResultHolder attackerElementDamage = GetElementalDamage(attacker, paybackHolder.Element, damageDealt);

                //Get Payback damage - Payback damage is calculated after everything else, including Constant Payback.
                //However, it does NOT factor in Double Pain or any sort of Defense modifiers.
                int paybackDamage = paybackHolder.GetPaybackDamage(attackerElementDamage.Damage);

                //If Constant Payback, update the damage value to use the element
                if (paybackHolder.PaybackType == PaybackTypes.Constant)
                {
                    paybackDamage = GetElementalDamage(attacker, paybackHolder.Element, paybackDamage).Damage;
                }

                //Clamp Attacker damage
                attackerElementDamage.Damage = UtilityGlobals.Clamp(paybackDamage, BattleGlobals.MinDamage, BattleGlobals.MaxDamage);

                //Get the Status Effects to inflict
                StatusChanceHolder[] attackerInflictedStatuses = GetFilteredInflictedStatuses(attacker, paybackHolder.StatusesInflicted);

                //Check if the Attacker is Invincible. If so, ignore all damage and Status Effects
                if (attacker.EntityProperties.GetAdditionalProperty <bool>(AdditionalProperty.Invincible) == true)
                {
                    attackerElementDamage.Damage            = 0;
                    attackerElementDamage.InteractionResult = ElementInteractionResult.Damage;
                    attackerInflictedStatuses = null;
                }

                finalInteractionResult.AttackerResult = new InteractionHolder(attacker, attackerElementDamage.Damage, paybackHolder.Element,
                                                                              attackerElementDamage.InteractionResult, ContactTypes.None, true, attackerInflictedStatuses, true, DamageEffects.None);
            }

            #endregion

            return(finalInteractionResult);
        }