/// <summary> /// It checks for the collision between a collision ray and a collision sphere. /// </summary> /// <param name="sourceCollide">Source collision ray</param> /// <param name="targetCollide">Target collision sphere</param> /// <param name="result">A result report</param> /// <returns>True if there is a collision</returns> public bool TestRayintersectSphere(CollideRay sourceCollide, CollideSphere targetCollide, ref CollisionResult result) { totalCollidingCount++; // Test ray with the sphere float?distance = sourceCollide.Ray.Intersects(targetCollide.BoundingSphere); if (distance != null) { if (result != null) { Vector3 dir = Vector3.Normalize(sourceCollide.Ray.Position - targetCollide.BoundingSphere.Center); Vector3 length = dir * targetCollide.Radius; result.distance = (float)distance; result.detectedCollide = targetCollide; result.intersect = targetCollide.BoundingSphere.Center + length; result.normal = null; result.collideCount++; } return(true); } return(false); }
/// <summary> /// It checks for the collision between a collision ray and a collision box. /// </summary> /// <param name="sourceCollide">Source collision ray</param> /// <param name="targetCollide">Target collision box</param> /// <param name="result">A result report</param> /// <returns>True if there is a collision</returns> public bool TestRayintersectBox(CollideRay sourceCollide, CollideBox targetCollide, ref CollisionResult result) { totalCollidingCount++; // Test ray with the box float?distance = sourceCollide.Ray.Intersects(targetCollide.BoundingBox); if (distance != null) { if (result != null) { result.distance = (float)distance; result.detectedCollide = targetCollide; result.intersect = null; result.normal = null; result.collideCount++; } return(true); } return(false); }
/// <summary> /// It checks for the collision between a collision ray and a collision model. /// </summary> /// <param name="sourceCollide">Source collision ray</param> /// <param name="targetCollide">Target collision model</param> /// <param name="result">A result report</param> /// <returns>True if there is a collision</returns> public bool TestRayintersectModel(CollideRay sourceCollide, CollideModel targetCollide, ref CollisionResult result) { Vector3 intersect; Vector3 normal; float distance; // use quad tree. if (targetCollide.QuadTree != null) { if (TestUsingQuadTree((CollideElement)sourceCollide, targetCollide.QuadTree.RootNode, out intersect, out normal, out distance)) { result.detectedCollide = targetCollide; result.intersect = intersect; result.normal = normal; result.distance = distance; result.collideCount++; return(true); } } // Test ray with the model else { if (TestRayintersectModel(sourceCollide.Ray, targetCollide.Vertices, targetCollide.TransformMatrix, out intersect, out normal, out distance)) { result.distance = distance; result.detectedCollide = targetCollide; result.intersect = intersect; result.normal = normal; result.collideCount++; } } return(false); }
/// <summary> /// checks contaning. /// </summary> public bool Contains(ref CollideElement bounds) { if (bounds is CollideBox) { CollideBox target = bounds as CollideBox; return(containBox.Intersects(target.BoundingBox)); } else if (bounds is CollideSphere) { CollideSphere target = bounds as CollideSphere; return(containBox.Intersects(target.BoundingSphere)); } else if (bounds is CollideRay) { CollideRay target = bounds as CollideRay; return(containBox.Intersects(target.Ray) != null); } return(false); }
protected bool TestUsingQuadTree(CollideElement sourceCollide, QuadNode quadNode, out Vector3 intersect, out Vector3 normal, out float distance) { bool result = false; float tempDistance = 0.0f; Vector3 tempIntersect = Vector3.Zero; Vector3 tempNormal = Vector3.Zero; float closestDistance = float.MaxValue; Vector3 closestIntersection = Vector3.Zero; Vector3 closestNormal = Vector3.Zero; distance = 0.0f; intersect = Vector3.Zero; normal = Vector3.Zero; // checks upper left node. if (quadNode.UpperLeftNode != null) { if (TestUsingQuadTree(sourceCollide, quadNode.UpperLeftNode, out tempIntersect, out tempNormal, out tempDistance)) { result = true; // checks closest if (closestDistance > tempDistance) { closestDistance = tempDistance; closestIntersection = tempIntersect; closestNormal = tempNormal; } } } // checks upper right node. if (quadNode.UpperRightNode != null) { if (TestUsingQuadTree(sourceCollide, quadNode.UpperRightNode, out tempIntersect, out tempNormal, out tempDistance)) { result = true; // checks closest if (closestDistance > tempDistance) { closestDistance = tempDistance; closestIntersection = tempIntersect; closestNormal = tempNormal; } } } // checks lower left node. if (quadNode.LowerLeftNode != null) { if (TestUsingQuadTree(sourceCollide, quadNode.LowerLeftNode, out tempIntersect, out tempNormal, out tempDistance)) { result = true; // checks closest if (closestDistance > tempDistance) { closestDistance = tempDistance; closestIntersection = tempIntersect; closestNormal = tempNormal; } } } // checks lower right node. if (quadNode.LowerRightNode != null) { if (TestUsingQuadTree(sourceCollide, quadNode.LowerRightNode, out tempIntersect, out tempNormal, out tempDistance)) { result = true; // checks closest if (closestDistance > tempDistance) { closestDistance = tempDistance; closestIntersection = tempIntersect; closestNormal = tempNormal; } } } // checks vertices in quad node. if (quadNode.Contains(ref sourceCollide)) { // checks vertices with bounding sphere. if (sourceCollide is CollideSphere) { CollideSphere collide = sourceCollide as CollideSphere; // Hit test sphere with the model BoundingSphere sphere = collide.BoundingSphere; if (quadNode.Vertices != null) { if (TestSphereintersectModel(sphere, quadNode.Vertices, Matrix.Identity, out tempIntersect, out tempNormal, out tempDistance)) { result = true; // checks closest if (closestDistance > tempDistance) { closestDistance = tempDistance; closestIntersection = tempIntersect; closestNormal = tempNormal; } } } } // checks vertices with ray. else if (sourceCollide is CollideRay) { CollideRay collide = sourceCollide as CollideRay; if (quadNode.Vertices != null) { if (TestRayintersectModel(collide.Ray, quadNode.Vertices, Matrix.Identity, out tempIntersect, out tempNormal, out tempDistance)) { result = true; // checks closest if (closestDistance > tempDistance) { closestDistance = tempDistance; closestIntersection = tempIntersect; closestNormal = tempNormal; } } } } } // resolve final result. if (result) { distance = closestDistance; intersect = closestIntersection; normal = closestNormal; } return(result); }
/// <summary> /// It tests for collision among the collision elements which /// have been registered to the collision layer and returns the result. /// </summary> /// <param name="collide">Source collsion element</param> /// <param name="targetLayer">Target collison layer</param> /// <param name="resultType">type of result</param> /// <returns>A result report</returns> public CollisionResult HitTest(CollideElement collide, ref CollisionLayer targetLayer, ResultType resultType) { CollisionResult result = null; tempResult.Clear(); totalCollidingCount = 0; if (activeOn == false) { return(null); } if (collide == null) { throw new ArgumentNullException("collide"); } if (targetLayer == null) { throw new ArgumentNullException("targetLayer"); } // checking all collisions in current collision layer for (int i = 0; i < targetLayer.CollideCount; i++) { CollideElement targetCollide = targetLayer.GetCollide(i); // Skip ifself if (collide.Equals(targetCollide)) { continue; } else if (collide.Id != 0 && targetCollide.Id != 0) { if (collide.Id == targetCollide.Id) { continue; } } // If source collision is BoundingSphere if (collide is CollideSphere) { CollideSphere sourceCollideSphere = collide as CollideSphere; // Test with target sphere if (targetCollide is CollideSphere) { CollideSphere targetCollideSphere = targetCollide as CollideSphere; TestSphereintersectSphere(sourceCollideSphere, targetCollideSphere, ref tempResult); } // Test with target model else if (targetCollide is CollideModel) { CollideModel targetCollideModel = targetCollide as CollideModel; TestSphereintersectModel(sourceCollideSphere, targetCollideModel, ref tempResult); } // Test with target box else if (targetCollide is CollideBox) { CollideBox targetCollideBox = targetCollide as CollideBox; TestSphereintersectBox(sourceCollideSphere, targetCollideBox, ref tempResult); } // Test with target ray if (targetCollide is CollideRay) { CollideRay targetCollideRay = targetCollide as CollideRay; TestRayintersectSphere(targetCollideRay, sourceCollideSphere, ref tempResult); } } // If source collision is Ray else if (collide is CollideRay) { CollideRay sourceCollideRay = collide as CollideRay; // Test with target model if (targetCollide is CollideModel) { CollideModel targetCollideModel = targetCollide as CollideModel; TestRayintersectModel(sourceCollideRay, targetCollideModel, ref tempResult); } // Test with target sphere else if (targetCollide is CollideSphere) { CollideSphere targetCollideSphere = targetCollide as CollideSphere; TestRayintersectSphere(sourceCollideRay, targetCollideSphere, ref tempResult); } // Test with target box else if (targetCollide is CollideBox) { CollideBox targetCollideBox = targetCollide as CollideBox; TestRayintersectBox(sourceCollideRay, targetCollideBox, ref tempResult); } } // If source collision is Ray else if (collide is CollideBox) { CollideBox sourceCollideBox = collide as CollideBox; // Test with target sphere if (targetCollide is CollideSphere) { CollideSphere targetCollideSphere = targetCollide as CollideSphere; TestSphereintersectBox(targetCollideSphere, sourceCollideBox, ref tempResult); } // Test with target box else if (targetCollide is CollideBox) { CollideBox targetCollideBox = targetCollide as CollideBox; TestBoxintersectBox(sourceCollideBox, targetCollideBox, ref tempResult); } // Test with target ray else if (targetCollide is CollideRay) { CollideRay targetCollideRay = targetCollide as CollideRay; TestRayintersectBox(targetCollideRay, sourceCollideBox, ref tempResult); } } // To find the nearest detected collision. if (resultType == ResultType.NearestOne) { if (tempResult.collideCount > 0) { if (result == null) { result = new CollisionResult(); result.distance = float.MaxValue; } if (result.distance > tempResult.distance) { tempResult.CopyTo(ref result); } } } } return(result); }
/// <summary> /// It checks for the collision between a collision ray and a collision sphere. /// </summary> /// <param name="sourceCollide">Source collision ray</param> /// <param name="targetCollide">Target collision sphere</param> /// <param name="result">A result report</param> /// <returns>True if there is a collision</returns> public bool TestRayintersectSphere(CollideRay sourceCollide, CollideSphere targetCollide, ref CollisionResult result) { totalCollidingCount++; // Test ray with the sphere float? distance = sourceCollide.Ray.Intersects(targetCollide.BoundingSphere); if (distance != null) { if (result != null) { Vector3 dir = Vector3.Normalize(sourceCollide.Ray.Position - targetCollide.BoundingSphere.Center); Vector3 length = dir * targetCollide.Radius; result.distance = (float)distance; result.detectedCollide = targetCollide; result.intersect = targetCollide.BoundingSphere.Center + length; result.normal = null; result.collideCount++; } return true; } return false; }
/// <summary> /// It checks for the collision between a collision ray and a collision box. /// </summary> /// <param name="sourceCollide">Source collision ray</param> /// <param name="targetCollide">Target collision box</param> /// <param name="result">A result report</param> /// <returns>True if there is a collision</returns> public bool TestRayintersectBox(CollideRay sourceCollide, CollideBox targetCollide, ref CollisionResult result) { totalCollidingCount++; // Test ray with the box float? distance = sourceCollide.Ray.Intersects(targetCollide.BoundingBox); if (distance != null) { if (result != null) { result.distance = (float)distance; result.detectedCollide = targetCollide; result.intersect = null; result.normal = null; result.collideCount++; } return true; } return false; }
/// <summary> /// It checks for the collision between a collision ray and a collision model. /// </summary> /// <param name="sourceCollide">Source collision ray</param> /// <param name="targetCollide">Target collision model</param> /// <param name="result">A result report</param> /// <returns>True if there is a collision</returns> public bool TestRayintersectModel(CollideRay sourceCollide, CollideModel targetCollide, ref CollisionResult result) { Vector3 intersect; Vector3 normal; float distance; // use quad tree. if (targetCollide.QuadTree != null) { if( TestUsingQuadTree((CollideElement)sourceCollide, targetCollide.QuadTree.RootNode, out intersect, out normal, out distance)) { result.detectedCollide = targetCollide; result.intersect = intersect; result.normal = normal; result.distance = distance; result.collideCount++; return true; } } // Test ray with the model else { if( TestRayintersectModel(sourceCollide.Ray, targetCollide.Vertices, targetCollide.TransformMatrix, out intersect, out normal, out distance)) { result.distance = distance; result.detectedCollide = targetCollide; result.intersect = intersect; result.normal = normal; result.collideCount++; } } return false; }
/// <summary> /// checks for collision between the 3rd view camera, /// which follows the player moving, and the world. /// </summary> public void CheckCollisionCamera() { CollideSphere playerSphere = Collide as CollideSphere; if ((FrameworkCore.CurrentCamera.FirstCamera is FollowCamera) == false) return; // Check collison of the follow camera ViewCamera viewCamera = FrameworkCore.CurrentCamera; FollowCamera camera = null; switch (this.PlayerIndex) { case PlayerIndex.One: camera = viewCamera.GetCamera(0) as FollowCamera; break; case PlayerIndex.Two: camera = viewCamera.GetCamera(1) as FollowCamera; break; case PlayerIndex.Three: camera = viewCamera.GetCamera(2) as FollowCamera; break; case PlayerIndex.Four: camera = viewCamera.GetCamera(3) as FollowCamera; break; } // Default setting offset Vector3 followCameraOffset = SpecData.CameraPositionOffset; float distanceBetweenCamera = Math.Abs(Vector3.Distance(Vector3.Zero, followCameraOffset)); CollisionResult finalResult, leftResult, rightResult; finalResult = leftResult = rightResult = null; // Booster camera if (this.isActiveBooster && this.isDelayBooster == false) { followCameraOffset.Z *= 1.5f; } Vector3 start = camera.Target; Vector3 dir = camera.Position - start; dir.Normalize(); // check to left side of camera { CollideRay simulateRay = new CollideRay(start - camera.Right, dir); // check collison with world leftResult = FrameworkCore.CollisionContext.HitTest( simulateRay, ref colLayerMoveWorld, ResultType.NearestOne); } // check to right side of camera { CollideRay simulateRay = new CollideRay(start + camera.Right, dir); // check collison with world rightResult = FrameworkCore.CollisionContext.HitTest( simulateRay, ref colLayerMoveWorld, ResultType.NearestOne); } if (leftResult != null && rightResult != null) { if( leftResult.distance < rightResult.distance) finalResult = leftResult; else finalResult = rightResult; } else if (leftResult != null) { finalResult = leftResult; } else if (rightResult != null) { finalResult = rightResult; } if (finalResult != null) { // The camera collided behind player with world if (finalResult.distance < distanceBetweenCamera) { float distance = finalResult.distance; if (finalResult.distance < playerSphere.Radius) distance = playerSphere.Radius; // Change camera position camera.PositionOffset = new Vector3( 0.0f, followCameraOffset.Y * (distance / distanceBetweenCamera), -distance); } else { camera.PositionOffset = followCameraOffset; } } else { camera.PositionOffset = followCameraOffset; } }
/// <summary> /// checks for the weapon firing collision. /// When collision check succeeds, returns a result report. /// If not, returns null. /// </summary> /// <param name="position">the start position of firing</param> /// <param name="direction">the direction of firing</param> /// <param name="distance">the range of firing</param> /// <param name="targetCollisionLayer">target collision layer</param> /// <param name="worldCollisionLayer">world collision layer</param> /// <returns>result report</returns> protected static CollisionResult FireHitTest(Vector3 position, Vector3 direction, float distance, ref CollisionLayer targetCollisionLayer, ref CollisionLayer worldCollisionLayer) { bool doHit = false; CollideRay collideRay = new CollideRay(position, direction); // checks with enemies. CollisionResult fireResult = FrameworkCore.CollisionContext.HitTest( collideRay, ref targetCollisionLayer, ResultType.NearestOne); if (fireResult != null) { if (fireResult.distance <= distance) { // Hit unit doHit = true; } } // checks with world. CollisionResult worldResult = FrameworkCore.CollisionContext.HitTest( collideRay, ref worldCollisionLayer, ResultType.NearestOne); if (worldResult != null) { // Hit world if (worldResult.distance <= distance) { if (doHit) { // closer world if (worldResult.distance < fireResult.distance) { return worldResult; } } else { return worldResult; } } } if (doHit) { return fireResult; } return null; }
public CollisionResult HitTestWithWorld(Vector3 start, Vector3 direction) { CollideRay simulateRay = new CollideRay(start, direction); simulateRay.Id = Collide.Id; // Test collision CollisionResult result = FrameworkCore.CollisionContext.HitTest(simulateRay, ref colLayerMoveWorld, ResultType.NearestOne); return result; }
public CollisionResult MoveHitTestWithWorld(Vector3 velocityAmount) { CollideSphere playerSphere = Collide as CollideSphere; float radius = playerSphere.Radius; // calculate simulated position for collision. Matrix transformSimulate = TransformedMatrix * Matrix.CreateTranslation(velocityAmount); // first, check using sphere. { CollideSphere simulateSphere = new CollideSphere(playerSphere.LocalCenter, radius); simulateSphere.Transform(transformSimulate); simulateSphere.Id = playerSphere.Id; CollisionResult result = FrameworkCore.CollisionContext.HitTest( simulateSphere, ref colLayerMoveWorld, ResultType.NearestOne); if (result != null) { return result; } } // second, check using ray. { Vector3 direction = velocityAmount; direction.Normalize(); CollideRay simulateRay = new CollideRay(playerSphere.BoundingSphere.Center, direction); simulateRay.Id = playerSphere.Id; CollisionResult result = FrameworkCore.CollisionContext.HitTest( simulateRay, ref colLayerMoveWorld, ResultType.NearestOne); if (result != null) { if (result.distance <= radius) return result; } } return null; }