/// <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 two collision spheres. /// </summary> /// <param name="sourceCollide">Source collision sphere</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 TestSphereintersectSphere(CollideSphere sourceCollide, CollideSphere targetCollide, ref CollisionResult result) { totalCollidingCount++; // Test sphere with the other sphere if (sourceCollide.BoundingSphere.Intersects(targetCollide.BoundingSphere)) { if (result != null) { float twoSphereDistance = Vector3.Distance( targetCollide.BoundingSphere.Center, sourceCollide.BoundingSphere.Center); Vector3 twoSphereDirection = Vector3.Normalize( targetCollide.BoundingSphere.Center - sourceCollide.BoundingSphere.Center); result.distance = Math.Abs(twoSphereDistance) - (sourceCollide.Radius + targetCollide.Radius); result.detectedCollide = targetCollide; result.intersect = twoSphereDirection * result.distance; result.collideCount++; } return(true); } return(false); }
/// <summary> /// It checks for the collision between a collision sphere 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 TestSphereintersectBox(CollideSphere sourceCollide, CollideBox targetCollide, ref CollisionResult result) { totalCollidingCount++; // Test sphere with the box if (sourceCollide.BoundingSphere.Intersects(targetCollide.BoundingBox)) { if (result != null) { Vector3 centerBox = 0.5f * (targetCollide.BoundingBox.Max + targetCollide.BoundingBox.Min); result.distance = (float)Vector3.Distance( sourceCollide.BoundingSphere.Center, centerBox) - sourceCollide.BoundingSphere.Radius; result.detectedCollide = targetCollide; result.intersect = null; result.normal = null; result.collideCount++; } return(true); } return(false); }
/// <summary> /// It checks for the collision between a collision sphere and a collision model. /// </summary> /// <param name="sourceCollide">Source collision sphere</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 TestSphereintersectModel(CollideSphere sourceCollide, CollideModel targetCollide, ref CollisionResult result) { Vector3 intersect; Vector3 normal; float distance; BoundingSphere sphere = sourceCollide.BoundingSphere; // 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); } } // Hit test sphere with the model else { if (TestSphereintersectModel(sphere, targetCollide.Vertices, targetCollide.TransformMatrix, out intersect, out normal, out distance)) { result.detectedCollide = targetCollide; result.intersect = intersect; result.normal = normal; result.distance = distance; result.collideCount++; return(true); } } 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 sphere 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 TestSphereintersectBox(CollideSphere sourceCollide, CollideBox targetCollide, ref CollisionResult result) { totalCollidingCount++; // Test sphere with the box if (sourceCollide.BoundingSphere.Intersects(targetCollide.BoundingBox)) { if (result != null) { Vector3 centerBox = 0.5f * (targetCollide.BoundingBox.Max + targetCollide.BoundingBox.Min); result.distance = (float)Vector3.Distance( sourceCollide.BoundingSphere.Center, centerBox) - sourceCollide.BoundingSphere.Radius; result.detectedCollide = targetCollide; result.intersect = null; result.normal = null; result.collideCount++; } return true; } return false; }
/// <summary> /// It checks for the collision between a collision sphere and a collision model. /// </summary> /// <param name="sourceCollide">Source collision sphere</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 TestSphereintersectModel(CollideSphere sourceCollide, CollideModel targetCollide, ref CollisionResult result) { Vector3 intersect; Vector3 normal; float distance; BoundingSphere sphere = sourceCollide.BoundingSphere; // 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; } } // Hit test sphere with the model else { if( TestSphereintersectModel(sphere, targetCollide.Vertices, targetCollide.TransformMatrix, out intersect, out normal, out distance)) { result.detectedCollide = targetCollide; result.intersect = intersect; result.normal = normal; result.distance = distance; result.collideCount++; return true; } } return false; }
/// <summary> /// It checks for the collision between two collision spheres. /// </summary> /// <param name="sourceCollide">Source collision sphere</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 TestSphereintersectSphere(CollideSphere sourceCollide, CollideSphere targetCollide, ref CollisionResult result) { totalCollidingCount++; // Test sphere with the other sphere if (sourceCollide.BoundingSphere.Intersects(targetCollide.BoundingSphere)) { if (result != null) { float twoSphereDistance = Vector3.Distance( targetCollide.BoundingSphere.Center, sourceCollide.BoundingSphere.Center); Vector3 twoSphereDirection = Vector3.Normalize( targetCollide.BoundingSphere.Center - sourceCollide.BoundingSphere.Center); result.distance = Math.Abs(twoSphereDistance) - (sourceCollide.Radius + targetCollide.Radius); result.detectedCollide = targetCollide; result.intersect = twoSphereDirection * result.distance; result.collideCount++; } return true; } return false; }
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; }
public CollisionResult MoveHitTestWithItem(Vector3 velocityAmount) { CollideSphere playerSphere = Collide as CollideSphere; float radius = playerSphere.Radius; // creates simulation sphere for collision. Matrix transformSimulate = TransformedMatrix * Matrix.CreateTranslation(velocityAmount); CollideSphere sphereSimulate = new CollideSphere(playerSphere.LocalCenter, radius); sphereSimulate.Transform(transformSimulate); sphereSimulate.Id = playerSphere.Id; // checks for the collision with items. CollisionResult result = FrameworkCore.CollisionContext.HitTest( sphereSimulate, ref colLayerItems, ResultType.NearestOne); if (result != null) { if (0.0f >= result.distance) { return result; } } return null; }