Processing Model -- use Ray-traced for Collision Detection on small and fast objects

Source: Internet
Author: User
Problem

Most collision detection methods only detect two objects in the event of physical collisions. However, if one small object quickly passes through another object, YourProgramThe update speed may not be able to keep up with and the collision cannot be detected.

For example, a bullet in a bottle. A bullet shoots at a speed of 5000 km/h to a bottle, and the width of the bottle is only 15 cm. The xNa program updates 60 times per second, so each update of the bullet will move forward to a distance of 23 meters. In this case, the collision between the bullet and the bottle is almost impossible to detect when the update method is called, even if the last bullet does pass through the bottle.

Solution

You can create a ray between the last position of the bullet and the current position. Then, we call Ray or intersect to check whether Ray is in conflict with the ball. If a collision occurs, this method returns the distance between the collision point and the ray end point (you can use the previous position of the bullet ).

You can use this distance to check whether a collision has occurred between the previous position of the bullet and the current position.

Working Principle

This method needs to be stored in the global sphere of the model tag attribute, as shown in tutorial 4-5:

 
Mymodel = xnautils. loadmodelwithboundingsphere (ref modeltransforms, "tank", content );

You will create a method that takes the model, the world matrix of the model, and the previous position and current position of the fast object as the parameter.

Private bool raycollision (model, Matrix world, vector3 lastposition, vector3 currentposition) {boundingsphere modelspere = (boundingsphere) model. Tag; boundingsphere transsphere = transformboundingsphere (modelspere, world );}

First, you need to move the sphere of the model to the current position of the model in 3D space. This step can be done by converting the sphere of the world matrix of the model (as explained in the previous tutorial ). Note: If you want to scale the model in advance, you also need to combine the zoom matrix into the world matrix so that the previousCodeCorrectly scale the surround ball.

Next, find the motion direction of the fast object and the distance since the last frame:

 
Vector3 direction = currentposition-lastposition; float distancecovered = direction. Length (); direction. normalize ();

You can subtract B from A to get A to B, and call the length method in this direction to get the distance between the two. For the direction, you usually need to normalize it to 1. Therefore, you need to normalize the length after it is stored, otherwise the distance will always be 1.

Now we can create a ray with a dot and its direction. You will use the intersect method of this Ray to detect the collision between the ball surrounded by the slow model.

 
Ray = new ray (lastposition, direction );

Now with Ray, you are ready to complete this method:

Bool collision = false; float? Intersection = Ray. intersects (transsphere); If (intersection! = NULL) if (intersection <= distancecovered) collision = true; return collision;

First define a collision variable, which will remain false unless a collision occurs. This variable will be returned at the end of the method.

Call Ray's intersect method and pass it to the transformed sphere of the model.

The intersection method is a bit special. If a collision occurs, this method returns the distance between the collision point and the point used to define the ray. However, if Ray does not collide with the ball, this method returns NULL. So you need a float? Variable instead of float, because it needs to be able to store null values.

Note:If the collision point is after the ray point, this method returns NULL. Because you specified the direction when creating the ray, xNa knows which side of the ray is before or after this point.

If a collision occurs between Ray and the ball surround and the collision point is before the final position point, the intersection is not null. To verify whether a collision occurs between two frames, you need to check whether the distance between the collision point and the previous point of the fast object is smaller than the distance between the object's motion in the previous frame. If yes, a collision occurs.

More accurate method

As explained in the previous tutorial, because the ball is surrounded, this method may detect a collision even if there is no collision. So again, you can improve the accuracy by performing Ray and ball Collision Detection on small ball surrounded by different modelmesh models.

Large and fast objects

The collision detection method described earlier requires that fast objects be very small, similar to a point in 3D space. However, when a fast object cannot be regarded as a point, you need to regard it as a ball. One solution is to perform multiple Ray checks based on different points on the fast object, but this is more complicated.

A quick and simpler method is to add the radius of a fast object to the radius of a slow object, as shown in Figure 4-15. This figure shows the collision edge of two objects. If you add a small radius to a large radius, the result is the same. Using this method, you can use a simple vertex to represent a fast object and use the same collision detection method as before.

Figure 4-15 increase the surround ball to get the same result.

Code

After loading the slow model, you need to store the ball in the tag attribute:

 
Protected override void loadcontent () {Device = graphics. graphicsdevice; basiceffect = new basiceffect (device, null); ccross = new coordcross (device); mymodel = xnautils. loadmodelwithboundingsphere (ref modeltransforms, "tank", content );}

With the ball enclosed, you can call the following method to check whether a collision occurs during the last frame:

 private bool raycollision (model, Matrix world, vector3 lastposition, vector3 currentposition) {boundingsphere modelspere = (boundingsphere) model. tag; boundingsphere transsphere = xnautils. transformboundingsphere (modelspere, world); vector3 direction = currentposition-lastposition; float distancecovered = direction. length (); direction. normalize (); Ray = new ray (lastposition, direct Ion); bool collision = false; float? Intersection = Ray. intersects (transsphere); If (intersection! = NULL) if (intersection <= distancecovered) collision = true; return collision ;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.