//Raugh version void OnCollisionEnter(Collision collision) { foreach (ContactPoint contact in collision.contacts) { finalContact = contact; } collision.rigidbody.AddForce(finalContact.normal * bouncyness); }
/* we need to determine what direction we collided with environment so we can change direction. * we check first and last point in the collection and determine what pieces of the vector positions match * and then flip horizontal/vertical while maintaining the opposite movement (vertical/horizontal respectively) */ void SwitchDirection(ContactPoint[] hits) { // InverseTransformPoint will convert to local space so we can easily tell where it is in relation to us Vector3 relativePosition1 = transform.InverseTransformPoint(hits[0].point); Vector3 relativePosition2 = transform.InverseTransformPoint(hits[hits.Length - 1].point); if (relativePosition1.x > 0 && relativePosition2.x > 0) // right { if (currentDirection == "NE") currentDirection = "NW"; if (currentDirection == "SE") currentDirection = "SW"; GetComponent<tk2dSprite>().FlipX = true; } if (relativePosition1.x < 0 && relativePosition2.x < 0) // left { if (currentDirection == "NW") currentDirection = "NE"; if (currentDirection == "SW") currentDirection = "SE"; GetComponent<tk2dSprite>().FlipX = false; } if (relativePosition1.y > 0 && relativePosition2.y > 0) // up { if (currentDirection == "NE") currentDirection = "SE"; if (currentDirection == "NW") currentDirection = "SW"; } if (relativePosition1.y < 0 && relativePosition2.y < 0) // down { if (currentDirection == "SE") currentDirection = "NE"; if (currentDirection == "SW") currentDirection = "NW"; } }
void Explode(ContactPoint[] contacts) { gameObject.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeAll; gameObject.GetComponent<Renderer>().enabled = false; if(halo != null) { halo.GetType().GetProperty("enabled").SetValue(halo, false, null); } Destroy(gameObject, ProjectileDeathTimer);//Kind of hacky, can modify to use the time property in the trail system. }
void OnCollisionEnter(Collision col) { m_CurrentNbBounces++; m_LastHit = col.contacts[0]; if (m_InstanciateOnBounce != null) { GameObject.Instantiate(m_InstanciateOnBounce, m_LastHit.point + m_LastHit.normal.normalized/10.0f, //m_InstanciateOnBounce.transform.rotation); Quaternion.FromToRotation(Vector3.up, m_LastHit.normal)); } }
public void ShowDustParticles(ContactPoint contactPoint) { if (contactPoint.point != null) { // Place Particle Effect where it hits the ground GameObject gObj = Instantiate(PFX_HittingGround); gObj.transform.position = contactPoint.point; // Play Hitting Sand Sound int soundNum = Random.Range (0,2); if(soundNum == 0) GetComponent<SoundsTriggered>().playSound2(true, 1); else if (soundNum == 1) GetComponent<SoundsTriggered>().playSound3(true, 1); } }
private void ProcessBuffPackage(ContactPoint contact, PackageType buffType) { TankHealth healthComponent = contact.otherCollider.GetComponent<TankHealth>(); TankMovement movementComponent = contact.otherCollider.GetComponent<TankMovement>(); switch (buffType) { case PackageType.Health: healthComponent.Heal(m_HealthBenefit); break; case PackageType.Speed: movementComponent.m_HasSpeedBuff = true; break; default: break; } }
public void In( [FriendlyName("ContactPoint", "The ContactPoint to randomly choose from. Connect a ContactPoint List or individual ContactPoint variables to this socket.")] ContactPoint[] ObjectSet, [FriendlyName("Target ContactPoint", "The ContactPoint value that gets set.")] out ContactPoint Target ) { if (ObjectSet == null) { Target = new ContactPoint(); return; } int index = Random.Range(0, ObjectSet.Length); Target = ObjectSet[index]; }
public void In( [FriendlyName("Value", "The variable you wish to use to set the target's value.")] object Value, [FriendlyName("Target", "The Target variable you wish to set.")] out ContactPoint Target ) { if ( Value.GetType() != typeof(ContactPoint) ) { uScriptDebug.Log( "Set ContactPoint: Value is not a ContactPoint!", uScriptDebug.Type.Error ); Target = new ContactPoint( ); } else { Target = (ContactPoint) Value; } }
public void LaunchBall(ContactPoint cp, bool platformFlag) { this.StopTheBall(); this.BallRigRef.freezeRotation = false; Vector3 newDir = Vector3.zero; Vector3 curDir = this.BallRigRef.transform.TransformDirection(Vector3.forward); float differenceBetweenContactAndCenter = cp.point.x - this.gameObject.transform.position.x; if (platformFlag) //hit the platform { if (Mathf.Abs(differenceBetweenContactAndCenter) < 0.1f) // presuming it hit the center { newDir = Vector3.Reflect(curDir, cp.normal); LaunchBallStraight(newDir, curDir); this.BallRigRef.freezeRotation = true; } else // hit the side { float modifier = 60.0f * differenceBetweenContactAndCenter; GameObject.Find("RotationDummy").transform.Rotate(0.0f, modifier, 0.0f); Quaternion targetRotation = GameObject.Find("RotationDummy").transform.rotation; this.BallRigRef.transform.rotation = targetRotation; Vector3 targVector = this.BallRigRef.transform.TransformDirection(Vector3.forward); this.BallRigRef.AddForce(targVector * this.thrust); this.BallRigRef.freezeRotation = true; GameObject.Find("RotationDummy").transform.rotation = Quaternion.identity; } } else // hit something else { newDir = Vector3.Reflect(curDir, cp.normal); if (this.CheckForStraightAngleBug(newDir)) { Vector3 tmpDir = new Vector3(newDir.x + (Random.Range(0.5f, 1.5f) - 1.0f), 0.0f, (Random.Range(0.5f, 1.5f) - 1.0f)); newDir = tmpDir; } LaunchBallStraight(newDir, curDir); this.BallRigRef.freezeRotation = true; } this.lastCp = cp; }
//When the haptic point is in the object void OnCollisionStay(Collision other) { //Debug.Log("Name: " + other.gameObject.name); //Get Collider of the PHANToM pointer var thisCollider = GetComponent <Collider>(); ContactPoint contactPoint = other.contacts[0]; Vector3 center = other.collider.bounds.center; //For penetration computation Vector3 otherPosition = other.gameObject.transform.position; Quaternion otherRotation = other.gameObject.transform.rotation; Vector3 direction; float distance; //Compute depth of penetration bool overlapped = Physics.ComputePenetration( other.collider, otherPosition, otherRotation, thisCollider, transform.position, transform.rotation, out direction, out distance ); //if the colliders are overlapped compute the force //should be all the time when we are in the OnCollisionStay method if (overlapped) { depth = (transform.position - center).magnitude; ratio = 1 - ((1 / totalDepth) * depth); //Debug.Log( "Depth ratio: " + ratio); force[0] = forceDirection.x * computeForce(Mathf.Abs(ratio)); force[1] = forceDirection.y * computeForce(Mathf.Abs(ratio)); force[2] = forceDirection.z * computeForce(Mathf.Abs(ratio)); } //Debug.Log("force: " + force[0] + ", " + force[1] + ", " + force[2]); talker.SendForceVector(force, torque); }
void Explode(ContactPoint[] contacts) { GameObject explosion = Instantiate(explosionPrefab, contacts[0].point, Quaternion.identity) as GameObject; Destroy(explosion, ExplosionDeathTimer); for (int i = -5; i <= 5; ++i) { for (int j = -5; j <= 5; ++j) { for (int k = -5; k <= 5; ++k) { RaycastHit hit; Ray ray = new Ray(transform.position, new Vector3(i, j, k)); Physics.Raycast(ray, out hit); Rigidbody body = hit.rigidbody; if (body != null) { Vector3 direction = body.transform.position - transform.position; direction = direction.normalized; body.AddForce(direction * ExplosionStrength); Health hp = body.gameObject.GetComponent<Health>(); if(hp != null) { hp.TakeDamage(damage); } //if(body.gameObject.tag != "Player" && body.gameObject.tag != "Projectile") // Destroy(body.gameObject, 1.0f); } } } } gameObject.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeAll; gameObject.GetComponent<Rigidbody>().isKinematic = true; gameObject.GetComponent<Renderer>().enabled = false; Destroy(gameObject, ProjectileDeathTimer); }
void SplatLocation(ContactPoint contact) { splatsX = SplatManagerSystem.instance.splatsX; splatsY = SplatManagerSystem.instance.splatsY; channelMask = projectileColor; Vector3 leftVec = Vector3.Cross(contact.normal, Vector3.up); float randScale = Random.Range(0.5f, 1.5f); GameObject newSplatObject = new GameObject(); newSplatObject.transform.position = contact.point; if (leftVec.magnitude > 0.001f) { newSplatObject.transform.rotation = Quaternion.LookRotation(leftVec, contact.normal); } newSplatObject.transform.RotateAround(contact.point, contact.normal, Random.Range(-180, 180)); newSplatObject.transform.localScale = new Vector3(randScale, randScale * 0.5f, randScale) * splatScale; Splat newSplat; newSplat.splatMatrix = newSplatObject.transform.worldToLocalMatrix; newSplat.channelMask = channelMask; float splatscaleX = 1.0f / splatsX; float splatscaleY = 1.0f / splatsY; float splatsBiasX = Mathf.Floor(Random.Range(0, splatsX * 0.99f)) / splatsX; float splatsBiasY = Mathf.Floor(Random.Range(0, splatsY * 0.99f)) / splatsY; newSplat.scaleBias = new Vector4(splatscaleX, splatscaleY, splatsBiasX, splatsBiasY); SplatManagerSystem.instance.AddSplat(newSplat); GameObject.Destroy(newSplatObject); }
// Update is called once per frame void Update() { if (doExplosion) { Collider[] cols = Physics.OverlapSphere(this.transform.position, radius); float maxDist = 0; foreach (Collider c in cols) { float dist = Vector3.Distance(c.transform.position, transform.position); if (dist > maxDist) { maxDist = dist; } } contactPointsHit.Clear(); foreach (Collider c in cols) { ContactPoint cp = c.GetComponent <ContactPoint>(); if (cp != null) { contactPointsHit.Add(cp); cp.force = force - (force / maxDist * Vector3.Distance(c.transform.position, transform.position)); if (!knownContactPoints.Contains(cp)) { knownContactPoints.Add(cp); } } } foreach (ContactPoint cp in knownContactPoints) { if (!contactPointsHit.Contains(cp)) { cp.force = 0; } } } }
void OnCollisionEnter(Collision collision) { if (collision.gameObject.GetComponent <MainPlayer_Single>() != null) { //Destroy(collision.gameObject); float imp = collision.impulse.magnitude; imp -= 7000f; ContactPoint cp = collision.contacts[0]; Vector3 toDirection = cp.point - transform.position; Quaternion r = Quaternion.FromToRotation(Vector3.forward, toDirection); Instantiate(EffectManager.main.get_hit_effect(), cp.point, r, EffectManager.main.effect_parent); AudioClips.main.play(4); if (imp > 0) { Instantiate(effect1, transform); StoryChapter1.main.contrastResolve += imp / 550000f; StoryChapter1.main.setContrast(Mathf.Max(1f, 3f - imp / 2000f)); if (StoryChapter1.main.contrastResolve > StoryChapter1.main.contrastMax) { DestroyAfter da = gameObject.AddComponent <DestroyAfter>(); AudioClips.main.play(5); da.destroy_after = 3f; foreach (ParticleSystem ps in gameObject.GetComponentsInChildren <ParticleSystem>()) { ps.Stop(); } gameObject.GetComponent <SphereCollider>().enabled = false; gameObject.GetComponent <MeshRenderer>().enabled = false; Instantiate(effect2, transform); } } } }
private void OnCollisionEnter(Collision collision) { if (collision.gameObject.CompareTag("Player")) { Rigidbody Koda = collision.gameObject.GetComponent <Rigidbody>(); //Vector3 Koda_old_velocity = Koda.velocity; ContactPoint contact = collision.contacts[0]; Vector3 temp_orientation = -collision.contacts[0].normal.normalized; temp_orientation.x = 0; //temp_orientation.y = temp_orientation.y / Mathf.Abs(temp_orientation.y); temp_orientation.y = (temp_orientation.y == 0)?0:temp_orientation.y / Mathf.Abs(temp_orientation.y); temp_orientation.z = 0; //================================================ SoundController.instance.SelectENVQuick("Bumper"); //================================================ Koda.velocity = Vector3.zero; Koda.AddForce(temp_orientation * coeffRebond, ForceMode.Impulse); // 200 = coeffRebond } else if (collision.gameObject.CompareTag("Lure")) { Rigidbody Lure = collision.gameObject.GetComponent <Rigidbody>(); Lure.velocity = Vector3.zero; ContactPoint contact = collision.contacts[0]; Lure.AddForce(Vector3.up * 5 * 999 + Vector3.forward * 5 * 999 * Random.Range(-1.0f, 1.0f) + Vector3.right * 5 * 999 * Random.Range(-1.0f, 1.0f), ForceMode.Impulse); // 200 = coeffRebond } else { Rigidbody other = collision.gameObject.GetComponent <Rigidbody>(); other.velocity = Vector3.zero; ContactPoint contact = collision.contacts[0]; other.AddForce(Vector3.up * 5 + Vector3.forward * 5 * Random.Range(-1.0f, 1.0f) + Vector3.right * 5 * Random.Range(-1.0f, 1.0f), ForceMode.Impulse); // 200 = coeffRebond } //Debug.Log("BOING"); }
//接地、衝突判定------------------------------------------------------------------------------ void OnCollisionEnter(Collision other) { if (other.gameObject.CompareTag("Ground")) { _currentSecond = 0; _slowdownForce = 0; _jumpTopHeight = _rigid.transform.position.y; _jump = 0; _animator.SetInteger("Jump", 4); _attack = 0; _animator.SetBool("useAirJump", false); } if (other.gameObject.CompareTag("Enemy") && !_isInvisible) { _isDamege = true; _isInvisible = true; ContactPoint contact = other.contacts[0]; Vector3 contactPos = contact.point; var vec1 = contactPos; var vec2 = myCentral.transform.position; var res = vec1 - vec2; _rigid.velocity = Vector3.zero; _rigid.AddForce(-res * 600); _animator.SetBool("Damege", true); StartCoroutine("DamegeCheck"); } }
void OnCollisionEnter(Collision col) { if (debuggerScript == null) { Debug.Log("DebuggerScript null"); } if (debugShellImpact == true) { Debug.Log("hit " + col.gameObject.name); } if (col.gameObject.name != gameObject.name && col.gameObject.layer == 9) { ShipStatsScript sss = col.gameObject.GetComponent <ShipStatsScript>(); ContactPoint cont = col.contacts[0]; // new ContactPoint exp = shellHolderScript.get_Exp(); if (!exp) { Debug.Log("Exp is null"); } exp.transform.position = cont.point; // exp.transform.position = gameObject.transform.position; shellHolderScript.invoke_return_Exp(exp); sss.take_damage(damage); damage = Constants.MINIMUMDAMAGE; } if (col.gameObject.tag == "water") { /* ContactPoint cont = col.contacts[0]; // new ContactPoint * GameObject splash = Instantiate(splashPref, cont.point, Quaternion.identity); * Destroy(splash, 3.0f); */ } }
void PreSolve(Contact contact, ref Manifold oldManifold) { if ((Flags & DebugViewFlags.ContactPoints) == DebugViewFlags.ContactPoints) { Manifold manifold = contact.Manifold; if (manifold.PointCount == 0) { return; } Fixture fixtureA = contact.FixtureA; FixedArray2 <PointState> state1, state2; FarseerPhysics.Collision.Collision.GetPointStates(out state1, out state2, ref oldManifold, ref manifold); FixedArray2 <System.Numerics.Vector2> points; System.Numerics.Vector2 normal; contact.GetWorldManifold(out normal, out points); for (int i = 0; i < manifold.PointCount && _pointCount < maxContactPoints; ++i) { if (fixtureA == null) { _points[i] = new ContactPoint(); } ContactPoint cp = _points[_pointCount]; cp.Position = points[i]; cp.Normal = normal; cp.State = state2[i]; _points[_pointCount] = cp; ++_pointCount; } } }
private void OnCollisionEnter(Collision collision) { if (collision.transform.tag == "Player") { collision.gameObject.GetComponent <PlayersHealth>().currentHealth -= damage; meshRenderer.enabled = false; rb.detectCollisions = false; GameObject woodGO = collision.transform.Find("WoodImpacts").gameObject; ParticleSystem theHit = woodGO.GetComponentInChildren <ParticleSystem>(); audioSource.PlayOneShot(boatHits[Random.Range(0, boatHits.Length)], 0.1f); doEmit(theHit); } else if (collision.transform.tag == "Sea") { meshRenderer.enabled = false; ContactPoint hitPoint = collision.GetContact(0); GameObject splashMiss = Instantiate(splash, hitPoint.point, Quaternion.identity) as GameObject; splashMiss.transform.Rotate(90.0f, 0f, 0f, Space.Self); if (audioSource) { audioSource.PlayOneShot(splashes[Random.Range(0, splashes.Length)], 0.05f); } } }
/*private void OnTriggerEnter(Collider other) * { * if (other.gameObject.tag == "hookable") * { * Ray ray = new Ray(transform.position, directionOfTravel); * RaycastHit hit; * if (other.Raycast(ray, out hit, 10)) * { * float angle = AngleBetweenVector2(directionOfTravel, hit.normal); * if (angle < 0) * { * angle = 2 * (Mathf.Abs(angle) - 90); * angle *= -1; * } * else * { * angle = 2 * (Mathf.Abs(angle) - 90); * angle *= 1; * } * * angle += UnityEngine.Random.Range(-2, 2); * * directionOfTravel = Quaternion.Euler(0, angle, 0) * directionOfTravel; * directionOfTravel.Normalize(); * } * } * }*/ void OnCollisionEnter(Collision collision) { ContactPoint contact = collision.contacts[0]; if (collision.gameObject.tag == "hookable") { float angle = AngleBetweenVector2(directionOfTravel, contact.normal); if (angle < 0) { angle = 2 * (Mathf.Abs(angle) - 90); angle *= -1; } else { angle = 2 * (Mathf.Abs(angle) - 90); angle *= 1; } angle += UnityEngine.Random.Range(-2, 2); directionOfTravel = Quaternion.Euler(0, angle, 0) * directionOfTravel; directionOfTravel.Normalize(); ActionManager.OnBulletHitWall(); } else if (collision.gameObject.tag == "enemy") { collision.transform.gameObject.SendMessage("hit"); } else if (collision.gameObject.tag == "Player") { if (PlayerController.isPlayerAlive && PlayerController.canRecieveDamage) { ActionManager.OnPlayerHit(); } } }
void OnCollisionEnter(Collision collision) { if (ripple == null || rippleAnimator == null) { return; } Transform parentOfOther = collision.gameObject.transform.parent; bool hitHand = (parentOfOther != null && (parentOfOther.name == "CollisionHand_L" || parentOfOther.name == "CollisionHand_R")); if (!hitHand) { // Move ripple to the contact position ContactPoint contact = collision.contacts[0]; if (name == "Left" || name == "Right") { ripple.transform.position = new Vector3(ripple.transform.position.x, contact.point.y, contact.point.z); } else if (name == "Front" || name == "Back") { ripple.transform.position = new Vector3(contact.point.x, contact.point.y, ripple.transform.position.z); } else if (name == "Top" || name == "Bottom") { ripple.transform.position = new Vector3(contact.point.x, ripple.transform.position.y, contact.point.z); } // Animate ripple rippleAnimator.Animate(); // Make surrounding bars glow foreach (Renderer barRenderer in barRenderers) { StartCoroutine(MakeBarGlow(barRenderer, barGlowDuration)); } } }
/// <summary> /// /// </summary> /// <param name="enterObject"></param> void OnCollisionEnter(Collision enterObject) { // things to add: // maybe a distance or time check to see if grenade is far enough away to arm before exploding // ... maybe a non armed grenade will bounce then explode // similar to direct noob tube shots in CoD if (!OnHit) { return; } switch (enterObject.transform.tag) { case "Projectile": //return; break; default: Destroy(gameObject, 0); //GetComponent<Rigidbody>().useGravity = false; ContactPoint contact = enterObject.contacts[0]; Quaternion rotation = gameObject.GetComponent <Rigidbody>().rotation; //Quaternion.FromToRotation(Vector3.up, contact.normal); GameObject e = Object.Instantiate(explosion, contact.point, rotation) as GameObject; bl_Blast blast = e.GetComponent <bl_Blast>(); if (blast != null) { blast.isNetwork = isNetwork; blast.WeaponID = ID; blast.WeaponName = mName; blast.explosionDamage = damage; } if (enterObject.rigidbody) { enterObject.rigidbody.AddForce(transform.forward * impactForce, ForceMode.Impulse); } break; } }
void CollideCircles() { Vector2D center1 = Vector2D.Zero; Vector2D center2 = Vector2D.Zero; Vector2D.Transform(ref body1.Matrices.ToWorld, ref center1, out center1); Vector2D.Transform(ref body2.Matrices.ToWorld, ref center2, out center2); Vector2D normal; Vector2D.Subtract(ref center2, ref center1, out normal); Scalar distance; Vector2D.Normalize(ref normal, out distance, out normal); Scalar depth = distance - (circle1.Radius + circle2.Radius); if (depth > 0) { contacts.Clear(); } else { ContactPoint contact; if (contacts.First == null) { contact = new ContactPoint(); contacts.AddLast(contact); } else { contact = contacts.First.Value; } contact.distance = depth; contact.normal = normal; contact.position.X = center2.X - normal.X * circle2.Radius; contact.position.Y = center2.Y - normal.Y * circle2.Radius; } }
/// <summary> /// AddPoint /// if pt is less than Sqrt(combinationDistanceSq) from one of the /// others the original is replaced with the mean of it /// and pt, and false is returned. true means that pt was /// added to pts /// </summary> private static bool AddPoint(List <ContactPoint> pts, ref Vector3 pt, float combinationDistanceSq) { for (int i = pts.Count; i-- != 0;) { ContactPoint cpt = pts[i]; #region INLINE: float len = (cpt.Pos-pt).LengthSquared(); float xd = cpt.Pos.X - pt.X; float yd = cpt.Pos.Y - pt.Y; float zd = cpt.Pos.Z - pt.Z; float len = (xd * xd) + (yd * yd) + (zd * zd); #endregion if (len < combinationDistanceSq) { cpt.Pos = (cpt.Count * cpt.Pos + pt) / (cpt.Count + 1); cpt.Count += 1; return(false); } } pts.Add(new ContactPoint(ref pt)); return(true); }
private void OnCollisionEnter(Collision collision) { if (this.enabled) { if (collision.gameObject.CompareTag("Enemy")) { collision.gameObject.GetComponent <GoombaMachine>().RecieveDamage(1); } else if (collision.gameObject.CompareTag("Player")) { collision.gameObject.GetComponent <MarioController>().LoseHP(1, transform.forward); } for (int i = 0; i < collision.contactCount; i++) { ContactPoint contact = collision.GetContact(i); if (contact.normal.x != 0 || contact.normal.z != 0) { Bounce(contact); } } } }
private void OnCollisionEnter(Collision collision) { for (int i = 0; i < collision.contacts.Length; i++) { ContactPoint contact = collision.contacts[i]; if (collision.contacts[i].otherCollider.tag == "Tank") { TankMovement movementComponent = collision.contacts[i].otherCollider.GetComponent <TankMovement>(); if (!movementComponent.m_HasCollided) { movementComponent.m_HasCollided = true; if (m_Type == PackageType.Health || m_Type == PackageType.Speed) { ProcessBuffPackage(collision.contacts[i], m_Type); } else { ProcessBulletPackage(contact, m_Type); } RemoveCarePackage(); } } } }
public void OnCollisionEnter(Collision collision) { if (topAngle == 0) { return; } GameObject other = collision.gameObject; Character[] characters = other.GetComponentsInParent <Character>(); if (characters.Length == 0) { return; } Character character = characters[0]; ContactPoint hit = collision.GetContact(0); float collisionAngle = ( Quaternion.FromToRotation(Vector3.up, hit.normal).eulerAngles.z + 180 ) % 360; TryAction(character, collisionAngle); }
private IEnumerator Collide(Collision collision) { Vector3 previousPosition = transform.position; Vector3 motion; ContactPoint[] contacts = new ContactPoint[128]; yield return(new WaitForEndOfFrame()); while (true) { motion = transform.position - previousPosition; int num = collision.GetContacts(contacts); for (int i = 0; i < num; i++) { float dot = Vector3.Dot(motion, contacts[i].normal.normalized); if (dot < 0) { transform.position -= dot * contacts[i].normal.normalized; } } previousPosition = transform.position; yield return(null); } }
void OnCollisionEnter(Collision collision) { ContactPoint contact = collision.contacts[0]; //Debug.Log("PCollision-->OnCollisionEnter" + contact.normal); //Debug.DrawRay(contact.point, contact.normal, Color.red, 500); Vector3 pos = contact.point; if (collision.collider.tag == TagEnum.Block.ToString() || collision.collider.tag == transform.tag) { if (contact.normal.x != 0) { //Debug.Log("PCollision-->OnCollisionEnter Reverse"); rbMove.directionReverse(); } if (contact.normal.y > 0) { if (rbMove.velocity == Vector3.zero) { //Debug.Log("PCollision-->OnCollisionEnter Default"); rbMove.defaultAutoMove(); } } } }
void OnCollisionEnter(Collision collision) { Destroy(gameObject); ContactPoint contact = collision.contacts[0]; GameObject objHit = collision.gameObject; if (objHit.tag == "AI Tank") { int health = objHit.GetComponent <StateManager>().getHealth(); Debug.Log("****************** Health: " + health); Object exp = Instantiate(explosion, contact.point, Quaternion.identity); health -= 10; objHit.GetComponent <StateManager>().setHealth(health); Destroy(exp, 0.5f); } else if (objHit.tag == "Player") { Object exp = Instantiate(explosion, contact.point, Quaternion.identity); Destroy(exp, 0.5f); } }
public void OnCollisionEnter(Collision collision) { if (collision.gameObject.tag == "CurrentWeapon" || collision.gameObject.tag == "CanGrab" || collision.gameObject.tag == "Hammer" || collision.gameObject.tag == "Sickle") { //sparks = (GameObject)GameObject.Instantiate(Resources.Load("sparks", typeof(GameObject))); ContactPoint contact = collision.contacts[0]; Quaternion sparkrot = Quaternion.FromToRotation(Vector3.up, contact.normal); Vector3 sparkpos = contact.point; GameObject sparks2 = Instantiate(sparks, sparkpos, sparkrot) as GameObject; if (chainCollisionjusthappened) { BossBrain.switchBallDirection(); } chainCollisionjusthappened = true; //sparks.gameObject.transform.SetParent() Debug.Log("Weapon Collision worked"); StartCoroutine(WaitQuick()); // hitOnce = true; Destroy(sparks2, .4f); } }
void OnCollisionEnter(Collision collision) { ContactPoint contact = collision.contacts[0]; //Debug.Log("ECollision-->OnCollisionEnter" + contact.normal + collision.collider.tag.ToString()); //Debug.DrawRay(contact.point, contact.normal, Color.red, 500); Vector3 pos = contact.point; if (collision.collider.tag == TagEnum.Block.ToString() || collision.collider.tag == transform.tag) { if (contact.normal.x != 0) { //Debug.Log("ECollision-->OnCollisionEnter Reverse"); cMovement.movement(0, MotionEnum.ReverseXAxis);; } } CharacterMode playerMode; if (!ReferenceEquals(collision.collider.transform.parent, null) && collision.collider.transform.parent.tag == TagEnum.Player.ToString()) { playerMode = collision.collider.GetComponentInParent <CharacterMode>(); playerMode.Interact(InteractEnum.Enemy, enemyAI.eDamage); } }
/// <summary> /// { code : contactpoint-value, system : contactpoint-use } /// </summary> /// <param name="element"></param> /// <returns></returns> private List <Expression> ToExpressions(ContactPoint element) { if (element == null) { return(null); } var values = new List <IndexValue>(); if (element.Value != null) { values.Add(new IndexValue("code", Map(element.ValueElement))); } if (element.System != null) { values.Add(new IndexValue("system", Map(element.SystemElement))); } if (element.Use != null) { values.Add(new IndexValue("use", Map(element.UseElement))); } return(ListOf(new CompositeValue(values))); }
void OnCollisionEnter(Collision collision) { // Instantiate explosion at the impact point and rotate the explosion // so that the y-axis faces along the surface normal ContactPoint contact = collision.contacts[0]; Quaternion rotation = Quaternion.FromToRotation(Vector3.up, contact.normal); Vector3 pos = contact.point; if (explosion) { ObjectPool.Spawn(explosion, pos, rotation); } collision.collider.gameObject.SendMessageUpwards("TakeDamage", weapon.damage, SendMessageOptions.DontRequireReceiver); if (collision.rigidbody) { Vector3 force = transform.forward * weapon.force; collision.rigidbody.AddForce(force, ForceMode.Impulse); } // Call function to destroy the rocket Kill(); }
private void HandleCollision(Collision collision) { // See if any contact point with this collider is below the gravity receiver if (!groundColliders.Contains(collision.collider)) { for (int i = 0; i < collision.contactCount; i++) { ContactPoint contact = collision.GetContact(i); float dot = Vector3.Dot(contact.normal, -gravityDirection); if (dot >= minGroundDotProduct) { groundColliders.Add(collision.collider); totalGroundNormal += contact.normal; totalGroundFriction += collision.collider.material.staticFriction; totalGroundContactPoint += contact.point; UpdateIsGrounded(); return; } } } }
void OnCollisionEnter(Collision collision) { if (canCollide == true) { canCollide = false; ContactPoint contactPoint = collision.contacts [0]; GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.transform.localScale = new Vector3(5, 5, 5); cube.transform.position = contactPoint.point; iTween.MoveTo(cube, iTween.Hash( "y", 40, "time", 0.5)); iTween.MoveTo(cube, iTween.Hash( "position", new Vector3(55, 79, 10), "time", 0.5f, "delay", 0.5f, "oncompletetarget", this.gameObject, "oncompleteparams", cube, "oncomplete", "DestroyCubeAndIncrementGauge" )); } }
/// <summary> /// Creates sparks at point of hit. /// </summary> void SparkCreator(Collision other) { if (other.transform) { ContactPoint contact = other.contacts[0]; Quaternion rot = Quaternion.FromToRotation(Vector3.up, contact.normal) * Quaternion.Euler(-90, 0, 0); Vector3 pos = contact.point; if (sparks) { GameObject spark = (GameObject)Instantiate(sparks, pos, rot); spark.transform.localScale = transform.localScale * 2; foreach (Transform _spark in spark.transform) { _spark.localScale = transform.localScale * 2; } StartCoroutine(SparksCleaner(spark)); } else { Debug.LogError("You did not assign a spark prefab effect, default is located in DroneController/Prefabs/..."); } } }
private void OnCollisionEnter(Collision other) { if (other.gameObject.tag == "Lightsaber") { if (other.gameObject.GetComponent <SabreBehaviourControl>().defending) { int probability = Random.Range(1, 100); if (probability > 75) { travelAlong = -travelAlong; } else { transform.forward = travelAlong = ShootRay(); } boltFire.Play(); } } else if (other.gameObject.tag == "Player") { print("Hit player"); Destroy(gameObject); } else { print("destroyed"); Destroy(gameObject); } ContactPoint contact = other.contacts[0]; Quaternion rot = Quaternion.FromToRotation(Vector3.up, -transform.forward); Vector3 pos = contact.point; GameObject tempFX = Instantiate(sparkFX, pos, rot); Destroy(tempFX, 2f); }
protected virtual bool _proccess_wall( ContactPoint contact, Collision collision) { debug.draw.arrow( contact.point, contact.normal, Color.red, 5f); debug.draw.arrow( contact.point, Vector3.up, Color.magenta, 5f); var slope_angle = Vector3.Angle(contact.normal, Vector3.up); manager_collisions.add(new Collision_info( STR_WALL, collision, slope_angle)); if (contact.normal.z > 0) { manager_collisions.add(new Collision_info( STR_WALL_left, collision, slope_angle)); } else if (contact.normal.z < 0) { manager_collisions.add(new Collision_info( STR_WALL_right, collision, slope_angle)); } return(true); }
private Part GetCollidingPart(ContactPoint contactPoint) { GameObject searchObject = contactPoint.thisCollider.gameObject; Part foundPart = null; bool searchedOtherCollider = false; while (searchObject != null) { foundPart = searchObject.GetComponent <Part>(); if (foundPart != null) { return(foundPart); } searchObject = searchObject.transform == null ? null : searchObject.transform.parent == null ? null : searchObject.transform.parent.gameObject; if (searchObject == null && !searchedOtherCollider) // "thisCollider" is sometimes the ground... { searchedOtherCollider = true; searchObject = contactPoint.otherCollider.gameObject; } } return(null); }
public void addCollider(uint localID, ContactPoint contact) { ContactPoint oldCol; if (!m_objCollisionList.TryGetValue(localID, out oldCol)) m_objCollisionList.Add(localID, contact); else { if (oldCol.PenetrationDepth < contact.PenetrationDepth) m_objCollisionList[localID] = contact; } }
/* * \brief Works out if a value is almost another value (for floating point accuracy) */ public void CallOnCollisionContactEnter(ContactPoint contact) { // check the normal to see if the collision is in the horizontal plain if (!m_colliding && (contact.normal.y < 0.1 && contact.normal.y > -0.1)) { m_velocity = 0.0f; m_colliding = true; } }
/// <summary> /// This is our near callback. A geometry is near a body /// </summary> /// <param name="space">The space that contains the geoms. Remember, spaces are also geoms</param> /// <param name="g1">a geometry or space</param> /// <param name="g2">another geometry or space</param> private void near(IntPtr space, IntPtr g1, IntPtr g2) { // no lock here! It's invoked from within Simulate(), which is thread-locked if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) return; // Test if we're colliding a geom with a space. // If so we have to drill down into the space recursively if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) { // Separating static prim geometry spaces. // We'll be calling near recursivly if one // of them is a space to find all of the // contact points in the space try { d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); } catch (AccessViolationException) { m_log.Warn("[PHYSICS]: Unable to collide test a space"); return; } //Colliding a space or a geom with a space or a geom. so drill down //Collide all geoms in each space.. //if (d.GeomIsSpace(g1)) // d.SpaceCollide(g1, IntPtr.Zero, nearCallback); //if (d.GeomIsSpace(g2)) // d.SpaceCollide(g2, IntPtr.Zero, nearCallback); return; } IntPtr b1 = d.GeomGetBody(g1); IntPtr b2 = d.GeomGetBody(g2); int FindContactsTime = Util.EnvironmentTickCount(); // d.GeomClassID id = d.GeomGetClass(g1); //if (id == d.GeomClassId.TriMeshClass) //{ // m_log.InfoFormat("near: A collision was detected between {1} and {2}", 0, name1, name2); //m_log.Debug("near: A collision was detected between {1} and {2}", 0, name1, name2); //} // Figure out how many contact points we have int count = 0; PhysicsActor p1; PhysicsActor p2; if (!actor_name_map.TryGetValue (g1, out p1)) p1 = PANull; if (!actor_name_map.TryGetValue (g2, out p2)) p2 = PANull; if (p1 is AuroraODEPrim && (p1 as AuroraODEPrim)._zeroFlag) if (p2 is AuroraODEPrim && (p2 as AuroraODEPrim)._zeroFlag) return;//If its frozen, don't collide it against other objects, let them collide against it else (p1 as AuroraODEPrim)._zeroFlag = false; try { // Colliding Geom To Geom // This portion of the function 'was' blatantly ripped off from BoxStack.cs if (g1 == g2) return; // Can't collide with yourself if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) return; lock (contacts) { count = d.Collide(g1, g2, (contacts.Length & 0xffff), contacts, d.ContactGeom.SizeOf); } } catch (SEHException) { m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); ode.drelease(world); } catch (Exception e) { m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.ToString()); return; } if (count == 0) return; m_StatFindContactsTime = Util.EnvironmentTickCountSubtract(FindContactsTime); ContactPoint maxDepthContact = new ContactPoint(); if (!DisableCollisions) { if (p1.CollisionScore + count >= float.MaxValue) p1.CollisionScore = 0; p1.CollisionScore += count; if (p2.CollisionScore + count >= float.MaxValue) p2.CollisionScore = 0; p2.CollisionScore += count; } int ContactLoopTime = Util.EnvironmentTickCount(); #region Contact Loop for (int i = 0; i < count; i++) { d.ContactGeom curContact = contacts[i]; if (curContact.depth > maxDepthContact.PenetrationDepth) { maxDepthContact.PenetrationDepth = curContact.depth; maxDepthContact.Position.X = curContact.pos.X; maxDepthContact.Position.Y = curContact.pos.Y; maxDepthContact.Position.Z = curContact.pos.Z; maxDepthContact.SurfaceNormal.X = curContact.normal.X; maxDepthContact.SurfaceNormal.Y = curContact.normal.Y; maxDepthContact.SurfaceNormal.Z = curContact.normal.Z; // maxDepthContact = new ContactPoint( // new Vector3((float)curContact.pos.X, (float)curContact.pos.Y, (float)curContact.pos.Z), // new Vector3((float)curContact.normal.X, (float)curContact.normal.Y, (float)curContact.normal.Z), // (float)curContact.depth // ); } //m_log.Warn("[CCOUNT]: " + count); IntPtr joint; // If we're colliding with terrain, use 'TerrainContact' instead of contact. // allows us to have different settings // we don't want prim or avatar to explode #region InterPenetration Handling - Unintended physics explosions #region disabled code1 /* if (curContact.depth >= 0.08f) { //This is disabled at the moment only because it needs more tweaking //It will eventually be uncommented if (contact.depth >= 1.00f) { //m_log.Debug("[PHYSICS]: " + contact.depth.ToString()); } //If you interpenetrate a prim with an agent if ((p2.PhysicsActorType == (int) ActorTypes.Agent && p1.PhysicsActorType == (int) ActorTypes.Prim) || (p1.PhysicsActorType == (int) ActorTypes.Agent && p2.PhysicsActorType == (int) ActorTypes.Prim)) { //contact.depth = contact.depth * 4.15f; if (p2.PhysicsActorType == (int) ActorTypes.Agent) { p2.CollidingObj = true; contact.depth = 0.003f; p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 2.5f); OdeCharacter character = (OdeCharacter) p2; character.SetPidStatus(true); contact.pos = new d.Vector3(contact.pos.X + (p1.Size.X / 2), contact.pos.Y + (p1.Size.Y / 2), contact.pos.Z + (p1.Size.Z / 2)); } else { //contact.depth = 0.0000000f; } if (p1.PhysicsActorType == (int) ActorTypes.Agent) { p1.CollidingObj = true; contact.depth = 0.003f; p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 2.5f); contact.pos = new d.Vector3(contact.pos.X + (p2.Size.X / 2), contact.pos.Y + (p2.Size.Y / 2), contact.pos.Z + (p2.Size.Z / 2)); OdeCharacter character = (OdeCharacter)p1; character.SetPidStatus(true); } else { //contact.depth = 0.0000000f; } } */ // If you interpenetrate a prim with another prim /* if (p1.PhysicsActorType == (int) ActorTypes.Prim && p2.PhysicsActorType == (int) ActorTypes.Prim) { #region disabledcode2 //OdePrim op1 = (OdePrim)p1; //OdePrim op2 = (OdePrim)p2; //op1.m_collisionscore++; //op2.m_collisionscore++; //if (op1.m_collisionscore > 8000 || op2.m_collisionscore > 8000) //{ //op1.m_taintdisable = true; //AddPhysicsActorTaint(p1); //op2.m_taintdisable = true; //AddPhysicsActorTaint(p2); //} //if (contact.depth >= 0.25f) //{ // Don't collide, one or both prim will expld. //op1.m_interpenetrationcount++; //op2.m_interpenetrationcount++; //interpenetrations_before_disable = 200; //if (op1.m_interpenetrationcount >= interpenetrations_before_disable) //{ //op1.m_taintdisable = true; //AddPhysicsActorTaint(p1); //} //if (op2.m_interpenetrationcount >= interpenetrations_before_disable) //{ // op2.m_taintdisable = true; //AddPhysicsActorTaint(p2); //} //contact.depth = contact.depth / 8f; //contact.normal = new d.Vector3(0, 0, 1); //} //if (op1.m_disabled || op2.m_disabled) //{ //Manually disabled objects stay disabled //contact.depth = 0f; //} #endregion } // if (curContact.depth >= 1.0f) { //m_log.Info("[P]: " + contact.depth.ToString()); if ((p2.PhysicsActorType == (int)ActorTypes.Agent && p1.PhysicsActorType == (int)ActorTypes.Ground) || (p1.PhysicsActorType == (int)ActorTypes.Agent && p2.PhysicsActorType == (int)ActorTypes.Ground)) { if (p2.PhysicsActorType == (int)ActorTypes.Agent) { if (p2 is AuroraODECharacter) { AuroraODECharacter character = (AuroraODECharacter)p2; //p2.CollidingObj = true; if (p2.Position.Z < curContact.pos.Z) // don't colide from underside { p2.CollidingGround = false; p2.CollidingGround = false; continue; } curContact.depth = 0.00000003f; p2.Velocity = p2.Velocity + new Vector3(0f, 0f, 1.5f); curContact.pos = new d.Vector3(curContact.pos.X + (p2.Size.X / 2), curContact.pos.Y + (p2.Size.Y / 2), curContact.pos.Z + (p2.Size.Z / 2)); character.SetPidStatus(true); } } if (p1.PhysicsActorType == (int)ActorTypes.Agent) { if (p1 is AuroraODECharacter) { AuroraODECharacter character = (AuroraODECharacter)p1; //p2.CollidingObj = true; if (p1.Position.Z < curContact.pos.Z) { p1.CollidingGround = false; p1.CollidingGround = false; continue; } curContact.depth = 0.00000003f; p1.Velocity = p1.Velocity + new Vector3(0f, 0f, 0.5f); curContact.pos = new d.Vector3(curContact.pos.X + (p1.Size.X / 2), curContact.pos.Y + (p1.Size.Y / 2), curContact.pos.Z + (p1.Size.Z / 2)); character.SetPidStatus(true); } } } } } */ #endregion #endregion // Logic for collision handling // Note, that if *all* contacts are skipped (VolumeDetect) // The prim still detects (and forwards) collision events but // appears to be phantom for the world Boolean skipThisContact = false; if (p1 is PhysicsObject && ((PhysicsObject)p1).VolumeDetect) skipThisContact = true; // No collision on volume detect prims if (p2 is PhysicsObject && ((PhysicsObject)p2).VolumeDetect) skipThisContact = true; // No collision on volume detect prims if (curContact.depth < 0f) skipThisContact = true; if (!skipThisContact && m_filterCollisions && checkDupe (curContact, p2.PhysicsActorType)) skipThisContact = true; joint = IntPtr.Zero; if (!skipThisContact) { // If we're colliding against terrain if (p1.PhysicsActorType == (int)ActorTypes.Ground) { if (p2.PhysicsActorType == (int)ActorTypes.Prim) { if (m_filterCollisions) _perloopContact.Add(curContact); //Add restitution and friction changes d.Contact contact = ((AuroraODEPrim)p2).GetContactPoint (ActorTypes.Ground); contact.geom = curContact; if (m_global_contactcount < m_currentmaxContactsbeforedeath) { joint = d.JointCreateContact (world, contactgroup, ref contact); m_global_contactcount++; } } //Can't collide against anything else, agents do their own ground checks } else { // we're colliding with prim or avatar // check if we're moving if ((p2.PhysicsActorType == (int)ActorTypes.Agent)) { if ((Math.Abs (p2.Velocity.X) > 0.01f || Math.Abs (p2.Velocity.Y) > 0.01f)) { // Use the Movement prim contact AvatarMovementprimContact.geom = curContact; if (m_filterCollisions) _perloopContact.Add (curContact); if (m_global_contactcount < m_currentmaxContactsbeforedeath) { joint = d.JointCreateContact (world, contactgroup, ref AvatarMovementprimContact); m_global_contactcount++; } } else { // Use the non movement contact contact.geom = curContact; if (m_filterCollisions) _perloopContact.Add (curContact); if (m_global_contactcount < m_currentmaxContactsbeforedeath) { joint = d.JointCreateContact (world, contactgroup, ref contact); m_global_contactcount++; } } } else if (p2.PhysicsActorType == (int)ActorTypes.Prim) { if (m_filterCollisions) _perloopContact.Add(curContact); //Add restitution and friction changes d.Contact contact = ((AuroraODEPrim)p2).GetContactPoint (ActorTypes.Prim); contact.geom = curContact; if (m_global_contactcount < m_currentmaxContactsbeforedeath) { joint = d.JointCreateContact (world, contactgroup, ref contact); m_global_contactcount++; } } } if (m_global_contactcount < m_currentmaxContactsbeforedeath && joint != IntPtr.Zero) // stack collide! { d.JointAttach(joint, b1, b2); m_global_contactcount++; } } //m_log.Debug(count.ToString()); //m_log.Debug("near: A collision was detected between {1} and {2}", 0, name1, name2); } #endregion m_StatContactLoopTime = Util.EnvironmentTickCountSubtract(ContactLoopTime); int CollisionAccountingTime = Util.EnvironmentTickCount(); if (!DisableCollisions) { bool p2col = false; // We only need to test p2 for 'jump crouch purposes' if (p2 is AuroraODECharacter && p1.PhysicsActorType == (int)ActorTypes.Prim) { // Testing if the collision is at the feet of the avatar if ((p2.Position.Z - maxDepthContact.Position.Z) > (p2.Size.Z * 0.6f)) p2col = true; } else p2col = true; p2.IsColliding = p2col; if (count > geomContactPointsStartthrottle) { // If there are more then 3 contact points, it's likely // that we've got a pile of objects, so ... // We don't want to send out hundreds of terse updates over and over again // so lets throttle them and send them again after it's somewhat sorted out. p2.ThrottleUpdates = true; } collision_accounting_events(p1, p2, maxDepthContact); } m_StatCollisionAccountingTime = Util.EnvironmentTickCountSubtract(CollisionAccountingTime); }
private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact) { if (!p2.SubscribedEvents() && !p1.SubscribedEvents()) return; FireCollisionEvent (p1, p2, contact); p1.AddCollisionEvent (p2.LocalID, contact); p2.AddCollisionEvent (p1.LocalID, contact); }
private void ProcessContact(uint cont, uint contWith, ContactPoint contact, ref List<BulletDotNETPrim> primsWithCollisions, ref List<BulletDotNETCharacter> charactersWithCollisions) { BulletDotNETPrim bdnp; // collisions with a normal prim? if (m_primsLocalID.TryGetValue(cont, out bdnp)) { // Added collision event to the prim. This creates a pile of events // that will be sent to any subscribed listeners. bdnp.AddCollision(contWith, contact); if (!primsWithCollisions.Contains(bdnp)) { primsWithCollisions.Add(bdnp); } } else { BulletDotNETCharacter bdnc; // if not a prim, maybe it's one of the characters if (m_charactersLocalID.TryGetValue(cont, out bdnc)) { bdnc.AddCollision(contWith, contact); if (!charactersWithCollisions.Contains(bdnc)) { charactersWithCollisions.Add(bdnc); } } } }
public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { if (m_eventsubscription > 0) { CollisionEventsThisFrame.addCollider(CollidedWith, contact); } }
public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { if (CollisionEventsThisFrame == null) CollisionEventsThisFrame = new CollisionEventUpdate(); CollisionEventsThisFrame.addCollider(CollidedWith, contact); }
public void AddCollider(uint localID, ContactPoint contact) { if (!m_objCollisionList.ContainsKey(localID)) { m_objCollisionList.Add(localID, contact); } else { if (m_objCollisionList[localID].PenetrationDepth < contact.PenetrationDepth) m_objCollisionList[localID] = contact; } }
public void PhysicsCollision(EventArgs e) { // single threaded here if (e == null) return; CollisionEventUpdate a = (CollisionEventUpdate) e; Dictionary<uint, ContactPoint> collissionswith = a.GetCollisionEvents(); List<uint> thisHitColliders = new List<uint>(); List<uint> startedColliders = new List<uint>(); ContactPoint startedCollider = new ContactPoint(); // calculate things that started colliding this time // and build up list of colliders this time foreach (uint localID in collissionswith.Keys) { thisHitColliders.Add(localID); if (!m_lastColliders.Contains(localID)) { startedCollider = collissionswith[localID]; startedColliders.Add(localID); } //MainConsole.Instance.Debug("[OBJECT]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString()); } // calculate things that ended colliding List<uint> endedColliders = m_lastColliders.Where(localID => !thisHitColliders.Contains(localID)).ToList(); //add the items that started colliding this time to the last colliders list. m_lastColliders.AddRange(startedColliders); // remove things that ended colliding from the last colliders list foreach (uint localID in endedColliders) m_lastColliders.Remove(localID); if (m_parentGroup == null) return; if (m_parentGroup.IsDeleted) return; const string SoundGlassCollision = "6a45ba0b-5775-4ea8-8513-26008a17f873"; const string SoundMetalCollision = "9e5c1297-6eed-40c0-825a-d9bcd86e3193"; const string SoundStoneCollision = "9538f37c-456e-4047-81be-6435045608d4"; const string SoundFleshCollision = "dce5fdd4-afe4-4ea1-822f-dd52cac46b08"; const string SoundPlasticCollision = "0e24a717-b97e-4b77-9c94-b59a5a88b2da"; const string SoundRubberCollision = "153c8bf7-fb89-4d89-b263-47e58b1b4774"; const string SoundWoodCollision = "063c97d3-033a-4e9b-98d8-05c8074922cb"; // play the sound. if (startedColliders.Count > 0 && CollisionSound != UUID.Zero && CollisionSoundVolume > 0.0f) { SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, 0, 0); } else if (startedColliders.Count > 0) { switch (startedCollider.Type) { case ActorTypes.Agent: break; // Agents will play the sound so we don't case ActorTypes.Ground: SendSound(SoundWoodCollision, 1, true, 0, 0); break; //Always play the click or thump sound when hitting ground case ActorTypes.Prim: switch (Material) { case (int) OpenMetaverse.Material.Flesh: SendSound(SoundFleshCollision, 1, true, 0, 0); break; case (int) OpenMetaverse.Material.Glass: SendSound(SoundGlassCollision, 1, true, 0, 0); break; case (int) OpenMetaverse.Material.Metal: SendSound(SoundMetalCollision, 1, true, 0, 0); break; case (int) OpenMetaverse.Material.Plastic: SendSound(SoundPlasticCollision, 1, true, 0, 0); break; case (int) OpenMetaverse.Material.Rubber: SendSound(SoundRubberCollision, 1, true, 0, 0); break; case (int) OpenMetaverse.Material.Stone: SendSound(SoundStoneCollision, 1, true, 0, 0); break; case (int) OpenMetaverse.Material.Wood: SendSound(SoundWoodCollision, 1, true, 0, 0); break; } break; //Play based on material type in prim2prim collisions default: break; //Unclear of what this object is, no sounds } } if (CollisionSprite != UUID.Zero && CollisionSoundVolume > 0.0f) // The collision volume isn't a mistake, its an SL feature/bug { // TODO: make a sprite! } if (((AggregateScriptEvents & scriptEvents.collision) != 0) || ((AggregateScriptEvents & scriptEvents.collision_end) != 0) || ((AggregateScriptEvents & scriptEvents.collision_start) != 0) || ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0) || ((AggregateScriptEvents & scriptEvents.land_collision) != 0) || ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) || (CollisionSound != UUID.Zero) || PassCollisions != 2) { if ((AggregateScriptEvents & scriptEvents.collision_start) != 0 || (AggregateScriptEvents & scriptEvents.collision) != 0) { // do event notification if (startedColliders.Count > 0) { ColliderArgs StartCollidingMessage = new ColliderArgs(); List<DetectedObject> colliding = new List<DetectedObject>(); foreach (uint localId in startedColliders) { if (localId != 0) { // always running this check because if the user deletes the object it would return a null reference. if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; ISceneChildEntity obj = m_parentGroup.Scene.GetSceneObjectPart(localId); string data = ""; if (obj != null) { if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this object if (found) { DetectedObject detobj = new DetectedObject { keyUUID = obj.UUID, nameStr = obj.Name, ownerUUID = obj.OwnerID, posVector = obj.AbsolutePosition, rotQuat = obj.GetWorldRotation(), velVector = obj.Velocity, colliderType = 0, groupUUID = obj.GroupID }; colliding.Add(detobj); } //If it is 0, it is to not accept collisions from this object else { } } else { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work if (!found) { DetectedObject detobj = new DetectedObject { keyUUID = obj.UUID, nameStr = obj.Name, ownerUUID = obj.OwnerID, posVector = obj.AbsolutePosition, rotQuat = obj.GetWorldRotation(), velVector = obj.Velocity, colliderType = 0, groupUUID = obj.GroupID }; colliding.Add(detobj); } } } else { IScenePresence av = ParentGroup.Scene.GetScenePresence(localId); if (av != null) { if (av.LocalId == localId) { if ( m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar if (found) { DetectedObject detobj = new DetectedObject { keyUUID = av.UUID, nameStr = av.ControllingClient.Name, ownerUUID = av.UUID, posVector = av.AbsolutePosition, rotQuat = av.Rotation, velVector = av.Velocity, colliderType = 0, groupUUID = av.ControllingClient .ActiveGroupId }; colliding.Add(detobj); } //If it is 0, it is to not accept collisions from this avatar else { } } else { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work if (!found) { DetectedObject detobj = new DetectedObject { keyUUID = av.UUID, nameStr = av.ControllingClient.Name, ownerUUID = av.UUID, posVector = av.AbsolutePosition, rotQuat = av.Rotation, velVector = av.Velocity, colliderType = 0, groupUUID = av.ControllingClient .ActiveGroupId }; colliding.Add(detobj); } } } } } } } if (colliding.Count > 0) { StartCollidingMessage.Colliders = colliding; // always running this check because if the user deletes the object it would return a null reference. if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; //Always send to the prim it is occuring to m_parentGroup.Scene.EventManager.TriggerScriptCollidingStart(this, StartCollidingMessage); if ((this.UUID != this.ParentGroup.RootPart.UUID)) { const int PASS_IF_NOT_HANDLED = 0; const int PASS_ALWAYS = 1; const int PASS_NEVER = 2; if (this.PassCollisions == PASS_NEVER) { } if (this.PassCollisions == PASS_ALWAYS) { m_parentGroup.Scene.EventManager.TriggerScriptCollidingStart( this.ParentGroup.RootPart, StartCollidingMessage); } else if (((this.ScriptEvents & scriptEvents.collision_start) == 0) && this.PassCollisions == PASS_IF_NOT_HANDLED) //If no event in this prim, pass to parent { m_parentGroup.Scene.EventManager.TriggerScriptCollidingStart( this.ParentGroup.RootPart, StartCollidingMessage); } } } } } if ((AggregateScriptEvents & scriptEvents.collision) != 0) { if (m_lastColliders.Count > 0) { ColliderArgs CollidingMessage = new ColliderArgs(); List<DetectedObject> colliding = new List<DetectedObject>(); foreach (uint localId in m_lastColliders) { if (localId != 0) { if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; ISceneChildEntity obj = m_parentGroup.Scene.GetSceneObjectPart(localId); string data = ""; if (obj != null) { if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this object if (found) { DetectedObject detobj = new DetectedObject { keyUUID = obj.UUID, nameStr = obj.Name, ownerUUID = obj.OwnerID, posVector = obj.AbsolutePosition, rotQuat = obj.GetWorldRotation(), velVector = obj.Velocity, colliderType = 0, groupUUID = obj.GroupID }; colliding.Add(detobj); } //If it is 0, it is to not accept collisions from this object else { } } else { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work if (!found) { DetectedObject detobj = new DetectedObject { keyUUID = obj.UUID, nameStr = obj.Name, ownerUUID = obj.OwnerID, posVector = obj.AbsolutePosition, rotQuat = obj.GetWorldRotation(), velVector = obj.Velocity, colliderType = 0, groupUUID = obj.GroupID }; colliding.Add(detobj); } } } else { IScenePresence av = ParentGroup.Scene.GetScenePresence(localId); if (av != null) { if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar if (found) { DetectedObject detobj = new DetectedObject { keyUUID = av.UUID, nameStr = av.ControllingClient.Name, ownerUUID = av.UUID, posVector = av.AbsolutePosition, rotQuat = av.Rotation, velVector = av.Velocity, colliderType = 0, groupUUID = av.ControllingClient.ActiveGroupId }; colliding.Add(detobj); } //If it is 0, it is to not accept collisions from this avatar else { } } else { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work if (!found) { DetectedObject detobj = new DetectedObject { keyUUID = av.UUID, nameStr = av.ControllingClient.Name, ownerUUID = av.UUID, posVector = av.AbsolutePosition, rotQuat = av.Rotation, velVector = av.Velocity, colliderType = 0, groupUUID = av.ControllingClient.ActiveGroupId }; colliding.Add(detobj); } } } } } } if (colliding.Count > 0) { CollidingMessage.Colliders = colliding; // always running this check because if the user deletes the object it would return a null reference. if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; m_parentGroup.Scene.EventManager.TriggerScriptColliding(this, CollidingMessage); if ((this.UUID != this.ParentGroup.RootPart.UUID)) { const int PASS_IF_NOT_HANDLED = 0; const int PASS_ALWAYS = 1; const int PASS_NEVER = 2; if (this.PassCollisions == PASS_NEVER) { } if (this.PassCollisions == PASS_ALWAYS) { m_parentGroup.Scene.EventManager.TriggerScriptColliding(this.ParentGroup.RootPart, CollidingMessage); } else if (((this.ScriptEvents & scriptEvents.collision) == 0) && this.PassCollisions == PASS_IF_NOT_HANDLED) //If no event in this prim, pass to parent { m_parentGroup.Scene.EventManager.TriggerScriptColliding( this.ParentGroup.RootPart, CollidingMessage); } } } } } if ((AggregateScriptEvents & scriptEvents.collision_end) != 0) { if (endedColliders.Count > 0) { ColliderArgs EndCollidingMessage = new ColliderArgs(); List<DetectedObject> colliding = new List<DetectedObject>(); foreach (uint localId in endedColliders) { if (localId != 0) { // always running this check because if the user deletes the object it would return a null reference. if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; ISceneChildEntity obj = m_parentGroup.Scene.GetSceneObjectPart(localId); string data = ""; if (obj != null) { if (m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name)) { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this object if (found) { DetectedObject detobj = new DetectedObject { keyUUID = obj.UUID, nameStr = obj.Name, ownerUUID = obj.OwnerID, posVector = obj.AbsolutePosition, rotQuat = obj.GetWorldRotation(), velVector = obj.Velocity, colliderType = 0, groupUUID = obj.GroupID }; colliding.Add(detobj); } //If it is 0, it is to not accept collisions from this object else { } } else { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this object, so this other object will not work if (!found) { DetectedObject detobj = new DetectedObject { keyUUID = obj.UUID, nameStr = obj.Name, ownerUUID = obj.OwnerID, posVector = obj.AbsolutePosition, rotQuat = obj.GetWorldRotation(), velVector = obj.Velocity, colliderType = 0, groupUUID = obj.GroupID }; colliding.Add(detobj); } } } else { IScenePresence av = ParentGroup.Scene.GetScenePresence(localId); if (av != null) { if (av.LocalId == localId) { if ( m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(av.Name)) { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar if (found) { DetectedObject detobj = new DetectedObject { keyUUID = av.UUID, nameStr = av.ControllingClient.Name, ownerUUID = av.UUID, posVector = av.AbsolutePosition, rotQuat = av.Rotation, velVector = av.Velocity, colliderType = 0, groupUUID = av.ControllingClient .ActiveGroupId }; colliding.Add(detobj); } //If it is 0, it is to not accept collisions from this avatar else { } } else { bool found = m_parentGroup.RootPart.CollisionFilter.TryGetValue(1, out data); //If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work if (!found) { DetectedObject detobj = new DetectedObject { keyUUID = av.UUID, nameStr = av.ControllingClient.Name, ownerUUID = av.UUID, posVector = av.AbsolutePosition, rotQuat = av.Rotation, velVector = av.Velocity, colliderType = 0, groupUUID = av.ControllingClient .ActiveGroupId }; colliding.Add(detobj); } } } } } } } if (colliding.Count > 0) { EndCollidingMessage.Colliders = colliding; // always running this check because if the user deletes the object it would return a null reference. if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; m_parentGroup.Scene.EventManager.TriggerScriptCollidingEnd(this, EndCollidingMessage); if ((this.UUID != this.ParentGroup.RootPart.UUID)) { const int PASS_IF_NOT_HANDLED = 0; const int PASS_ALWAYS = 1; const int PASS_NEVER = 2; if (this.PassCollisions == PASS_NEVER) { } if (this.PassCollisions == PASS_ALWAYS) { m_parentGroup.Scene.EventManager.TriggerScriptCollidingEnd( this.ParentGroup.RootPart, EndCollidingMessage); } else if (((this.ScriptEvents & scriptEvents.collision_end) == 0) && this.PassCollisions == PASS_IF_NOT_HANDLED) //If no event in this prim, pass to parent { m_parentGroup.Scene.EventManager.TriggerScriptCollidingEnd( this.ParentGroup.RootPart, EndCollidingMessage); } } } } } if ((AggregateScriptEvents & scriptEvents.land_collision_start) != 0 || (AggregateScriptEvents & scriptEvents.land_collision) != 0) { if (startedColliders.Count > 0) { ColliderArgs LandStartCollidingMessage = new ColliderArgs(); List<DetectedObject> colliding = (from localId in startedColliders where localId == 0 select new DetectedObject { keyUUID = UUID.Zero, nameStr = "", ownerUUID = UUID.Zero, posVector = m_parentGroup.RootPart.AbsolutePosition, rotQuat = Quaternion.Identity, velVector = Vector3.Zero, colliderType = 0, groupUUID = UUID.Zero }).ToList(); if (colliding.Count > 0) { LandStartCollidingMessage.Colliders = colliding; // always running this check because if the user deletes the object it would return a null reference. if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingStart(this, LandStartCollidingMessage); if ((this.UUID != this.ParentGroup.RootPart.UUID)) { const int PASS_IF_NOT_HANDLED = 0; const int PASS_ALWAYS = 1; const int PASS_NEVER = 2; if (this.PassCollisions == PASS_NEVER) { } if (this.PassCollisions == PASS_ALWAYS) { m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingStart( this.ParentGroup.RootPart, LandStartCollidingMessage); } else if (((this.ScriptEvents & scriptEvents.land_collision_start) == 0) && this.PassCollisions == PASS_IF_NOT_HANDLED) //If no event in this prim, pass to parent { m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingStart( this.ParentGroup.RootPart, LandStartCollidingMessage); } } } } } if ((AggregateScriptEvents & scriptEvents.land_collision) != 0) { if (m_lastColliders.Count > 0) { ColliderArgs LandCollidingMessage = new ColliderArgs(); List<DetectedObject> colliding = new List<DetectedObject>(); foreach (uint localId in m_lastColliders) { if (localId == 0) { //Hope that all is left is ground! DetectedObject detobj = new DetectedObject { keyUUID = UUID.Zero, nameStr = "", ownerUUID = UUID.Zero, posVector = m_parentGroup.RootPart.AbsolutePosition, rotQuat = Quaternion.Identity, velVector = Vector3.Zero, colliderType = 0, groupUUID = UUID.Zero }; colliding.Add(detobj); } } if (colliding.Count > 0) { LandCollidingMessage.Colliders = colliding; // always running this check because if the user deletes the object it would return a null reference. if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; m_parentGroup.Scene.EventManager.TriggerScriptLandColliding(this, LandCollidingMessage); if ((this.UUID != this.ParentGroup.RootPart.UUID)) { const int PASS_IF_NOT_HANDLED = 0; const int PASS_ALWAYS = 1; const int PASS_NEVER = 2; if (this.PassCollisions == PASS_NEVER) { } if (this.PassCollisions == PASS_ALWAYS) { m_parentGroup.Scene.EventManager.TriggerScriptLandColliding( this.ParentGroup.RootPart, LandCollidingMessage); } else if (((this.ScriptEvents & scriptEvents.land_collision) == 0) && this.PassCollisions == PASS_IF_NOT_HANDLED) //If no event in this prim, pass to parent { m_parentGroup.Scene.EventManager.TriggerScriptLandColliding( this.ParentGroup.RootPart, LandCollidingMessage); } } } } } if ((AggregateScriptEvents & scriptEvents.land_collision_end) != 0) { if (endedColliders.Count > 0) { ColliderArgs LandEndCollidingMessage = new ColliderArgs(); List<DetectedObject> colliding = (from localId in startedColliders where localId == 0 select new DetectedObject { keyUUID = UUID.Zero, nameStr = "", ownerUUID = UUID.Zero, posVector = m_parentGroup.RootPart.AbsolutePosition, rotQuat = Quaternion.Identity, velVector = Vector3.Zero, colliderType = 0, groupUUID = UUID.Zero }).ToList(); if (colliding.Count > 0) { LandEndCollidingMessage.Colliders = colliding; // always running this check because if the user deletes the object it would return a null reference. if (m_parentGroup == null) return; if (m_parentGroup.Scene == null) return; m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd(this, LandEndCollidingMessage); if ((this.UUID != this.ParentGroup.RootPart.UUID)) { const int PASS_IF_NOT_HANDLED = 0; const int PASS_ALWAYS = 1; const int PASS_NEVER = 2; if (this.PassCollisions == PASS_NEVER) { } if (this.PassCollisions == PASS_ALWAYS) { m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd( this.ParentGroup.RootPart, LandEndCollidingMessage); } else if (((this.ScriptEvents & scriptEvents.land_collision_end) == 0) && this.PassCollisions == PASS_IF_NOT_HANDLED) //If no event in this prim, pass to parent { m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd( this.ParentGroup.RootPart, LandEndCollidingMessage); } } } } } } }
public override void AddCollisionEvent (uint CollidedWith, ContactPoint contact) { if (base.SubscribedToCollisions () && SubscribedEvents())//If we don't have anything that we are going to trigger, don't even add { if (CollisionEventsThisFrame == null) CollisionEventsThisFrame = new CollisionEventUpdate (); CollisionEventsThisFrame.addCollider (CollidedWith, contact); } }
private void PreSolve(Contact contact, ref Manifold oldManifold) { if ((Flags & DebugViewFlags.ContactPoints) == DebugViewFlags.ContactPoints) { Manifold manifold = contact.Manifold; if (manifold.PointCount == 0) return; Fixture fixtureA = contact.FixtureA; FixedArray2<PointState> state1, state2; Collision.Collision.GetPointStates(out state1, out state2, ref oldManifold, ref manifold); FixedArray2<Vector2> points; Vector2 normal; contact.GetWorldManifold(out normal, out points); for (int i = 0; i < manifold.PointCount && _pointCount < MaxContactPoints; ++i) { if (fixtureA == null) _points[i] = new ContactPoint(); ContactPoint cp = _points[_pointCount]; cp.Position = points[i]; cp.Normal = normal; cp.State = state2[i]; _points[_pointCount] = cp; ++_pointCount; } } }
public virtual void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { }
private void near(IntPtr space, IntPtr g1, IntPtr g2) { // no lock here! It's invoked from within Simulate(), which is thread-locked if (m_global_contactcount >= maxContactsbeforedeath) return; // Test if we're colliding a geom with a space. // If so we have to drill down into the space recursively if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) return; if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) { // We'll be calling near recursivly if one // of them is a space to find all of the // contact points in the space try { d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); } catch (AccessViolationException) { m_log.Warn("[PHYSICS]: Unable to collide test a space"); return; } //here one should check collisions of geoms inside a space // but on each space we only should have geoms that not colide amoung each other // so we don't dig inside spaces return; } // get geom bodies to check if we already a joint contact // guess this shouldn't happen now IntPtr b1 = d.GeomGetBody(g1); IntPtr b2 = d.GeomGetBody(g2); // d.GeomClassID id = d.GeomGetClass(g1); // Figure out how many contact points we have int count = 0; try { // Colliding Geom To Geom // This portion of the function 'was' blatantly ripped off from BoxStack.cs if (g1 == g2) return; // Can't collide with yourself if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) return; count = d.CollidePtr(g1, g2, (contactsPerCollision & 0xffff), ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); } catch (SEHException) { m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); // ode.drelease(world); base.TriggerPhysicsBasedRestart(); } catch (Exception e) { m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message); return; } // no contacts so done if (count == 0) return; // now we have a contact describing colision of 2 things // but with my changes now we don't know what they are // so code gets more complex now // try get physical actors PhysicsActor p1; PhysicsActor p2; if (!actor_name_map.TryGetValue(g1, out p1)) { p1 = PANull; } if (!actor_name_map.TryGetValue(g2, out p2)) { p2 = PANull; } // update actors collision score if (p1.CollisionScore >= float.MaxValue - count) p1.CollisionScore = 0; p1.CollisionScore += count; if (p2.CollisionScore >= float.MaxValue - count) p2.CollisionScore = 0; p2.CollisionScore += count; // get geoms names String name1 = null; String name2 = null; if (!geom_name_map.TryGetValue(g1, out name1)) { name1 = "null"; } if (!geom_name_map.TryGetValue(g2, out name2)) { name2 = "null"; } ContactPoint maxDepthContact = new ContactPoint(); d.ContactGeom curContact = new d.ContactGeom(); float mu; float bounce; ContactData contactdata1; ContactData contactdata2; for (int i = 0; i < count; i++) { if (!GetCurContactGeom(i, ref curContact)) break; if (curContact.depth <= 0) continue; if(curContact.g1 == IntPtr.Zero) curContact.g1 = g1; if(curContact.g2 == IntPtr.Zero) curContact.g2 = g2; //for debug d.Quaternion qtmp = d.BodyGetQuaternion(b1); if (curContact.depth > maxDepthContact.PenetrationDepth) { maxDepthContact = new ContactPoint( new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z), new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z), curContact.depth ); } IntPtr Joint; // inform actors about colision if (p1 is OdeCharacter && p2.PhysicsActorType == (int)ActorTypes.Prim) { // Testing if the collision is at the feet of the avatar if ((p1.Position.Z - curContact.pos.Z) > (p1.Size.Z - avCapRadius) * 0.5f) p1.IsColliding = true; } else { p1.IsColliding = true; } switch (p2.PhysicsActorType) { case (int)ActorTypes.Agent: p1.CollidingObj = true; break; case (int)ActorTypes.Prim: if (p1.Velocity.LengthSquared() > 0.0f) p1.CollidingObj = true; break; case (int)ActorTypes.Unknown: p1.CollidingGround = true; break; default: p1.CollidingGround = true; break; } if (p2 is OdeCharacter && p1.PhysicsActorType == (int)ActorTypes.Prim) { // Testing if the collision is at the feet of the avatar if ((p2.Position.Z - curContact.pos.Z) > (p2.Size.Z - avCapRadius) * 0.5f) p2.IsColliding = true; } else { p2.IsColliding = true; } switch (p1.PhysicsActorType) { case (int)ActorTypes.Agent: p2.CollidingObj = true; break; case (int)ActorTypes.Prim: if (p2.Velocity.LengthSquared() > 0.0f) p2.CollidingObj = true; break; case (int)ActorTypes.Unknown: p2.CollidingGround = true; break; default: p2.CollidingGround = true; break; } if (m_global_contactcount >= maxContactsbeforedeath) break; // we don't want prim or avatar to explode // not in use section, so removed see older commits if needed // skip actors with volumeDetect Boolean skipThisContact = false; if ((p1 is OdePrim) && (((OdePrim)p1).m_isVolumeDetect)) skipThisContact = true; // No collision on volume detect prims if (!skipThisContact && (p2 is OdePrim) && (((OdePrim)p2).m_isVolumeDetect)) skipThisContact = true; // No collision on volume detect prims // if (!skipThisContact && curContact.depth < 0f) // skipThisContact = true; // if (!skipThisContact && checkDupe(curContact, p2.PhysicsActorType)) // skipThisContact = true; Joint = IntPtr.Zero; if (!skipThisContact) { // If we're colliding against terrain if (name1 == "Terrain") { // avatar to ground /* not done by ode if (p2.PhysicsActorType == (int)ActorTypes.Agent) { // If we're moving if (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f) { float mu = AvatarMovementTerrainContactSurf.mu; float bounce = AvatarMovementTerrainContactSurf.bounce; float soft_cfm = AvatarMovementTerrainContactSurf.soft_cfm; float soft_erp = AvatarMovementTerrainContactSurf.soft_erp; doJoint = SetGlobalContact(ref curContact, mu, bounce, soft_cfm, soft_erp); } else { // Use the non moving terrain contact float mu = TerrainContactSurf.mu; float bounce = TerrainContactSurf.bounce; float soft_cfm = TerrainContactSurf.soft_cfm; float soft_erp = TerrainContactSurf.soft_erp; doJoint = SetGlobalContact(ref curContact, mu, bounce, soft_cfm, soft_erp); } } else */ if (p2.PhysicsActorType == (int)ActorTypes.Prim) { // prim terrain contact contactdata2 = p2.ContactData; bounce = contactdata2.bounce * TerrainBounce; mu = (float)Math.Sqrt(contactdata2.mu * TerrainFriction); if (Math.Abs(p2.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y) > 0.1f) mu *= frictionMovementMult; Joint = CreateContacJoint(ref curContact, mu, bounce, true); } } else if (name2 == "Terrain") { // avatar to ground /* not done by ode if (p1.PhysicsActorType == (int)ActorTypes.Agent) { // If we're moving if (Math.Abs(p1.Velocity.X) > 0.01f || Math.Abs(p1.Velocity.Y) > 0.01f) { // Use the movement terrain contact float mu = AvatarMovementTerrainContactSurf.mu; float bounce = AvatarMovementTerrainContactSurf.bounce; float soft_cfm = AvatarMovementTerrainContactSurf.soft_cfm; float soft_erp = AvatarMovementTerrainContactSurf.soft_erp; doJoint = SetGlobalContact(ref curContact, mu, bounce, soft_cfm, soft_erp); } else { // Use the non moving terrain contact float mu = TerrainContactSurf.mu; float bounce = TerrainContactSurf.bounce; float soft_cfm = TerrainContactSurf.soft_cfm; float soft_erp = TerrainContactSurf.soft_erp; doJoint = SetGlobalContact(ref curContact, mu, bounce, soft_cfm, soft_erp); } } else */ if (p1.PhysicsActorType == (int)ActorTypes.Prim) { // prim terrain contact contactdata1 = p1.ContactData; bounce = contactdata1.bounce * TerrainBounce; mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction); if (Math.Abs(p1.Velocity.X) > 0.1f || Math.Abs(p1.Velocity.Y) > 0.1f) mu *= frictionMovementMult; Joint = CreateContacJoint(ref curContact, mu, bounce, true); } } // collisions with water else if (name1 == "Water" || name2 == "Water") { if (curContact.depth > 0.1f) { curContact.depth *= 52; //contact.normal = new d.Vector3(0, 0, 1); //contact.pos = new d.Vector3(0, 0, contact.pos.Z - 5f); } mu = 0; bounce = 0; Joint = CreateContacJoint(ref curContact, mu, bounce,true); } else { // we're colliding with prim or avatar if (p1 != null && p2 != null) { contactdata1 = p1.ContactData; contactdata2 = p2.ContactData; bool erpsoft; // avatars fail colisions if 2 soft if (p1.PhysicsActorType == (int)ActorTypes.Agent || p2.PhysicsActorType == (int)ActorTypes.Agent) erpsoft = false; else erpsoft = true; bounce = contactdata1.bounce * contactdata2.bounce; mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); if ((Math.Abs(p2.Velocity.X - p1.Velocity.X) > 0.1f || Math.Abs(p2.Velocity.Y - p1.Velocity.Y) > 0.1f)) mu *= frictionMovementMult; Joint = CreateContacJoint(ref curContact, mu, bounce, erpsoft); } } if (Joint != IntPtr.Zero) { m_global_contactcount++; d.JointAttach(Joint, b1, b2); } } } // this was inside above loop ? collision_accounting_events(p1, p2, maxDepthContact); /* if (notskipedcount > geomContactPointsStartthrottle) { // If there are more then 3 contact points, it's likely // that we've got a pile of objects, so ... // We don't want to send out hundreds of terse updates over and over again // so lets throttle them and send them again after it's somewhat sorted out. this needs checking so out for now if (b1 != IntPtr.Zero) p1.ThrottleUpdates = true; if (b2 != IntPtr.Zero) p2.ThrottleUpdates = true; } */ }
private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact) { // obj1LocalID = 0; //returncollisions = false; obj2LocalID = 0; //ctype = 0; //cStartStop = 0; if (!(p2.SubscribedEvents() || p1.SubscribedEvents())) return; switch ((ActorTypes)p1.PhysicsActorType) { case ActorTypes.Agent: cc1 = (OdeCharacter)p1; switch ((ActorTypes)p2.PhysicsActorType) { case ActorTypes.Agent: cc2 = (OdeCharacter)p2; obj2LocalID = cc2.m_localID; if (p2.SubscribedEvents()) cc2.AddCollisionEvent(cc1.m_localID, contact); break; case ActorTypes.Prim: if (p2 is OdePrim) { cp2 = (OdePrim)p2; obj2LocalID = cp2.m_localID; if (p2.SubscribedEvents()) cp2.AddCollisionEvent(cc1.m_localID, contact); } break; case ActorTypes.Ground: case ActorTypes.Unknown: default: obj2LocalID = 0; break; } if (p1.SubscribedEvents()) { contact.SurfaceNormal = -contact.SurfaceNormal; cc1.AddCollisionEvent(obj2LocalID, contact); } break; case ActorTypes.Prim: if (p1 is OdePrim) { cp1 = (OdePrim)p1; // obj1LocalID = cp2.m_localID; switch ((ActorTypes)p2.PhysicsActorType) { case ActorTypes.Agent: if (p2 is OdeCharacter) { cc2 = (OdeCharacter)p2; obj2LocalID = cc2.m_localID; if (p2.SubscribedEvents()) cc2.AddCollisionEvent(cp1.m_localID, contact); } break; case ActorTypes.Prim: if (p2 is OdePrim) { cp2 = (OdePrim)p2; obj2LocalID = cp2.m_localID; if (p2.SubscribedEvents()) cp2.AddCollisionEvent(cp1.m_localID, contact); } break; case ActorTypes.Ground: case ActorTypes.Unknown: default: obj2LocalID = 0; break; } if (p1.SubscribedEvents()) { contact.SurfaceNormal = -contact.SurfaceNormal; cp1.AddCollisionEvent(obj2LocalID, contact); } } break; } }
public void AddCollision(uint collideWith, ContactPoint contact) { if (CollisionEventsThisFrame == null) { CollisionEventsThisFrame = new CollisionEventUpdate(); } CollisionEventsThisFrame.addCollider(collideWith, contact); }
public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { CollisionEventsThisFrame.AddCollider(CollidedWith, contact); }
internal void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { if (m_eventsubscription > 0) { // m_log.DebugFormat( // "[PHYSICS]: Adding collision event for {0}, collidedWith {1}, contact {2}", "", CollidedWith, contact); CollisionEventsThisFrame.AddCollider(CollidedWith, contact); } }
private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact) { // obj1LocalID = 0; //returncollisions = false; obj2LocalID = 0; //ctype = 0; //cStartStop = 0; if (!p2.SubscribedEvents() && !p1.SubscribedEvents()) return; switch ((ActorTypes)p2.PhysicsActorType) { case ActorTypes.Agent: cc2 = (OdeCharacter)p2; // obj1LocalID = cc2.m_localID; switch ((ActorTypes)p1.PhysicsActorType) { case ActorTypes.Agent: cc1 = (OdeCharacter)p1; obj2LocalID = cc1.m_localID; cc1.AddCollisionEvent(cc2.m_localID, contact); //ctype = (int)CollisionCategories.Character; //if (cc1.CollidingObj) //cStartStop = (int)StatusIndicators.Generic; //else //cStartStop = (int)StatusIndicators.Start; //returncollisions = true; break; case ActorTypes.Prim: if (p1 is OdePrim) { cp1 = (OdePrim) p1; obj2LocalID = cp1.m_localID; cp1.AddCollisionEvent(cc2.m_localID, contact); } //ctype = (int)CollisionCategories.Geom; //if (cp1.CollidingObj) //cStartStop = (int)StatusIndicators.Generic; //else //cStartStop = (int)StatusIndicators.Start; //returncollisions = true; break; case ActorTypes.Ground: case ActorTypes.Unknown: obj2LocalID = 0; //ctype = (int)CollisionCategories.Land; //returncollisions = true; break; } cc2.AddCollisionEvent(obj2LocalID, contact); break; case ActorTypes.Prim: if (p2 is OdePrim) { cp2 = (OdePrim) p2; // obj1LocalID = cp2.m_localID; switch ((ActorTypes) p1.PhysicsActorType) { case ActorTypes.Agent: if (p1 is OdeCharacter) { cc1 = (OdeCharacter) p1; obj2LocalID = cc1.m_localID; cc1.AddCollisionEvent(cp2.m_localID, contact); //ctype = (int)CollisionCategories.Character; //if (cc1.CollidingObj) //cStartStop = (int)StatusIndicators.Generic; //else //cStartStop = (int)StatusIndicators.Start; //returncollisions = true; } break; case ActorTypes.Prim: if (p1 is OdePrim) { cp1 = (OdePrim) p1; obj2LocalID = cp1.m_localID; cp1.AddCollisionEvent(cp2.m_localID, contact); //ctype = (int)CollisionCategories.Geom; //if (cp1.CollidingObj) //cStartStop = (int)StatusIndicators.Generic; //else //cStartStop = (int)StatusIndicators.Start; //returncollisions = true; } break; case ActorTypes.Ground: case ActorTypes.Unknown: obj2LocalID = 0; //ctype = (int)CollisionCategories.Land; //returncollisions = true; break; } cp2.AddCollisionEvent(obj2LocalID, contact); } break; } //if (returncollisions) //{ //lock (m_storedCollisions) //{ //cDictKey = obj1LocalID.ToString() + obj2LocalID.ToString() + cStartStop.ToString() + ctype.ToString(); //if (m_storedCollisions.ContainsKey(cDictKey)) //{ //sCollisionData objd = m_storedCollisions[cDictKey]; //objd.NumberOfCollisions += 1; //objd.lastframe = framecount; //m_storedCollisions[cDictKey] = objd; //} //else //{ //sCollisionData objd = new sCollisionData(); //objd.ColliderLocalId = obj1LocalID; //objd.CollidedWithLocalId = obj2LocalID; //objd.CollisionType = ctype; //objd.NumberOfCollisions = 1; //objd.lastframe = framecount; //objd.StatusIndicator = cStartStop; //m_storedCollisions.Add(cDictKey, objd); //} //} // } }
static int _CreateContactPoint(IntPtr L) { LuaScriptMgr.CheckArgsCount(L, 0); ContactPoint obj = new ContactPoint(); LuaScriptMgr.PushValue(L, obj); return 1; }
/// <summary> /// This is our near callback. A geometry is near a body /// </summary> /// <param name="space">The space that contains the geoms. Remember, spaces are also geoms</param> /// <param name="g1">a geometry or space</param> /// <param name="g2">another geometry or space</param> private void near(IntPtr space, IntPtr g1, IntPtr g2) { // no lock here! It's invoked from within Simulate(), which is thread-locked // Test if we're colliding a geom with a space. // If so we have to drill down into the space recursively if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) { if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) return; // Separating static prim geometry spaces. // We'll be calling near recursivly if one // of them is a space to find all of the // contact points in the space try { d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); } catch (AccessViolationException) { m_log.Warn("[PHYSICS]: Unable to collide test a space"); return; } //Colliding a space or a geom with a space or a geom. so drill down //Collide all geoms in each space.. //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback); //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback); return; } if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) return; IntPtr b1 = d.GeomGetBody(g1); IntPtr b2 = d.GeomGetBody(g2); // d.GeomClassID id = d.GeomGetClass(g1); String name1 = null; String name2 = null; if (!geom_name_map.TryGetValue(g1, out name1)) { name1 = "null"; } if (!geom_name_map.TryGetValue(g2, out name2)) { name2 = "null"; } //if (id == d.GeomClassId.TriMeshClass) //{ // m_log.InfoFormat("near: A collision was detected between {1} and {2}", 0, name1, name2); //m_log.Debug("near: A collision was detected between {1} and {2}", 0, name1, name2); //} // Figure out how many contact points we have int count = 0; try { // Colliding Geom To Geom // This portion of the function 'was' blatantly ripped off from BoxStack.cs if (g1 == g2) return; // Can't collide with yourself if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) return; lock (contacts) { count = d.Collide(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf); if (count > contacts.Length) m_log.Error("[PHYSICS]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length); } } catch (SEHException) { m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); ode.drelease(world); base.TriggerPhysicsBasedRestart(); } catch (Exception e) { m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message); return; } PhysicsActor p1; PhysicsActor p2; if (!actor_name_map.TryGetValue(g1, out p1)) { p1 = PANull; } if (!actor_name_map.TryGetValue(g2, out p2)) { p2 = PANull; } ContactPoint maxDepthContact = new ContactPoint(); if (p1.CollisionScore + count >= float.MaxValue) p1.CollisionScore = 0; p1.CollisionScore += count; if (p2.CollisionScore + count >= float.MaxValue) p2.CollisionScore = 0; p2.CollisionScore += count; for (int i = 0; i < count; i++) { d.ContactGeom curContact = contacts[i]; if (curContact.depth > maxDepthContact.PenetrationDepth) { maxDepthContact = new ContactPoint( new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z), new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z), curContact.depth ); } //m_log.Warn("[CCOUNT]: " + count); IntPtr joint; // If we're colliding with terrain, use 'TerrainContact' instead of contact. // allows us to have different settings // We only need to test p2 for 'jump crouch purposes' if (p2 is OdeCharacter && p1.PhysicsActorType == (int)ActorTypes.Prim) { // Testing if the collision is at the feet of the avatar //m_log.DebugFormat("[PHYSICS]: {0} - {1} - {2} - {3}", curContact.pos.Z, p2.Position.Z, (p2.Position.Z - curContact.pos.Z), (p2.Size.Z * 0.6f)); if ((p2.Position.Z - curContact.pos.Z) > (p2.Size.Z * 0.6f)) p2.IsColliding = true; } else { p2.IsColliding = true; } //if ((framecount % m_returncollisions) == 0) switch (p1.PhysicsActorType) { case (int)ActorTypes.Agent: p2.CollidingObj = true; break; case (int)ActorTypes.Prim: if (p2.Velocity.LengthSquared() > 0.0f) p2.CollidingObj = true; break; case (int)ActorTypes.Unknown: p2.CollidingGround = true; break; default: p2.CollidingGround = true; break; } // we don't want prim or avatar to explode #region InterPenetration Handling - Unintended physics explosions # region disabled code1 if (curContact.depth >= 0.08f) { //This is disabled at the moment only because it needs more tweaking //It will eventually be uncommented /* if (contact.depth >= 1.00f) { //m_log.Debug("[PHYSICS]: " + contact.depth.ToString()); } //If you interpenetrate a prim with an agent if ((p2.PhysicsActorType == (int) ActorTypes.Agent && p1.PhysicsActorType == (int) ActorTypes.Prim) || (p1.PhysicsActorType == (int) ActorTypes.Agent && p2.PhysicsActorType == (int) ActorTypes.Prim)) { //contact.depth = contact.depth * 4.15f; /* if (p2.PhysicsActorType == (int) ActorTypes.Agent) { p2.CollidingObj = true; contact.depth = 0.003f; p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 2.5f); OdeCharacter character = (OdeCharacter) p2; character.SetPidStatus(true); contact.pos = new d.Vector3(contact.pos.X + (p1.Size.X / 2), contact.pos.Y + (p1.Size.Y / 2), contact.pos.Z + (p1.Size.Z / 2)); } else { //contact.depth = 0.0000000f; } if (p1.PhysicsActorType == (int) ActorTypes.Agent) { p1.CollidingObj = true; contact.depth = 0.003f; p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 2.5f); contact.pos = new d.Vector3(contact.pos.X + (p2.Size.X / 2), contact.pos.Y + (p2.Size.Y / 2), contact.pos.Z + (p2.Size.Z / 2)); OdeCharacter character = (OdeCharacter)p1; character.SetPidStatus(true); } else { //contact.depth = 0.0000000f; } } */ // If you interpenetrate a prim with another prim /* if (p1.PhysicsActorType == (int) ActorTypes.Prim && p2.PhysicsActorType == (int) ActorTypes.Prim) { #region disabledcode2 //OdePrim op1 = (OdePrim)p1; //OdePrim op2 = (OdePrim)p2; //op1.m_collisionscore++; //op2.m_collisionscore++; //if (op1.m_collisionscore > 8000 || op2.m_collisionscore > 8000) //{ //op1.m_taintdisable = true; //AddPhysicsActorTaint(p1); //op2.m_taintdisable = true; //AddPhysicsActorTaint(p2); //} //if (contact.depth >= 0.25f) //{ // Don't collide, one or both prim will expld. //op1.m_interpenetrationcount++; //op2.m_interpenetrationcount++; //interpenetrations_before_disable = 200; //if (op1.m_interpenetrationcount >= interpenetrations_before_disable) //{ //op1.m_taintdisable = true; //AddPhysicsActorTaint(p1); //} //if (op2.m_interpenetrationcount >= interpenetrations_before_disable) //{ // op2.m_taintdisable = true; //AddPhysicsActorTaint(p2); //} //contact.depth = contact.depth / 8f; //contact.normal = new d.Vector3(0, 0, 1); //} //if (op1.m_disabled || op2.m_disabled) //{ //Manually disabled objects stay disabled //contact.depth = 0f; //} #endregion } */ #endregion if (curContact.depth >= 1.00f) { //m_log.Info("[P]: " + contact.depth.ToString()); if ((p2.PhysicsActorType == (int) ActorTypes.Agent && p1.PhysicsActorType == (int) ActorTypes.Unknown) || (p1.PhysicsActorType == (int) ActorTypes.Agent && p2.PhysicsActorType == (int) ActorTypes.Unknown)) { if (p2.PhysicsActorType == (int) ActorTypes.Agent) { if (p2 is OdeCharacter) { OdeCharacter character = (OdeCharacter) p2; //p2.CollidingObj = true; curContact.depth = 0.00000003f; p2.Velocity = p2.Velocity + new Vector3(0f, 0f, 0.5f); curContact.pos = new d.Vector3(curContact.pos.X + (p1.Size.X/2), curContact.pos.Y + (p1.Size.Y/2), curContact.pos.Z + (p1.Size.Z/2)); character.SetPidStatus(true); } } if (p1.PhysicsActorType == (int) ActorTypes.Agent) { if (p1 is OdeCharacter) { OdeCharacter character = (OdeCharacter) p1; //p2.CollidingObj = true; curContact.depth = 0.00000003f; p1.Velocity = p1.Velocity + new Vector3(0f, 0f, 0.5f); curContact.pos = new d.Vector3(curContact.pos.X + (p1.Size.X/2), curContact.pos.Y + (p1.Size.Y/2), curContact.pos.Z + (p1.Size.Z/2)); character.SetPidStatus(true); } } } } } #endregion // Logic for collision handling // Note, that if *all* contacts are skipped (VolumeDetect) // The prim still detects (and forwards) collision events but // appears to be phantom for the world Boolean skipThisContact = false; if ((p1 is OdePrim) && (((OdePrim)p1).m_isVolumeDetect)) skipThisContact = true; // No collision on volume detect prims if (!skipThisContact && (p2 is OdePrim) && (((OdePrim)p2).m_isVolumeDetect)) skipThisContact = true; // No collision on volume detect prims if (!skipThisContact && curContact.depth < 0f) skipThisContact = true; if (!skipThisContact && checkDupe(curContact, p2.PhysicsActorType)) skipThisContact = true; const int maxContactsbeforedeath = 4000; joint = IntPtr.Zero; if (!skipThisContact) { // If we're colliding against terrain if (name1 == "Terrain" || name2 == "Terrain") { // If we're moving if ((p2.PhysicsActorType == (int) ActorTypes.Agent) && (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) { // Use the movement terrain contact AvatarMovementTerrainContact.geom = curContact; _perloopContact.Add(curContact); if (m_global_contactcount < maxContactsbeforedeath) { joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact); m_global_contactcount++; } } else { if (p2.PhysicsActorType == (int)ActorTypes.Agent) { // Use the non moving terrain contact TerrainContact.geom = curContact; _perloopContact.Add(curContact); if (m_global_contactcount < maxContactsbeforedeath) { joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); m_global_contactcount++; } } else { if (p2.PhysicsActorType == (int)ActorTypes.Prim && p1.PhysicsActorType == (int)ActorTypes.Prim) { // prim prim contact // int pj294950 = 0; int movintYN = 0; int material = (int) Material.Wood; // prim terrain contact if (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f) { movintYN = 1; } if (p2 is OdePrim) material = ((OdePrim)p2).m_material; //m_log.DebugFormat("Material: {0}", material); m_materialContacts[material, movintYN].geom = curContact; _perloopContact.Add(curContact); if (m_global_contactcount < maxContactsbeforedeath) { joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); m_global_contactcount++; } } else { int movintYN = 0; // prim terrain contact if (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f) { movintYN = 1; } int material = (int)Material.Wood; if (p2 is OdePrim) material = ((OdePrim)p2).m_material; //m_log.DebugFormat("Material: {0}", material); m_materialContacts[material, movintYN].geom = curContact; _perloopContact.Add(curContact); if (m_global_contactcount < maxContactsbeforedeath) { joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); m_global_contactcount++; } } } } //if (p2.PhysicsActorType == (int)ActorTypes.Prim) //{ //m_log.Debug("[PHYSICS]: prim contacting with ground"); //} } else if (name1 == "Water" || name2 == "Water") { /* if ((p2.PhysicsActorType == (int) ActorTypes.Prim)) { } else { } */ //WaterContact.surface.soft_cfm = 0.0000f; //WaterContact.surface.soft_erp = 0.00000f; if (curContact.depth > 0.1f) { curContact.depth *= 52; //contact.normal = new d.Vector3(0, 0, 1); //contact.pos = new d.Vector3(0, 0, contact.pos.Z - 5f); } WaterContact.geom = curContact; _perloopContact.Add(curContact); if (m_global_contactcount < maxContactsbeforedeath) { joint = d.JointCreateContact(world, contactgroup, ref WaterContact); m_global_contactcount++; } //m_log.Info("[PHYSICS]: Prim Water Contact" + contact.depth); } else { // we're colliding with prim or avatar // check if we're moving if ((p2.PhysicsActorType == (int)ActorTypes.Agent)) { if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) { // Use the Movement prim contact AvatarMovementprimContact.geom = curContact; _perloopContact.Add(curContact); if (m_global_contactcount < maxContactsbeforedeath) { joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); m_global_contactcount++; } } else { // Use the non movement contact contact.geom = curContact; _perloopContact.Add(curContact); if (m_global_contactcount < maxContactsbeforedeath) { joint = d.JointCreateContact(world, contactgroup, ref contact); m_global_contactcount++; } } } else if (p2.PhysicsActorType == (int)ActorTypes.Prim) { //p1.PhysicsActorType int material = (int)Material.Wood; if (p2 is OdePrim) material = ((OdePrim)p2).m_material; //m_log.DebugFormat("Material: {0}", material); m_materialContacts[material, 0].geom = curContact; _perloopContact.Add(curContact); if (m_global_contactcount < maxContactsbeforedeath) { joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, 0]); m_global_contactcount++; } } } if (m_global_contactcount < maxContactsbeforedeath && joint != IntPtr.Zero) // stack collide! { d.JointAttach(joint, b1, b2); m_global_contactcount++; } } collision_accounting_events(p1, p2, maxDepthContact); if (count > geomContactPointsStartthrottle) { // If there are more then 3 contact points, it's likely // that we've got a pile of objects, so ... // We don't want to send out hundreds of terse updates over and over again // so lets throttle them and send them again after it's somewhat sorted out. p2.ThrottleUpdates = true; } //m_log.Debug(count.ToString()); //m_log.Debug("near: A collision was detected between {1} and {2}", 0, name1, name2); } }