public void CopyTo(ref CollisionResult target) { target.distance = this.distance; target.collideCount = this.collideCount; target.detectedCollide = this.detectedCollide; target.intersect = this.intersect; target.normal = this.normal; }
/// <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 two collision boxes. /// </summary> /// <param name="sourceCollide">Source collision box</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 TestBoxintersectBox(CollideBox sourceCollide, CollideBox targetCollide, ref CollisionResult result) { totalCollidingCount++; // // Test two boxes if (sourceCollide.BoundingBox.Intersects(targetCollide.BoundingBox)) { if (result != null) { Vector3 centerSourceBox = 0.5f * (sourceCollide.BoundingBox.Max + sourceCollide.BoundingBox.Min); Vector3 centerTargetBox = 0.5f * (targetCollide.BoundingBox.Max + targetCollide.BoundingBox.Min); result.distance = (float)Vector3.Distance(centerSourceBox, centerTargetBox); 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 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 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> /// 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 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; }