public static bool ShiftCollision(Vector3 planeChange) { for (int i = 0; i < groundsArray.Length; i++) { groundBoundingBox = groundsArray[i].BoundingBox; var groundMin = groundBoundingBox.Center - new Vector3(groundBoundingBox.HalfWidth, groundBoundingBox.HalfHeight); var pBoundingBox = player.BoundingBox; var unitMax = pBoundingBox.Center + new Vector3(pBoundingBox.HalfWidth, pBoundingBox.HalfHeight) + pBoundingBox.Velocity * Time.deltaTime; if (groundMin.x > unitMax.x) { break; } var BoundingBoxCenter = pBoundingBox.Center + planeChange; AABB3D checkBoundingBox = new AABB3D(BoundingBoxCenter, pBoundingBox.HalfWidth * 2, pBoundingBox.HalfHeight * 2, pBoundingBox.HalfDepth * 2); if (aabbIntersection.Intersect(groundBoundingBox, checkBoundingBox)) { return false; } //if (Math.Abs(groundBoundingBox.Center.z - (playerBoundingBox.Center.z + planeChange.z)) // > (groundBoundingBox.HalfDepth + playerBoundingBox.HalfDepth)) // return false; } return true; }
private void normalCollision(AABB3D movingBox, AABB3D b0, AABB3D b1) { resetNormals(b0); wy = (movingBox.HalfWidth * 2 + b1.HalfWidth * 2) * (movingBox.Center.y - b1.Center.y); hx = (movingBox.HalfHeight * 2 + b1.HalfHeight * 2) * (movingBox.Center.x - b1.Center.x); if (wy > hx) { if (wy > -hx && b1.IgnoreCollision != IgnoreCollision.Y_AXIS) { b0.NormalCollision[1] = Vector3.down; } else if(b1.IgnoreCollision != IgnoreCollision.X_AXIS) { b0.NormalCollision[0] = Vector3.right; } } else { if (wy > -hx && b1.IgnoreCollision != IgnoreCollision.X_AXIS) { b0.NormalCollision[0] = Vector3.left; } else if(b1.IgnoreCollision != IgnoreCollision.Y_AXIS) { b0.NormalCollision[1] = Vector3.up; } } }
protected override void Start() { // TODO remove player checks from this class once a better solution than flipping the elbo is found if (this is Player) { playerWrist = GameObject.FindGameObjectWithTag("GunRotator"); gunFlip = playerWrist.GetComponent<Gun>(); } var boxCollider = gameObject.GetComponent<BoxCollider>(); rotationBox = new AABB3D(Vector3.zero, boxCollider.size.x * transform.lossyScale.x, boxCollider.size.y * transform.lossyScale.y, boxCollider.size.z * transform.lossyScale.z); if (transform.GetChild(preventDeformation).name == "PreventDeformedObject") { findModelWithDeformationProtection(); } else { findModelWithoutDeformationProtection(); } base.Start(); }
public bool TestMovingAABB(AABB3D b0, Vector3 d, float time0, float time1, AABB3D b1, ref float time) { float mid = (time0 + time1) * 0.5f; float midTest = mid - time0; Vector3 adjustedD = d * mid; //Debug.Log("Time tested: " + centerTest); b.Center = b0.Center + adjustedD; b.HalfWidths[0] = midTest * d.magnitude + b0.HalfWidth; b.HalfWidths[1] = midTest * d.magnitude + b0.HalfHeight; b.HalfWidths[2] = midTest * d.magnitude + b0.HalfDepth; //b = new AABB3D(b0.Center + adjustedD, midTest * d.magnitude // + (b0.HalfWidth * 2), midTest * d.magnitude // + (b0.HalfHeight * 2), midTest * d.magnitude // + (b0.HalfDepth * 2)); //Debug.Log(b); //intervalHalvedRects.Add(b); //b0.DrawBoundingBox(Color.green); //foreach (var rects in intervalHalvedRects) //{ // rects.DrawBoundingBox(Color.red); //} if (!aabbIntersection.Intersect(b, b1)) return false; if (time1 - time0 < 0.1f) { normalCollision(b, b0, b1); time = time0; return true; } if (TestMovingAABB(b0, d, time0, mid, b1, ref time)) return true; return TestMovingAABB(b0, d, mid, time1, b1, ref time); }
private void resetNormals(AABB3D checkedObject) { for (int i = 0; i < checkedObject.NormalCollision.Length; i++) { checkedObject.NormalCollision[i] = Vector3.zero; } }
public void UpdateAABB(AABB3D a, float[][] m, Vector3 t, ref AABB3D b) { Vector3 modify = b.Center; modify.x = t.x; modify.y = t.y; modify.z = t.z; b.HalfHeight = 0.0f; b.HalfWidth = 0.0f; b.HalfDepth = 0.0f; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (i == 0) { if(j == 0) { modify.x += m[i][j] * a.Center.x; b.HalfWidth += Math.Abs(m[i][j]) * a.HalfWidth; } else if (j == 1) { modify.x += m[i][j]*a.center.y; b.HalfWidth += Math.Abs(m[i][j]) * a.HalfHeight; } else if (j == 2) { modify.x += m[i][j]*a.center.z; b.HalfWidth += Math.Abs(m[i][j])*a.HalfDepth; } } else if (i == 1) { if(j == 0) { modify.y += m[i][j] * a.Center.x; b.HalfHeight += Math.Abs(m[i][j]) * a.HalfWidth; } else if(j == 1) { modify.y += m[i][j] * a.Center.y; b.HalfHeight += Math.Abs(m[i][j]) * a.HalfHeight; } else if (j == 2) { modify.y += m[i][j]*a.Center.z; b.HalfHeight += Math.Abs(m[i][j])*a.HalfDepth; } } else if (i == 2) { if (j == 0) { modify.z += m[i][j]*a.Center.x; b.HalfDepth += Math.Abs(m[i][j])*a.HalfWidth; } else if (j == 1) { modify.z += m[i][j]*a.Center.y; b.HalfDepth += Math.Abs(m[i][j])*a.HalfHeight; } else if (j == 2) { modify.z += m[i][j]*a.Center.z; b.HalfDepth += Math.Abs(m[i][j])*a.HalfDepth; } } } } b.Center = modify; }
public void CLosestPointptAABB(Vector3 p, AABB3D b, ref Vector3 q) { for (int i = 0; i < 3; i++) { float v = p[i]; if (v < b.HalfWidths[i]*2) v = b.Center[i] - b.HalfWidths[i]; if (v > b.HalfWidths[i]*2) v = b.Center[i] + b.HalfWidths[i]; q[i] = v; } }
public void CalculateNormal(AABB3D collided) { }
public AABB3D AdjustForHitTime(AABB3D movingBox, Vector3 velocity, float hitTime) { //hitTime = 1.0f - clamp(hitTime - float.Epsilon, 0f, 1f); Vector3 adjustedCenter = movingBox.Center + (velocity*hitTime); float width = (movingBox.HalfWidth*2) + (velocity.x*hitTime); float height = (movingBox.HalfHeight * 2) + (velocity.y * hitTime); float depth = (movingBox.HalfDepth*2) + (velocity.z*hitTime); AABB3D test = new AABB3D(adjustedCenter, width, height, depth); //Vector3 direction = velocity; //direction.Normalize(); //test.Center += new Vector3(direction.x * test.HalfWidth, direction.y * test.HalfHeight, // direction.z * test.HalfDepth); if (hitTime < 1.0f) { Debug.Log("---------------" + hitTime); } test.DrawBoundingBox(Color.blue); //if (Velocity != Vector3.zero) //{ // Debug.Log("Center hit point: " + test.center.ToString()); // Debug.Log("Actual Center: " + center.ToString()); //} return test; }
private void GroundCollision() { quicksort(unitPhysicsMediators, 0, unitPhysicsMediators.Length - 1); float hitTime = 0f; for (int k = 0; k < unitPhysicsMediators.Length; k++) { try { unitPhysicsMediators[k].UpdateVelocity(gravity); playerBoundingBox = unitPhysicsMediators[k].BoundingBox; } catch (MissingReferenceException e) { Debug.Log("Test"); throw e; } for (int i = 0; i < groundsArray.Length; i++) { groundBoundingBox = groundsArray[i].BoundingBox; var groundMin = groundBoundingBox.Center - new Vector3(groundBoundingBox.HalfWidth, groundBoundingBox.HalfHeight); var unitMax = playerBoundingBox.Center + new Vector3(playerBoundingBox.HalfWidth, playerBoundingBox.HalfHeight) + playerBoundingBox.Velocity * Time.deltaTime; if (groundMin.x > unitMax.x) { break; } if (aabbIntersection.Intersect(playerBoundingBox, groundBoundingBox)) { var penetrationVector = playerBoundingBox.Center - groundBoundingBox.Center; unitPhysicsMediators[k].UpdateVelocity(Vector3.up * penetrationVector.y - gravity); } else if (sweep.TestMovingAABB(playerBoundingBox, playerBoundingBox.Velocity * Time.deltaTime, 0f, 1f, groundBoundingBox, ref hitTime)) { float actualHittime = 1.0f - hitTime; if (playerBoundingBox.NormalCollision[0].x > 0.0f) { velocity.x = playerBoundingBox.Velocity.x; velocity.y = 0.0f; velocity.z = 0.0f; unitPhysicsMediators[k].UpdateVelocity(-velocity * actualHittime); } else if (playerBoundingBox.NormalCollision[0].x < 0.0f) { velocity.x = playerBoundingBox.Velocity.x; velocity.y = 0.0f; velocity.z = 0.0f; unitPhysicsMediators[k].UpdateVelocity(-velocity * actualHittime); } // TODO find out if better way for avoiding getting caught in platforms if (playerBoundingBox.NormalCollision[1].y < 0.0f && playerBoundingBox.Velocity.y < 0.0f) { velocity.x = 0.0f; velocity.y = playerBoundingBox.Velocity.y; velocity.z = 0.0f; unitPhysicsMediators[k].UpdateVelocity(-velocity * actualHittime); } } else if (unitPhysicsMediators[k] is Player && unitPhysicsMediators[k].velocity.y < Vector3.zero.y && (unitPhysicsMediators[k] as Player).TouchGroundFrameCount > 2) { (unitPhysicsMediators[k] as Player).TouchGroundFrameCount = 0; } } try { unitPhysicsMediators[k].UpdatePosition(); unitPhysicsMediators[k].ResetVelocity(); } catch (MissingReferenceException e) { throw e; } } }
private int findPosition(PhysicsMediator[] ground, AABB3D movable) { for (int i = 0; i < ground.Length; i++) { if (ground[i].BoundingBox.Center.x > movable.Center.x) { Debug.Log(i); return i; } } Debug.Log(0); return 0; }
private int compareAABBS(PhysicsMediator left, PhysicsMediator right) { float leftMin = 0f; float rightMin = 0f; if(left == null) { return 1; } else if( right == null) { return -1; } else { a = left.BoundingBox; b = right.BoundingBox; leftMin = a.Center.x - a.HalfWidth; rightMin = b.Center.x - b.HalfWidth; } if (leftMin < rightMin) return -1; if (leftMin > rightMin) return 1; return 0; }