/// <summary> /// Analyzes the support state of the character based on the speculative input support and traction contacts. /// </summary> /// <param name="tractionContacts">Contacts providing the character with traction.</param> /// <param name="supportContacts">Contacts providing the character with support.</param> /// <param name="state">State of the contacts relative to the speculative character position.</param> /// <param name="supportContact">Representative contact to use, if any.</param> public void AnalyzeSupportState(ref QuickList<CharacterContact> tractionContacts, ref QuickList<CharacterContact> supportContacts, out CharacterContactPositionState state, out CharacterContact 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].Contact.PenetrationDepth > maxDepth) { maxDepth = tractionContacts.Elements[i].Contact.PenetrationDepth; deepestIndex = i; } } 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].Contact.PenetrationDepth > maxDepth) { maxDepth = supportContacts.Elements[i].Contact.PenetrationDepth; deepestIndex = i; } } supportContact = supportContacts.Elements[deepestIndex]; } else { state = CharacterContactPositionState.NoHit; supportContact = new CharacterContact(); return; } //Check the depth. if (maxDepth > CollisionDetectionSettings.AllowedPenetration) { //It's too deep. state = CharacterContactPositionState.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 = CharacterContactPositionState.NoHit; } else { //The deepest contact appears to be very nicely aligned with the ground! //It's fully supported. state = CharacterContactPositionState.Accepted; } }
/// <summary> /// Analyzes the support state of the character based on the speculative input support and traction contacts. /// </summary> /// <param name="tractionContacts">Contacts providing the character with traction.</param> /// <param name="supportContacts">Contacts providing the character with support.</param> /// <param name="state">State of the contacts relative to the speculative character position.</param> /// <param name="supportContact">Representative contact to use, if any.</param> public void AnalyzeSupportState(ref QuickList <CharacterContact> tractionContacts, ref QuickList <CharacterContact> supportContacts, out CharacterContactPositionState state, out CharacterContact supportContact) { Fix64 maxDepth = -Fix64.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].Contact.PenetrationDepth > maxDepth) { maxDepth = tractionContacts.Elements[i].Contact.PenetrationDepth; deepestIndex = i; } } 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].Contact.PenetrationDepth > maxDepth) { maxDepth = supportContacts.Elements[i].Contact.PenetrationDepth; deepestIndex = i; } } supportContact = supportContacts.Elements[deepestIndex]; } else { state = CharacterContactPositionState.NoHit; supportContact = new CharacterContact(); return; } //Check the depth. if (maxDepth > CollisionDetectionSettings.AllowedPenetration) { //It's too deep. state = CharacterContactPositionState.TooDeep; } else if (maxDepth < F64.C0) { //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 = CharacterContactPositionState.NoHit; } else { //The deepest contact appears to be very nicely aligned with the ground! //It's fully supported. state = CharacterContactPositionState.Accepted; } }