public ContactPersonViewModel(ContactData contactPerson)
 {
     OrganisationId = contactPerson.OrganisationId;
     FirstName = contactPerson.FirstName;
     LastName = contactPerson.LastName;
     Position = contactPerson.Position;
 }
        /// <summary>
        /// Find a mapping for a given contactdata object
        /// We use different methods to find a skype handle
        /// </summary>
        /// <param name="contact"></param>
        /// <returns></returns>
        public string FindMapping(ContactData contact)
        {
            // Extract skypeName from TFS Power Tools 2012 custom id
            string skypeNameCustomId = FindSkypeUserByCustomId(contact);
            if (!string.IsNullOrEmpty(skypeNameCustomId))
            {
                return skypeNameCustomId;
            }

            // Find skypename from 2012 skype provider mapping file
            string skypeName2012Mapping = FindSkypeUserIn2012MappingFile(contact);
            if (!string.IsNullOrEmpty(skypeName2012Mapping))
            {
                return skypeName2012Mapping;
            }

            // Find skypename from old 2008 + 2010 skype provider mapping file
            string skypeName2008Mapping = FindSkypeUserIn20082010MappingFile(contact);
            if (!string.IsNullOrEmpty(skypeName2008Mapping))
            {
                return skypeName2008Mapping;
            }

            // Find skypename in Skype contact list
            string skypeNameFromSkypeContactList = FindSkypeUserInSkypeContactList(contact);
            if (!string.IsNullOrEmpty(skypeNameFromSkypeContactList))
            {
                return skypeNameFromSkypeContactList;
            }

            // Found nothing
            Logger.Write(string.Format("Found no mapping for user {0}.", contact.Name));
            return string.Empty;
        }
Exemple #3
0
 protected virtual void Add(ref ContactData contactCandidate)
 {
     Contact adding = unusedContacts.Take();
     adding.Setup(ref contactCandidate);
     contacts.Add(adding);
     OnAdded(adding);
 }
Exemple #4
0
		internal Contact(ContactData contact, IntPtr relativeTo, long timestamp)
		{
			Area = contact.Area;
			Bounds = contact.Bounds;
			Id = contact.Id;
			MajorAxis = contact.MajorAxis;
			MinorAxis = contact.MinorAxis;
			Orientation = contact.Orientation;
			Hwnd = contact.Hwnd;
			RelativeTo = relativeTo;
			Position = ConvertPosition(contact.Position);

			switch (contact.State)
			{
				case Service.ContactState.New:
					State = ContactState.New;
					break;
				case Service.ContactState.Removed:
					State = ContactState.Removed;
					break;
				case Service.ContactState.Moved:
					State = ContactState.Moved;
					break;
				default:
					throw new ArgumentOutOfRangeException();
			}
			Timestamp = timestamp;
		}
 public JsonResult Contact(string MyChecked)
 {
     Contact ct = new Contact();
     ContactData ctd = new ContactData();
     var array = MyChecked.Split(',');
     if (MyChecked != "" && MyChecked != null)
     {
         for (var i = 0; i < array.Length; i++)
         {
             //var Original = dred.Get().ToList().Where(a => a.num.ToString() == array[i]).SingleOrDefault();
             ////var DelPath = System.IO.Path.Combine(Server.MapPath("~/upload/dressdesign/"), Original.img);
             ////System.IO.File.Delete(DelPath);
             //if (Original.jsonimg != "no_img.jpg")
             //{
             //    var jsonstr = JsonConvert.DeserializeObject<List<jsonSer>>(Original.jsonimg);
             //    var DelJsonPath = Server.MapPath("~/upload/dressdesign/");
             //    foreach (var j in jsonstr)
             //    {
             //        var DelJsonPathing = System.IO.Path.Combine(DelJsonPath, j.content);
             //        System.IO.File.Delete(DelJsonPathing);
             //    }
             //}
             ct.num = Convert.ToInt32(array[i]);
             ctd.Delete(ct);
         }
     }
     return Json("");
 }
 public JsonResult Contact(string MyChecked)
 {
     Contact n = new Contact();
     ContactData nd = new ContactData();
     var array = MyChecked.Split(',');
     if (MyChecked != "" && MyChecked != null)
     {
         for (var i = 0; i < array.Length; i++)
         {
             //var Original = nd.Get().ToList().Where(a => a.num.ToString() == array[i]).SingleOrDefault();
             //var DelPath = System.IO.Path.Combine(Server.MapPath("~/upload/News/"), Original.pic1);
             //System.IO.File.Delete(DelPath);
             //if (Original.jsonimg != "no_img.jpg")
             //{
             //    var jsonstr = JsonConvert.DeserializeObject<List<jsonSer>>(Original.jsonimg);
             //    var DelJsonPath = Server.MapPath("~/upload/photograhy/");
             //    foreach (var j in jsonstr)
             //    {
             //        var DelJsonPathing = System.IO.Path.Combine(DelJsonPath, j.content);
             //        System.IO.File.Delete(DelJsonPathing);
             //    }
             //}
             n.isdel = 1;
             n.udate = DateTime.Now;
             n.num = Convert.ToInt32(array[i]);
             nd.Delete(n);
         }
     }
     return Json("");
 }
Exemple #7
0
 ///<summary>
 /// Sets upt he contact with new information.
 ///</summary>
 ///<param name="candidate">Contact data to initialize the contact with.</param>
 public void Setup(ref ContactData candidate)
 {
     Position = candidate.Position;
     Normal = candidate.Normal;
     PenetrationDepth = candidate.PenetrationDepth;
     Id = candidate.Id;
 }
        private void Events_InitialCollisionDetected(EntityCollidable sender, Collidable info, CollidablePairHandler pair, ContactData contact)
        {
            try
            {
                //var contact = pair.Contacts[0].Contact;

                //if(contact.PenetrationDepth>2f)
                //DebugSystem.Instance.DebugCommandUI.Echo(contact.PenetrationDepth.ToString());

                // Select collisionInformation for object in contact with instead of the ships own collisionInformation
                Collidable candidate = (pair.BroadPhaseOverlap.EntryA == racerEntity.CollisionInformation ? pair.BroadPhaseOverlap.EntryB : pair.BroadPhaseOverlap.EntryA) as Collidable;
                if (candidate.Equals(Physics.currentTrackFloor))
                {

                    ReactToTrackHit(contact);
                }
                else if (candidate.Equals(Physics.currentTrackWall))
                {
                    ReactToWallHit(contact);
                }
                else
                {

                    ReactToShipShipCollision(contact, candidate);
                }
            }
            catch (Exception e)
            {
                // System.Diagnostic.Debug.WriteLine("Unfound pair");
            }
        }
Exemple #9
0
        /// <summary>
        /// Computes contact data for two spheres.
        /// </summary>
        /// <param name="a">First sphere.</param>
        /// <param name="b">Second sphere.</param>
        /// <param name="positionA">Position of the first sphere.</param>
        /// <param name="positionB">Position of the second sphere.</param>
        /// <param name="contact">Contact data between the spheres, if any.</param>
        /// <returns>Whether or not the spheres are touching.</returns>
        public static bool AreSpheresColliding(SphereShape a, SphereShape b, ref Vector3 positionA, ref Vector3 positionB, out ContactData contact)
        {
            contact = new ContactData();

            float radiusSum = a.collisionMargin + b.collisionMargin;
            Vector3 centerDifference;
            Vector3.Subtract(ref positionB, ref positionA, out centerDifference);
            float centerDistance = centerDifference.LengthSquared();

            if (centerDistance < (radiusSum + CollisionDetectionSettings.maximumContactDistance) * (radiusSum + CollisionDetectionSettings.maximumContactDistance))
            {
                //In collision!

                if (radiusSum > Toolbox.Epsilon) //This would be weird, but it is still possible to cause a NaN.
                    Vector3.Multiply(ref centerDifference, a.collisionMargin / (radiusSum), out  contact.Position);
                else contact.Position = new Vector3();
                Vector3.Add(ref contact.Position, ref positionA, out contact.Position);

                centerDistance = (float)Math.Sqrt(centerDistance);
                if (centerDistance > Toolbox.BigEpsilon)
                {
                    Vector3.Divide(ref centerDifference, centerDistance, out contact.Normal);
                }
                else
                {
                    contact.Normal = Toolbox.UpVector;
                }
                contact.PenetrationDepth = radiusSum - centerDistance;

                return true;

            }
            return false;
        }
Exemple #10
0
        public List<ContactData> getContactList()
        {
            if (contactCache == null)
            {
                short i = -1;
                contactCache = new List<ContactData>();
                ICollection<IWebElement> elements = driver.FindElements(By.XPath("//div[@class='contactInfo']/div[@class='name']"));

                foreach (IWebElement element in elements)
                {
                    ContactData contact = new ContactData()
                    {
                        ID = ++i
                    };
                    contactCache.Add(contact);
                }

                string allContactNames = driver.FindElement(By.CssSelector("div#contactsContainer")).Text;
                string[] parts = allContactNames.Split('\n');

                for (int j = 0; j < parts.Length; j++)
                {
                    parts[j] = parts[j].Replace("\r", "");
                }

                string[] newParts = parts.Where(w => w.Length > 2).ToArray();

                for (int j = 0; j < contactCache.Count; j++)
                {
                    contactCache[j].FirstName = newParts[j];
                }
            }

            return new List<ContactData>(contactCache);
        }
        public EditCarrierViewModel()
        {
            Address = new AddressData();

            Contact = new ContactData();

            Business = new BusinessTypeViewModel();
        }
        public ImporterViewModel()
        {
            Address = new AddressData();

            Contact = new ContactData();

            Business = new BusinessTypeViewModel();
        }
        public EditProducerViewModel()
        {
            Address = new AddressData();

            Contact = new ContactData();

            Business = new ProducerBusinessTypeViewModel();
        }
        public ImporterData()
        {
            Address = new AddressData();

            Contact = new ContactData();

            Business = new BusinessInfoData();
        }
        public EditFacilityViewModel()
        {
            Address = new AddressData();

            Contact = new ContactData();

            Business = new BusinessTypeViewModel();
        }
        protected override void Add(ref ContactData contactCandidate)
        {
            contact.Normal = contactCandidate.Normal;
            contact.PenetrationDepth = contactCandidate.PenetrationDepth;
            contact.Position = contactCandidate.Position;

            contacts.Add(contact);
            OnAdded(contact);
        }
Exemple #17
0
 private Contact Create(ContactData contactData)
 {
     return new Contact
     {
         EmailAddress = contactData.EmailAddress,
         Name = contactData.Name,
         PhoneNumber = contactData.PhoneNumber
     };
 }
 public static Contact CreateContact(ContactData contact)
 {
     contact.Telephone = contact.TelephonePrefix + "-" + contact.Telephone;
     if (!string.IsNullOrWhiteSpace(contact.Fax))
     {
         contact.Fax = contact.FaxPrefix + "-" + contact.Fax;
     }
     return new Contact(contact.FullName, contact.Telephone, contact.Email, contact.Fax);
 }
        public ExporterViewModel()
        {
            Address = new AddressData();

            Contact = new ContactData();

            Business = new BusinessTypeViewModel();
            Business.DisplayAdditionalNumber = true;
            Business.DisplayCompaniesHouseHint = true;
        }
 public AddContactPersonToOrganisation ToAddRequest()
 {
     var contact = new ContactData
     {   
         FirstName = FirstName,
         LastName = LastName,
         Position = Position
     };
     return new AddContactPersonToOrganisation(OrganisationId, contact);
 }
		IntPtr mouseHook_MessageIntercepted(int nCode, IntPtr wParam, IntPtr lParam)
		{
			if (nCode >= 0)
			{
				FrameData data = new FrameData();
				data.Timestamp = Stopwatch.GetTimestamp();
				data.Images = new Service.ImageData[0];

				NativeMethods.MSLLHOOKSTRUCT mouseStructure = (NativeMethods.MSLLHOOKSTRUCT) Marshal.PtrToStructure(lParam, typeof (NativeMethods.MSLLHOOKSTRUCT));

				ContactData contact = new ContactData();
				contact.MajorAxis = 10;
				contact.MinorAxis = 10;
				contact.Orientation = 0;

				IntPtr hwnd = NativeMethods.WindowFromPoint(mouseStructure.pt);
				if (hwnd != IntPtr.Zero)
				{
					contact.Hwnd = hwnd;

					NativeMethods.POINT clientPoint = NativeMethods.ScreenToClient(mouseStructure.pt, hwnd);
					contact.Position = new Point(clientPoint.X, clientPoint.Y);

					if (wParam == (IntPtr) NativeMethods.MouseMessages.WM_LBUTTONDOWN)
					{
						id++;
						if (id == int.MaxValue)
							id = 0;
						contact.State = Service.ContactState.New;
					}
					else if (wParam == (IntPtr) NativeMethods.MouseMessages.WM_LBUTTONUP)
					{
						contact.State = Service.ContactState.Removed;
					}
					else if (wParam == (IntPtr) NativeMethods.MouseMessages.WM_MOUSEMOVE)
					{
						contact.State = Service.ContactState.Moved;
					}
					contact.Id = id;
					contact.Bounds = new Rect(contact.Position.X - (contact.MajorAxis/2), contact.Position.Y - (contact.MinorAxis/2),
					                          contact.MajorAxis, contact.MinorAxis);
					data.Contacts = new[] {contact};

					if (contact.State == Service.ContactState.New)
						contactPressent = true;

					if (contactPressent)
						Frame(data);

					else if (contact.State == Service.ContactState.Removed)
						contactPressent = false;
				}
			}
			return NativeMethods.CallNextHookEx(hookId, nCode, wParam, lParam);
		}
		internal static ContactData GetContactData(int id, ContactState state, Point point)
		{
			ContactData contactData = new ContactData();
			contactData.Position = point;
			contactData.Id = id;
			contactData.MajorAxis = 20;
			contactData.MinorAxis = 30;
			contactData.State = state;
			contactData.Orientation = 0;
			return contactData;
		}
Exemple #23
0
 public void FillContactForm(ContactData contact)
 {
     Thread.Sleep(2000);
     Type(By.Id("contact_firstName"), contact.FirstName);
     Type(By.Id("contact_lastName"), contact.LastName);
     Type(By.Id("contact_jobTitle"), contact.Job);
     Type(By.Id("contact_company"), contact.Company);
     Type(By.XPath(".//*[@id='phoneTable']/tr[1]/td[2]/input"), contact.Phone);
     new SelectElement(driver.FindElement(By.Id("contact_bMonth"))).SelectByText("February");
     new SelectElement(driver.FindElement(By.Id("contact_bDay"))).SelectByText("4");
     new SelectElement(driver.FindElement(By.Id("contact_bYear"))).SelectByText("1903");
 }
		private HidContactInfo CreateContact(HidContactState state, int id, int x, int y, int width, int height)
		{
			long timestamp = Stopwatch.GetTimestamp();

			ContactData data = new ContactData();
			data.Id = id;
			data.Position = new Point(x, y);
			data.MajorAxis = width;
			data.MinorAxis = height;
			data.Area = width * height;
			Contact contact = new Contact(data, IntPtr.Zero, timestamp);
			HidContactInfo hidContactInfo = new HidContactInfo(state, contact);
			return hidContactInfo;
		}
Exemple #25
0
        ///<summary>
        /// Generates a contact between the objects, if possible.
        ///</summary>
        ///<param name="contact">Contact created between the pair, if possible.</param>
        ///<returns>Whether or not the objects were colliding.</returns>
        public bool GenerateContactCandidate(out ContactData contact)
        {
            //Generate contacts.  This will just find one closest point using general supportmapping based systems like MPR and GJK.

            //The collision system moves through a state machine depending on the latest collision generation result.
            //At first, assume that the pair is completely separating.  This is almost always the correct guess for new pairs.
            //An extremely fast, warm-startable boolean GJK test can be performed.  If it returns with nonintersection, we can quit and do nothing.
            //If the initial boolean GJK test finds intersection, move onto a shallow contact test.
            //The shallow contact test is a different kind of GJK test that finds the closest points between the shape pair.  It's not as speedy as the boolean version.
            //The algorithm is run between the marginless versions of the shapes, so that the closest points will form a contact somewhere in the space separating the cores.
            //If the closest point system finds no intersection and returns the closest points, the state is changed to ShallowContact.
            //If the closest point system finds intersection of the core shapes, then the state is changed to DeepContact, and MPR is run to determine contact information.
            //The system tries to escape from deep contact to shallow contact, and from shallow contact to separated whenever possible.

            //Here's the state flow:
            //On Separated: BooleanGJK
            //  -Intersecting -> Go to ShallowContact.
            //  -Nonintersecting -> Do nothing.
            //On ShallowContact: ClosestPointsGJK
            //  -Intersecting -> Go to DeepContact.
            //  -Nonintersecting: Go to Separated (without test) if squared distance > margin squared, otherwise use closest points to make contact.
            //On DeepContact: MPR
            //  -Intersecting -> Go to ShallowContact if penetration depth < margin
            //  -Nonintersecting -> This case is rare, but not impossible.  Go to Separated (without test).

            previousState = state;
            switch (state)
            {
                case CollisionState.Separated:
                    if (GJKToolbox.AreShapesIntersecting(collidableA.Shape, collidableB.Shape, ref collidableA.worldTransform, ref collidableB.worldTransform, ref localSeparatingAxis))
                    {
                        state = CollisionState.ShallowContact;
                        return DoShallowContact(out contact);
                    }
                    contact = new ContactData();
                    return false;
                case CollisionState.ShallowContact:
                    return DoShallowContact(out contact);
                case CollisionState.DeepContact:
                    return DoDeepContact(out contact);
            }

            contact = new ContactData();
            return false;
        }
        private string FindSkypeUserIn20082010MappingFile(ContactData contact)
        {
            Logger.Write(string.Format("Find FindSkypeUserIn20082010MappingFile was executed for user {0}", contact.Name));
            // Maybe we replace later the old deserializer by an xml linq query
            var mappedUsers = new UserMappingCollection();
            mappedUsers.Load();

            // the old power tools has used the mail adress for identifing users in communicator / messenger
            IEnumerable<string> result;
            try
            {
                result = from user in mappedUsers
                         where
                             user.TfsName.ToLower().Equals(contact.Email, StringComparison.InvariantCultureIgnoreCase) &
                             !user.IsIgnored &
                             !user.IsUnassigned
                         select user.SkypeName;
            }

            catch (Exception ex)
            {
                return string.Empty;
            }

            // if more than one result was found we return the first mapping
            // ReSharper disable PossibleMultipleEnumeration
            if (result.Any())
            // ReSharper restore PossibleMultipleEnumeration
            {
                // ReSharper disable PossibleMultipleEnumeration
                Logger.Write(string.Format("Found mapping for user {0}. skypeName {1}", contact.Name,
                                           result.FirstOrDefault()));
                // ReSharper restore PossibleMultipleEnumeration
                // ReSharper disable PossibleMultipleEnumeration
                return result.FirstOrDefault();
                // ReSharper restore PossibleMultipleEnumeration
            }

            // if no mapping was found we return an empty string
            Logger.Write(string.Format("Found no mapping for user {0}.", contact.Name));
            return string.Empty;
        }
Exemple #27
0
        protected string UniqueJohnDoe()
        {
            var id = "" + _uniqueId;

            if (id.Length == 1)
            {
                id = "00" + id;
            }
            if (id.Length == 2)
            {
                id = "0" + id;
            }
            var unique =
                UserData.From(
                    id, //"" + uniqueId,
                    NameData.From("John", "Doe"),
                    ContactData.From("*****@*****.**", "+1 212-555-1212"));

            ++_uniqueId;

            var serialized = JsonSerialization.Serialized(unique);

            return(serialized);
        }
Exemple #28
0
        public void ContactRemovalTest()
        {
            //prepare
            app.Contact.ContactsShouldNotBeEmpty();
            List <ContactData> oldContacts = app.Contact.GetContactsList();

            //action
            app.Contact.Remove(CONTACT_INDEX);
            System.Threading.Thread.Sleep(1000);

            //verification
            List <ContactData> newContacts = app.Contact.GetContactsList();
            ContactData        toBeRemoved = oldContacts[0];

            oldContacts.RemoveAt(CONTACT_INDEX);
            oldContacts.Sort();
            newContacts.Sort();
            Assert.AreEqual(oldContacts, newContacts);

            foreach (ContactData contact in newContacts)
            {
                Assert.AreNotEqual(contact.Id, toBeRemoved.Id);
            }
        }
Exemple #29
0
        bool TryToStepUsingContact(ref ContactData contact, ref System.Numerics.Vector3 down, out System.Numerics.Vector3 newPosition)
        {
            System.Numerics.Vector3 position = characterBody.Position;
            //The normal of the contact may not be facing perfectly out to the side.
            //The detection process allows a bit of slop.
            //Correct it by removing any component of the normal along the local up vector.
            System.Numerics.Vector3 normal = contact.Normal;
            float dot;

            Vector3Ex.Dot(ref normal, ref down, out dot);
            System.Numerics.Vector3 error;
            Vector3Ex.Multiply(ref down, dot, out error);
            Vector3Ex.Subtract(ref normal, ref error, out normal);
            normal.Normalize();

            //Now we need to ray cast out from the center of the character in the direction of this normal to check for obstructions.
            //Compute the ray origin location.  Fire it out of the top of the character; if we're stepping, this must be a valid location.
            //Putting it as high as possible helps to reject more invalid step geometry.
            Ray   ray;
            float downRayLength = characterBody.Height;// MaximumStepHeight + upStepMargin;

            Vector3Ex.Multiply(ref down, characterBody.Height * .5f - downRayLength, out ray.Position);
            Vector3Ex.Add(ref ray.Position, ref position, out ray.Position);
            ray.Direction = normal;
            //Include a little margin in the length.
            //Technically, the character only needs to teleport horizontally by the complicated commented expression.
            //That puts it just far enough to have traction on the new surface.
            //In practice, the current contact refreshing approach used for many pair types causes contacts to persist horizontally a bit,
            //which can cause side effects for the character.
            float horizontalOffsetAmount = characterBody.CollisionInformation.Shape.CollisionMargin; // (float)((1 - character.SupportFinder.sinMaximumSlope) * character.Body.CollisionInformation.Shape.CollisionMargin + 0);
            float length = characterBody.Radius + horizontalOffsetAmount;                            // -contact.PenetrationDepth;


            if (QueryManager.RayCastHitAnything(ray, length))
            {
                //The step is obstructed!
                newPosition = new System.Numerics.Vector3();
                return(false);
            }

            //The down-cast ray origin has been verified by the previous ray cast.
            //Let's look for a support!
            System.Numerics.Vector3 horizontalOffset;
            Vector3Ex.Multiply(ref normal, length, out horizontalOffset);
            Vector3Ex.Add(ref ray.Position, ref horizontalOffset, out ray.Position);
            ray.Direction = down;

            //Find the earliest hit, if any.
            RayHit earliestHit;

            if (!QueryManager.RayCast(ray, downRayLength, out earliestHit) ||      //Can't do anything if it didn't hit.
                earliestHit.T <= 0 ||                                              //Can't do anything if the hit was invalid.
                earliestHit.T - downRayLength > -minimumUpStepHeight ||            //Don't bother doing anything if the step is too small.
                earliestHit.T - downRayLength < -maximumStepHeight - upStepMargin) //Can't do anything if the step is too tall.
            {
                //No valid hit was detected.
                newPosition = new System.Numerics.Vector3();
                return(false);
            }

            //Ensure the candidate surface supports traction.
            System.Numerics.Vector3 supportNormal;
            Vector3Ex.Normalize(ref earliestHit.Normal, out supportNormal);
            //Calibrate the normal to face in the same direction as the down vector for consistency.
            Vector3Ex.Dot(ref supportNormal, ref down, out dot);
            if (dot < 0)
            {
                Vector3Ex.Negate(ref supportNormal, out supportNormal);
                dot = -dot;
            }

            //If the new surface does not have traction, do not attempt to step up.
            if (dot < ContactCategorizer.TractionThreshold)
            {
                newPosition = new System.Numerics.Vector3();
                return(false);
            }

            //Since contact queries are frequently expensive compared to ray cast tests,
            //do one more ray cast test.  This time, starting from the same position, cast upwards.
            //In order to step up, the previous down-ray hit must be at least a character height away from the result of the up-ray.
            Vector3Ex.Negate(ref down, out ray.Direction);
            //Find the earliest hit, if any.
            //RayHit earliestHitUp = new RayHit();
            //earliestHitUp.T = float.MaxValue;
            float upLength = characterBody.Height - earliestHit.T;

            //If the sum of the up and down distances is less than the height, the character can't fit.
            if (QueryManager.RayCastHitAnything(ray, upLength))
            {
                newPosition = new System.Numerics.Vector3();
                return(false);
            }

            //By now, a valid ray hit has been found.  Now we need to validate it using contact queries.
            //This process is very similar in concept to the down step verification, but it has some extra
            //requirements.

            //Predict a hit location based on the time of impact and the normal at the intersection.
            //Take into account the radius of the character (don't forget the collision margin!)



            RigidTransform transform = characterBody.CollisionInformation.WorldTransform;

            //The transform must be modified to position the query body at the right location.
            //The horizontal offset of the queries ensures that a tractionable part of the character will be put onto the new support.
            Vector3Ex.Multiply(ref normal, horizontalOffsetAmount, out horizontalOffset);
            Vector3Ex.Add(ref transform.Position, ref horizontalOffset, out transform.Position);
            System.Numerics.Vector3 verticalOffset;
            Vector3Ex.Multiply(ref down, -downRayLength, out verticalOffset);
            Vector3Ex.Add(ref transform.Position, ref verticalOffset, out transform.Position);

            //We know that the closest point to the plane will be the extreme point in the plane's direction.
            //Use it as the ray origin.
            Ray downRay;

            characterBody.CollisionInformation.Shape.GetExtremePoint(supportNormal, ref transform, out downRay.Position);
            downRay.Direction = down;

            //Intersect the ray against the plane defined by the support hit.
            System.Numerics.Vector3 intersection;
            Vector3Ex.Dot(ref earliestHit.Location, ref supportNormal, out dot);
            Plane plane = new Plane(supportNormal, dot);

            System.Numerics.Vector3 candidatePosition;

            //Define the interval bounds to be used later.

            //The words 'highest' and 'lowest' here refer to the position relative to the character's body.
            //The ray cast points downward relative to the character's body.
            float highestBound  = -maximumStepHeight;
            float lowestBound   = characterBody.CollisionInformation.Shape.CollisionMargin - downRayLength + earliestHit.T;
            float currentOffset = lowestBound;
            float hintOffset;

            var tractionContacts = new QuickList <CharacterContact>(BufferPools <CharacterContact> .Thread);
            var supportContacts  = new QuickList <CharacterContact>(BufferPools <CharacterContact> .Thread);
            var sideContacts     = new QuickList <CharacterContact>(BufferPools <CharacterContact> .Thread);
            var headContacts     = new QuickList <CharacterContact>(BufferPools <CharacterContact> .Thread);

            try
            {
                //This guess may either win immediately, or at least give us a better idea of where to search.
                float hitT;
                if (Toolbox.GetRayPlaneIntersection(ref downRay, ref plane, out hitT, out intersection))
                {
                    hitT = -downRayLength + hitT + CollisionDetectionSettings.AllowedPenetration;
                    if (hitT < highestBound)
                    {
                        //Don't try a location known to be too high.
                        hitT = highestBound;
                    }
                    currentOffset = hitT;
                    if (currentOffset > lowestBound)
                    {
                        lowestBound = currentOffset;
                    }
                    candidatePosition = characterBody.Position + down * currentOffset + horizontalOffset;
                    switch (TryUpStepPosition(ref normal, ref candidatePosition, ref down,
                                              ref tractionContacts, ref supportContacts, ref sideContacts, ref headContacts,
                                              out hintOffset))
                    {
                    case CharacterContactPositionState.Accepted:
                        currentOffset += hintOffset;
                        //Only use the new position location if the movement distance was the right size.
                        if (currentOffset < 0 && currentOffset > -maximumStepHeight - CollisionDetectionSettings.AllowedPenetration)
                        {
                            //It's possible that we let a just-barely-too-high step occur, limited by the allowed penetration.
                            //Just clamp the overall motion and let it penetrate a bit.
                            newPosition = characterBody.Position + Math.Max(-maximumStepHeight, currentOffset) * down + horizontalOffset;
                            return(true);
                        }
                        else
                        {
                            newPosition = new System.Numerics.Vector3();
                            return(false);
                        }

                    case CharacterContactPositionState.Rejected:
                        newPosition = new System.Numerics.Vector3();
                        return(false);

                    case CharacterContactPositionState.NoHit:
                        highestBound  = currentOffset + hintOffset;
                        currentOffset = (lowestBound + currentOffset) * .5f;
                        break;

                    case CharacterContactPositionState.Obstructed:
                        lowestBound   = currentOffset;
                        currentOffset = (highestBound + currentOffset) * .5f;
                        break;

                    case CharacterContactPositionState.HeadObstructed:
                        highestBound  = currentOffset + hintOffset;
                        currentOffset = (lowestBound + currentOffset) * .5f;
                        break;

                    case CharacterContactPositionState.TooDeep:
                        currentOffset += hintOffset;
                        lowestBound    = currentOffset;
                        break;
                    }
                } //TODO: If the ray cast doesn't hit, that could be used to early out...  Then again, it pretty much can't happen.

                //Our guesses failed.
                //Begin the regular process.  Start at the time of impact of the ray itself.
                //How about trying the time of impact of the ray itself?

                //Since we wouldn't be here unless there were no contacts at the body's current position,
                //testing the ray cast location gives us the second bound we need to do an informed binary search.



                int attempts = 0;
                //Don't keep querying indefinitely.  If we fail to reach it in a few informed steps, it's probably not worth continuing.
                //The bound size check prevents the system from continuing to search a meaninglessly tiny interval.
                while (attempts++ < 5 && lowestBound - highestBound > Toolbox.BigEpsilon)
                {
                    candidatePosition = characterBody.Position + currentOffset * down + horizontalOffset;
                    switch (TryUpStepPosition(ref normal, ref candidatePosition, ref down,
                                              ref tractionContacts, ref supportContacts, ref sideContacts, ref headContacts,
                                              out hintOffset))
                    {
                    case CharacterContactPositionState.Accepted:
                        currentOffset += hintOffset;
                        //Only use the new position location if the movement distance was the right size.
                        if (currentOffset < 0 && currentOffset > -maximumStepHeight - CollisionDetectionSettings.AllowedPenetration)
                        {
                            //It's possible that we let a just-barely-too-high step occur, limited by the allowed penetration.
                            //Just clamp the overall motion and let it penetrate a bit.
                            newPosition = characterBody.Position + Math.Max(-maximumStepHeight, currentOffset) * down + horizontalOffset;
                            return(true);
                        }
                        else
                        {
                            newPosition = new System.Numerics.Vector3();
                            return(false);
                        }

                    case CharacterContactPositionState.Rejected:
                        newPosition = new System.Numerics.Vector3();
                        return(false);

                    case CharacterContactPositionState.NoHit:
                        highestBound  = currentOffset + hintOffset;
                        currentOffset = (lowestBound + highestBound) * .5f;
                        break;

                    case CharacterContactPositionState.Obstructed:
                        lowestBound   = currentOffset;
                        currentOffset = (highestBound + lowestBound) * .5f;
                        break;

                    case CharacterContactPositionState.HeadObstructed:
                        highestBound  = currentOffset + hintOffset;
                        currentOffset = (lowestBound + currentOffset) * .5f;
                        break;

                    case CharacterContactPositionState.TooDeep:
                        currentOffset += hintOffset;
                        lowestBound    = currentOffset;
                        break;
                    }
                }
            }
            finally
            {
                tractionContacts.Dispose();
                supportContacts.Dispose();
                sideContacts.Dispose();
                headContacts.Dispose();
            }
            //Couldn't find a candidate.
            newPosition = new System.Numerics.Vector3();
            return(false);
        }
Exemple #30
0
 public void ParticleHit(ContactData contactData, Gradient colorGradient)
 {
     SetParticleData(contactData, colorGradient);
     DisplayParticles();
 }
        /// <summary>
        /// Computes contact data for two spheres.
        /// </summary>
        /// <param name="a">First sphere.</param>
        /// <param name="b">Second sphere.</param>
        /// <param name="positionA">Position of the first sphere.</param>
        /// <param name="positionB">Position of the second sphere.</param>
        /// <param name="contact">Contact data between the spheres, if any.</param>
        /// <returns>Whether or not the spheres are touching.</returns>
        public static bool AreSpheresColliding(SphereShape a, SphereShape b, ref Vector3 positionA, ref Vector3 positionB, out ContactData contact)
        {
            contact = new ContactData();

            float   radiusSum = a.collisionMargin + b.collisionMargin;
            Vector3 centerDifference;

            Vector3.Subtract(ref positionB, ref positionA, out centerDifference);
            float centerDistance = centerDifference.LengthSquared();

            if (centerDistance < (radiusSum + CollisionDetectionSettings.maximumContactDistance) * (radiusSum + CollisionDetectionSettings.maximumContactDistance))
            {
                //In collision!

                if (radiusSum > Toolbox.Epsilon) //This would be weird, but it is still possible to cause a NaN.
                {
                    Vector3.Multiply(ref centerDifference, a.collisionMargin / (radiusSum), out contact.Position);
                }
                else
                {
                    contact.Position = new Vector3();
                }
                Vector3.Add(ref contact.Position, ref positionA, out contact.Position);

                centerDistance = (float)Math.Sqrt(centerDistance);
                if (centerDistance > Toolbox.BigEpsilon)
                {
                    Vector3.Divide(ref centerDifference, centerDistance, out contact.Normal);
                }
                else
                {
                    contact.Normal = Toolbox.UpVector;
                }
                contact.PenetrationDepth = radiusSum - centerDistance;

                return(true);
            }
            return(false);
        }
 internal ContactEventArgs(ContactData contact, IntPtr relativeTo, long timestamp)
 {
     Contact = new Contact(contact, relativeTo, timestamp);
 }
        private bool DoPlaneTest(TriangleShape triangle, out TinyStructList <ContactData> contactList)
        {
            //Find closest point between object and plane.
            Vector3 reverseNormal;
            Vector3 ab, ac;

            Vector3.Subtract(ref triangle.vB, ref triangle.vA, out ab);
            Vector3.Subtract(ref triangle.vC, ref triangle.vA, out ac);
            Vector3.Cross(ref ac, ref ab, out reverseNormal);
            //Convex position dot normal is ALWAYS zero.  The thing to look at is the plane's 'd'.
            //If the distance along the normal is positive, then the convex is 'behind' that normal.
            float dotA;

            Vector3.Dot(ref triangle.vA, ref reverseNormal, out dotA);

            contactList = new TinyStructList <ContactData>();
            switch (triangle.sidedness)
            {
            case TriangleSidedness.DoubleSided:
                if (dotA < 0)
                {
                    //The reverse normal is pointing towards the convex.
                    //It needs to point away from the convex so that the direction
                    //will get the proper extreme point.
                    Vector3.Negate(ref reverseNormal, out reverseNormal);
                    dotA = -dotA;
                }
                break;

            case TriangleSidedness.Clockwise:
                //if (dotA < 0)
                //{
                //    //The reverse normal is pointing towards the convex.
                //    return false;
                //}
                break;

            case TriangleSidedness.Counterclockwise:
                //if (dotA > 0)
                //{
                //    //The reverse normal is pointing away from the convex.
                //    return false;
                //}

                //The reverse normal is pointing towards the convex.
                //It needs to point away from the convex so that the direction
                //will get the proper extreme point.
                Vector3.Negate(ref reverseNormal, out reverseNormal);
                dotA = -dotA;
                break;
            }
            Vector3 extremePoint;

            convex.GetLocalExtremePointWithoutMargin(ref reverseNormal, out extremePoint);


            //See if the extreme point is within the face or not.
            //It might seem like the easy "depth" test should come first, since a barycentric
            //calculation takes a bit more time.  However, transferring from plane to depth is 'rare'
            //(like all transitions), and putting this test here is logically closer to its requirements'
            //computation.

            if (GetVoronoiRegion(triangle, ref extremePoint) != VoronoiRegion.ABC)
            {
                state = CollisionState.ExternalSeparated;
                return(DoExternalSeparated(triangle, out contactList));
            }



            float dotE;

            Vector3.Dot(ref extremePoint, ref reverseNormal, out dotE);
            float t = (dotA - dotE) / reverseNormal.LengthSquared();



            Vector3 offset;

            Vector3.Multiply(ref reverseNormal, t, out offset);

            //Compare the distance from the plane to the convex object.
            float distanceSquared = offset.LengthSquared();

            float marginSum = triangle.collisionMargin + convex.collisionMargin;

            //TODO: Could just normalize early and avoid computing point plane before it's necessary.
            //Exposes a sqrt but...
            if (t <= 0 || distanceSquared < marginSum * marginSum)
            {
                //The convex object is in the margin of the plane.
                //All that's left is to create the contact.


                var contact = new ContactData();
                //Displacement is from A to B.  point = A + t * AB, where t = marginA / margin.
                if (marginSum > Toolbox.Epsilon)                                                            //This can be zero! It would cause a NaN is unprotected.
                {
                    Vector3.Multiply(ref offset, convex.collisionMargin / marginSum, out contact.Position); //t * AB
                }
                else
                {
                    contact.Position = new Vector3();
                }
                Vector3.Add(ref extremePoint, ref contact.Position, out contact.Position); //A + t * AB.

                float normalLength = reverseNormal.Length();
                Vector3.Divide(ref reverseNormal, normalLength, out contact.Normal);
                float distance = normalLength * t;



                contact.PenetrationDepth = marginSum - distance;

                if (contact.PenetrationDepth > marginSum)
                {
                    //Check to see if the inner sphere is touching the plane.
                    //This does not override other tests; there can be more than one contact from a single triangle.

                    ContactData alternateContact;
                    if (TryInnerSphereContact(triangle, out alternateContact))// && alternateContact.PenetrationDepth > contact.PenetrationDepth)
                    {
                        contactList.Add(ref alternateContact);
                    }

                    //The convex object is stuck deep in the plane!
                    //The most problematic case for this is when
                    //an object is right on top of a cliff.
                    //The lower, vertical triangle may occasionally detect
                    //a contact with the object, but would compute an extremely
                    //deep depth if the normal plane test was used.



                    //Verify that the depth is correct by trying another approach.
                    CollisionState previousState = state;
                    state = CollisionState.ExternalNear;
                    TinyStructList <ContactData> alternateContacts;
                    if (DoExternalNear(triangle, out alternateContacts))
                    {
                        alternateContacts.Get(0, out alternateContact);
                        if (alternateContact.PenetrationDepth + .01f < contact.PenetrationDepth) //Bias against the subtest's result, since the plane version will probably have a better position.
                        {
                            //It WAS a bad contact.
                            contactList.Add(ref alternateContact);
                            //DoDeepContact (which can be called from within DoExternalNear) can generate two contacts, but the second contact would just be an inner sphere (which we already generated).
                            //DoExternalNear can only generate one contact.  So we only need the first contact!
                            //TODO: This is a fairly fragile connection between the two stages.  Consider robustifying. (Also, the TryInnerSphereContact is done twice! This process is very rare for marginful pairs, though)
                        }
                        else
                        {
                            //Well, it really is just that deep.
                            contactList.Add(ref contact);
                            state = previousState;
                        }
                    }
                    else
                    {
                        //If the external near test finds that there was no collision at all,
                        //just return to plane testing.  If the point turns up outside the face region
                        //next time, the system will adapt.
                        state = previousState;
                        return(false);
                    }
                }
                else
                {
                    contactList.Add(ref contact);
                }
                return(true);
            }
            return(false);
        }
Exemple #34
0
        public void Test_Evaluate()
        {
            VelocityContext c = new VelocityContext();

            c.Put("key", "value");
            c.Put("firstName", "Cort");
            c.Put("lastName", "Schaefer");
            Hashtable h = new Hashtable();

            h.Add("foo", "bar");
            c.Put("hashtable", h);

            AddressData address = new AddressData();

            address.Address1 = "9339 Grand Teton Drive";
            address.Address2 = "Office in the back";
            c.Put("address", address);

            ContactData contact = new ContactData();

            contact.Name    = "Cort";
            contact.Address = address;
            c.Put("contact", contact);

            // test simple objects (no nesting)
            StringWriter sw = new StringWriter();
            Boolean      ok = Velocity.Evaluate(c, sw, "", "$firstName is my first name, my last name is $lastName");

            Assertion.Assert("Evalutation returned failure", ok);
            String s = sw.ToString();

            Assertion.Assert("test simple objects (no nesting)", s.Equals("Cort is my first name, my last name is Schaefer"));

            // test nested object
            sw = new StringWriter();
            String template = "These are the individual properties:\naddr1=9339 Grand Teton Drive\naddr2=Office in the back";

            ok = Velocity.Evaluate(c, sw, "", template)
            ;
            Assertion.Assert("Evalutation returned failure", ok);
            s = sw.ToString();
            Assertion.Assert("test nested object", !s.Equals(String.Empty));

            // test hashtable
            //	    sw = new StringWriter();
            //	    template = "Hashtable lookup: foo=$hashtable.foo";
            //	    ok = Velocity.Evaluate(c, sw, "", template);
            //	    Assert("Evalutation returned failure", ok);
            //	    s = sw.ToString();
            //	    Assert("Evaluation did not evaluate right", s.Equals("Hashtable lookup: foo=bar"));

            // test nested properties
            //          sw = new StringWriter();
            //	    template = "These are the nested properties:\naddr1=$contact.Address.Address1\naddr2=$contact.Address.Address2";
            //	    ok = Velocity.Evaluate(c, sw, "", template);
            //	    Assert("Evalutation returned failure", ok);
            //	    s = sw.ToString();
            //	    Assert("test nested properties", s.Equals("These are the nested properties:\naddr1=9339 Grand Teton Drive\naddr2=Office in the back"));

            // test key not found in context
            sw       = new StringWriter();
            template = "$!NOT_IN_CONTEXT";
            ok       = Velocity.Evaluate(c, sw, "", template)
            ;
            Assertion.Assert("Evalutation returned failure", ok);
            s = sw.ToString();
            Assertion.Assert("test key not found in context", s.Equals(String.Empty));

            // test nested properties where property not found
            //	    sw = new StringWriter();
            //	    template = "These are the non-existent nested properties:\naddr1=$contact.Address.Address1.Foo\naddr2=$contact.Bar.Address.Address2";
            //	    ok = Velocity.Evaluate(c, sw, "", template);
            //	    Assert("Evalutation returned failure", ok);
            //	    s = sw.ToString();
            //	    Assert("test nested properties where property not found", s.Equals("These are the non-existent nested properties:\naddr1=\naddr2="));
        }
Exemple #35
0
        private bool DoShallowContact(out ContactData contact)
        {
            Vector3 closestA, closestB;

            //RigidTransform transform = RigidTransform.Identity;
            //Vector3 closestAnew, closestBnew;
            //CachedSimplex cachedTest = cachedSimplex;
            //bool intersecting = GJKToolbox.GetClosestPoints(informationA.Shape, informationB.Shape, ref informationA.worldTransform, ref informationB.worldTransform, ref cachedTest, out closestAnew, out closestBnew);

            ////bool otherIntersecting = OldGJKVerifier.GetClosestPointsBetweenObjects(informationA.Shape, informationB.Shape, ref informationA.worldTransform, ref informationB.worldTransform, 0, 0, out closestA, out closestB);
            //bool otherIntersecting = GJKToolbox.GetClosestPoints(informationA.Shape, informationB.Shape, ref informationA.worldTransform, ref informationB.worldTransform, out closestA, out closestB);

            //Vector3 closestAold, closestBold;
            //bool oldIntersecting = OldGJKVerifier.GetClosestPointsBetweenObjects(informationA.Shape, informationB.Shape, ref informationA.worldTransform, ref informationB.worldTransform, 0, 0, out closestAold, out closestBold);

            //if (otherIntersecting != intersecting || (!otherIntersecting && !intersecting &&
            //    Vector3.DistanceSquared(closestAnew, closestBnew) - Vector3.DistanceSquared(closestA, closestB) > .0001f &&
            //    (Vector3.DistanceSquared(closestA, closestAnew) > .0001f ||
            //    Vector3.DistanceSquared(closestB, closestBnew) > .0001f)))// ||
            //    //Math.Abs(Vector3.Dot(closestB - closestA, closestBnew - closestAnew) - Vector3.Dot(closestB - closestA, closestB - closestA)) > Toolbox.Epsilon)))
            //    Debug.WriteLine("Break.");

            //Vector3 sub;
            //Vector3.Subtract(ref closestA, ref closestB, out sub);
            //if (sub.LengthSquared() < Toolbox.Epsilon)

            bool intersecting;
            if (UseSimplexCaching)
                intersecting = GJKToolbox.GetClosestPoints(collidableA.Shape, collidableB.Shape, ref collidableA.worldTransform, ref collidableB.worldTransform, ref cachedSimplex, out closestA, out closestB);
            else
            {
                //The initialization of the pair creates a pretty decent simplex to start from.
                //Just don't try to update it.
                CachedSimplex preInitializedSimplex = cachedSimplex;
                intersecting = GJKToolbox.GetClosestPoints(collidableA.Shape, collidableB.Shape, ref collidableA.worldTransform, ref collidableB.worldTransform, ref preInitializedSimplex, out closestA, out closestB);
            }

            Vector3 displacement;
            Vector3.Subtract(ref closestB, ref closestA, out displacement);
            if (intersecting)
            //if (OldGJKVerifier.GetClosestPointsBetweenObjects(informationA.Shape, informationB.Shape, ref informationA.worldTransform, ref informationB.worldTransform, 0, 0, out closestA, out closestB))
            {
                state = CollisionState.DeepContact;
                return DoDeepContact(out contact);
            }

            localDirection = displacement; //Use this as the direction for future deep contacts.
            float distanceSquared = displacement.LengthSquared();
            float margin = collidableA.Shape.collisionMargin + collidableB.Shape.collisionMargin;


            if (distanceSquared < margin * margin)
            {
                //Generate a contact.
                contact = new ContactData();
                //Displacement is from A to B.  point = A + t * AB, where t = marginA / margin.
                if (margin > Toolbox.Epsilon) //Avoid a NaN!
                    Vector3.Multiply(ref displacement, collidableA.Shape.collisionMargin / margin, out contact.Position); //t * AB
                else
                    contact.Position = new Vector3();

                Vector3.Add(ref closestA, ref contact.Position, out contact.Position); //A + t * AB.


                contact.Normal = displacement;
                float distance = (float)Math.Sqrt(distanceSquared);
                Vector3.Divide(ref contact.Normal, distance, out contact.Normal);
                contact.PenetrationDepth = margin - distance;
                return true;

            }
            //Too shallow to make a contact- move back to separation.
            state = CollisionState.Separated;
            contact = new ContactData();
            return false;
        }
Exemple #36
0
 public override VoronoiRegion GetRegion(TriangleShape triangle, ref ContactData contact)
 {
     return(lastRegion);
 }
Exemple #37
0
 public Contact Map(ContactData contactData) => new Contact(contactData);
Exemple #38
0
        /// <summary>
        /// Gets Chat Update Data
        /// </summary>
        /// <param name="message"></param>
        /// <param name="callType"></param>
        /// <param name="duration"></param>
        /// <param name="chatContent"></param>
        /// <returns></returns>
        public ContactData GetContactChatUpdateData(IXNCustomData chatData, string eventName)
        {
            try
            {
                IMessage     message  = chatData.InteractionEvent;
                SFDCCallType callType = chatData.InteractionType;
                string       duration = chatData.Duration;
                this.logger.Info("GetContactChatUpdateData :  Reading Contact Update Data.....");
                this.logger.Info("GetContactChatUpdateData :  Event Name : " + message.Name);
                dynamic popupEvent = Convert.ChangeType(message, message.GetType());
                if (popupEvent != null)
                {
                    ContactData contact = new ContactData();

                    #region Collect Contact Data

                    contact.ObjectName = contactChatOptions.ObjectName;
                    if (callType == SFDCCallType.InboundChat)
                    {
                        if (contactChatOptions.InboundCanUpdateLog)
                        {
                            contact.UpdateActivityLog     = true;
                            contact.UpdateActivityLogData = this.sfdcUtility.GetUpdateActivityLogData(ContactChatLogConfig, popupEvent, callType, duration, emailData: chatData);
                            if (!string.IsNullOrWhiteSpace(contactChatOptions.ChatAppendActivityLogEventNames) && contactChatOptions.ChatAppendActivityLogEventNames.Contains(eventName))
                            {
                                contact.AppendActivityLogData = this.sfdcUtility.GetUpdateActivityLogData(this.ContactChatLogConfig, null, callType, duration, emailData: chatData, isAppendLogData: true);
                            }
                        }
                    }
                    else if (callType == SFDCCallType.ConsultChatReceived)
                    {
                        if (contactChatOptions.ConsultCanUpdateLog)
                        {
                            contact.UpdateActivityLog     = true;
                            contact.UpdateActivityLogData = this.sfdcUtility.GetUpdateActivityLogData(this.ContactChatLogConfig, popupEvent, callType, duration, emailData: chatData);
                            if (!string.IsNullOrWhiteSpace(contactChatOptions.ChatAppendActivityLogEventNames) && contactChatOptions.ChatAppendActivityLogEventNames.Contains(eventName))
                            {
                                contact.AppendActivityLogData = this.sfdcUtility.GetUpdateActivityLogData(this.ContactChatLogConfig, null, callType, duration, emailData: chatData, isAppendLogData: true);
                            }
                        }
                    }

                    //update case record fields
                    contact.UpdateRecordFields = contactChatOptions.CanUpdateRecordData;
                    if (SFDCObjectHelper.GetNoRecordFoundAction(callType, contactChatOptions).Equals("createnew") && this.ContactChatRecordConfig != null)
                    {
                        if (contactChatOptions.CanUpdateRecordData)
                        {
                            contact.UpdateRecordFieldsData = this.sfdcUtility.GetUpdateActivityLogData(this.ContactChatRecordConfig, popupEvent, callType, duration, emailData: chatData);
                        }
                    }

                    #endregion Collect Contact Data

                    return(contact);
                }
            }
            catch (Exception generalException)
            {
                this.logger.Error("GetContactChatUpdateData : Error occurred while reading Contact Data : " + generalException.ToString());
            }
            return(null);
        }
Exemple #39
0
        /// <summary>
        /// Get Account Popup Data for Email
        /// </summary>
        /// <param name="emailData"></param>
        /// <param name="callType"></param>
        /// <returns></returns>
        public ContactData GetContactEmailPopupData(IXNCustomData emailData, SFDCCallType callType)
        {
            try
            {
                this.logger.Info("GetContactEmailPopupData :  Reading Account Popup Data.....");
                this.logger.Info("GetContactEmailPopupData :  CallType Name : " + callType.ToString());

                if (emailData != null)
                {
                    ContactData _contact = new ContactData();

                    #region Collect Contact Data

                    _contact.SearchData                             = this.sfdcUtilityHelper.GetEmailSearchValue(contactEmailOptions, emailData, callType);
                    _contact.ObjectName                             = contactEmailOptions.ObjectName;
                    _contact.NoRecordFound                          = SFDCObjectHelper.GetNoRecordFoundAction(callType, contactEmailOptions);
                    _contact.MultipleMatchRecord                    = SFDCObjectHelper.GetMultiMatchRecordAction(callType, contactEmailOptions);
                    _contact.NewRecordFieldIds                      = contactEmailOptions.NewrecordFieldIds;
                    _contact.SearchCondition                        = contactEmailOptions.SearchCondition;
                    _contact.CreateLogForNewRecord                  = contactEmailOptions.CanCreateLogForNewRecordCreate;
                    _contact.MaxRecordOpenCount                     = contactEmailOptions.MaxNosRecordOpen;
                    _contact.SearchpageMode                         = contactEmailOptions.SearchPageMode;
                    _contact.PhoneNumberSearchFormat                = contactEmailOptions.PhoneNumberSearchFormat;
                    _contact.CanCreateNoRecordActivityLog           = SFDCObjectHelper.GetCanCreateProfileActivity(callType, contactEmailOptions, true);
                    _contact.CanPopupNoRecordActivityLog            = SFDCObjectHelper.GetCanPopupProfileActivity(callType, contactEmailOptions, true);
                    _contact.CanCreateMultiMatchActivityLog         = SFDCObjectHelper.GetCanCreateProfileActivity(callType, contactEmailOptions);
                    _contact.CanPopupMultiMatchActivityLog          = SFDCObjectHelper.GetCanPopupProfileActivity(callType, contactEmailOptions);
                    _contact.CanCreateProfileActivityforInbNoRecord = contactEmailOptions.CanCreateProfileActivityforInbNoRecord;
                    _contact.CanCreateProfileActivityforOutNoRecord = contactEmailOptions.CanCreateProfileActivityforOutNoRecord;
                    //_contact.CanCreateProfileActivityforConNoRecord = contactEmailOptions.CanCreateProfileActivityforConNoRecord;
                    if (_contact.NoRecordFound.Equals("createnew") && this.ContactEmailRecordConfig != null)
                    {
                        _contact.CreateRecordFieldData = this.sfdcUtility.GetCreateActivityLogData(this.ContactEmailRecordConfig, null, callType, emailData);
                    }
                    if (callType == SFDCCallType.InboundEmail || callType == SFDCCallType.InboundEmailPulled)
                    {
                        if (contactEmailOptions.InboundCanCreateLog)
                        {
                            _contact.CreateActvityLog = true;
                            _contact.ActivityLogData  = this.sfdcUtility.GetCreateActivityLogData(this.ContactEmailLogConfig, null, callType, emailData);
                        }
                    }
                    else if (callType == SFDCCallType.OutboundEmailFailure || callType == SFDCCallType.OutboundEmailSuccess || callType == SFDCCallType.OutboundEmailPulled)
                    {
                        if (contactEmailOptions.OutboundCanCreateLog)
                        {
                            _contact.CreateActvityLog = true;
                            _contact.ActivityLogData  = this.sfdcUtility.GetCreateActivityLogData(this.ContactEmailLogConfig, null, callType, emailData);
                        }
                    }

                    #endregion Collect Contact Data

                    return(_contact);
                }
            }
            catch (Exception generalException)
            {
                this.logger.Error("GetAccountEmailPopupData : Error occurred while reading Account Data : " + generalException.ToString());
            }
            return(null);
        }
Exemple #40
0
 /// <summary>
 /// Gets the triangle region in which the contact resides.
 /// </summary>
 /// <param name="triangle">Triangle to compare the contact against.</param>
 /// <param name="contact">Contact to check.</param>
 /// <returns>Region in which the contact resides.</returns>
 public abstract VoronoiRegion GetRegion(TriangleShape triangle, ref ContactData contact);
        IntPtr mouseHook_MessageIntercepted(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                FrameData data = new FrameData();
                data.Timestamp = Stopwatch.GetTimestamp();
                data.Images    = new Service.ImageData[0];

                NativeMethods.MSLLHOOKSTRUCT mouseStructure = (NativeMethods.MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(NativeMethods.MSLLHOOKSTRUCT));

                ContactData contact = new ContactData();
                contact.MajorAxis   = 10;
                contact.MinorAxis   = 10;
                contact.Orientation = 0;

                IntPtr hwnd = NativeMethods.WindowFromPoint(mouseStructure.pt);
                if (hwnd != IntPtr.Zero)
                {
                    contact.Hwnd = hwnd;

                    NativeMethods.POINT clientPoint = NativeMethods.ScreenToClient(mouseStructure.pt, hwnd);
                    contact.Position = new Point(clientPoint.X, clientPoint.Y);

                    if (wParam == (IntPtr)NativeMethods.MouseMessages.WM_LBUTTONDOWN)
                    {
                        id++;
                        if (id == int.MaxValue)
                        {
                            id = 0;
                        }
                        contact.State = Service.ContactState.New;
                    }
                    else if (wParam == (IntPtr)NativeMethods.MouseMessages.WM_LBUTTONUP)
                    {
                        contact.State = Service.ContactState.Removed;
                    }
                    else if (wParam == (IntPtr)NativeMethods.MouseMessages.WM_MOUSEMOVE)
                    {
                        contact.State = Service.ContactState.Moved;
                    }
                    contact.Id     = id;
                    contact.Bounds = new Rect(contact.Position.X - (contact.MajorAxis / 2), contact.Position.Y - (contact.MinorAxis / 2),
                                              contact.MajorAxis, contact.MinorAxis);
                    data.Contacts = new[] { contact };

                    if (contact.State == Service.ContactState.New)
                    {
                        contactPressent = true;
                    }

                    if (contactPressent)
                    {
                        Frame(data);
                    }

                    else if (contact.State == Service.ContactState.Removed)
                    {
                        contactPressent = false;
                    }
                }
            }
            return(NativeMethods.CallNextHookEx(hookId, nCode, wParam, lParam));
        }
Exemple #42
0
        internal bool HasSupports(out bool hasTraction, out PositionState state, out ContactData supportContact)
        {
            float maxDepth = -float.MaxValue;
            int deepestIndex = -1;
            if (tractionContacts.Count > 0)
            {
                //It has traction!
                //But is it too deep?
                //Find the deepest contact.
                for (int i = 0; i < tractionContacts.Count; i++)
                {
                    if (tractionContacts.Elements[i].PenetrationDepth > maxDepth)
                    {
                        maxDepth = tractionContacts.Elements[i].PenetrationDepth;
                        deepestIndex = i;
                    }
                }
                hasTraction = true;
                supportContact = tractionContacts.Elements[deepestIndex];
            }
            else if (supportContacts.Count > 0)
            {
                //It has support!
                //But is it too deep?
                //Find the deepest contact.

                for (int i = 0; i < supportContacts.Count; i++)
                {
                    if (supportContacts.Elements[i].PenetrationDepth > maxDepth)
                    {
                        maxDepth = supportContacts.Elements[i].PenetrationDepth;
                        deepestIndex = i;
                    }
                }
                hasTraction = false;
                supportContact = supportContacts.Elements[deepestIndex];
            }
            else
            {
                hasTraction = false;
                state = PositionState.NoHit;
                supportContact = new ContactData();
                return false;
            }
            //Check the depth.
            if (maxDepth > CollisionDetectionSettings.AllowedPenetration)
            {
                //It's too deep.
                state = PositionState.TooDeep;
            }
            else if (maxDepth < 0)
            {
                //The depth is negative, meaning it's separated.  This shouldn't happen with the initial implementation of the character controller,
                //but this case could conceivably occur in other usages of a system like this (or in a future version of the character),
                //so go ahead and handle it.
                state = PositionState.NoHit;
            }
            else
            {
                //The deepest contact appears to be very nicely aligned with the ground!
                //It's fully supported.
                state = PositionState.Accepted;
            }
            return true;
        }
        ///<summary>
        /// Updates the manifold.
        ///</summary>
        ///<param name="dt">Timestep duration.</param>
        public override void Update(float dt)
        {
            //Now, generate a contact between the two shapes.
            float               distance;
            Vector3             axis;
            BoxContactDataCache manifold;

            if (BoxBoxCollider.AreBoxesColliding(boxA.Shape, boxB.Shape, ref boxA.worldTransform, ref boxB.worldTransform, out distance, out axis, out manifold))
            {
                unsafe
                {
                    BoxContactData *manifoldPointer = &manifold.D1;
                    Vector3.Negate(ref axis, out axis);
                    var toRemove = new TinyList <int>();
                    for (int i = 0; i < contacts.Count; i++)
                    {
                        bool found = false;
                        for (int j = manifold.Count - 1; j >= 0; j--)
                        {
                            if (contacts.Elements[i].Id == manifoldPointer[j].Id)
                            {
                                found = true;
                                contacts.Elements[i].Validate();
                                //Update contact...
                                contacts.Elements[i].Position         = manifoldPointer[j].Position;
                                contacts.Elements[i].PenetrationDepth = -manifoldPointer[j].Depth;
                                contacts.Elements[i].Normal           = axis;
                                //Remove manifold entry
                                contacts.Elements[i].Validate();
                                manifold.RemoveAt(j);
                                break;
                            }
                        }
                        if (!found)
                        {//No match found
                            toRemove.Add(i);
                        }
                    }


                    //toRemove is sorted by increasing index.  Go backwards along it so that the indices are valid all the way through.
                    for (int i = toRemove.Count - 1; i >= 0; i--)
                    {
                        Remove(toRemove[i]);
                    }

                    //Add new contacts.
                    for (int i = 0; i < manifold.Count; i++)
                    {
                        var newContact = new ContactData
                        {
                            Position         = manifoldPointer[i].Position,
                            PenetrationDepth = -manifoldPointer[i].Depth,
                            Normal           = axis,
                            Id = manifoldPointer[i].Id
                        };

                        Add(ref newContact);
                    }
                }
            }
            else
            {
                //Not colliding, so get rid of it.
                for (int i = contacts.Count - 1; i >= 0; i--)
                {
                    Remove(i);
                }
            }
        }
        private bool DoExternalNear(TriangleShape triangle, out TinyStructList <ContactData> contactList)
        {
            Vector3 closestA, closestB;


            //Don't bother trying to do any clever caching.  The continually transforming simplex makes it very rarely useful.
            //TODO: Initialize the simplex of the GJK method using the 'true' center of the triangle.
            //If left unmodified, the simplex that is used in GJK will just be a point at 0,0,0, which of course is at the origin.
            //This causes an instant-out, always.  Not good!
            //By giving the contributing simplex the average centroid, it has a better guess.
            Vector3 triangleCentroid;

            Vector3.Add(ref triangle.vA, ref triangle.vB, out triangleCentroid);
            Vector3.Add(ref triangleCentroid, ref triangle.vC, out triangleCentroid);
            Vector3.Multiply(ref triangleCentroid, .33333333f, out triangleCentroid);

            var initialSimplex = new CachedSimplex {
                State = SimplexState.Point, LocalSimplexB = { A = triangleCentroid }
            };

            if (GJKToolbox.GetClosestPoints(convex, triangle, ref Toolbox.RigidIdentity, ref Toolbox.RigidIdentity, ref initialSimplex, out closestA, out closestB))
            {
                state = CollisionState.Deep;
                return(DoDeepContact(triangle, out contactList));
            }
            Vector3 displacement;

            Vector3.Subtract(ref closestB, ref closestA, out displacement);
            float distanceSquared = displacement.LengthSquared();
            float margin          = convex.collisionMargin + triangle.collisionMargin;

            contactList = new TinyStructList <ContactData>();
            if (distanceSquared < margin * margin)
            {
                //Try to generate a contact.
                var contact = new ContactData();

                //Determine if the normal points in the appropriate direction given the sidedness of the triangle.
                if (triangle.sidedness != TriangleSidedness.DoubleSided)
                {
                    Vector3 triangleNormal, ab, ac;
                    Vector3.Subtract(ref triangle.vB, ref triangle.vA, out ab);
                    Vector3.Subtract(ref triangle.vC, ref triangle.vA, out ac);
                    Vector3.Cross(ref ab, ref ac, out triangleNormal);
                    float dot;
                    Vector3.Dot(ref triangleNormal, ref displacement, out dot);
                    if (triangle.sidedness == TriangleSidedness.Clockwise && dot > 0)
                    {
                        return(false);
                    }
                    if (triangle.sidedness == TriangleSidedness.Counterclockwise && dot < 0)
                    {
                        return(false);
                    }
                }


                //Displacement is from A to B.  point = A + t * AB, where t = marginA / margin.
                if (margin > Toolbox.Epsilon)                                                                  //This can be zero! It would cause a NaN if unprotected.
                {
                    Vector3.Multiply(ref displacement, convex.collisionMargin / margin, out contact.Position); //t * AB
                }
                else
                {
                    contact.Position = new Vector3();
                }
                Vector3.Add(ref closestA, ref contact.Position, out contact.Position); //A + t * AB.



                contact.Normal = displacement;
                float distance = (float)Math.Sqrt(distanceSquared);
                Vector3.Divide(ref contact.Normal, distance, out contact.Normal);
                contact.PenetrationDepth = margin - distance;



                contactList.Add(ref contact);
                TryToEscape(triangle, ref contact.Position);
                return(true);
            }
            //Too far to make a contact- move back to separation.
            state = CollisionState.ExternalSeparated;
            return(false);
        }
Exemple #45
0
        private bool DoDeepContact(out ContactData contact)
        {
           
            #region Informed search
            if (previousState == CollisionState.Separated) //If it was shallow before, then its closest points will be used to find the normal.
            {
                //It's overlapping! Find the relative velocity at the point relative to the two objects.  The point is still in local space!
                //Vector3 velocityA;
                //Vector3.Cross(ref contact.Position, ref collidableA.entity.angularVelocity, out velocityA);
                //Vector3.Add(ref velocityA, ref collidableA.entity.linearVelocity, out velocityA);
                //Vector3 velocityB;
                //Vector3.Subtract(ref contact.Position, ref localTransformB.Position, out velocityB);
                //Vector3.Cross(ref velocityB, ref collidableB.entity.angularVelocity, out velocityB);
                //Vector3.Add(ref velocityB, ref collidableB.entity.linearVelocity, out velocityB);
                ////The velocity is negated because the direction so point backwards along the velocity.
                //Vector3.Subtract(ref velocityA, ref velocityB, out localDirection);

                //The above takes into account angular velocity, but linear velocity alone is a lot more stable and does the job just fine.
                if (collidableA.entity != null && collidableB.entity != null)
                    Vector3.Subtract(ref collidableA.entity.linearVelocity, ref collidableB.entity.linearVelocity, out localDirection);
                else
                    localDirection = localSeparatingAxis;

                if (localDirection.LengthSquared() < Toolbox.Epsilon)
                {
                    localDirection = Vector3.Up;
                }

            }
            if (MPRToolbox.GetContact(collidableA.Shape, collidableB.Shape, ref collidableA.worldTransform, ref collidableB.worldTransform, ref localDirection, out contact))
            {
                if (contact.PenetrationDepth < collidableA.Shape.collisionMargin + collidableB.Shape.collisionMargin)
                    state = CollisionState.ShallowContact;
                return true;
            }
            //This is rare, but could happen.
            state = CollisionState.Separated;
            return false;

            //if (MPRTesting.GetLocalOverlapPosition(collidableA.Shape, collidableB.Shape, ref localTransformB, out contact.Position))
            //{


            //    //First, try to use the heuristically found direction.  This comes from either the GJK shallow contact separating axis or from the relative velocity.
            //    Vector3 rayCastDirection;
            //    float lengthSquared = localDirection.LengthSquared();
            //    if (lengthSquared > Toolbox.Epsilon)
            //    {
            //        Vector3.Divide(ref localDirection, (float)Math.Sqrt(lengthSquared), out rayCastDirection);// (Vector3.Normalize(localDirection) + Vector3.Normalize(collidableB.worldTransform.Position - collidableA.worldTransform.Position)) / 2;
            //        MPRTesting.LocalSurfaceCast(collidableA.Shape, collidableB.Shape, ref localTransformB, ref rayCastDirection, out contact.PenetrationDepth, out contact.Normal);
            //    }
            //    else
            //    {
            //        contact.PenetrationDepth = float.MaxValue;
            //        contact.Normal = Toolbox.UpVector;
            //    }
            //    //Try the offset between the origins as a second option.  Sometimes this is a better choice than the relative velocity.
            //    //TODO: Could use the position-finding MPR iteration to find the A-B direction hit by continuing even after the origin has been found (optimization).
            //    Vector3 normalCandidate;
            //    float depthCandidate;
            //    lengthSquared = localTransformB.Position.LengthSquared();
            //    if (lengthSquared > Toolbox.Epsilon)
            //    {
            //        Vector3.Divide(ref localTransformB.Position, (float)Math.Sqrt(lengthSquared), out rayCastDirection);
            //        MPRTesting.LocalSurfaceCast(collidableA.Shape, collidableB.Shape, ref localTransformB, ref rayCastDirection, out depthCandidate, out normalCandidate);
            //        if (depthCandidate < contact.PenetrationDepth)
            //        {
            //            contact.Normal = normalCandidate;
            //        }
            //    }


            //    //Correct the penetration depth.
            //    MPRTesting.LocalSurfaceCast(collidableA.Shape, collidableB.Shape, ref localTransformB, ref contact.Normal, out contact.PenetrationDepth, out rayCastDirection);


            //    ////The local casting can optionally continue.  Eventually, it will converge to the local minimum.
            //    //while (true)
            //    //{
            //    //    MPRTesting.LocalSurfaceCast(collidableA.Shape, collidableB.Shape, ref localTransformB, ref contact.Normal, out depthCandidate, out normalCandidate);
            //    //    if (contact.PenetrationDepth - depthCandidate <= Toolbox.BigEpsilon)
            //    //        break;

            //    //    contact.PenetrationDepth = depthCandidate;
            //    //    contact.Normal = normalCandidate;
            //    //}

            //    contact.Id = -1;
            //    //we're still in local space! transform it all back.
            //    Matrix3X3 orientation;
            //    Matrix3X3.CreateFromQuaternion(ref collidableA.worldTransform.Orientation, out orientation);
            //    Matrix3X3.Transform(ref contact.Normal, ref orientation, out contact.Normal);
            //    //Vector3.Negate(ref contact.Normal, out contact.Normal);
            //    Matrix3X3.Transform(ref contact.Position, ref orientation, out contact.Position);
            //    Vector3.Add(ref contact.Position, ref collidableA.worldTransform.Position, out contact.Position);
            //    if (contact.PenetrationDepth < collidableA.Shape.collisionMargin + collidableB.Shape.collisionMargin)
            //        state = CollisionState.ShallowContact;
            //    return true;
            //}

            ////This is rare, but could happen.
            //state = CollisionState.Separated;
            //contact = new ContactData();
            //return false;
            #endregion

            #region Testing
            //RigidTransform localTransformB;
            //MinkowskiToolbox.GetLocalTransform(ref collidableA.worldTransform, ref collidableB.worldTransform, out localTransformB); 
            //contact.Id = -1;
            //if (MPRTesting.GetLocalOverlapPosition(collidableA.Shape, collidableB.Shape, ref localTransformB, out contact.Position))
            //{
            //    Vector3 rayCastDirection = localTransformB.Position;
            //    MPRTesting.LocalSurfaceCast(collidableA.Shape, collidableB.Shape, ref localTransformB, ref rayCastDirection, out contact.PenetrationDepth, out contact.Normal);
            //    MPRTesting.LocalSurfaceCast(collidableA.Shape, collidableB.Shape, ref localTransformB, ref contact.Normal, out contact.PenetrationDepth, out rayCastDirection);
            //    RigidTransform.Transform(ref contact.Position, ref collidableA.worldTransform, out contact.Position);
            //    Vector3.Transform(ref contact.Normal, ref collidableA.worldTransform.Orientation, out contact.Normal);
            //    return true;
            //}
            //contact.Normal = new Vector3();
            //contact.PenetrationDepth = 0;
            //return false;
            #endregion

            #region v0.15.2 and before
            //if (MPRToolbox.AreObjectsColliding(collidableA.Shape, collidableB.Shape, ref collidableA.worldTransform, ref collidableB.worldTransform, out contact))
            //{
            //    if (contact.PenetrationDepth < collidableA.Shape.collisionMargin + collidableB.Shape.collisionMargin)
            //        state = CollisionState.ShallowContact; //If it's emerged from the deep contact, we can go back to using the preferred GJK method.
            //    return true;
            //}
            ////This is rare, but could happen.
            //state = CollisionState.Separated;
            //return false;
            #endregion

        }
        bool AnalyzeCandidate(ref TriangleIndices indices, TrianglePairTester pairTester, ref ContactData contact)
        {
            switch (pairTester.GetRegion(ref contact))
            {
            case VoronoiRegion.A:
                //Add the contact.
                VertexContact vertexContact;
                GetNormal(ref contact.Normal, out vertexContact.CorrectedNormal);
                vertexContact.ContactData   = contact;
                vertexContact.Vertex        = indices.A;
                vertexContact.ShouldCorrect = pairTester.ShouldCorrectContactNormal;
                vertexContacts.Add(ref vertexContact);

                //Block all of the other voronoi regions.
                blockedEdgeRegions.Add(new Edge(indices.A, indices.B));
                blockedEdgeRegions.Add(new Edge(indices.B, indices.C));
                blockedEdgeRegions.Add(new Edge(indices.A, indices.C));
                blockedVertexRegions.Add(indices.B);
                blockedVertexRegions.Add(indices.C);

                break;

            case VoronoiRegion.B:
                //Add the contact.
                GetNormal(ref contact.Normal, out vertexContact.CorrectedNormal);
                vertexContact.ContactData   = contact;
                vertexContact.Vertex        = indices.B;
                vertexContact.ShouldCorrect = pairTester.ShouldCorrectContactNormal;
                vertexContacts.Add(ref vertexContact);

                //Block all of the other voronoi regions.
                blockedEdgeRegions.Add(new Edge(indices.A, indices.B));
                blockedEdgeRegions.Add(new Edge(indices.B, indices.C));
                blockedEdgeRegions.Add(new Edge(indices.A, indices.C));
                blockedVertexRegions.Add(indices.A);
                blockedVertexRegions.Add(indices.C);

                break;

            case VoronoiRegion.C:
                //Add the contact.
                GetNormal(ref contact.Normal, out vertexContact.CorrectedNormal);
                vertexContact.ContactData   = contact;
                vertexContact.Vertex        = indices.C;
                vertexContact.ShouldCorrect = pairTester.ShouldCorrectContactNormal;
                vertexContacts.Add(ref vertexContact);

                //Block all of the other voronoi regions.
                blockedEdgeRegions.Add(new Edge(indices.A, indices.B));
                blockedEdgeRegions.Add(new Edge(indices.B, indices.C));
                blockedEdgeRegions.Add(new Edge(indices.A, indices.C));
                blockedVertexRegions.Add(indices.A);
                blockedVertexRegions.Add(indices.B);

                break;

            case VoronoiRegion.AB:
                //Add the contact.
                EdgeContact edgeContact;
                GetNormal(ref contact.Normal, out edgeContact.CorrectedNormal);
                edgeContact.Edge          = new Edge(indices.A, indices.B);
                edgeContact.ContactData   = contact;
                edgeContact.ShouldCorrect = pairTester.ShouldCorrectContactNormal;
                edgeContacts.Add(ref edgeContact);

                //Block all of the other voronoi regions.
                blockedEdgeRegions.Add(new Edge(indices.B, indices.C));
                blockedEdgeRegions.Add(new Edge(indices.A, indices.C));
                blockedVertexRegions.Add(indices.A);
                blockedVertexRegions.Add(indices.B);
                blockedVertexRegions.Add(indices.C);
                break;

            case VoronoiRegion.AC:
                //Add the contact.
                GetNormal(ref contact.Normal, out edgeContact.CorrectedNormal);
                edgeContact.Edge          = new Edge(indices.A, indices.C);
                edgeContact.ContactData   = contact;
                edgeContact.ShouldCorrect = pairTester.ShouldCorrectContactNormal;
                edgeContacts.Add(ref edgeContact);

                //Block all of the other voronoi regions.
                blockedEdgeRegions.Add(new Edge(indices.A, indices.B));
                blockedEdgeRegions.Add(new Edge(indices.B, indices.C));
                blockedVertexRegions.Add(indices.A);
                blockedVertexRegions.Add(indices.B);
                blockedVertexRegions.Add(indices.C);
                break;

            case VoronoiRegion.BC:
                //Add the contact.
                GetNormal(ref contact.Normal, out edgeContact.CorrectedNormal);
                edgeContact.Edge          = new Edge(indices.B, indices.C);
                edgeContact.ContactData   = contact;
                edgeContact.ShouldCorrect = pairTester.ShouldCorrectContactNormal;
                edgeContacts.Add(ref edgeContact);

                //Block all of the other voronoi regions.
                blockedEdgeRegions.Add(new Edge(indices.A, indices.B));
                blockedEdgeRegions.Add(new Edge(indices.A, indices.C));
                blockedVertexRegions.Add(indices.A);
                blockedVertexRegions.Add(indices.B);
                blockedVertexRegions.Add(indices.C);
                break;

            default:
                //Block all of the other voronoi regions.
                blockedEdgeRegions.Add(new Edge(indices.A, indices.B));
                blockedEdgeRegions.Add(new Edge(indices.B, indices.C));
                blockedEdgeRegions.Add(new Edge(indices.A, indices.C));
                blockedVertexRegions.Add(indices.A);
                blockedVertexRegions.Add(indices.B);
                blockedVertexRegions.Add(indices.C);
                //Should add the contact.
                return(true);
            }


            return(false);
        }
 public IHttpActionResult UpdateContactData([FromBody] ContactData data)
 => this.Log(() => Operation.Try(() => data.ThrowIfNull(new MalformedApiArgumentsException()))
             .Then(opr => _account.UpdateContactData(data))
             .OperationResult(Request));
        protected override void ProcessCandidates(RawValueList <ContactData> candidates)
        {
            if (candidates.count == 0 && parentContactCount == 0 && Mesh.Shape.solidity == MobileMeshSolidity.Solid)
            {
                //If there's no new contacts on the mesh and it's supposed to be a solid,
                //then we must check the convex for containment within the shell.
                //We already know that it's not on the shell, meaning that the shape is either
                //far enough away outside the shell that there's no contact (and we're done),
                //or it's far enough inside the shell that the triangles cannot create contacts.

                //To find out which it is, raycast against the shell.

                Matrix3X3 orientation;
                Matrix3X3.CreateFromQuaternion(ref mesh.worldTransform.Orientation, out orientation);

                Ray ray;
                Vector3.Subtract(ref convex.worldTransform.Position, ref mesh.worldTransform.Position, out ray.Position);
                Matrix3X3.TransformTranspose(ref ray.Position, ref orientation, out ray.Position);

                //Cast from the current position back to the previous position.
                Vector3.Subtract(ref lastValidConvexPosition, ref ray.Position, out ray.Direction);
                float rayDirectionLength = ray.Direction.LengthSquared();
                if (rayDirectionLength < Toolbox.Epsilon)
                {
                    //The object may not have moved enough to normalize properly.  If so, choose something arbitrary.
                    //Try the direction from the center of the object to the convex's position.
                    ray.Direction      = ray.Position;
                    rayDirectionLength = ray.Direction.LengthSquared();
                    if (rayDirectionLength < Toolbox.Epsilon)
                    {
                        //This is unlikely; just pick something completely arbitrary then.
                        ray.Direction      = Vector3.Up;
                        rayDirectionLength = 1;
                    }
                }
                Vector3.Divide(ref ray.Direction, (float)Math.Sqrt(rayDirectionLength), out ray.Direction);

                RayHit hit;
                if (mesh.Shape.IsLocalRayOriginInMesh(ref ray, out hit))
                {
                    ContactData newContact = new ContactData();
                    newContact.Id = 2; //Give it a special id so that we know that it came from the inside.
                    Matrix3X3.Transform(ref ray.Position, ref orientation, out newContact.Position);
                    Vector3.Add(ref newContact.Position, ref mesh.worldTransform.Position, out newContact.Position);

                    newContact.Normal = hit.Normal;
                    newContact.Normal.Normalize();

                    float factor;
                    Vector3.Dot(ref ray.Direction, ref newContact.Normal, out factor);
                    newContact.PenetrationDepth = -factor * hit.T + convex.Shape.minimumRadius;

                    Matrix3X3.Transform(ref newContact.Normal, ref orientation, out newContact.Normal);

                    //Do not yet create a new contact.  Check to see if an 'inner contact' with id == 2 already exists.
                    bool addContact = true;
                    for (int i = 0; i < contacts.count; i++)
                    {
                        if (contacts.Elements[i].Id == 2)
                        {
                            contacts.Elements[i].Position                   = newContact.Position;
                            contacts.Elements[i].Normal                     = newContact.Normal;
                            contacts.Elements[i].PenetrationDepth           = newContact.PenetrationDepth;
                            supplementData.Elements[i].BasePenetrationDepth = newContact.PenetrationDepth;
                            supplementData.Elements[i].LocalOffsetA         = new Vector3();
                            supplementData.Elements[i].LocalOffsetB         = ray.Position; //convex local position in mesh.
                            addContact = false;
                            break;
                        }
                    }
                    if (addContact && contacts.count == 0)
                    {
                        Add(ref newContact);
                    }
                    previousDepth = newContact.PenetrationDepth;
                }
                else
                {
                    //It's possible that we had a false negative.  The previous frame may have been in deep intersection, and this frame just failed to come to the same conclusion.
                    //If we set the target location to the current location, the object will never escape the mesh.  Instead, only do that if two frames agree that we are no longer colliding.
                    if (previousDepth > 0)
                    {
                        //We're not touching the mesh.
                        lastValidConvexPosition = ray.Position;
                    }
                    previousDepth = 0;
                }
            }
        }
 protected override void Add(ref ContactData contactCandidate)
 {
     ContactSupplementData supplement;
     supplement.BasePenetrationDepth = contactCandidate.PenetrationDepth;
     RigidTransform convexTransform = convex.WorldTransform;
     RigidTransform gridTransform = new RigidTransform(mesh.Position);
     RigidTransform.TransformByInverse(ref contactCandidate.Position, ref convexTransform, out supplement.LocalOffsetA);
     RigidTransform.TransformByInverse(ref contactCandidate.Position, ref gridTransform, out supplement.LocalOffsetB);
     supplementData.Add(ref supplement);
     base.Add(ref contactCandidate);
 }
Exemple #50
0
        internal bool HasSupports(out bool hasTraction, out PositionState state, out ContactData supportContact)
        {
            float maxDepth     = -float.MaxValue;
            int   deepestIndex = -1;

            if (tractionContacts.Count > 0)
            {
                //It has traction!
                //But is it too deep?
                //Find the deepest contact.
                for (int i = 0; i < tractionContacts.Count; i++)
                {
                    if (tractionContacts.Elements[i].PenetrationDepth > maxDepth)
                    {
                        maxDepth     = tractionContacts.Elements[i].PenetrationDepth;
                        deepestIndex = i;
                    }
                }
                hasTraction    = true;
                supportContact = tractionContacts.Elements[deepestIndex];
            }
            else if (supportContacts.Count > 0)
            {
                //It has support!
                //But is it too deep?
                //Find the deepest contact.

                for (int i = 0; i < supportContacts.Count; i++)
                {
                    if (supportContacts.Elements[i].PenetrationDepth > maxDepth)
                    {
                        maxDepth     = supportContacts.Elements[i].PenetrationDepth;
                        deepestIndex = i;
                    }
                }
                hasTraction    = false;
                supportContact = supportContacts.Elements[deepestIndex];
            }
            else
            {
                hasTraction    = false;
                state          = PositionState.NoHit;
                supportContact = new ContactData();
                return(false);
            }
            //Check the depth.
            if (maxDepth > CollisionDetectionSettings.AllowedPenetration)
            {
                //It's too deep.
                state = PositionState.TooDeep;
            }
            else if (maxDepth < 0)
            {
                //The depth is negative, meaning it's separated.  This shouldn't happen with the initial implementation of the character controller,
                //but this case could conceivably occur in other usages of a system like this (or in a future version of the character),
                //so go ahead and handle it.
                state = PositionState.NoHit;
            }
            else
            {
                //The deepest contact appears to be very nicely aligned with the ground!
                //It's fully supported.
                state = PositionState.Accepted;
            }
            return(true);
        }
        private bool TryInnerSphereContact(TriangleShape triangle, out ContactData contact)
        {
            Vector3 closestPoint;

            Toolbox.GetClosestPointOnTriangleToPoint(ref triangle.vA, ref triangle.vB, ref triangle.vC, ref Toolbox.ZeroVector, out closestPoint);
            float length        = closestPoint.LengthSquared();
            float minimumRadius = convex.MinimumRadius * (MotionSettings.CoreShapeScaling + .01f);

            if (length < minimumRadius * minimumRadius)
            {
                Vector3 triangleNormal, ab, ac;
                Vector3.Subtract(ref triangle.vB, ref triangle.vA, out ab);
                Vector3.Subtract(ref triangle.vC, ref triangle.vA, out ac);
                Vector3.Cross(ref ab, ref ac, out triangleNormal);
                float dot;
                Vector3.Dot(ref closestPoint, ref triangleNormal, out dot);
                if ((triangle.sidedness == TriangleSidedness.Clockwise && dot > 0) || (triangle.sidedness == TriangleSidedness.Counterclockwise && dot < 0))
                {
                    //Normal was facing the wrong way.
                    contact = new ContactData();
                    return(false);
                }

                length           = (float)Math.Sqrt(length);
                contact.Position = closestPoint;

                if (length > Toolbox.Epsilon) //Watch out for NaN's!
                {
                    Vector3.Divide(ref closestPoint, length, out contact.Normal);
                }
                else
                {
                    //The direction is undefined.  Use the triangle's normal.
                    //One sided triangles can only face in the appropriate direction.
                    float normalLength = triangleNormal.LengthSquared();
                    if (triangleNormal.LengthSquared() > Toolbox.Epsilon)
                    {
                        Vector3.Divide(ref triangleNormal, (float)Math.Sqrt(normalLength), out triangleNormal);
                        if (triangle.sidedness == TriangleSidedness.Clockwise)
                        {
                            contact.Normal = triangleNormal;
                        }
                        else
                        {
                            Vector3.Negate(ref triangleNormal, out contact.Normal);
                        }
                    }
                    else
                    {
                        //Degenerate triangle!
                        contact = new ContactData();
                        return(false);
                    }
                }

                //Compute the actual depth of the contact.
                //This is conservative; the minimum radius is guaranteed to be no larger than the shape itself.
                //But that's ok- this is strictly a deep contact protection scheme. Other contacts will make the objects separate.
                contact.PenetrationDepth = convex.MinimumRadius - length;
                contact.Id = -1;
                return(true);
            }
            contact = new ContactData();
            return(false);
        }
Exemple #52
0
 public ContactRepository()
 {
     data = ContactData.getInstance();
 }
Exemple #53
0
        /// <summary>
        /// Gets the Contact Update Data
        /// </summary>
        /// <param name="message"></param>
        /// <param name="callType"></param>
        /// <param name="duration"></param>
        /// <returns></returns>
        public ContactData GetContactVoiceUpdateData(IMessage message, string eventName, SFDCCallType callType, string duration, string notes)
        {
            try
            {
                this.logger.Info("GetContactVoiceUpdateData :  Reading contact Update Data.....");
                this.logger.Info("GetContactVoiceUpdateData :  Event Name : " + message.Name);
                dynamic popupEvent = Convert.ChangeType(message, message.GetType());
                if (popupEvent != null)
                {
                    ContactData contact = new ContactData();

                    #region Collect contact Data

                    contact.ObjectName = contactVoiceOptions.ObjectName;

                    if (callType == SFDCCallType.InboundVoice)
                    {
                        if (contactVoiceOptions.InboundCanUpdateLog)
                        {
                            contact.UpdateActivityLog     = true;
                            contact.UpdateActivityLogData = this.sfdcUtility.GetUpdateActivityLogData(this.ContactLogConfig, popupEvent, callType, duration, voiceComments: notes);
                            if (!string.IsNullOrWhiteSpace(contactVoiceOptions.VoiceAppendActivityLogEventNames) && contactVoiceOptions.VoiceAppendActivityLogEventNames.Contains(eventName))
                            {
                                contact.AppendActivityLogData = this.sfdcUtility.GetUpdateActivityLogData(this.ContactLogConfig, null, callType, duration, voiceComments: notes, isAppendLogData: true);
                            }
                        }
                    }
                    else if (callType == SFDCCallType.OutboundVoiceSuccess || callType == SFDCCallType.OutboundVoiceFailure)
                    {
                        if (contactVoiceOptions.OutboundCanUpdateLog)
                        {
                            contact.UpdateActivityLog     = true;
                            contact.UpdateActivityLogData = this.sfdcUtility.GetUpdateActivityLogData(this.ContactLogConfig, popupEvent, callType, duration, voiceComments: notes);
                            if (!string.IsNullOrWhiteSpace(contactVoiceOptions.VoiceAppendActivityLogEventNames) && contactVoiceOptions.VoiceAppendActivityLogEventNames.Contains(eventName))
                            {
                                contact.AppendActivityLogData = this.sfdcUtility.GetUpdateActivityLogData(this.ContactLogConfig, null, callType, duration, voiceComments: notes, isAppendLogData: true);
                            }
                        }
                    }
                    else if (callType == SFDCCallType.ConsultVoiceReceived)
                    {
                        if (contactVoiceOptions.ConsultCanUpdateLog)
                        {
                            contact.UpdateActivityLog     = true;
                            contact.UpdateActivityLogData = this.sfdcUtility.GetUpdateActivityLogData(this.ContactLogConfig, popupEvent, callType, duration, voiceComments: notes);
                            if (!string.IsNullOrWhiteSpace(contactVoiceOptions.VoiceAppendActivityLogEventNames) && contactVoiceOptions.VoiceAppendActivityLogEventNames.Contains(eventName))
                            {
                                contact.AppendActivityLogData = this.sfdcUtility.GetUpdateActivityLogData(this.ContactLogConfig, null, callType, duration, voiceComments: notes, isAppendLogData: true);
                            }
                        }
                    }

                    if (contactVoiceOptions.CanUpdateRecordData)
                    {
                        contact.UpdateRecordFields     = true;
                        contact.UpdateRecordFieldsData = this.sfdcUtility.GetUpdateActivityLogData(this.ContactVoiceRecordConfig, popupEvent, callType, duration);
                    }

                    #endregion Collect contact Data

                    return(contact);
                }
            }
            catch (Exception generalException)
            {
                this.logger.Error("GetContactVoiceUpdateData : Error occurred while reading contact Data : " + generalException.ToString());
            }
            return(null);
        }
        public override VoronoiRegion GetRegion(TriangleShape triangle, ref ContactData contact)
        {
            //Deep contact can produce non-triangle normals while still being within the triangle.
            //To solve this problem, find the voronoi region to which the contact belongs using its normal.
            //The voronoi region will be either the most extreme vertex, or the edge that includes
            //the first and second most extreme vertices.
            //If the normal dotted with an extreme edge direction is near 0, then it belongs to the edge.
            //Otherwise, it belongs to the vertex.
            //MPR tends to produce 'approximate' normals, though.
            //Use a fairly forgiving epsilon.
            float dotA, dotB, dotC;

            Vector3.Dot(ref triangle.vA, ref contact.Normal, out dotA);
            Vector3.Dot(ref triangle.vB, ref contact.Normal, out dotB);
            Vector3.Dot(ref triangle.vC, ref contact.Normal, out dotC);

            //Since normal points from convex to triangle always, reverse dot signs.
            dotA = -dotA;
            dotB = -dotB;
            dotC = -dotC;


            float       faceEpsilon = .01f;
            const float edgeEpsilon = .01f;

            float   edgeDot;
            Vector3 edgeDirection;

            if (dotA > dotB && dotA > dotC)
            {
                //A is extreme.
                if (dotB > dotC)
                {
                    //B is second most extreme.
                    if (Math.Abs(dotA - dotC) < faceEpsilon)
                    {
                        //The normal is basically a face normal.  This can happen at the edges occasionally.
                        return(VoronoiRegion.ABC);
                    }
                    else
                    {
                        Vector3.Subtract(ref triangle.vB, ref triangle.vA, out edgeDirection);
                        Vector3.Dot(ref edgeDirection, ref contact.Normal, out edgeDot);
                        if (edgeDot * edgeDot < edgeDirection.LengthSquared() * edgeEpsilon)
                        {
                            return(VoronoiRegion.AB);
                        }
                        else
                        {
                            return(VoronoiRegion.A);
                        }
                    }
                }
                else
                {
                    //C is second most extreme.
                    if (Math.Abs(dotA - dotB) < faceEpsilon)
                    {
                        //The normal is basically a face normal.  This can happen at the edges occasionally.
                        return(VoronoiRegion.ABC);
                    }
                    else
                    {
                        Vector3.Subtract(ref triangle.vC, ref triangle.vA, out edgeDirection);
                        Vector3.Dot(ref edgeDirection, ref contact.Normal, out edgeDot);
                        if (edgeDot * edgeDot < edgeDirection.LengthSquared() * edgeEpsilon)
                        {
                            return(VoronoiRegion.AC);
                        }
                        else
                        {
                            return(VoronoiRegion.A);
                        }
                    }
                }
            }
            else if (dotB > dotC)
            {
                //B is extreme.
                if (dotC > dotA)
                {
                    //C is second most extreme.
                    if (Math.Abs(dotB - dotA) < faceEpsilon)
                    {
                        //The normal is basically a face normal.  This can happen at the edges occasionally.
                        return(VoronoiRegion.ABC);
                    }
                    else
                    {
                        Vector3.Subtract(ref triangle.vC, ref triangle.vB, out edgeDirection);
                        Vector3.Dot(ref edgeDirection, ref contact.Normal, out edgeDot);
                        if (edgeDot * edgeDot < edgeDirection.LengthSquared() * edgeEpsilon)
                        {
                            return(VoronoiRegion.BC);
                        }
                        else
                        {
                            return(VoronoiRegion.B);
                        }
                    }
                }
                else
                {
                    //A is second most extreme.
                    if (Math.Abs(dotB - dotC) < faceEpsilon)
                    {
                        //The normal is basically a face normal.  This can happen at the edges occasionally.
                        return(VoronoiRegion.ABC);
                    }
                    else
                    {
                        Vector3.Subtract(ref triangle.vA, ref triangle.vB, out edgeDirection);
                        Vector3.Dot(ref edgeDirection, ref contact.Normal, out edgeDot);
                        if (edgeDot * edgeDot < edgeDirection.LengthSquared() * edgeEpsilon)
                        {
                            return(VoronoiRegion.AB);
                        }
                        else
                        {
                            return(VoronoiRegion.B);
                        }
                    }
                }
            }
            else
            {
                //C is extreme.
                if (dotA > dotB)
                {
                    //A is second most extreme.
                    if (Math.Abs(dotC - dotB) < faceEpsilon)
                    {
                        //The normal is basically a face normal.  This can happen at the edges occasionally.
                        return(VoronoiRegion.ABC);
                    }
                    else
                    {
                        Vector3.Subtract(ref triangle.vA, ref triangle.vC, out edgeDirection);
                        Vector3.Dot(ref edgeDirection, ref contact.Normal, out edgeDot);
                        if (edgeDot * edgeDot < edgeDirection.LengthSquared() * edgeEpsilon)
                        {
                            return(VoronoiRegion.AC);
                        }
                        else
                        {
                            return(VoronoiRegion.C);
                        }
                    }
                }
                else
                {
                    //B is second most extreme.
                    if (Math.Abs(dotC - dotA) < faceEpsilon)
                    {
                        //The normal is basically a face normal.  This can happen at the edges occasionally.
                        return(VoronoiRegion.ABC);
                    }
                    else
                    {
                        Vector3.Subtract(ref triangle.vB, ref triangle.vC, out edgeDirection);
                        Vector3.Dot(ref edgeDirection, ref contact.Normal, out edgeDot);
                        if (edgeDot * edgeDot < edgeDirection.LengthSquared() * edgeEpsilon)
                        {
                            return(VoronoiRegion.BC);
                        }
                        else
                        {
                            return(VoronoiRegion.C);
                        }
                    }
                }
            }
        }
Exemple #55
0
        /// <summary>
        /// Gets Contact Popup Data
        /// </summary>
        /// <param name="message"></param>
        /// <param name="callType"></param>
        /// <returns></returns>
        public ContactData GetContactVoicePopupData(IMessage message, SFDCCallType callType)
        {
            try
            {
                this.logger.Info("GetContactVoicePopupData :  Reading Contact Popup Data.....");
                this.logger.Info("GetContactVoicePopupData :  Event Name : " + message.Name);
                this.logger.Info("GetContactVoicePopupData :  CallType Name : " + callType.ToString());
                dynamic _popupEvent = Convert.ChangeType(message, message.GetType());
                if (_popupEvent != null)
                {
                    ContactData _contact = new ContactData();

                    #region Collect contact Data

                    _contact.SearchData                             = this.sfdcUtilityHelper.GetVoiceSearchValue(contactVoiceOptions, message, callType);
                    _contact.ObjectName                             = contactVoiceOptions.ObjectName;
                    _contact.NoRecordFound                          = SFDCObjectHelper.GetNoRecordFoundAction(callType, contactVoiceOptions);
                    _contact.MultipleMatchRecord                    = SFDCObjectHelper.GetMultiMatchRecordAction(callType, contactVoiceOptions);
                    _contact.NewRecordFieldIds                      = contactVoiceOptions.NewrecordFieldIds;
                    _contact.SearchCondition                        = contactVoiceOptions.SearchCondition;
                    _contact.CreateLogForNewRecord                  = contactVoiceOptions.CanCreateLogForNewRecordCreate;
                    _contact.MaxRecordOpenCount                     = contactVoiceOptions.MaxNosRecordOpen;
                    _contact.SearchpageMode                         = contactVoiceOptions.SearchPageMode;
                    _contact.PhoneNumberSearchFormat                = contactVoiceOptions.PhoneNumberSearchFormat;
                    _contact.CanCreateNoRecordActivityLog           = SFDCObjectHelper.GetCanCreateProfileActivity(callType, contactVoiceOptions, true);
                    _contact.CanPopupNoRecordActivityLog            = SFDCObjectHelper.GetCanPopupProfileActivity(callType, contactVoiceOptions, true);
                    _contact.CanCreateMultiMatchActivityLog         = SFDCObjectHelper.GetCanCreateProfileActivity(callType, contactVoiceOptions);
                    _contact.CanPopupMultiMatchActivityLog          = SFDCObjectHelper.GetCanPopupProfileActivity(callType, contactVoiceOptions);
                    _contact.CanCreateProfileActivityforInbNoRecord = contactVoiceOptions.CanCreateProfileActivityforInbNoRecord;
                    _contact.CanCreateProfileActivityforOutNoRecord = contactVoiceOptions.CanCreateProfileActivityforOutNoRecord;
                    _contact.CanCreateProfileActivityforConNoRecord = contactVoiceOptions.CanCreateProfileActivityforConNoRecord;
                    if (_contact.NoRecordFound.Equals("createnew") && this.ContactVoiceRecordConfig != null)
                    {
                        _contact.CreateRecordFieldData = this.sfdcUtility.GetCreateActivityLogData(this.ContactVoiceRecordConfig, message, callType);
                    }
                    if (callType == SFDCCallType.InboundVoice)
                    {
                        if (contactVoiceOptions.InboundCanCreateLog)
                        {
                            _contact.CreateActvityLog = true;
                            _contact.ActivityLogData  = this.sfdcUtility.GetCreateActivityLogData(this.ContactLogConfig, _popupEvent, callType);
                        }
                    }
                    else if (callType == SFDCCallType.OutboundVoiceSuccess)
                    {
                        if (contactVoiceOptions.OutboundCanCreateLog)
                        {
                            _contact.CreateActvityLog = true;
                            _contact.ActivityLogData  = this.sfdcUtility.GetCreateActivityLogData(this.ContactLogConfig, _popupEvent, callType);
                        }
                    }
                    else if (callType == SFDCCallType.OutboundVoiceFailure)
                    {
                        if (contactVoiceOptions.OutboundFailureCanCreateLog)
                        {
                            _contact.CreateActvityLog = true;
                            _contact.ActivityLogData  = this.sfdcUtility.GetCreateActivityLogData(this.ContactLogConfig, _popupEvent, callType);
                        }
                    }
                    else if (callType == SFDCCallType.ConsultVoiceReceived)
                    {
                        if (contactVoiceOptions.ConsultCanCreateLog)
                        {
                            _contact.CreateActvityLog = true;
                            _contact.ActivityLogData  = this.sfdcUtility.GetCreateActivityLogData(this.ContactLogConfig, _popupEvent, callType);
                        }
                    }
                    return(_contact);
                }

                #endregion Collect contact Data
            }
            catch (Exception generalException)
            {
                this.logger.Error("GetContactVoicePopupData : Error occurred while reading Contact Data on EventRinging Event : " + generalException.ToString());
            }
            return(null);
        }
Exemple #56
0
        private bool DoShallowContact(out ContactData contact)
        {
            Vector3 closestA, closestB;

            //RigidTransform transform = RigidTransform.Identity;
            //Vector3 closestAnew, closestBnew;
            //CachedSimplex cachedTest = cachedSimplex;
            //bool intersecting = GJKToolbox.GetClosestPoints(informationA.Shape, informationB.Shape, ref informationA.worldTransform, ref informationB.worldTransform, ref cachedTest, out closestAnew, out closestBnew);

            ////bool otherIntersecting = OldGJKVerifier.GetClosestPointsBetweenObjects(informationA.Shape, informationB.Shape, ref informationA.worldTransform, ref informationB.worldTransform, 0, 0, out closestA, out closestB);
            //bool otherIntersecting = GJKToolbox.GetClosestPoints(informationA.Shape, informationB.Shape, ref informationA.worldTransform, ref informationB.worldTransform, out closestA, out closestB);

            //Vector3 closestAold, closestBold;
            //bool oldIntersecting = OldGJKVerifier.GetClosestPointsBetweenObjects(informationA.Shape, informationB.Shape, ref informationA.worldTransform, ref informationB.worldTransform, 0, 0, out closestAold, out closestBold);

            //if (otherIntersecting != intersecting || (!otherIntersecting && !intersecting &&
            //    Vector3.DistanceSquared(closestAnew, closestBnew) - Vector3.DistanceSquared(closestA, closestB) > .0001f &&
            //    (Vector3.DistanceSquared(closestA, closestAnew) > .0001f ||
            //    Vector3.DistanceSquared(closestB, closestBnew) > .0001f)))// ||
            //    //Math.Abs(Vector3.Dot(closestB - closestA, closestBnew - closestAnew) - Vector3.Dot(closestB - closestA, closestB - closestA)) > Toolbox.Epsilon)))
            //    Debug.WriteLine("Break.");

            //Vector3 sub;
            //Vector3.Subtract(ref closestA, ref closestB, out sub);
            //if (sub.LengthSquared() < Toolbox.Epsilon)

            if (UseSimplexCaching)
            {
                GJKToolbox.GetClosestPoints(collidableA.Shape, collidableB.Shape, ref collidableA.worldTransform, ref collidableB.worldTransform, ref cachedSimplex, out closestA, out closestB);
            }
            else
            {
                //The initialization of the pair creates a pretty decent simplex to start from.
                //Just don't try to update it.
                CachedSimplex preInitializedSimplex = cachedSimplex;
                GJKToolbox.GetClosestPoints(collidableA.Shape, collidableB.Shape, ref collidableA.worldTransform, ref collidableB.worldTransform, ref preInitializedSimplex, out closestA, out closestB);
            }

            Vector3 displacement;

            Vector3.Subtract(ref closestB, ref closestA, out displacement);
            float distanceSquared = displacement.LengthSquared();

            if (distanceSquared < Toolbox.Epsilon)
            {
                state = CollisionState.DeepContact;
                return(DoDeepContact(out contact));
            }

            localDirection = displacement; //Use this as the direction for future deep contacts.
            float margin = collidableA.Shape.collisionMargin + collidableB.Shape.collisionMargin;


            if (distanceSquared < margin * margin)
            {
                //Generate a contact.
                contact = new ContactData();
                //Displacement is from A to B.  point = A + t * AB, where t = marginA / margin.
                if (margin > Toolbox.Epsilon)                                                                             //Avoid a NaN!
                {
                    Vector3.Multiply(ref displacement, collidableA.Shape.collisionMargin / margin, out contact.Position); //t * AB
                }
                else
                {
                    contact.Position = new Vector3();
                }

                Vector3.Add(ref closestA, ref contact.Position, out contact.Position); //A + t * AB.

                contact.Normal = displacement;
                float distance = (float)Math.Sqrt(distanceSquared);
                Vector3.Divide(ref contact.Normal, distance, out contact.Normal);
                contact.PenetrationDepth = margin - distance;
                return(true);
            }
            //Too shallow to make a contact- move back to separation.
            state   = CollisionState.Separated;
            contact = new ContactData();
            return(false);
        }
        ///<summary>
        /// Tests if a box and sphere are colliding.
        ///</summary>
        ///<param name="box">Box to test.</param>
        ///<param name="sphere">Sphere to test.</param>
        ///<param name="boxTransform">Transform to apply to the box.</param>
        ///<param name="spherePosition">Transform to apply to the sphere.</param>
        ///<param name="contact">Contact point between the shapes, if any.</param>
        ///<returns>Whether or not the shapes were colliding.</returns>
        public static bool AreShapesColliding(BoxShape box, SphereShape sphere, ref RigidTransform boxTransform, ref Vector3f spherePosition, out ContactData contact)
        {
            contact = new ContactData();

            Vector3f localPosition;

            RigidTransform.TransformByInverse(ref spherePosition, ref boxTransform, out localPosition);
#if !WINDOWS
            Vector3f localClosestPoint = new Vector3f();
#else
            Vector3f localClosestPoint;
#endif
            localClosestPoint.X = MathHelper.Clamp(localPosition.X, -box.halfWidth, box.halfWidth);
            localClosestPoint.Y = MathHelper.Clamp(localPosition.Y, -box.halfHeight, box.halfHeight);
            localClosestPoint.Z = MathHelper.Clamp(localPosition.Z, -box.halfLength, box.halfLength);

            RigidTransform.Transform(ref localClosestPoint, ref boxTransform, out contact.Position);

            Vector3f offset;
            Vector3f.Subtract(ref spherePosition, ref contact.Position, out offset);
            float offsetLength = offset.LengthSquared;

            if (offsetLength > (sphere.collisionMargin + CollisionDetectionSettings.maximumContactDistance) * (sphere.collisionMargin + CollisionDetectionSettings.maximumContactDistance))
            {
                return(false);
            }

            //Colliding.
            if (offsetLength > MathHelper.Epsilon)
            {
                offsetLength = (float)Math.Sqrt(offsetLength);
                //Outside of the box.
                Vector3f.Divide(ref offset, offsetLength, out contact.Normal);
                contact.PenetrationDepth = sphere.collisionMargin - offsetLength;
            }
            else
            {
                //Inside of the box.
                Vector3f penetrationDepths;
                penetrationDepths.X = localClosestPoint.X < 0 ? localClosestPoint.X + box.halfWidth : box.halfWidth - localClosestPoint.X;
                penetrationDepths.Y = localClosestPoint.Y < 0 ? localClosestPoint.Y + box.halfHeight : box.halfHeight - localClosestPoint.Y;
                penetrationDepths.Z = localClosestPoint.Z < 0 ? localClosestPoint.Z + box.halfLength : box.halfLength - localClosestPoint.Z;
                if (penetrationDepths.X < penetrationDepths.Y && penetrationDepths.X < penetrationDepths.Z)
                {
                    contact.Normal           = localClosestPoint.X > 0 ? Toolbox.RightVector : Toolbox.LeftVector;
                    contact.PenetrationDepth = penetrationDepths.X;
                }
                else if (penetrationDepths.Y < penetrationDepths.Z)
                {
                    contact.Normal           = localClosestPoint.Y > 0 ? Toolbox.UpVector : Toolbox.DownVector;
                    contact.PenetrationDepth = penetrationDepths.Y;
                }
                else
                {
                    contact.Normal           = localClosestPoint.Z > 0 ? Toolbox.BackVector : Toolbox.ForwardVector;
                    contact.PenetrationDepth = penetrationDepths.Z;
                }
                contact.PenetrationDepth += sphere.collisionMargin;
                Vector3f.Transform(ref contact.Normal, ref boxTransform.Orientation, out contact.Normal);
            }


            return(true);
        }
Exemple #58
0
        private bool DoDeepContact(out ContactData contact)
        {
            #region Informed search
            if (previousState == CollisionState.Separated) //If it was shallow before, then its closest points will be used to find the normal.
            {
                //It's overlapping! Find the relative velocity at the point relative to the two objects.  The point is still in local space!
                //Vector3 velocityA;
                //Vector3.Cross(ref contact.Position, ref collidableA.entity.angularVelocity, out velocityA);
                //Vector3.Add(ref velocityA, ref collidableA.entity.linearVelocity, out velocityA);
                //Vector3 velocityB;
                //Vector3.Subtract(ref contact.Position, ref localTransformB.Position, out velocityB);
                //Vector3.Cross(ref velocityB, ref collidableB.entity.angularVelocity, out velocityB);
                //Vector3.Add(ref velocityB, ref collidableB.entity.linearVelocity, out velocityB);
                ////The velocity is negated because the direction so point backwards along the velocity.
                //Vector3.Subtract(ref velocityA, ref velocityB, out localDirection);

                //The above takes into account angular velocity, but linear velocity alone is a lot more stable and does the job just fine.
                if (collidableA.entity != null && collidableB.entity != null)
                {
                    Vector3.Subtract(ref collidableA.entity.linearVelocity, ref collidableB.entity.linearVelocity, out localDirection);
                }
                else
                {
                    localDirection = localSeparatingAxis;
                }

                if (localDirection.LengthSquared() < Toolbox.Epsilon)
                {
                    localDirection = Vector3.Up;
                }
            }
            if (MPRToolbox.GetContact(collidableA.Shape, collidableB.Shape, ref collidableA.worldTransform, ref collidableB.worldTransform, ref localDirection, out contact))
            {
                if (contact.PenetrationDepth < collidableA.Shape.collisionMargin + collidableB.Shape.collisionMargin)
                {
                    state = CollisionState.ShallowContact;
                }
                return(true);
            }
            //This is rare, but could happen.
            state = CollisionState.Separated;
            return(false);

            //if (MPRTesting.GetLocalOverlapPosition(collidableA.Shape, collidableB.Shape, ref localTransformB, out contact.Position))
            //{


            //    //First, try to use the heuristically found direction.  This comes from either the GJK shallow contact separating axis or from the relative velocity.
            //    Vector3 rayCastDirection;
            //    float lengthSquared = localDirection.LengthSquared();
            //    if (lengthSquared > Toolbox.Epsilon)
            //    {
            //        Vector3.Divide(ref localDirection, (float)Math.Sqrt(lengthSquared), out rayCastDirection);// (Vector3.Normalize(localDirection) + Vector3.Normalize(collidableB.worldTransform.Position - collidableA.worldTransform.Position)) / 2;
            //        MPRTesting.LocalSurfaceCast(collidableA.Shape, collidableB.Shape, ref localTransformB, ref rayCastDirection, out contact.PenetrationDepth, out contact.Normal);
            //    }
            //    else
            //    {
            //        contact.PenetrationDepth = float.MaxValue;
            //        contact.Normal = Toolbox.UpVector;
            //    }
            //    //Try the offset between the origins as a second option.  Sometimes this is a better choice than the relative velocity.
            //    //TODO: Could use the position-finding MPR iteration to find the A-B direction hit by continuing even after the origin has been found (optimization).
            //    Vector3 normalCandidate;
            //    float depthCandidate;
            //    lengthSquared = localTransformB.Position.LengthSquared();
            //    if (lengthSquared > Toolbox.Epsilon)
            //    {
            //        Vector3.Divide(ref localTransformB.Position, (float)Math.Sqrt(lengthSquared), out rayCastDirection);
            //        MPRTesting.LocalSurfaceCast(collidableA.Shape, collidableB.Shape, ref localTransformB, ref rayCastDirection, out depthCandidate, out normalCandidate);
            //        if (depthCandidate < contact.PenetrationDepth)
            //        {
            //            contact.Normal = normalCandidate;
            //        }
            //    }


            //    //Correct the penetration depth.
            //    MPRTesting.LocalSurfaceCast(collidableA.Shape, collidableB.Shape, ref localTransformB, ref contact.Normal, out contact.PenetrationDepth, out rayCastDirection);


            //    ////The local casting can optionally continue.  Eventually, it will converge to the local minimum.
            //    //while (true)
            //    //{
            //    //    MPRTesting.LocalSurfaceCast(collidableA.Shape, collidableB.Shape, ref localTransformB, ref contact.Normal, out depthCandidate, out normalCandidate);
            //    //    if (contact.PenetrationDepth - depthCandidate <= Toolbox.BigEpsilon)
            //    //        break;

            //    //    contact.PenetrationDepth = depthCandidate;
            //    //    contact.Normal = normalCandidate;
            //    //}

            //    contact.Id = -1;
            //    //we're still in local space! transform it all back.
            //    Matrix3X3 orientation;
            //    Matrix3X3.CreateFromQuaternion(ref collidableA.worldTransform.Orientation, out orientation);
            //    Matrix3X3.Transform(ref contact.Normal, ref orientation, out contact.Normal);
            //    //Vector3.Negate(ref contact.Normal, out contact.Normal);
            //    Matrix3X3.Transform(ref contact.Position, ref orientation, out contact.Position);
            //    Vector3.Add(ref contact.Position, ref collidableA.worldTransform.Position, out contact.Position);
            //    if (contact.PenetrationDepth < collidableA.Shape.collisionMargin + collidableB.Shape.collisionMargin)
            //        state = CollisionState.ShallowContact;
            //    return true;
            //}

            ////This is rare, but could happen.
            //state = CollisionState.Separated;
            //contact = new ContactData();
            //return false;
            #endregion

            #region Testing
            //RigidTransform localTransformB;
            //MinkowskiToolbox.GetLocalTransform(ref collidableA.worldTransform, ref collidableB.worldTransform, out localTransformB);
            //contact.Id = -1;
            //if (MPRTesting.GetLocalOverlapPosition(collidableA.Shape, collidableB.Shape, ref localTransformB, out contact.Position))
            //{
            //    Vector3 rayCastDirection = localTransformB.Position;
            //    MPRTesting.LocalSurfaceCast(collidableA.Shape, collidableB.Shape, ref localTransformB, ref rayCastDirection, out contact.PenetrationDepth, out contact.Normal);
            //    MPRTesting.LocalSurfaceCast(collidableA.Shape, collidableB.Shape, ref localTransformB, ref contact.Normal, out contact.PenetrationDepth, out rayCastDirection);
            //    RigidTransform.Transform(ref contact.Position, ref collidableA.worldTransform, out contact.Position);
            //    Vector3.Transform(ref contact.Normal, ref collidableA.worldTransform.Orientation, out contact.Normal);
            //    return true;
            //}
            //contact.Normal = new Vector3();
            //contact.PenetrationDepth = 0;
            //return false;
            #endregion

            #region v0.15.2 and before
            //if (MPRToolbox.AreObjectsColliding(collidableA.Shape, collidableB.Shape, ref collidableA.worldTransform, ref collidableB.worldTransform, out contact))
            //{
            //    if (contact.PenetrationDepth < collidableA.Shape.collisionMargin + collidableB.Shape.collisionMargin)
            //        state = CollisionState.ShallowContact; //If it's emerged from the deep contact, we can go back to using the preferred GJK method.
            //    return true;
            //}
            ////This is rare, but could happen.
            //state = CollisionState.Separated;
            //return false;
            #endregion
        }
Exemple #59
0
        //Relies on the triangle being located in the local space of the convex object.  The convex transform is used to transform the
        //contact points back from the convex's local space into world space.
        ///<summary>
        /// Generates a contact between the triangle and convex.
        ///</summary>
        ///<param name="contactList">Contact between the shapes, if any.</param>
        ///<returns>Whether or not the shapes are colliding.</returns>
        public override bool GenerateContactCandidates(TriangleShape triangle, out TinyStructList <ContactData> contactList)
        {
            contactList = new TinyStructList <ContactData>();


            Vector3 ab, ac;

            Vector3.Subtract(ref triangle.vB, ref triangle.vA, out ab);
            Vector3.Subtract(ref triangle.vC, ref triangle.vA, out ac);
            Vector3 triangleNormal;

            Vector3.Cross(ref ab, ref ac, out triangleNormal);
            if (triangleNormal.LengthSquared() < Toolbox.Epsilon * .01f)
            {
                //If the triangle is degenerate, use the offset between its center and the sphere.
                Vector3.Add(ref triangle.vA, ref triangle.vB, out triangleNormal);
                Vector3.Add(ref triangleNormal, ref triangle.vC, out triangleNormal);
                Vector3.Multiply(ref triangleNormal, 1 / 3f, out triangleNormal);
                if (triangleNormal.LengthSquared() < Toolbox.Epsilon * .01f)
                {
                    triangleNormal = Toolbox.UpVector; //Alrighty then! Pick a random direction.
                }
            }


            float dot;

            Vector3.Dot(ref triangleNormal, ref triangle.vA, out dot);
            switch (triangle.sidedness)
            {
            case TriangleSidedness.DoubleSided:
                if (dot < 0)
                {
                    Vector3.Negate(ref triangleNormal, out triangleNormal);     //Normal must face outward.
                }
                break;

            case TriangleSidedness.Clockwise:
                if (dot > 0)
                {
                    return(false);    //Wrong side, can't have a contact pointing in a reasonable direction.
                }
                break;

            case TriangleSidedness.Counterclockwise:
                if (dot < 0)
                {
                    return(false);    //Wrong side, can't have a contact pointing in a reasonable direction.
                }
                break;
            }


            Vector3 closestPoint;

            //Could optimize this process a bit.  The 'point' being compared is always zero.  Additionally, since the triangle normal is available,
            //there is a little extra possible optimization.
            lastRegion = Toolbox.GetClosestPointOnTriangleToPoint(ref triangle.vA, ref triangle.vB, ref triangle.vC, ref Toolbox.ZeroVector, out closestPoint);
            float lengthSquared = closestPoint.LengthSquared();
            float marginSum     = triangle.collisionMargin + sphere.collisionMargin;

            if (lengthSquared <= marginSum * marginSum)
            {
                var contact = new ContactData();
                if (lengthSquared < Toolbox.Epsilon)
                {
                    //Super close to the triangle.  Normalizing would be dangerous.

                    Vector3.Negate(ref triangleNormal, out contact.Normal);
                    contact.Normal.Normalize();
                    contact.PenetrationDepth = marginSum;
                    contactList.Add(ref contact);
                    return(true);
                }

                lengthSquared = (float)Math.Sqrt(lengthSquared);
                Vector3.Divide(ref closestPoint, lengthSquared, out contact.Normal);
                contact.PenetrationDepth = marginSum - lengthSquared;
                contact.Position         = closestPoint;
                contactList.Add(ref contact);
                return(true);
            }
            return(false);
        }
        public override void Update(float dt)
        {
            //Now, generate a contact between the two shapes.
            float   distance;
            Vector3 axis;
            var     manifold = new TinyStructList <BoxContactData>();

            if (BoxBoxCollider.AreBoxesColliding(boxA.Shape, boxB.Shape, ref boxA.worldTransform, ref boxB.worldTransform, out distance, out axis, out manifold))
            {
                Vector3.Negate(ref axis, out axis);
                TinyList <int> toRemove = new TinyList <int>();
                BoxContactData data;
                for (int i = 0; i < contacts.Count; i++)
                {
                    bool found = false;
                    for (int j = manifold.Count - 1; j >= 0; j--)
                    {
                        manifold.Get(j, out data);
                        if (contacts.Elements[i].Id == data.Id)
                        {
                            found = true;
                            //Update contact...
                            contacts.Elements[i].Position         = data.Position;
                            contacts.Elements[i].PenetrationDepth = -data.Depth;
                            contacts.Elements[i].Normal           = axis;
                            contacts.Elements[i].Validate();
                            //Remove manifold entry
                            manifold.RemoveAt(j);
                            break;
                        }
                    }
                    if (!found)
                    {//No match found
                        toRemove.Add(i);
                    }
                }

                ////Go through the indices to remove.
                ////For each one, replace the removal index with a contact in the new manifold.
                //int removalIndex;
                //for (removalIndex = toRemove.count - 1; removalIndex >= 0 && manifold.count > 0; removalIndex--)
                //{
                //    int indexToReplace = toRemove[removalIndex];
                //    toRemove.RemoveAt(removalIndex);
                //    manifold.Get(manifold.count - 1, out data);
                //    //Update contact...
                //    contacts.Elements[indexToReplace].Position = data.Position;
                //    contacts.Elements[indexToReplace].PenetrationDepth = -data.Depth;
                //    contacts.Elements[indexToReplace].Normal = axis;
                //    contacts.Elements[indexToReplace].Id = data.Id;
                //    //Remove manifold entry
                //    manifold.RemoveAt(manifold.count - 1);

                //}

                //Alright, we ran out of contacts to replace (if, in fact, toRemove isn't empty now).  Just remove the remainder.
                //toRemove is sorted by increasing index.  Go backwards along it so that the indices are valid all the way through.
                for (int i = toRemove.Count - 1; i >= 0; i--)
                {
                    Remove(toRemove[i]);
                }

                //Add new contacts.
                for (int i = 0; i < manifold.Count; i++)
                {
                    manifold.Get(i, out data);
                    ContactData newContact = new ContactData();
                    newContact.Position         = data.Position;
                    newContact.PenetrationDepth = -data.Depth;
                    newContact.Normal           = axis;
                    newContact.Id = data.Id;

                    Add(ref newContact);
                }
            }
            else
            {
                //Not colliding, so get rid of it.
                for (int i = contacts.Count - 1; i >= 0; i--)
                {
                    Remove(i);
                }
            }
        }